本文主要由三个部分构成:视锥,视场与透视投影矩阵的推导.
视锥:
如图所见,视锥是一个锥形的几何体,其中near与far之前的空间就是我们的可视范围.
其中near和far也分别被称为近平面与远平面.
再算上,上下左右四个面,一个视椎总共由6个面构成.
视场:
视场分为水平视场,与垂直视场,先来说水平视场.
水平视场.
如图所见,水平视场是在xz平面上的锥形区域,且被限制在[-1,1]之间.
角度α = 2arctan(1/e)
焦距e=1/tan(α/2)
tan是对边比邻边,所以对边越大tan越大,然后1/tan就越小.根据公式可知,e越小远平面所占据的比例就越大,视场就越宽.
垂直视场:
焦距与角度的计算与水平视场相同.
透视投影矩阵的推导
根据相似三角形定理可知投影点x,y坐标的表达式为:
(1)
x = (-e/Pz)*Px
y = (-e/Pz)*Py
Px,Py,Pz为屏幕中的点的坐标.
现在来将x与y的取值范围为限定在[-1,1]
定义l<=x<=r,b<=y<=t
那么
(2)
x' = (x-l) * 2/(r-l) - 1
y' = (y-b) * 2/(t-b) - 1
现在我们就获得了取值范围在[-1,1]之间的x'与y'.
接下来是取值范围在[-1,1]的z':
列出能让-n = -1与-f=1到表达式:
z' = A/z + B
-1 = A/-n + B
-1 = A/-f + B
推导出下列公式:
A = 2nf/(f-n)
B = (f+n)/(f-n)
最后可得将z'限制在[-1,1]之间的表达式.:
z' = (2nf/(f-n))/Pz + (f+n)/(f-n)
现在列出x',y',z'的表达式:
x' = ((-e/Pz)*Px-l) * 2/(r-l) - 1 = [2e/(r-l)](-Px/Pz)-(r+l)/(r-l)
y' = ((-e/Pz)*Py-b) * 2/(t-b) - 1 = [2e/(t-b)](-Py/Pz)-(t+b)/(t-b)
z' = (2nf/(f-n))/Pz + (f+n)/(f-n)
到了这一步,就可以开始构建透视投影矩阵了,在排版更好的书里,可以一眼看见每一个表达式里都是有-1/Pz的,所以可以直接把x',y',z'这个三维向量,通过乘以-Pz转换成四维向量,从而构建出透视投影矩阵. 转换后的四维向量:
-x'Pz = [2e/(r-l)]*Px+(r+l)/(r-l)*Pz
-y'Pz = [2e/(t-b)]*Py+(t+b)/(t-b)*Pz
-z'Pz = -(2nf/(f-n)) - (f+n)/(f-n)*Pz
建透视投影矩阵M: 点P:
2e/(r-l), 0, (r+l)/(r-l), Pz Px
0, 2e/(t-b), (t+b)/(t-b), 0 Py
0, 0, -(f+n)/(f-n), -(2nf/(f-n)) Pz
0, 0, -1, 0 1
P' = M*P
透视投影矩阵推导这块较为繁琐,推荐参阅3D游戏与计算机图形学中的数学方法一书.