[简化版 GAMES 101] 计算机图形学 06:相机视图矩阵的由来

✨ 图形学入门:从二维变换到三维MVP,一次讲透旋转、齐次坐标与视图投影

  • [Bilibili 同步视频](#Bilibili 同步视频)
  • [一、💫 二维变换:旋转矩阵的优雅性质](#一、💫 二维变换:旋转矩阵的优雅性质)
    • [1. 旋转矩阵的基本形式](#1. 旋转矩阵的基本形式)
    • [2. 旋转 -θ 角:转置 = 逆?✨](#2. 旋转 -θ 角:转置 = 逆?✨)
    • [3. 平移的 "小尴尬"😥](#3. 平移的 “小尴尬”😥)
  • [二、🚀 三维变换:二维思路的完美延伸](#二、🚀 三维变换:二维思路的完美延伸)
    • [1. 三维齐次坐标📐](#1. 三维齐次坐标📐)
    • [2. 基础变换:缩放 & 平移](#2. 基础变换:缩放 & 平移)
    • [3. 三维旋转:绕轴旋转 + 欧拉角🔄](#3. 三维旋转:绕轴旋转 + 欧拉角🔄)
      • (1)绕单轴旋转
      • [(2)任意旋转:欧拉角 + 罗德里格斯公式](#(2)任意旋转:欧拉角 + 罗德里格斯公式)
      • [(3)四元数:旋转插值的 "神器"](#(3)四元数:旋转插值的 “神器”)
  • [三、🎥 View矩阵:三维视角的核心变换(详细推导)](#三、🎥 View矩阵:三维视角的核心变换(详细推导))
    • [1. 先明确:定义相机的3个核心参数📸](#1. 先明确:定义相机的3个核心参数📸)
    • [2. 图形学约定:相机的"标准姿态"✨](#2. 图形学约定:相机的“标准姿态”✨)
    • [3. View矩阵推导:两步完成(平移 + 旋转)](#3. View矩阵推导:两步完成(平移 + 旋转))
      • [(1)第一步:推导平移矩阵 T t e x t v i e w T_{text{view}} Ttextview(把相机移到原点)](#(1)第一步:推导平移矩阵 T t e x t v i e w T_{text{view}} Ttextview(把相机移到原点))
      • [(2)第二步:推导旋转矩阵 R t e x t v i e w R_{text{view}} Rtextview(把相机朝向转到标准轴)](#(2)第二步:推导旋转矩阵 R t e x t v i e w R_{text{view}} Rtextview(把相机朝向转到标准轴))
      • (3)第三步:合并得到View矩阵最终形式
    • [4. View矩阵推导总结(新手可直接套用)](#4. View矩阵推导总结(新手可直接套用))
  • [四、📝 本章核心总结](#四、📝 本章核心总结)
  • [五、💡 课后小任务](#五、💡 课后小任务)

Bilibili 同步视频

[简化版 GAMES 101] 计算机图形学 06:相机视图矩阵的由来

在计算机图形学的世界里,变换是连接三维空间与二维屏幕的桥梁🌉。从最简单的二维旋转,到复杂的三维模型观测,每一步矩阵运算都在为虚拟世界的呈现铺路。今天,我们就顺着课程思路,把**二维变换→三维变换→View矩阵(视图变换)**这条核心脉络,一次性梳理清楚~


一、💫 二维变换:旋转矩阵的优雅性质

抛开复杂公式,二维变换的核心其实很纯粹:不使用齐次坐标时,一切线性变换都浓缩在 2×2 矩阵中

1. 旋转矩阵的基本形式

绕原点旋转 θ 角,矩阵长这样:KaTeX parse error: Expected 'EOF', got '&' at position 33: ...atrix}costheta &̲amp; -sintheta ...

2. 旋转 -θ 角:转置 = 逆?✨

当我们旋转 -θ 角(反向旋转),只需把 θ 替换为 -θ:

  • cos (-θ)=cosθ(偶函数不变)

  • sin (-θ)=-sinθ(奇函数变号)

最终得到:KaTeX parse error: Expected 'EOF', got '&' at position 34: ...atrix}costheta &̲amp; sintheta -...

⚠️ 关键结论:旋转矩阵的转置 = 旋转矩阵的逆 满足这个性质的矩阵,在数学上有一个超美的名字 ------正交矩阵 ! 这意味着:求旋转的逆变换,不用复杂计算,转置一下就搞定

3. 平移的 "小尴尬"😥

平移变换很特殊:无法写成 矩阵 × 向量 的形式 ,必须额外加平移分量。 为了统一所有变换,齐次坐标 应运而生 ------ 二维点 (x,y)→(x,y,1),二维向量 (x,y)→(x,y,0) 变换矩阵也升级为3×3,从此线性变换 + 平移完美融合!


二、🚀 三维变换:二维思路的完美延伸

三维变换完全继承二维逻辑,只是维度 + 1,思路一模一样~

1. 三维齐次坐标📐

  • 三维点:(x,y,z,1)

  • 三维向量:(x,y,z,0)

  • 若 w≠0,点 (x,y,z,w) 等价于 (x/w,y/w,z/w)

  • 变换矩阵:4×4(线性变换 3×3 + 平移 + 固定行 [0,0,0,1])

2. 基础变换:缩放 & 平移

  • 缩放:左上角 3×3 对角阵,各轴独立缩放

  • 平移:最后一列存 Tx/Ty/Tz,左侧 3×3 为单位矩阵

3. 三维旋转:绕轴旋转 + 欧拉角🔄

三维旋转分两步:简单绕轴旋转任意旋转分解

(1)绕单轴旋转

  • 绕 X 轴:X 坐标不变,Y-Z 平面旋转

  • 绕 Z 轴:Z 坐标不变,X-Y 平面旋转

  • 绕 Y 轴:符号相反 ! 原因:右手坐标系循环对称------X×Y=Z,Y×Z=X,Z×X=Y,轴顺序导致符号差异。

(2)任意旋转:欧拉角 + 罗德里格斯公式

任意 3D 旋转 = 绕 X (α)+ 绕 Y (β)+ 绕 Z (γ),这三个角就是欧拉角 。 更通用的罗德里格斯旋转公式 ,可直接给出绕任意过原点轴的旋转矩阵。

💡 小技巧:绕任意轴旋转? 先平移→使轴过原点→旋转→平移回去,三步搞定!

(3)四元数:旋转插值的 "神器"

旋转矩阵直接平均≠中间角度插值,而四元数完美解决这个问题,是动画、游戏引擎的常用工具~


三、🎥 View矩阵:三维视角的核心变换(详细推导)

在三维图形学中,View矩阵(视图矩阵)是连接三维场景与相机视角的关键,它的核心作用只有一个:把相机从任意位置和姿态,变换到图形学约定的标准位置,同时让整个场景同步变换,保证相机与场景的相对位置不变。 下面我们一步步拆解其推导过程,从原理到公式,新手也能看懂~

1. 先明确:定义相机的3个核心参数📸

想要唯一确定一个相机的姿态,必须给出3个关键向量,缺一不可:

  1. 相机位置 e (eye):相机在世界坐标系中的具体坐标,记为 (eₓ, eᵧ, e_z),代表"相机在哪";

  2. 观察方向 g (gaze/look-at):相机的朝向向量,指向相机所看的方向,代表"相机看哪";

  3. 向上方向 t (up):相机"头顶"的朝向向量,用于确定相机的旋转角度,避免画面倾斜,代表"相机怎么旋转"。

2. 图形学约定:相机的"标准姿态"✨

为了统一计算规则,减少复杂运算,图形学中约定了相机的"标准位置和姿态",我们的目标就是把任意姿态的相机,变换到这个标准状态:

  • 标准位置:世界坐标系的原点 (0, 0, 0)

  • 标准朝向:指向 -Z 轴方向(视线沿 -Z 轴看向场景)

  • 标准向上:指向 +Y 轴方向(画面正立,不倾斜)

核心思路:我们不移动相机,而是反向移动整个场景 ------ 相机固定在标准位置不动,让场景跟着反向移动,最终相机与场景的相对位置和姿态,和"移动相机、场景不动"的效果完全一致,这样能极大简化矩阵计算。

3. View矩阵推导:两步完成(平移 + 旋转)

View矩阵由"平移矩阵"和"旋转矩阵"复合而成,矩阵运算顺序为:先平移,后旋转 ,总公式为: M t e x t v i e w = R t e x t v i e w c d o t T t e x t v i e w M_{text{view}} = R_{text{view}} cdot T_{text{view}} Mtextview=RtextviewcdotTtextview

注:齐次坐标下,矩阵运算遵循"右到左"的执行顺序,因此平移矩阵 T t e x t v i e w T_{text{view}} Ttextview 写在右侧(先执行),旋转矩阵 R t e x t v i e w R_{text{view}} Rtextview 写在左侧(后执行)。

(1)第一步:推导平移矩阵 T t e x t v i e w T_{text{view}} Ttextview(把相机移到原点)

平移的目标:将相机的初始位置 e = (eₓ, eᵧ, e_z) 移动到标准位置(0, 0, 0),本质是让整个场景向相机位置的反方向平移。

三维齐次坐标下,平移矩阵的通用格式为:KaTeX parse error: Expected 'EOF', got '&' at position 44: ...egin{bmatrix}1 &̲amp; 0 & 0 ...

为了让相机从 (eₓ, eᵧ, e_z) 移到原点,平移量需取相机位置的相反数,即: D e l t a x = − e x Delta x = -e_x Deltax=−ex, D e l t a y = − e y Delta y = -e_y Deltay=−ey, D e l t a z = − e z Delta z = -e_z Deltaz=−ez

因此,视图平移矩阵最终为:KaTeX parse error: Expected 'EOF', got '&' at position 32: ...egin{bmatrix}1 &̲amp; 0 & 0 ...

(2)第二步:推导旋转矩阵 R t e x t v i e w R_{text{view}} Rtextview(把相机朝向转到标准轴)

旋转的目标:将相机的观察方向 g 转到 -Z 轴、向上方向 t 转到 +Y 轴、相机右方向转到 +X 轴。直接写"任意方向→标准轴"的旋转矩阵很困难,这里用一个巧妙的思路:先求逆变换,再利用正交矩阵性质求最终旋转矩阵

① 构造相机自身的正交坐标系(u-v-w 坐标系)

首先基于相机的3个参数,构造出相机自身的三个正交单位向量(右手坐标系),这三个向量将作为旋转的核心依据:

  • w 向量(相机后视方向): w = − t e x t n o r m a l i z e ( g ) w = -text{normalize}(g) w=−textnormalize(g) ------ 观察方向 g 指向相机前方,w 向量则指向后方,归一化后保证是单位向量;

  • u 向量(相机右方向): u = t e x t n o r m a l i z e ( t t i m e s w ) u = text{normalize}(t times w) u=textnormalize(ttimesw) ------ 由向上方向 t 和后视方向 w 做叉乘,得到相机的右方向,归一化后为单位向量;

  • v 向量(相机真正上方向): v = w t i m e s u v = w times u v=wtimesu ------ 由 w 和 u 做叉乘,修正初始向上方向 t 的偏差,确保三个向量两两正交,构成标准右手坐标系。

② 写出逆旋转矩阵 R t e x t i n v R_{text{inv}} Rtextinv

逆旋转的含义:把世界坐标系的标准轴(X, Y, Z),旋转到相机自身的 u-v-w 坐标系(X→u,Y→v,Z→w)。这个逆旋转矩阵非常好写,直接将 u、v、w 三个向量按"列"摆放即可:

KaTeX parse error: Expected 'EOF', got '&' at position 33: ...in{bmatrix}u_x &̲amp; v_x & ...

③ 利用正交矩阵性质求 R t e x t v i e w R_{text{view}} Rtextview

我们之前学到核心性质:旋转矩阵是正交矩阵,其逆矩阵 = 转置矩阵 。而我们需要的旋转矩阵 R t e x t v i e w R_{text{view}} Rtextview,正是逆旋转矩阵 R t e x t i n v R_{text{inv}} Rtextinv 的逆矩阵,因此:

R t e x t v i e w = ( R t e x t i n v ) − 1 = ( R t e x t i n v ) T R_{text{view}} = (R_{text{inv}})^{-1} = (R_{text{inv}})^T Rtextview=(Rtextinv)−1=(Rtextinv)T

对 R t e x t i n v R_{text{inv}} Rtextinv 做转置(行变列、列变行),得到最终的视图旋转矩阵:

KaTeX parse error: Expected 'EOF', got '&' at position 34: ...in{bmatrix}u_x &̲amp; u_y & ...

(3)第三步:合并得到View矩阵最终形式

将旋转矩阵 R t e x t v i e w R_{text{view}} Rtextview 与平移矩阵 T t e x t v i e w T_{text{view}} Ttextview 相乘,即可得到完整的View矩阵:

KaTeX parse error: Expected 'EOF', got '&' at position 73: ...in{bmatrix}u_x &̲amp; u_y & ...

展开后,得到工程中最常用的最简形式(利用向量点积简化):

KaTeX parse error: Expected 'EOF', got '&' at position 34: ...in{bmatrix}u_x &̲amp; u_y & ...

注: u c d o t e ucdot e ucdote、 v c d o t e vcdot e vcdote、 w c d o t e wcdot e wcdote 分别是 u、v、w 向量与相机位置 e 的点积,本质是简化后的平移分量。

4. View矩阵推导总结(新手可直接套用)

  1. 输入已知参数:相机位置 e、观察方向 g、向上方向 t;

  2. 构造相机自身坐标系 u-v-w: w = − t e x t n o r m a l i z e ( g ) w=-text{normalize}(g) w=−textnormalize(g), u = t e x t n o r m a l i z e ( t × w ) u=text{normalize}(t×w) u=textnormalize(t×w), v = w × u v=w×u v=w×u;

  3. 构造平移矩阵 T t e x t v i e w T_{text{view}} Ttextview:平移量为 -eₓ、-eᵧ、-e_z;

  4. 构造旋转矩阵 R t e x t v i e w R_{text{view}} Rtextview:对 R t e x t i n v R_{text{inv}} Rtextinv 转置( R t e x t i n v R_{text{inv}} Rtextinv 由 u、v、w 按列摆放得到);

  5. 旋转矩阵 × 平移矩阵,得到最终View矩阵。


四、📝 本章核心总结

  1. 旋转矩阵:逆 = 转置,正交矩阵,计算超方便,是View矩阵旋转部分的核心依据;

  2. 齐次坐标:统一线性变换 + 平移,二维用 3×3 矩阵,三维用 4×4 矩阵,是View矩阵的基础;

  3. 三维旋转:绕轴分解 + 欧拉角 + 罗德里格斯公式,为View矩阵旋转提供思路;

  4. View矩阵:核心是"移场景而非移相机",由平移矩阵和旋转矩阵复合而成,推导关键是构造相机自身坐标系和利用正交矩阵性质。


五、💡 课后小任务

  • 手写推导罗德里格斯旋转公式,放入课程补充材料;

  • 尝试用正交矩阵性质,手动计算旋转逆矩阵;

  • 给定相机参数 e=(2,3,4)、g=(0,0,-1)、t=(0,1,0),手动推导View矩阵。


💬 图形学的变换看似公式繁多,实则逻辑连贯、环环相扣。只要抓住齐次坐标正交矩阵这两个核心,View矩阵的推导就会变得清晰又优雅,而掌握View矩阵,也为后续理解完整MVP变换打下了坚实基础~

相关推荐
一叶之秋14122 小时前
哈希密钥:解锁unordered容器的极速潜能
开发语言·c++·哈希算法
艾莉丝努力练剑2 小时前
剑指巅峰,磨砺芳华:我的 CSDN 创作一周年深度总结
linux·运维·服务器·c++·学习
t***5442 小时前
如何在Dev-C++中设置Clang编译参数
开发语言·c++
头发够用的程序员11 小时前
从滑动窗口到矩阵运算:img2col算法基本原理
人工智能·算法·yolo·性能优化·矩阵·边缘计算·jetson
郝YH是人间理想12 小时前
考研数学二图鉴——向量
线性代数·考研·矩阵
万法若空13 小时前
C++ <memory> 库全方位详解
开发语言·c++
代码中介商13 小时前
C++ 类型转换深度解析:static_cast、dynamic_cast、const_cast、reinterpret_cast
开发语言·c++
青小莫13 小时前
C++之string(OJ练习)
开发语言·c++·stl
6Hzlia13 小时前
【Hot 100 刷题计划】 LeetCode 199. 二叉树的右视图 | C++ DFS 逆序遍历
c++·leetcode·深度优先