视图变换 Viewing transformation
1.视图变换 Viewing Transformation
视图变换的目的是将三维空间中的点\((x, y, z)\)(在世界坐标系中)映射到平面图像中(二维坐标系),以像素为基本表示单位。类似通过相机拍照得到一张相片。视图变换主要包括三个步骤:
- 相机变换(camera/view transformation)
- 投影变换(projection transformation)
- 视口变换(viewport transformation)

2.相机变换 Camera Transformation

相机变换的目的是得到所有可是物体与相机的相对位置,通常包括平移、旋转、缩放。
规定相机拍摄方向朝向-Z,相机的位置位于e,相机的正上方用向量t来表示,相机的朝向用g表示,\(\overrightarrow{e}=(x_e, y_e, z_e)\)。首先将相机点平移至世界坐标原点,平移矩阵为: \[ T_{\text {view }}=\left[\begin{array}{cccc} 1 & 0 & 0 & -x_{e} \\ 0 & 1 & 0 & -y_{e} \\ 0 & 0 & 1 & -z_{e} \\ 0 & 0 & 0 & 1 \end{array}\right] \] 然后,对相机坐标进行旋转变换,使其与世界坐标系重合。需要将相机朝向g旋转到-Z轴上,t旋转到Y轴上,再通过g叉乘t的方向旋转到X。然而,这个旋转对应的旋转矩阵并不容易写出,但是如果将Z旋转到-g,将Y旋转到t,将X旋转到g叉积t的方向,直接取旋转矩阵的逆矩阵\(R^{-1}=(u,v,w)\)即可[1],其中\(u=\hat{g} \times \hat{t},v=\hat{t},w = -\hat{g}\),因此旋转矩阵的逆矩阵和旋转矩阵可以写成: \[ R_{\text {view }}^{-1}=\left[\begin{array}{cccc} x_{\hat{g} \times \hat{t}} & x_{t} & x_{-g} & 0 \\ y_{\hat{g} \times \hat{t}} & y_{t} & y_{-g} & 0 \\ z_{\hat{g} \times \hat{t}} & z_{t} & z_{-g} & 0 \\ 0 & 0 & 0 & 1 \end{array}\right] \quad \Rightarrow \quad R_{\text {view }}=\left[\begin{array}{cccc} x_{\hat{g} \times \hat{t}} & y_{\hat{g} \times \hat{t}} & z_{\hat{g} \times \hat{t}} & 0 \\ x_{t} & y_{t} & z_{t} & 0 \\ x_{-g} & y_{-g} & z_{-g} & 0 \\ 0 & 0 & 0 & 1 \end{array}\right] \] 所以最终的相机变换矩阵为:\(M_{\text {view }}=R_{\text {view }}T_{\text {view }}\)。
PS: 从世界坐标系变换到相机坐标系属于刚体变换:即物体不会发生形变,只需要进行旋转和平移。
3.投影变换 Projection Transformation

投影变换的目的是将相机空间中的点映射到\([-1, 1]^3\)的立方体上,并且相机\(e=0\)的射线穿过里立方体中心。这样的立方体叫做规范视图体(Canonical View Volume)或者标准化设备坐标系(normalized device coordinates)。投影变换可以分为两个步骤进行:
- 正交投影(orthographic projection)
- 透视投影(perspection projection)
透视投影
透视投影就是最类似人眼所看东西的方式,遵循近大远小,通过投影到平面来进行解释。
图中的原点代表视点,
Z=-n
表示近平面(投影平面),Z=-z
表示远平面,需要进行压缩。利用相似三角形可以计算出\(y^{'}=\frac{n}{z}y, x^{'}=\frac{n}{z}x\),假定透视矩阵为P,我们计算透视投影后的齐次坐标。 \[ P\left[\begin{array}{c} x \\ y \\ z \\ 1 \end{array}\right] = \left[\begin{array}{c} nx \\ ny \\ ? \\ z \end{array}\right] \quad \Rightarrow \quad P=\left[\begin{array}{cccc} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ ? & ? & ? & ? \\ 0 & 0 & 0 & 1 \end{array}\right] \] 中间的?
可以通过远平面Z=-f
和近平面Z=-n
的值来计算,当Z=-f
时,前面的单独?
为\(f^2\),当Z=-n
时,前面的单独?
为\(n^2\)。假设第三行为\((0,0,A,B)\),分别带入n
和f
可以列出两个等式: \[ \begin{array}{l} A_{n}+B=n^{2} \\ A_{f}+B=f^{2} \\ \end{array} \quad \Rightarrow \quad \begin{array}{l} A=n+f \\ B=-nf \\ \end{array} \]最后的透视投影的变换矩阵为: \[ M_{persp \to -ortho} = P=\left[\begin{array}{cccc}n & 0 & 0 & 0 \\0 & n & 0 & 0 \\0 & 0 & n+f & -nf \\0 & 0 & 0 & 1\end{array}\right] \] 通过计算可知,远平面通过透视投影矩阵的变换后,该平面会沿着Z轴的反向移动,即远离近平面。
正交投影
正交投影变换坐标的相对位置都不会改变,所有光线都是平行传播,只需将物体全部转换到\([-1,1]^3\)的立方体中,主要的操作有平移和旋转。
通过计算可以求得立方体的中心点为\((x_0, y_0, z_0)\),其中\(x_0=-\frac{r+l}{2}, y_0=-\frac{t+b}{2},z_0=-\frac{n+f}{2}\)。因此平移矩阵可以表示为: \[ T=\left[\begin{array}{cccc} 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{array}\right] \] 接下来就需要求缩放矩阵,-1到1的间距为2,而物体在各个轴上的间距分别为\(\: l-r,b-t,n-f\),因此,在各个轴方向的缩放因子可以表示为\(S_x=\frac{2}{l-r}, S_y=\frac{2}{b-t},S_z=\frac{2}{n-f}\)。所以缩放矩阵可以表示为: \[ S=\left[\begin{array}{cccc} \frac{2}{l-r} & 0 & 0 & 0 \\ 0 & \frac{2}{b-t}& 0 & 0 \\ 0 & 0 & \frac{2}{n-f} & 0 \\ 0 & 0 & 0 & 1 \end{array}\right] \] 计算完两个矩阵之后,可以知道最终的正交投影矩阵为两个矩阵的乘积\(M_{orth}=S \times T\): \[ M_{orth}=\left[\begin{array}{cccc} \frac{2}{l-r} & 0 & 0 & 0 \\ 0 & \frac{2}{b-t}& 0 & 0 \\ 0 & 0 & \frac{2}{n-f} & 0 \\ 0 & 0 & 0 & 1 \end{array}\right] \left[\begin{array}{cccc} 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{array}\right] = \left[\begin{array}{cccc} \frac{2}{l-r} & 0 & 0 & -\frac{r+l}{2} \\ 0 & \frac{2}{b-t}& 0 & -\frac{t+b}{2} \\ 0 & 0 & \frac{2}{n-f} & -\frac{n+f}{2} \\ 0 & 0 & 0 & 1 \end{array}\right] \] 3.投影变换矩阵
通过上述的两个矩阵的乘积可以得出最终的变换矩阵\(M_{per} = M_{orhto}M_{persp \to -ortho}\) \[ M_{per} = \left[\begin{array}{cccc} \frac{2n}{l-r} & 0 & -\frac{l+r}{l-r} & 0 \\ 0 & \frac{2n}{b-t}& -\frac{b+t}{b-t} & 0 \\ 0 & 0 & \frac{n+f}{n-f} & -\frac{2nf}{n-f} \\ 0 & 0 & 1 & 0 \end{array}\right] \]
4.视口变换 viewport transformation
经过上述变换,可以将任意三维空间中的物体投影到标准立方体上,但是之后还需要投影到\(2 \times2\)的二维平面(栅格图像)上进行显示,高度为H,宽度为W,单位为像素。所以,需要将标准立方体中的中的点,转换到屏幕上,所以还是需要先平移,再缩放,形式同正交矩阵: \[ M_{viewport}=\left[\begin{array}{cccc} \frac{W}{2} & 0 & 0 & \frac{W}{2} \\ 0 & \frac{H}{2}& 0 & \frac{H}{2} \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{array}\right] \]
栅格图像(Raster Image),也称为位图(Bitmap),是由像素阵列组成的数字图像。在栅格图像中,每个像素都包含一个特定的颜色值或灰度值,以描述图像中相应位置的颜色和亮度。与矢量图形不同,栅格图像是像素化图像,它通常使用像素阵列来表示图像。每个像素都具有一个X和Y坐标,并包含一个或多个数字值来表示其颜色信息。这些数字值通常使用8位或更高位深度来表示,以提供足够的精度来描述图像细节。
PS: NeRF中只需要进行投影变换。因为NeRF将相对于世界坐标的相机坐标点作为MLP的输入,它也没有使用视口变换,因为信息是从多层感知器(MLP)中隐式查询而不是从测量对象构建的。