一 前言
上一篇讨论了D3D/OGL如何将Shader输出的图元顶点坐标及属性转化为其所覆盖像素和像素的属性。本篇将继续地讨论光栅化其他步骤相关的细节。包括Face Cull,Fill Mode,Clipping, 透视矫正等。
二 几个概念
Render Target
对应显示存储中的一块数据(Surface),存储着用于画到屏幕上每个像素的颜色、深度等数据。
Viewport
由一个二维矩形区域和一维的z范围构成,表示要显示渲染输出的区域,它是NDC立方体所映射的区域。例如RenderTarget大小为64*64,当设置Viewport左上角为(32,32),大小为32*32时,我们将在Render Target的右下角1/4的区域画图。
坐标系
D3D和OGL的屏幕坐标系有所区别,D3D将NDC中y的范围[-1,1]映射到Viewport的[Viewport.Top+Viewport.Height, Viewport.Top],例如下图中(假设Viewport区域与Render Target相等)Viewport.Top=0,Viewport.Height=-1,NDC中y=-1映射到屏幕上y=8,y=1映射到屏幕上y=0。
由下图可知,D3D的坐标系原点位于屏幕的左上角,像素的长宽为1,像素中心的坐标小数位均为0.5。
下图是OGL的坐标系,其坐标原点位于屏幕的左下角(在新的OGL版本中,可通过Clip Control选择坐标原点为左上角或左下角),其余特征与D3D类似。
透视除法和Viewport变换
Raster从Shader收到的顶点位置坐标属于齐次坐标(或裁剪坐标),在较简单的情况下(可能需要做裁剪,在后文继续做讨论),
透视除法:Raster首先将xyz都除以w,将齐次坐标转化为笛卡尔坐标,这时的坐标系称为正规化设备坐标(NDC, Normalized Device Coordinate)。完整的透视除法还包括将非Const的attribute除以w(在透视矫正部分将解释这样做的原因)
Viewport变换:NDC坐标再经过
Viewport变换得到屏幕坐标,这样NDC立方体将被映射到viewport,这一步实际是通过拉伸偏移,将独立于屏幕的标准化设备坐标映射到实际的屏幕上。以D3D为例: