文章目录
概述
本文的图片来源和主要参考文献为:Fundamentals of Computer Graphics
渲染中的空间转换如下图所示:
在渲染过程中会涉及到五个空间以及四个转换.
屏幕映射(Viewport transformation)
基础知识
像素坐标约定
像素值其实就是一个个的小格子,它的索引及坐标都是整数.但是我们现实中使用的坐标都为实数坐标.
像素坐标无固定的定义,这里仅作为一种约定方便讨论.
这里假设横向格子为nx,纵向格子为ny. 那么我们实际使用的坐标区域为:
R=[−0.5,nx−0.5]×[−0.5,ny−0.5]
窗口转换
窗口转换的目标为构建一个映射,把矩形A中的点映射到矩形B中.
这里假定矩形A为 [xl,xh]×[yl,yh]
矩形B为[xl′,xh′]×[yl′,yh′].
一种方法是先把A缩放到和B一样的大小,然后再通过平移让矩阵对齐.
但是由于直接缩放会让平移的参数难以获得,另一种更直观的方案如下图所示:
我们先让矩形A的左下角平移至原点,然后进行缩放使得矩形A的大小和矩阵B的大小一致.
其次我们再通过平移使得矩形A和矩形B对齐即可.
这里我们不用过多关心构建的过程,因为我们经我们组合后只会获得一个最终矩阵. 所以在构建过程中越简单越直观越好.
我们使用列向量来表示坐标,所以矩阵的应用从右手边开始. 我们矩阵如下:
窗口转换=(平移使A和B对齐)(缩放A使A大小和B一致)(平移A使左下角到原点)
即:
window=translate(xl′,yl′)scale(xh−xlxh′−xl′,yh−ylyh′−yl′)translate(−xl,−yl)
使用矩阵表示:
window=⎣⎢⎢⎡000000000000xl′yl′01⎦⎥⎥⎤⎣⎢⎢⎢⎡xh−xlxh′−xl′0000yh−ylyh′−yl′0000000001⎦⎥⎥⎥⎤⎣⎢⎢⎡000000000000−xl−yl01⎦⎥⎥⎤
window=⎣⎢⎢⎢⎡xh−xlxh′−xl′0000yh−ylyh′−yl′000000xh−xlxl′xh−xh′xlyh−ylyl′yh−yh′yl01⎦⎥⎥⎥⎤
扩展一维同理.
假设我们要把长方体 [xl,xh]×[yl,yh]×[zl,zh]映射到 [xl′,xh′]×[yl′,yh′]×[zl′,zh′]:
window=⎣⎢⎢⎢⎡xh−xlxh′−xl′0000yh−ylyh′−yl′0000zh−zlzh′−zl′0xh−xlxl′xh−xh′xlyh−ylyl′yh−yh′ylzh−zlzl′zh−zh′zl1⎦⎥⎥⎥⎤
屏幕映射
在这一步中分别牵扯到两个空间: 归一化设备坐标(下文简称NDC)和屏幕空间.
这里做以下假定:
- 我们需要去渲染的所有顶点都在一个小立方体里, 小立方体的范围为:(x,y,z)∈[−1,1]3.
- 摄像机朝向为-z方向,up方向为+y方向.
现在我们需要去做的是把正方形[−1,1]2映射到矩形[−0.5,nx−0.5]×[−0.5,ny−0.5]
根据我们上文的窗口转换可以推导出:
⎣⎢⎢⎡xscreenyscreenzscreen1⎦⎥⎥⎤=⎣⎢⎢⎡2nx00002ny0000102nx−12ny−101⎦⎥⎥⎤⎣⎢⎢⎡xcanonicalycanonicalzcanonical1⎦⎥⎥⎤
注意这里我们保留了z值 即 zscreen=zcanonical. z值可以用于比较物体的远近.
由此我们得到了屏幕映射矩阵:
Mvp=⎣⎢⎢⎡2nx00002ny0000102nx−12ny−101⎦⎥⎥⎤
注意,这里的vp代表的是viewport.
小结
至此,我们知道了给定一个小立方体如何投射到屏幕上. 这里我们忽略了z值,真正渲染的时候z是用来判定物品远近的. 这点在后续的博文中将会更一进步介绍.
正交映射(Orth projection transformation)
在上文中,我们已知如何把小立方体映射到屏幕上. 现在我们把难度升级,假设我们想要渲染一个长方体如下图所示:
由于我们已知如何把小立方体映射到屏幕上,所以如果我们可以把长方体映射到小立方体上即可.
即[l,r]×[b,t]×[n,f]→[−1,1]3.
利用窗口转换可以得出:
Morth=⎣⎢⎢⎡r−l20000t−b20000n−f20−r−lr+l−t−bt+b−n−f