一、前言
经过上篇文章,大家已经了解了整个MVP变换的过程,但是正如我前篇所说,在完成了MVP变换之后,我们只是把3D场景变成二维图像的准备工作做完了,而如何把图像“画”在显示器上,还需要进一步的操作,也就是本文要讲解的光栅化。
二、屏幕映射
我们知道,经过MVP变换之后,我们已经把视锥体变成了一个标准的正则立方体,接下来我们还要进行最后一步变换,把图像变换至屏幕空间。
屏幕空间的定义:本质上是一个二维数组,而每个元素储存的是一个n元组,每个元组可储存颜色信息如:R、G、B的值或其它信息(如灰度),而每个元素对应着一个像素。同时定义其分辨率为width*height。如下图为一个4x3分辨率的屏幕。
同时定义每个像素的坐标为(width-1,height-1),例如上图蓝色的像素坐标为(2,1)。
则像素的中心的坐标为(x+0.5,y+0.5)。则整个屏幕覆盖范围从(0,0)到(width,height)。
那么如何将上节我们说的3维的边长为2的正则立方体变换成屏幕空间的二维图像呢?
学完基础的变换我们应该能很容易写出这个变换矩阵,这里不做赘述。如图:
三、光栅化
1.光栅化的定义:
我们知道所有模型都是由多边形组成的,而多边形的面数决定了模型的光滑程度,而组成模型的最基本图形是三角形,这些三角形的顶点在经过变换投影到屏幕上后仍然为三角形,而通过知道这些三角形覆盖了哪些像素从而在屏幕上采样,进而画出一张该模型二为图像的过程就称作光栅化。
2.三角形的优点:
为什么要用三角形?因为它有很多优点。
首先三角形是最基础的多边形。
其次任何多边形都可以拆成三角形。
且三角形的三个点可以直接确定一个平面。
点在三角形的内外关系可以通过叉积也就是cross清楚的知道。
只要知道了三角形的三个点的顶点属性,就可以通过插值计算出三角形内所有点的属性。
如上图是一个三角形投影在光栅化后的样子,经过光栅化采样之后变成如下图所示
在逐行扫描之后,三角形中间的像素的参数会由三角形顶点的信息差值获得。(如深度,颜色等等......)
3.采样的改进:
(1)包围盒:
默认情况下,我们的采样采用逐行扫描,逐行判断每个像素是否在三角形内。但是这显然不够经济,实际上我们对一个有限大小的三角形只需要扫描一块特定大小的正方形即可,而这就是包围盒,如下图:
如何构造这么一个包围盒呢我们假设三角形的三个点如上图为P0,P1,P2。
那么包围盒的坐标很好得出:
x的最右坐标即为Max(x坐标){P0,P1,P2},x的最左坐标即为Min(x坐标){P0,P1,P2}
y坐标同理,不做赘述。
(2)其他方法:
对每行的最左最右逐行扫描,这样能避免因狭长型三角形而产生大包围盒的浪费。如下图:
此方法很复杂,有兴趣的朋友可以自行搜索了解。
参考资料:
GAMES101-现代计算机图形学入门-闫令琪_哔哩哔哩_bilibili
《Unity Shader 入门精要》