补充

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

$$ R^{-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 $\vec{e}$
  • 相机对着哪里拍照 Look-At $\vec{g}$
  • 相机有没有绕着拍照方向旋转(因为你可以竖着手机拍照,也可以横着拍照) Up direction $\vec{t}$

第二步,如何进行View Transformation 我们上过高中物理的都知道相对运动这么一回事,所以在图形学中,我们一般不直接移动一个相机,而是让相机固定不动,而让物体相对于相机移动 那么我们应该怎么做呢? 我们先将相机位置 $\vec{e}$ 移动到原点,然后我们让相机 $\vec{g}$ 旋转到-z方向,向上方向旋转到y轴,然后剩下的绿色的轴就对其到x轴了 我们可以如下的矩阵操作完成上述任务: 我们先将 $\vec{e}$ 通过$T_{view}$平移到原点,然后通过$R_{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]\times [-1,1]$的一个可视范围就行了

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

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

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

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

Perspective Projection

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

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

此时

$$\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
我们知道我们需要通过$M_{persp->ortho}$这个矩阵进行挤压操作,那么这个矩阵应该是什么样子呢?由于我们不知道z是什么样子的所以我们只能写出 我们知道这么几个信息

  1. 在近平面上的点在挤压操作之后没有发生任何变换
  2. 在远平面上的点他们的z轴在挤压操作后也没有发生任何变换
  3. 在远平面上的中心点在挤压操作后没有发生任何变换 挤压操作是 $$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$,进行挤压操作 $$M_{persp\to ortho}^{4\times 4}\begin{bmatrix} x \\ y \\ n \\ 1 \end{bmatrix}=\begin{bmatrix} nx \\ ny \\ n^2 \\ n \end{bmatrix}$$ 所以我们可以推测$M_{persp\to ortho}^{4\times 4}$的第三行乘以这个点等于 $n^2$, 所以我们推测 $$ 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} $$ $$ \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 = 0$是成立的,但是$A = 0,B = n^2$也是成立的所以这里不能确定这个解,还需要额外的信息。
    根据信息2和信息3,我们知道远平面的中心点在挤压操作后没有发生任何变换,即
    $$ 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}$$ 这让我们知道 $$ \begin{bmatrix} 0 & 0 & A & B \end{bmatrix}\begin{bmatrix} x\\ y\\ f \\ 1 \end{bmatrix}=f^2 $$ 最后我们可以得到两个方程 $$ \left\{\begin{matrix} An+B=n^2 \\ Af+B=f^2 \end{matrix}\right. $$ 我们可以解出$A,B$ $$ \left\{\begin{matrix} A =n+f \\ B = -nf \end{matrix}\right.$$ 还记得我们之前说透视投影是挤压+正交投影吗,现在我们知道透视投影的挤压操作矩阵是
$$ 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} $$

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

$$ M_{persp} = M_{ortho} M_{persp\to ortho} $$

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

作业解析

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

$$\begin{bmatrix} 0 & 0 & n+f & -nf \end{bmatrix}\begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix}=(n+f)z-nf$$

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

$$ z' =\frac{(n+f)z-nf}{z} $$

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

$$\Delta z = z'-z =\frac{(n+f)z-nf}{z}-z=\frac{-(z^2-(n+f)z+nf)}{z}$$
  • 如果 $\Delta z > 0$则说明 $z'> z$ 更靠近近平面
  • 如果 $\Delta z < 0$则说明 $z'< z$ 更靠近远平面
  • 如果 $\Delta z = 0$则说明 $z'= z$ 不变
    注意到式子可以因式分解,有 $$\Delta z = \frac{-(z-n)(z-f)}{z}$$ 并且我们知道$0>n>z>f$ 所以
  • $(z-n)<0$
  • $(z-f)>0$
  • $-(z-n)(z-f)>0$
  • $z<0$
    所以 $\Delta z$ 永远是小于0 的所以更靠近远平面,这是我们假设在z的负半轴上进行推导的,再正半轴上同理,最后也是更靠近远平面,在正半轴我们有 $f>z>n>0$ ,且是 $\Delta z>0$ 时更靠近远平面。