上篇文章做了视图矩阵的推导过程,实际上就是把物体的坐标转化成摄像机的相对坐标,之后呢需要把三维空间中的物体映射到二维平面上,这里就需要投影矩阵来实现。
投影矩阵一般有两种,一种是正交投影,还有一种是透视投影
正交投影
正交投影由于没有近大远小的特性,常用于显示在三维空间中的 2D 视图,比如,房子的顶面 2D 视图等。
正交相机一般有6个参数,分别是 left、right、bottom、top、near、far。 这6个参数就可以构成空间中的一个立方体,正交投影做的事也很简单,把空间中的立方体移动到原点为中心且 (x, y, z) 都缩放到 [-1, 1] 的立方体中。
为什么要这么做呢?很简单,要投影left-right的物体,那对于屏幕来说,中间点就是 left + right / 2, 所以要放到中间点。缩放到【-1, 1】主要是为了后面再放大到屏幕坐标上。
根据上面的分析,很容易得到正交投影的平移矩阵:
Mtranslate=100001000010−2l+r−2top+bottom−2near+far1
然后缩放矩阵:
Mscale=r−l20000top−bottom20000near−far200001
最后的矩阵结果:
M=MscaleMtranslate=r−l20000top−bottom20000near−far20−r−lr+l−top−bottomtop+bottom−near−farnear+far1
透视投影
透视投影实际上就是,先把视锥体,压成长方体,然后执行一次正交投影的方法,把长方体的投影到[-1, 1] 上。
首先,在压的过程中,会有两个特性:
- 远平面f所在平面变换完还在 f 平面
- 近平面n所在平面的点转换完还在 n 平面
然后算远平面(f)的点, 根据相似三角形的特性n/f=y′/y,所以 y′=fny,
所以可以推导:
M∗xyf1=fnxfnyf1=nxnyf2f
这样就可以推导出矩阵的部分内容。
M=n0000n0000?100?0
为什么有两个问好推导不了呢,因为 有可能第一个数是 f,第二个数是0,也可能第一个数是0,第二个数是f2.
那根据第二个性质,我们可以得出 (x, y, z) ⇒ 还是 (x, y, z)。
所以:
M∗xyn1=xyn1=nxnyn2n
这样也能推出:
M=n0000n0000?100?0
假设M[3,3] = A, M[3,4] = B。
所以有两个公式可以得出:
Af+B=f2An+B=n2
解:
A=f+nB=−nf
得到矩阵:
M=n0000n0000f+n100−nf0
最后再应用正交矩阵即可得到最后的矩阵:
M=r−l2n0000t−b2n00−r−lr+l−t−bt+bn−fn+f100−n−f2nf0
然后 t=−n∗tan(fov/2) , 这里n 是负数, 所以要乘-1。同理 b=n∗tan(fov/2)。
因为宽高比是 aspect, 所以:
r=−n∗aspect∗tan(fov/2)l=n∗aspect∗tan(fov/2)
带入得到实际用的矩阵:
M=−aspect∗tan(fov/2)10000−tan(fov/2)10000n−fn+f100−n−f2nf0