【GAMES101】图形学学习记录——光栅化
【GAMES101】图形学学习记录——光栅化
我们想要显示的三维模型基本上都是由大量多边形(一般为三角形)组成的,而将这些三角形渲染在屏幕上的过程即为光栅化。
视锥
首先,我们要知道我们的屏幕的信息。
fovY:这是一个角度,表示观测点距离平面的竖直范围。
Aspect ratio:宽高比,字面意思,为平面宽和高的比值。
通过下面这张图,我们可以知道以上两个值和之前在投影部分所说物体的t、b、l、r等值的关系,具体如下:
屏幕
什么是屏幕?在这里,我们将其简单地认为屏幕由一组具有单个颜色的像素排列而成。
光栅化的过程即为决定每一个像素应该显示什么颜色的过程。
视口变换
在正交投影时,我们将物体转换到了一个(-1,1)^3的正则立方体中,而在视口变换中,我们要将其显示在我们的屏幕中。
做法为将立方体的XY平面拉伸为屏幕的宽高。
判断像素是否在三角形内
现在,我们已经将物体(即组成它的三角形)在屏幕上表示出来了,但是如何判断一个像素在不在某个三角形内,该不该被渲染呢?
将两个向量做叉积,可以得到新的向量,新的向量垂直于这两个向量,方向与这两个向量有关,例如在右手坐标系中:
用叉积判断像素是否在三角形内的方法如下图所示:
注意,这里我们用来判断的点是像素的中心。
如果一个点在三角形的边缘,我们可以自行决定这个点在三角形内部还是三角形外部。
优化:一个三角形的范围有限,将整个屏幕的像素都判断一遍较为浪费资源。因此,我们可以为每个三角形建立一个Bounding Box,只需要将Bounding Box内的像素比较。如图:
或者是按行或列建立的Bounding Box(适用于较为瘦长的三角形):
反走样
这部分内容涉及很多理论内容,技术内容较少,因此我将简略描述。(并不是因为我懒
当我们按照上面的方法进行三角形的光栅化后,我们会发现,得到的结果和我们想象中的差很多,边缘会有很多“锯齿”。对于这种现象,我们称之为走样。
走样的本质原因是采样的频率过低,采样的结果的高频部分混叠导致的信息丢失。我们可以砍掉三角形的高频信息,根据三角形在像素内的覆盖面积进行模糊,再进行采样。具体的实现方法是超采样。
超采样(Supersampling):我们可以人为地在像素内模拟出多个点,分别判断这些点是否在三角形内,最终整个像素的结果有这些点综合得出(需要注意的是,最终的结果并不是像素是否在三角形内,而是一个中间结果)。
超采样的结果示例:
如今工业界已经有了许多抗锯齿的手段,例如MSAA、FXAA、TAA。
深度缓冲(Z-buffering)
在光栅化的过程中,我们判断哪个物体被遮挡,哪个物体没有的方法是使用深度缓冲。深度缓冲记录了每一个像素的最小深度,即每个像素中离摄像机最近的z值。在进行渲染时,我们只需要渲染离摄像机最近的物体。