2450 字
12 分钟
【CG】Games101-04学习笔记 & 作业解析

补充#

旋转矩阵的转置等于旋转矩阵的逆,所以我们如果要顺时针旋转,通常我们先写出它逆时针旋转对应角度的矩阵再求转置,如果一个矩阵的转置等于它的逆,那么这个是正交矩阵。

R−1=RTR^{-1} = R^T

3D Transformations#

Scale和Translation与2维变换类似不再赘述

在3维中间中比较复杂的是旋转变换。下面的3个旋转矩阵分辨是绕着x轴、y轴、z轴进行旋转 对于任意的旋转,我们可以通过分别将其分解为绕z轴旋转、绕y轴旋转、绕x轴旋转得到 对于绕任意过原点的轴旋转我们可以使用下面这个矩阵

其中的α、β、γ\alpha、\beta、\gamma是欧拉角,这些角我们分别叫做pitch,yaw,roll

Viewing Transformation#

我们学习变换最重要的一个目的就是为了将3维空间中的物体变为一张2维空间的图片,而你在3维空间空不同的位置观察一个物体,看到的内容肯定不一样。

思考一下我们现实生活中是怎么拍一张照片的。

  • 找一个好的位置让人去摆好pose,这对应了图形学中的 Model Transformation
  • 找一个好的”角度”放置你的相机,以及调整你相机的参数,这对应了图形学中的 View Transformation
  • Cheese! ,这对应了图形学中的 Projection Transformation
    我们将这些变换统称为MVP变换

View Transformation#

第一步,我们要先定义一个相机

  • 相机的位置在哪 Position e⃗\vec{e}
  • 相机对着哪里拍照 Look-At g⃗\vec{g}
  • 相机有没有绕着拍照方向旋转(因为你可以竖着手机拍照,也可以横着拍照) Up direction t⃗\vec{t}

第二步,如何进行View Transformation 我们上过高中物理的都知道相对运动这么一回事,所以在图形学中,我们一般不直接移动一个相机,而是让相机固定不动,而让物体相对于相机移动 那么我们应该怎么做呢? 我们先将相机位置 e⃗\vec{e} 移动到原点,然后我们让相机 g⃗\vec{g} 旋转到-z方向,向上方向旋转到y轴,然后剩下的绿色的轴就对其到x轴了 我们可以如下的矩阵操作完成上述任务: 我们先将 e⃗\vec{e} 通过TviewT_{view}平移到原点,然后通过RviewR_{view}将对应的轴旋转到希望的轴上去,由于我们将相机定义的轴旋转到坐标轴上非常的麻烦,所以我们可以通过逆矩阵来完成,我们将坐标轴旋转到定义的相机轴上非常的简单。 我们将这两个矩阵相乘,得到一个View Transformation矩阵。

Projection Transformation#

投影有两个种方法,一种是透视投影,一种是正交投影 而我们人眼是使用的是透视投影,透视投影会有一个近大远小的现象,而正交投影没有

  • 透视投影在数学上的模型就是下面这幅图的左边,他是一个4棱锥,他把场景中的物体映射到一个Near clip plane和Far clip plane之间,而相机看到的画面是Near clip plane,相机在四棱锥的最上面的顶点上
  • 正交投影在数学上的模型就是下面这幅图的右边,他一个长方体,他把场景中的物体映射到一个Near plane和Far plane之间,而相机看到的画面是Near plane,相机假设是无限远的,如果我们将透视投影的相机拿到无限远处其实也就变成了正交投影

Orthographic Projection#

正交投影非常的简单

  • 把相机摆放在原点让相机看向-z轴,y轴朝上
  • 然后我们把物体的z轴丢掉
  • 最后我们把物体的x和y轴进行缩放到一个[−1,1]×[−1,1][-1,1]\times [-1,1]的一个可视范围就行了

而在图形学中我们一般这么做

  • 我们先定义一个长方体[l,r]×[b,t]×[n,f][l,r]\times [b,t]\times [n,f]
  • 在将这个长方体平移到原点
  • 然后将这个长方体缩放到一个[−1,1]×[−1,1]×[0,1][-1,1]\times [-1,1]\times [0,1]的可视范围

这个操作非常的简单,我们需要一个平移矩阵和一个缩放矩阵就行了

  • 将长方体的中心平移到原点
  • 再将长方体的长宽高都缩放到2

Perspective Projection#

透视投影在图形学中有着非常广泛的应用,它满足近大远小,平行线不再平行 我们先复习一下齐次坐标中的点,在齐次坐标中(1,0,0,1)(1,0,0,1)和(2,0,0,2)(2,0,0,2)表示的是同一个点,这个我们后面要用。
在正交投影中,我们有一个立方体,而在透视投影中我们有一个类似的4棱台(Frustum) 可以发现他们的区别是在透视投影中原平面要大一点,那么我们怎么做透视投影呢?

  • 我们先把远平面”挤压”成立方体,近平面不变,远平面的中心点不会变,这一步我们对应了一个矩阵(Mpersp−>orthoM_{persp->ortho})
  • 再做一次正交投影(),这一步我们对应了一个矩阵(MorthoM_{ortho})

此时

[xyz1]⟹[nx/zny/zunkown1]=[nxnyunkownz]\begin{bmatrix} x\\ y \\ z \\ 1 \end{bmatrix}\Longrightarrow \begin{bmatrix} nx/z \\ ny/z \\unkown \\ 1 \end{bmatrix}=\begin{bmatrix} nx \\ ny \\ unkown \\ z \end{bmatrix}

在齐次坐标中,乘上一个z后还是原来那个点 我们目前不知道z是怎么变化的,所以我们先标记为unkown
我们知道我们需要通过Mpersp−>orthoM_{persp->ortho}这个矩阵进行挤压操作,那么这个矩阵应该是什么样子呢?由于我们不知道z是什么样子的所以我们只能写出 我们知道这么几个信息

  1. 在近平面上的点在挤压操作之后没有发生任何变换
  2. 在远平面上的点他们的z轴在挤压操作后也没有发生任何变换
  3. 在远平面上的中心点在挤压操作后没有发生任何变换 挤压操作是
Mpersp→ortho4×4[xyz1]=[nxnyunkonwz]M_{persp\to ortho}^{4\times 4}\begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix}=\begin{bmatrix} nx \\ ny \\ unkonw \\ z \end{bmatrix}

根据信息1,我们知道,对近平面上的点进行挤压操作后还是原来的点,即
对于近平面上的一个点(x,y,n,z)T(x,y,n,z)^T,进行挤压操作

Mpersp→ortho4×4[xyn1]=[nxnyn2n]M_{persp\to ortho}^{4\times 4}\begin{bmatrix} x \\ y \\ n \\ 1 \end{bmatrix}=\begin{bmatrix} nx \\ ny \\ n^2 \\ n \end{bmatrix}

所以我们可以推测Mpersp→ortho4×4M_{persp\to ortho}^{4\times 4}的第三行乘以这个点等于 n2n^2, 所以我们推测

Mpersp→ortho4×4=[n0000n0000AB0010]M_{persp\to ortho}^{4\times 4} =\begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ 0 & 0 & A & B\\ 0 & 0 & 1 & 0 \end{bmatrix}[00AB][xyn1]=n2\begin{bmatrix} 0 & 0 & A & B \end{bmatrix}\begin{bmatrix} x\\ y\\ n \\ 1 \end{bmatrix}=n^2

这里B or A 不能等于0 因为如果A=n,B=0A = n,B = 0是成立的,但是A=0,B=n2A = 0,B = n^2也是成立的所以这里不能确定这个解,还需要额外的信息。
根据信息2和信息3,我们知道远平面的中心点在挤压操作后没有发生任何变换,即

Mpersp→ortho4×4[00f1]=[n0000n0000AB0010][00f1]=[00f2f]M_{persp\to ortho}^{4\times 4} \begin{bmatrix} 0 \\ 0 \\ f \\ 1 \end{bmatrix}=\begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ 0 & 0 & A & B\\ 0 & 0 & 1 & 0 \end{bmatrix}\begin{bmatrix} 0 \\ 0 \\ f \\ 1 \end{bmatrix}=\begin{bmatrix} 0 \\ 0 \\ f^2 \\ f \end{bmatrix}

这让我们知道

[00AB][xyf1]=f2\begin{bmatrix} 0 & 0 & A & B \end{bmatrix}\begin{bmatrix} x\\ y\\ f \\ 1 \end{bmatrix}=f^2

最后我们可以得到两个方程

{An+B=n2Af+B=f2\left\{\begin{matrix} An+B=n^2 \\ Af+B=f^2 \end{matrix}\right.

我们可以解出A,BA,B

{A=n+fB=−nf\left\{\begin{matrix} A =n+f \\ B = -nf \end{matrix}\right.

还记得我们之前说透视投影是挤压+正交投影吗,现在我们知道透视投影的挤压操作矩阵是

Mpersp→ortho4×4=[n0000n0000n+f−nf0010]M_{persp\to ortho}^{4\times 4} =\begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ 0 & 0 & n+f & -nf\\ 0 & 0 & 1 & 0 \end{bmatrix}

所以最后我们得到透视投影的矩阵是

Mpersp=MorthoMpersp→orthoM_{persp} = M_{ortho} M_{persp\to ortho}

在视频的最后我的偶像闫令琪老师留下了一个思考题:对于透视投影的 Frustum,我们对它进行挤压操作,我们知道对于近平面和远平面的点,它们的z轴不会变,现在要问的是对于远近平面之间的点的z,在挤压之后z怎么变?变大还是变小还是不变(推向近平面还是远平面)? 这个问题我们作为作业留到作业解析中分析。

作业解析#

什么?作业0今天才放出来,我们已经在02中写过了。看作业解析请移步到02的文章,这里我们解决这个思考题。 根据我们最后推导得到的Mpersp→orthoM_{persp\to ortho}对于近平面和远平面之间的任何一个点(x,y,z,1)T(x,y,z,1)^T我们对它进行挤压操作,只考虑分量zz,有

[00n+f−nf][xyz1]=(n+f)z−nf\begin{bmatrix} 0 & 0 & n+f & -nf \end{bmatrix}\begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix}=(n+f)z-nf

这个点的zz在齐次坐标下等价于

z′=(n+f)z−nfzz' =\frac{(n+f)z-nf}{z}

由于我们想知道它是更靠近远平面还是近平面,我们拿这个变化后的点与变化前的点进行比较

Δz=z′−z=(n+f)z−nfz−z=−(z2−(n+f)z+nf)z\Delta z = z'-z =\frac{(n+f)z-nf}{z}-z=\frac{-(z^2-(n+f)z+nf)}{z}
  • 如果 Δz>0\Delta z > 0则说明 z′>zz'> z 更靠近近平面
  • 如果 Δz<0\Delta z < 0则说明 z′<zz'< z 更靠近远平面
  • 如果 Δz=0\Delta z = 0则说明 z′=zz'= z 不变
    注意到式子可以因式分解,有
Δz=−(z−n)(z−f)z\Delta z = \frac{-(z-n)(z-f)}{z}

并且我们知道0>n>z>f0>n>z>f 所以

  • (z−n)<0(z-n)<0
  • (z−f)>0(z-f)>0
  • −(z−n)(z−f)>0-(z-n)(z-f)>0
  • z<0z<0
    所以 Δz\Delta z 永远是小于0 的所以更靠近远平面,这是我们假设在z的负半轴上进行推导的,再正半轴上同理,最后也是更靠近远平面,在正半轴我们有 f>z>n>0f>z>n>0 ,且是 Δz>0\Delta z>0 时更靠近远平面。

Games101

已完结

第 4 篇,共 14 篇本文属于系列

【CG】Games101-04学习笔记 & 作业解析
https://blog.cglab.top/posts/games_series/games101_04/
作者
Artichoke
发布于
2026-03-27
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取

最后更新于 ,距今已过 211 天

部分内容可能已过时