前提条件:右手系坐标,目标将视锥体内的坐标压缩为x,y,z->[-1,1]
下面开始推导
第一步:把x,y方向上的点压缩,也即如下图所示的把视锥体压缩成长方体
P压缩后的点为
P
′
(
x
′
,
y
′
,
z
′
)
P'(x',y',z')
P′(x′,y′,z′).则根据相似定律,
y
z
=
y
′
−
n
,
x
z
=
x
′
−
n
\frac{y}{z}=\frac{y'}{-n},\frac{x}{z}=\frac{x'}{-n}
zy=−ny′,zx=−nx′
故有
y
′
=
−
n
y
/
z
,
x
′
=
−
n
x
/
z
;
y'=-{{ny}\Bigg/{z}},x'=-{{nx}\Bigg/{z}};
y′=−ny/z,x′=−nx/z;
现在我们可以推导压缩矩阵
M
t
\boldsymbol{M}_{\boldsymbol{t}}
Mt,将x’,y’替换为x,y,z的表达式.
[
]
[
x
y
z
1
]
=
[
x
′
y
′
z
′
1
]
=
[
−
n
x
/
z
−
n
y
/
z
z
′
1
]
\\ \left[ \begin{matrix} & & & \\ & & & \\ & & & \\ & & & \\ \end{matrix} \right] \left[ \begin{array}{c} x\\ y\\ z\\ 1\\ \end{array} \right] =\left[ \begin{array}{c} x'\\ y'\\ z'\\ 1\\ \end{array} \right] =\left[ \begin{array}{c} {{-nx}\Bigg/{z}}\\ -{{ny}\Bigg/{z}}\\ z'\\ 1\\ \end{array} \right] \\
⎣
⎡⎦
⎤⎣
⎡xyz1⎦
⎤=⎣
⎡x′y′z′1⎦
⎤=⎣
⎡−nx/z−ny/zz′1⎦
⎤
可以同乘z消除分子,接下来可以推出压缩矩阵的1,2,4行
[
]
[
x
y
z
1
]
=
[
n
x
n
y
?
−
z
]
⟶
[
n
0
0
0
0
n
0
0
0
0
−
1
0
]
[
x
y
z
1
]
=
[
n
x
n
y
?
−
z
]
\left[ \begin{matrix} & & & \\ & & & \\ & & & \\ & & & \\ \end{matrix} \right] \left[ \begin{array}{c} x\\ y\\ z\\ 1\\ \end{array} \right] =\left[ \begin{array}{c} nx\\ ny\\ ?\\ -z\\ \end{array} \right] \longrightarrow \left[ \begin{matrix} n& 0& 0& 0\\ 0& n& 0& 0\\ & & & \\ 0& 0& -1& 0\\ \end{matrix} \right] \left[ \begin{array}{c} x\\ y\\ z\\ 1\\ \end{array} \right] =\left[ \begin{array}{c} nx\\ ny\\ ?\\ -z\\ \end{array} \right] \\
⎣
⎡⎦
⎤⎣
⎡xyz1⎦
⎤=⎣
⎡nxny?−z⎦
⎤⟶⎣
⎡n000n000−1000⎦
⎤⎣
⎡xyz1⎦
⎤=⎣
⎡nxny?−z⎦
⎤
接下来观察压缩后的长方体,可以发现(0,0,-n)和(0,0,-f)点压缩后坐标不变故有
[
0
0
−
n
1
]
和
[
0
0
−
f
1
]
[
n
0
0
0
0
n
0
0
0
0
A
B
0
0
−
1
0
]
[
0
0
−
n
1
]
=
[
0
0
−
A
n
+
B
n
]
=
[
0
0
−
n
n
n
]
,
n
2
=
A
n
−
B
[
n
0
0
0
0
n
0
0
0
0
A
B
0
0
−
1
0
]
[
0
0
−
f
1
]
=
[
0
0
−
A
f
+
B
f
]
=
[
0
0
−
f
f
f
]
,
f
2
=
A
f
−
B
解得
A
=
n
+
f
,
B
=
n
f
,
\left[ \begin{array}{c} 0\\ 0\\ -n\\ 1\\ \end{array} \right] \text{和}\left[ \begin{array}{c} 0\\ 0\\ -f\\ 1\\ \end{array} \right] \\ \left[ \begin{matrix} n& 0& 0& 0\\ 0& n& 0& 0\\ 0& 0& A& B\\ 0& 0& -1& 0\\ \end{matrix} \right] \left[ \begin{array}{c} 0\\ 0\\ -n\\ 1\\ \end{array} \right] =\left[ \begin{array}{c} 0\\ 0\\ -An+B\\ n\\ \end{array} \right] =\left[ \begin{array}{c} 0\\ 0\\ -nn\\ n\\ \end{array} \right] ,n^2=An-B \\ \left[ \begin{matrix} n& 0& 0& 0\\ 0& n& 0& 0\\ 0& 0& A& B\\ 0& 0& -1& 0\\ \end{matrix} \right] \left[ \begin{array}{c} 0\\ 0\\ -f\\ 1\\ \end{array} \right] =\left[ \begin{array}{c} 0\\ 0\\ -Af+B\\ f\\ \end{array} \right] =\left[ \begin{array}{c} 0\\ 0\\ -ff\\ f\\ \end{array} \right] ,f^2=Af-B \\ \text{解得}A=n+f,B=nf, \\
⎣
⎡00−n1⎦
⎤和⎣
⎡00−f1⎦
⎤⎣
⎡n0000n0000A−100B0⎦
⎤⎣
⎡00−n1⎦
⎤=⎣
⎡00−An+Bn⎦
⎤=⎣
⎡00−nnn⎦
⎤,n2=An−B⎣
⎡n0000n0000A−100B0⎦
⎤⎣
⎡00−f1⎦
⎤=⎣
⎡00−Af+Bf⎦
⎤=⎣
⎡00−fff⎦
⎤,f2=Af−B解得A=n+f,B=nf,
故此矩阵
[
n
0
0
0
0
n
0
0
0
0
n
+
f
n
f
0
0
−
1
0
]
,
即为压缩矩阵,
接下来右乘平移矩阵把长方体中心移动到原点,再右乘缩放矩阵,将长方体变成2*2*2,
[
2
n
∗
tan
∗
a
s
p
e
c
t
0
0
0
0
2
n
∗
tan
0
0
0
0
2
f
−
n
0
0
0
0
1
]
,
\left[ \begin{matrix} n& 0& 0& 0\\ 0& n& 0& 0\\ 0& 0& n+f& nf\\ 0& 0& -1& 0\\ \end{matrix} \right] ,\text{即为压缩矩阵,} \\ \text{接下来右乘平移矩阵把长方体中心移动到原点,再右乘缩放矩阵,将长方体变成2*2*2,} \\ \left[ \begin{matrix} \frac{2}{n*\tan *aspect}& 0& 0& 0\\ 0& \frac{2}{n*\tan}& 0& 0\\ 0& 0& \frac{2}{f-n}& 0\\ 0& 0& 0& 1\\ \end{matrix} \right] , \\
⎣
⎡n0000n0000n+f−100nf0⎦
⎤,即为压缩矩阵,接下来右乘平移矩阵把长方体中心移动到原点,再右乘缩放矩阵,将长方体变成2*2*2,⎣
⎡n∗tan∗aspect20000n∗tan20000f−n200001⎦
⎤,
[
1
n
∗
tan
∗
a
s
p
e
c
t
0
0
0
0
1
n
∗
tan
0
0
0
0
2
n
−
f
0
0
0
0
1
]
[
1
0
0
0
0
1
0
0
0
0
1
f
+
n
2
0
0
0
1
]
[
n
0
0
0
0
n
0
0
0
0
n
+
f
n
f
0
0
−
1
0
]
=
[
1
n
∗
tan
∗
a
s
p
e
c
t
0
0
0
0
1
n
∗
tan
0
0
0
0
2
n
−
f
0
0
0
0
1
]
[
n
0
0
0
0
n
0
0
0
0
f
+
n
2
n
f
0
0
−
1
0
]
=
[
1
tan
∗
a
s
p
e
c
t
0
0
0
0
1
tan
0
0
0
0
−
f
+
n
f
−
n
−
2
n
f
f
−
n
0
0
−
1
0
]
\left[ \begin{matrix} \frac{1}{n*\tan *aspect}& 0& 0& 0\\ 0& \frac{1}{n*\tan}& 0& 0\\ 0& 0& \frac{2}{n-f}& 0\\ 0& 0& 0& 1\\ \end{matrix} \right] \left[ \begin{matrix} 1& 0& 0& 0\\ 0& 1& 0& 0\\ 0& 0& 1& \frac{f+n}{2}\\ 0& 0& 0& 1\\ \end{matrix} \right] \left[ \begin{matrix} n& 0& 0& 0\\ 0& n& 0& 0\\ 0& 0& n+f& nf\\ 0& 0& -1& 0\\ \end{matrix} \right] \\ =\left[ \begin{matrix} \frac{1}{n*\tan *aspect}& 0& 0& 0\\ 0& \frac{1}{n*\tan}& 0& 0\\ 0& 0& \frac{2}{n-f}& 0\\ 0& 0& 0& 1\\ \end{matrix} \right] \left[ \begin{matrix} n& 0& 0& 0\\ 0& n& 0& 0\\ 0& 0& \frac{f+n}{2}& nf\\ 0& 0& -1& 0\\ \end{matrix} \right] =\left[ \begin{matrix} \frac{1}{\tan *aspect}& 0& 0& 0\\ 0& \frac{1}{\tan}& 0& 0\\ 0& 0& -\frac{f+n}{f-n}& -\frac{2nf}{f-n}\\ 0& 0& -1& 0\\ \end{matrix} \right]
⎣
⎡n∗tan∗aspect10000n∗tan10000n−f200001⎦
⎤⎣
⎡100001000010002f+n1⎦
⎤⎣
⎡n0000n0000n+f−100nf0⎦
⎤=⎣
⎡n∗tan∗aspect10000n∗tan10000n−f200001⎦
⎤⎣
⎡n0000n00002f+n−100nf0⎦
⎤=⎣
⎡tan∗aspect10000tan10000−f−nf+n−100−f−n2nf0⎦
⎤
这个最终的矩阵就是OpenGL的透视投影矩阵