什么是投影?
我们在搭建3D游戏场景的时候,所有的物体都是3D的,然而我们通过屏幕观察的时候,
屏幕却是2D的平面,想要在2D屏幕表达3D的物体,那么就需要将3D的物体投影到2D的屏幕。
平截头体
我们在将3D世界的物体投影到2D屏幕的时候,不可能将所有的东西都投影过去,我们需要定义
一个范围,只有在这个范围内的物体,我们才将其投影到屏幕上,在这个范围以外的物体,我们就
将其剔除,而这个范围,叫做平截头体:
我们在观察空间中,定义平截头体的参数:
近平面:n
远平面:f
垂直视域角:a
纵横比:r = w/h
后台缓冲区:
GPU处理数据速度有波动,但是显示器却是以固定刷新率来刷新画面,为此,就需要一个缓冲区来存放数据,
然后再交由显示器显示。一般情况下,由两个缓冲区1和2,GPU将正在绘制的画面放到缓冲区1中,将2中的数据
用于显示器显示,当2中数据已经显示完成,则交换2个缓冲区。
需要注意的是,由于图像都存在于缓冲区中,那么需要后台缓冲区的纵横比 与显示窗口的纵横比保持一致,
否则就会出现图像被拉伸的情况,而图像缓冲区的尺寸,其实也就是投影窗口的纵横比。
下面推到一些比较重要的公式:
1.r = w/h,设 h =2,那么r =w/2 =>w=2r;
2.设近平面n 到起点的长度为d,那么可以得到 d = cot(a/2);
3.tan(β/2) =r*tan(a/2)
顶点投影:
将一个点P(x,y,z) 投影到平面z =d 的点为(x1,y1,d)
那么,可以得到,当
-r<x1<r
-1<y1<1
n<d<f
时,点P才在平截头体范围内。
NDC:
在观察空间中,投影窗口的高度我们设为2,宽度为2r,r则横纵比 =w/h。那么这里就有一个问题,那么就是必须要为GPU指定了横纵比之后,GPU才能工作,否则就GG。如果我们能去掉这个依赖,对于GPU来讲,运算
就会变得简单。为了解决这个问题,GPU将后天缓冲区的尺寸指定为[-1,1]这个区间。那么我们就需要将我们计算出来的投影坐标再次进行映射,从[-r,r]区间映射到[-1,1]这个区间。
-r<=x1<=r
-1<=x1/r<=1
将坐标映射后,x,y坐标称为规范化设备坐标,也叫作NDC,那么当以下条件成立时,点才在平截头体内:
-1<=x1/r<=1
-1<=y1<=1
n<=z<=f
需要注意的是,GPU会默认我们已经完成了这个工作,否则的话,GPU会产生错误。
将顶点数据投影到NDC变换公式用矩阵描述:
最终,完整的投影矩阵如下: