欢迎光临
我们一直在努力

Unity Shader 最详细的正交矩阵和透视矩阵推导!

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


在这里插入图片描述

1. 透视投影的核心需求:产生 “1/z” 关系

在相机空间(或观察空间)中,一个点写作 ((x, y, z))。透视投影需要满足“近大远小”,因此屏幕上的横纵坐标应随深度变化:

x′∝xz,y′∝yz
x' \\propto \\frac{x}{z},\\qquad y' \\propto \\frac{y}{z}
xzx,yzy

问题在于:线性变换(矩阵乘法)无法直接产生除法。因此图形学引入齐次坐标,通过“齐次除法”把除法纳入流程。


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}
xyzw

随后进行齐次除法:

(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)=(wx,wy,wz)

只要让 (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=MorthoMpersportho

拆分的动机是工程上非常清晰的两件事:

  • Step 1:编码透视关系(产生 (w’=z) 与深度约束),把视锥体变为“可按盒子处理”的形式;
  • Step 2:正交归一化(平移 + 缩放),把盒子映射到标准裁剪空间 ([-1,1]^3)。
  • 这样每一步都有明确几何目标,避免把最终矩阵当作黑盒记忆。


    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=1z

    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(fn)=f2n2=(fn)(f+n)A=f+n

    代回可得:

    B=−nf
    B=-nf
    B=nf

    因此第三行为:

    (00n+f−nf)
    (0\\quad 0\\quad n+f\\quad -nf)
    (00n+fnf)

    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}
    Mpersportho=n0000n0000n+f100nf0

    要点:它不负责把范围映射到 ([-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=1000010000102r+l2t+b2n+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=rl20000tb20000nf200001

    于是:
    Mortho=S⋅T
    M_{ortho}=S\\cdot T
    Mortho=ST

    说明:具体 (\\frac{2}{n-f}) 的符号与深度正方向、NDC 的 z 范围约定有关,但“先平移再缩放”的结构不变。


    6. 合在一起:每一步负责一件可解释的事

    在这里插入图片描述

    最终:
    Mpersp=Mortho⋅Mpersp→ortho
    M_{persp}=M_{ortho}\\cdot M_{persp\\to ortho}
    Mpersp=MorthoMpersportho

    • M_{persp\\to ortho}:负责透视(让 (w’=z),在齐次除法处产生 (1/z)),并构造深度项;
    • M_{ortho}:负责把范围归一化到标准裁剪空间,便于统一裁剪与后续光栅化。

    一句话记忆:先做透视,再做标准化。


    7. 常见理解误区(工程向)

    • 误区 1:以为“透视投影矩阵本身完成了除法”。
      实际上除法发生在齐次除法阶段;矩阵只是把 (w’) 构造成需要的量。

    • 误区 2:把 M_{ortho} 当作“只用于正交相机”。
      它更准确的角色是“把一个盒子归一化到标准裁剪空间”,在分解推导里是必需步骤。

    • 误区 3:纠结某个版本矩阵的正负号。
      符号差异通常来自坐标系(左/右手)、相机朝向、以及 NDC 深度范围约定。推导思想不变:w’=z + 盒子归一化。


    8. 小结

    透视投影矩阵拆分的价值在于:把复杂的最终矩阵分解成两件“可解释且可复用”的事情:

  • 透视关系来自齐次除法(通过构造 (w’=z));
  • 范围归一化是盒子到标准立方体的仿射映射(平移 + 缩放)。
  • 这种拆分不仅有助于理解,也有助于在不同坐标系与 API 约定下快速校验矩阵形式。

    赞(0)
    未经允许不得转载:171主机测评 » Unity Shader 最详细的正交矩阵和透视矩阵推导!
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址