文章

GAMES101 第4讲 观察变换(视图变换与投影变换)

GAMES101 第4讲 观察变换(视图变换与投影变换)

观察变换

观察变换(Viewing Transform)是将世界坐标系中的物体变换到裁剪坐标系中的过程

视图/相机变换

相机坐标系

视图/相机变换(View/Camera Transform)是将世界坐标系中的物体变换到相机坐标系中的过程

摆放相机

视图变换是在摆放照相机, 所以我们要定义相机的参数:

  • 坐标(Position): $\vec{e}$
  • 观察方向(Look At/Gaze): $\hat{g}$
  • 上方向(Up): $\hat{t}$

为了方便理解的相机参数

为了方便计算和理解, 我们认为相机坐标系是:

  1. 相机坐标永远位于原点
  2. 相机的上方向永远是 $y$ 轴方向
  3. 相机的观察方向永远是 $z$ 轴方向, 即 $-z$方向
  4. 所有物体随着相机的移动而移动

视图变换矩阵

相机的转换

假如相机本身的坐标是 $\vec{e}$, 观察方向是 $\hat{g}$, 上方向是 $\hat{t}$, 那么将其转换为相机坐标系的操作则有:

  1. 将 $\vec{e}$ 移动到原点
  2. 将 $\hat{g}$ 转换为 $-z$ 轴
  3. 将 $\hat{t}$ 转换为 $y$ 轴
  4. 将 $\hat{g} \times \hat{t}$ 转换为 $x$ 轴

将以上操作写成矩阵的形式:

\[M_{view} = R_{view} \cdot T_{view}\]

其中 $R_{view}$ 为旋转矩阵部分, $T_{view}$ 为平移矩阵部分

\[T_{view} = \begin{bmatrix} 1 & 0 & 0 & -x_e \\ 0 & 1 & 0 & -y_e \\ 0 & 0 & 1 & -z_e \\ 0 & 0 & 0 & 1 \end{bmatrix}\]

通过从$\hat{g} \times \hat{t}, \hat{t}, -\hat{g}$ 旋转到 $x, y, z$ 轴来直接推导旋转矩阵较为困难

但是已知 $x, y, z$ 轴的单位向量 , 求旋转到 $\hat{g} \times \hat{t}, \hat{t}, -\hat{g}$ 的旋转矩阵 $R_{view}^{-1}$ 是比较容易的

同时又因为旋转矩阵是正交矩阵, 所以有 $R_{view}^T = R_{view}^{-1}$

\[R_{view}^{-1} = \begin{bmatrix} x_{\hat{g} \times \hat{t}} & x_{\hat{t}} & x_{-\hat{g}} & 0 \\ y_{\hat{g} \times \hat{t}} & y_{\hat{t}} & y_{-\hat{g}} & 0 \\ z_{\hat{g} \times \hat{t}} & z_{\hat{t}} & z_{-\hat{g}} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}\] \[R_{view} = (R_{view}^{-1})^T = \begin{bmatrix} x_{\hat{g} \times \hat{t}} & y_{\hat{g} \times \hat{t}} & z_{\hat{g} \times \hat{t}} & 0 \\ x_{\hat{t}} & y_{\hat{t}} & z_{\hat{t}} & 0 \\ x_{-\hat{g}} & y_{-\hat{g}} & z_{-\hat{g}} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}\]

投影变换

投影变换(Projection Transform)是将相机坐标系中的物体变换到裁剪坐标系中的过程

正交投影与透视投影

投影变换分为正交投影(Orthographic Projection)透视投影(Perspective Projection)

正交投影

正交投影的简单理解

较为简单的理解:

  1. 相机放在原点, 观察方向是 $-z$ 轴, 向上方向是 $y$ 轴
  2. 将物体的 $z$ 坐标直接扔掉, 保留 $x, y$ 坐标
  3. 将 $x, y$ 坐标映射到 $[-1, 1]^2$ 的范围内(方便后续裁剪)

正交投影的图形学过程

在图形学中的正交投影:

  1. 在空间中定义一个立方体, 并规定其左右, 下上, 远近的边界分别在 $x, y, z$ 轴上的范围 $[l, r], [b, t], [f, n]$
  2. 将这个立方体映射到 $[-1, 1]^3$ 的正则立方体(Canonical Cube)中
    • 将立方体的中心移动到原点
    • 将 $x, y, z$ 轴分别拉伸到 $[-1, 1]$ 的范围内
  3. 注意: 不会抛弃 $z$ 轴的值, $z$ 值越小, 距离相机越远

矩阵的形式为(先平移再缩放):

\[M_{ortho} = S_{ortho} \cdot T_{ortho} = \begin{bmatrix} \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{bmatrix} \begin{bmatrix} 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{bmatrix}\]

左右手坐标系的不同会导致 $z$ 轴的方向不同, 所以在计算时要注意

透视投影

透视投影使用的最广泛的投影方式, 也是人眼看到的世界的投影方式

回顾: $(x, y, z, 1)$ 与 $(kx, ky, kz, k)$ 表示的是三维空间的同一个点 $(x, y, z)$ , 注意$k \neq 0$

因此, $(xz, yz, z^2, z)$ 与 $(x, y, z, 1)$ 表示的是三维空间的同一个点 $(x, y, z)$ , 注意$z \neq 0$

透视投影

  1. 先将视锥体的远端平面”挤压“到和近端平面齐平的位置, 此时成为了一个立方体
  2. 将立方体映射到 $[-1, 1]^3$ 的正则立方体(Canonical Cube)中, 操作类似于正交投影

挤压的过程中为了便于理解和计算, 我们规定:

近端平面的所有坐标都不变, 视锥体远端平面的 $z$ 坐标也都不变, 远端平面中心点的所有坐标也不发生变化, 此时挤压操作只有唯一解

挤压

根据相似三角形, 所有点的

\[x' = \frac{n}{z}x\] \[y' = \frac{n}{z}y\]

在齐次坐标中, 有:

\[\begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix} \rightarrow \begin{bmatrix} \frac{nx}{z} \\ \frac{ny}{z} \\ unknown \\ 1 \end{bmatrix} == \begin{bmatrix} nx \\ ny \\ still unknown \\ z \end{bmatrix}\]

我们想要知道挤压矩阵 $M_{persp \rightarrow ortho}^ {4 \times 4}$ 的形式, 使得:

\[M_{persp \rightarrow ortho}^ {4 \times 4} \begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix} = \begin{bmatrix} nx \\ ny \\ unknown \\ z \end{bmatrix}\]

可以反推出:

\[M_{persp \rightarrow ortho}^ {4 \times 4} = \begin{bmatrix} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ ? & ? & ? & ? \\ 0 & 0 & -1 & 0 \end{bmatrix}\]

又由于近端平面的所有坐标都不变, 我们假设有一个近平面上的点 $(x, y, n)$, 则有:

\[M_{persp \rightarrow ortho}^ {4 \times 4} \begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix} = \begin{bmatrix} nx \\ ny \\ unknown \\ z \end{bmatrix} \xrightarrow{z = n} \begin{bmatrix} x \\ y \\ n \\ 1 \end{bmatrix} \rightarrow \begin{bmatrix} x \\ y \\ n \\ 1 \end{bmatrix} == \begin{bmatrix} nx \\ ny \\ n^2 \\ n \end{bmatrix}\]

我们可以推断出矩阵的第三行 $\begin{bmatrix}0 & 0 & A & B \end{bmatrix}$ 满足:

\[\begin{bmatrix} 0 & 0 & A & B \end{bmatrix} \begin{bmatrix} x \\ y \\ n \\ 1 \end{bmatrix} = n^2\]

由于远端平面的中心点的坐标不变, 我们假设有一个远平面上的中心点 $(0, 0, f)$, 则有:

\[M_{persp \rightarrow ortho}^ {4 \times 4} \begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix} = \begin{bmatrix} nx \\ ny \\ unknown \\ z \end{bmatrix} \xrightarrow{x = 0 y = 0 z = f} \begin{bmatrix} 0 \\ 0 \\ f \\ 1 \end{bmatrix} \rightarrow \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} 0 & 0 & A & B \end{bmatrix} \begin{bmatrix} 0 \\ 0 \\ f \\ 1 \end{bmatrix} = f^2\]

综上有:

\[An + B = n^2 \\ Af + B = f^2\]

解方程得到:

\[A = n + f \\ B = -nf\]

所以挤压操作的矩阵形式为:

\[M_{persp \rightarrow 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} \cdot M_{persp \rightarrow ortho} = M_{ortho} \cdot M_{persp \rightarrow ortho}^ {4 \times 4}\]

思考: 在挤压操作时, 远端平面与近端平面中间的 $z$ 坐标是如何变化的? 变得更远(z更小)还是更近(z更大)?

本文由作者按照 CC BY 4.0 进行授权