Viewport transformation

Screen Space

从NDC(三维)到我们的屏幕空间(二维),也就是真正要显示在屏幕上;首先NDC空间范围是11,而屏幕空间表示像素范围对应的是(0,0)(w,h)例如我们屏幕分辨率为520×520那么就是(520,520),也就是说我们需要从NDC的(1,1)(1,1)映射到屏幕的(0,0)(520,520);假设有一点顶点为(0.5,0.5,0.5,1),是左下角的一个顶点 (也就是正交变换里我们计算并验证中的那个小盒子上的一个边界点)经过一个正交变换后是(1,1,0.992,1),假设有一屏幕长为520,宽为520顶点(0.5,0.5)也就是NDC中的(1,1)会变换到屏幕空间中的(0,0),同理如果是顶点(0.5,0.5),NDC中的(1,1)会变成屏幕空间中的(520,520),我们假设另外一个顶点(0.25,0.25),对应NDC中的(0.5,0.5)会变成屏幕空间中的(390,390)


Figure 1

根据这些我们可以得到我们的视口变换矩阵

[w200w20h20h20012120001]

(矩阵中的z12是为保持z值不变) 来验证一下,假设我们的屏幕是520×520的,则矩阵为

[2600026002600260000.50.50001]

顶点(0.25,0.25),NDC中为(0.50.5)

[0.50.511][2600026002600260000.50.50001][39039011]

顶点(0.5,0.5),NDC中为(11)

[1111][2600026002600260000.50.50001][0011]

映射到屏幕坐标(0,0)像素点(也就是说最左下的那个小盒子的边界点正好映射到屏幕的左下角)

如果长宽是不一样的

长宽不一样我们依然可以处理,只不过要多一个概念aspect,

aspect=widthheight

它是一个比例

左上图是比例为1:1的情况下,如果我们改变了窗口大小,例如改为了640×480,也就是比例为1:1.3333,如果我们此时什么都不做,则我们会得到左下的结果(仔细想想,为什么,是因为我们的视口变换矩阵,像素是一一对应的,即使窗口大小变了,但映射关系并没有变)所以我们如果才能得到右上的结果呢? 很简单,在进行正交变换或者透视变换的时候将x方向也就是水平方向按照aspect比例收缩一些