本文梳理透视投影矩阵的推演逻辑:为什么常把透视投影拆成两步,以及这两步分别解决什么问题。目标不是背公式,而是把矩阵结构与几何约束对应起来,形成可复用的理解框架。

1. 透视投影的核心需求:产生 “1/z” 关系
在相机空间(或观察空间)中,一个点写作 ((x, y, z))。透视投影需要满足“近大远小”,因此屏幕上的横纵坐标应随深度变化:
x′∝xz,y′∝yz
x' \\propto \\frac{x}{z},\\qquad y' \\propto \\frac{y}{z}
x′∝zx,y′∝zy
问题在于:线性变换(矩阵乘法)无法直接产生除法。因此图形学引入齐次坐标,通过“齐次除法”把除法纳入流程。
2. 齐次坐标解决了什么:把除法推迟到最后一步
把点写成齐次坐标:
(xyz1)
\\begin{pmatrix}
x \\\\ y \\\\ z \\\\ 1
\\end{pmatrix}
xyz1
经过一个 4×4 矩阵变换得到:
(x′y′z′w′)
\\begin{pmatrix}
x' \\\\ y' \\\\ z' \\\\ w'
\\end{pmatrix}
x′y′z′w′
随后进行齐次除法:
(xndc,yndc,zndc)=(x′w′,y′w′,z′w′)
(x_{ndc}, y_{ndc}, z_{ndc})=\\left(\\frac{x'}{w'},\\frac{y'}{w'},\\frac{z'}{w'}\\right)
(xndc,yndc,zndc)=(w′x′,w′y′,w′z′)
只要让 (w’ = z),那么齐次除法自然会产生:
x′z,y′z
\\frac{x'}{z},\\qquad \\frac{y'}{z}
zx′,zy′
结论:透视效果的根源不是“神秘矩阵”,而是齐次除法产生的 (1/z)。
3. 为什么拆成两步:把“透视”与“归一化”分开处理

常见分解方式:
Mpersp=Mortho⋅Mpersp→ortho
M_{persp}=M_{ortho}\\cdot M_{persp\\to ortho}
Mpersp=Mortho⋅Mpersp→ortho
拆分的动机是工程上非常清晰的两件事:
这样每一步都有明确几何目标,避免把最终矩阵当作黑盒记忆。
4. M_{persp\\to ortho}:负责“透视本身”
4.1 目标
M_{persp\\to ortho} 的职责可以概括为:
- 在齐次坐标里编码透视关系(让 (w’=z),从而得到 (x/z, y/z));
- 通过对 near/far 的约束,构造深度项的映射形式;
- 将视锥体转为后续可按“盒子”思路处理的中间结果。
4.2 关键设计:第四行令 w'=z
为了让齐次除法产生 (1/z),需要:
w′=z
w' = z
w′=z
因此矩阵的第四行必须形如:
(0010)
(0\\quad 0\\quad 1\\quad 0)
(0010)
使得:
w′=1⋅z
w' = 1\\cdot z
w′=1⋅z
4.3 为什么第三行必须是 (0 0 A B)
第三行若写成一般形式 ((a,b,c,d)),则:
z′=ax+by+cz+d
z' = ax + by + cz + d
z′=ax+by+cz+d
但深度映射应只依赖 (z),不应与 (x,y) 混入。因此必须令:
a=0,b=0
a=0,\\qquad b=0
a=0,b=0
于是第三行只能写为:
(00AB)
(0\\quad 0\\quad A\\quad B)
(00AB)
即:
z′=Az+B
z' = Az + B
z′=Az+B
4.4 解出 A、B(由 near/far 约束)
为了让 near/far 在后续归一化前具有正确的深度关系,常对 (z) 施加两条约束(具体右手/左手系与深度范围会影响符号,但解法一致)。一种常见写法是:
An+B=n2,Af+B=f2
An + B = n^2,\\qquad Af + B = f^2
An+B=n2,Af+B=f2
两式相减得:
A(f−n)=f2−n2=(f−n)(f+n)⇒A=f+n
A(f-n) = f^2-n^2 = (f-n)(f+n)\\Rightarrow A=f+n
A(f−n)=f2−n2=(f−n)(f+n)⇒A=f+n
代回可得:
B=−nf
B=-nf
B=−nf
因此第三行为:
(00n+f−nf)
(0\\quad 0\\quad n+f\\quad -nf)
(00n+f−nf)
4.5 一个常见形式
Mpersp→ortho=(n0000n0000n+f−nf0010)
M_{persp\\to ortho} =
\\begin{pmatrix}
n & 0 & 0 & 0 \\\\
0 & n & 0 & 0 \\\\
0 & 0 & n+f & -nf \\\\
0 & 0 & 1 & 0
\\end{pmatrix}
Mpersp→ortho=n0000n0000n+f100−nf0
要点:它不负责把范围映射到 ([-1,1]),它主要负责透视关系 + 深度项构造。
5. M_{ortho}:负责“正交归一化”
5.1 目标
正交投影矩阵的任务更“朴素”:把任意视景盒 ([l,r]\\times[b,t]\\times[n,f]) 映射到标准立方体:
x,y,z∈[−1,1]
x,y,z\\in[-1,1]
x,y,z∈[−1,1]
5.2 为什么可以写成“平移 + 缩放”
这是一个纯仿射问题:把一个盒子变成标准盒子只需要两步。
Step 1:平移中心到原点
盒子中心:
(r+l2,t+b2,n+f2)
\\left(\\frac{r+l}{2},\\frac{t+b}{2},\\frac{n+f}{2}\\right)
(2r+l,2t+b,2n+f)
平移矩阵:
T=(100−r+l2010−t+b2001−n+f20001)
T =
\\begin{pmatrix}
1 & 0 & 0 & -\\frac{r+l}{2} \\\\
0 & 1 & 0 & -\\frac{t+b}{2} \\\\
0 & 0 & 1 & -\\frac{n+f}{2} \\\\
0 & 0 & 0 & 1
\\end{pmatrix}
T=100001000010−2r+l−2t+b−2n+f1
Step 2:缩放到边长 2(映射到 [-1,1])
缩放矩阵:
S=(2r−l00002t−b00002n−f00001)
S =
\\begin{pmatrix}
\\frac{2}{r-l} & 0 & 0 & 0 \\\\
0 & \\frac{2}{t-b} & 0 & 0 \\\\
0 & 0 & \\frac{2}{n-f} & 0 \\\\
0 & 0 & 0 & 1
\\end{pmatrix}
S=r−l20000t−b20000n−f200001
于是:
Mortho=S⋅T
M_{ortho}=S\\cdot T
Mortho=S⋅T
说明:具体 (\\frac{2}{n-f}) 的符号与深度正方向、NDC 的 z 范围约定有关,但“先平移再缩放”的结构不变。
6. 合在一起:每一步负责一件可解释的事

最终:
Mpersp=Mortho⋅Mpersp→ortho
M_{persp}=M_{ortho}\\cdot M_{persp\\to ortho}
Mpersp=Mortho⋅Mpersp→ortho
- M_{persp\\to ortho}:负责透视(让 (w’=z),在齐次除法处产生 (1/z)),并构造深度项;
- M_{ortho}:负责把范围归一化到标准裁剪空间,便于统一裁剪与后续光栅化。
一句话记忆:先做透视,再做标准化。
7. 常见理解误区(工程向)
-
误区 1:以为“透视投影矩阵本身完成了除法”。
实际上除法发生在齐次除法阶段;矩阵只是把 (w’) 构造成需要的量。 -
误区 2:把 M_{ortho} 当作“只用于正交相机”。
它更准确的角色是“把一个盒子归一化到标准裁剪空间”,在分解推导里是必需步骤。 -
误区 3:纠结某个版本矩阵的正负号。
符号差异通常来自坐标系(左/右手)、相机朝向、以及 NDC 深度范围约定。推导思想不变:w’=z + 盒子归一化。
8. 小结
透视投影矩阵拆分的价值在于:把复杂的最终矩阵分解成两件“可解释且可复用”的事情:
这种拆分不仅有助于理解,也有助于在不同坐标系与 API 约定下快速校验矩阵形式。





