矩阵代数(二):秩与线性方程组
在本文中,我们主要研究秩的概念(矩阵的秩和向量组的秩),以及通过将线性方程组转化为矩阵的形式求解线性方程组。
矩阵代数(一):行列式与矩阵求逆
在本文中,我们主要研究矩阵的基本概念,行列式的概念和计算,矩阵的逆以及如何在矩阵不可逆的情况下求广义逆矩阵。
线性空间与线性变换概念浅析
在本文中,我们简单了解线性空间与线性变换的概念,并理解向量、矩阵和它们的关系。
数学分析初步(三):一元函数积分
在本文中,我们初识积分(不定积分,定积分),了解微积分学基本定理及相关应用。
数学分析初步(二):导数与微分
在本文中,我们研究导数和微分及其应用:微分中值定理,洛必达法则,泰勒公式,最后可以运用这些知识进行函数图像分析和求曲率。
数学分析初步(一):数与极限
在本文中,我们从最基本的实数和函数出发,了解极限,无穷小/大量,连续和一致连续这些数学分析的基础概念。
软光线追踪渲染器学习笔记(二):路径追踪与全局光照
Gamma矫正
Gamma矫正指的是:矫正由于计算机的显卡或者显示器的原因出现的源图像和实际输出的图像在亮度上的偏差的过程。通常而言,人眼对于外界亮度的感应并非是线性的,而CRT显示器模拟了这种非线性关系,从而在视觉上有比较好的效果,但是在程序中我们采用的线性RGB的计算关系,所以会导致实际输出的颜色产生偏差,通常会过暗,一般而言我们会采用以下方法进行修正:
RGBgamma=RGB12.2RGB_{gamma}=RGB^{\frac{1}{2.2}}\\
RGBgamma=RGB2.21
代码如下:
12const float gamma = 2.2f;Draw(x, y + startRow, Vector4f(powf(finalColor.x, 1.0f / gamma), powf(finalColor.y, 1.0f / gamma), powf(finalColor.z, 1.0f / gamma), powf(finalColor.w, 1.0f / gamma)));
渲染方程
渲染方程(The rendering equation)是James Kajiya在1 ...
软光线追踪渲染器学习笔记(一):Whitted-Style光线追踪
本文承接自软光栅化渲染器之后,参考Ray Tracing in One Weekend系列教程,GAMES101和众多大佬的文章梳理出的CPU光线追踪实现流程,仅作学习与记录。
摄像机与射线
Whitted-Style光线追踪的本质就是从摄像机处发出有限条射线,这些射线在穿过代表屏幕的近平面之后会与各种物体发生相交碰撞,之后射线可能会被反射或被折射,再与更多的物体发生相交碰撞,最后计算出每根射线代表的颜色值,这些颜色值即是应该显示在屏幕上的颜色值。
我们用直线方程 p(t)=a+tb⃗(t≥0)\boldsymbol{p}(t)=\boldsymbol{a}+t\vec{b}(t\geq0)p(t)=a+tb(t≥0) 来表示射线,通过一个在固定范围内可变的参量 ttt 就可以计算出射线经过的点,之后就可以用直线方程进行几何体求交,射线类Ray的代码如下:
1234567891011121314class Ray {public: Ray(){} Ray(const Vector3f& origin, const Vector3f& di ...
软光栅化渲染器学习笔记(三):细分几何
贝塞尔曲线
贝塞尔曲线(Bézier Curves) 是一种经典的多项式曲线模型,它提供了基于多个控制点(Control point)的曲线生成方法。Animated Bézier Curves - Jason Davies 用动画展现了贝塞尔曲线生成的过程,可以十分直观地了解这种优美的曲线背后的原理。
二次贝塞尔曲线
我们用三个控制点 p0,p1,p2\boldsymbol{p_0},\boldsymbol{p_1},\boldsymbol{p_2}p0,p1,p2 来生成最基础的二次贝塞尔曲线,首先可以在 p0\boldsymbol{p_0}p0 和 p1\boldsymbol{p_1}p1 , p1\boldsymbol{p_1}p1 和 p2\boldsymbol{p_2}p2 之间各自连一条直线,然后再直线上用相同的参量 t(0≤t≤1)t(0≤t≤1)t(0≤t≤1) 进行线性插值:
p01=(1−t)p0+tp1p11=(1−t)p1+tp2\boldsymbol{p_0^1}=(1-t)\boldsymbol{p_0}+t\boldsymbol{p_1} ...
软光栅化渲染器学习笔记(二):深入光栅化细节
深度缓冲
假如我们在场景中直接绘制一个立方体,那么它呈现出的样子会是这样的:
很显然,它并不符合正确的遮挡关系,而是后绘制出的会遮挡先绘制出的,为了实现正确的物体遮挡关系,也就是离摄像头近的遮挡离摄像头远的,我们需要一个深度缓冲区,也称作Z-Buffer。
原理:在每次绘制像素前将执行完透视除法后的z值与原本存储在Z-Buffer中同一位置的z值进行比较,如果小于(或等于)Z-Buffer中的z值,则深度测试通过,将新的z值写入,同时允许像素的绘制,反之不通过,像素被抛弃。
分配一块用于Z-Buffer的内存,并用于写入深度值及进行深度测试:
123456789101112float* zBuffer = new float[width * height];for (int i = 0; i < width * height; i++) { zBuffer[i] = FLT_MAX;}bool DepthTest(int x, int y, float z) { if (z <= zBuffer[y * width + x]) { ...