Bootstrap

【计算机图形学基础】相机矩阵

    最近在重温计算机图形学的基础知识,期望能做到温故知新,加深对其的理解,以便能从容应对工作中各种情况。
   小弟水平有限,若有不正确之处,欢迎大家批评指正。
相关文章链接
【计算机图形学基础】线性代数基础1
【计算机图形学基础】线性代数基础2
【计算机图形学基础】相机矩阵
【计算机图形学基础】投影矩阵
【计算机图形学基础】光照模型和着色频率
【计算机图形学基础】阴影映射

1. 相机矩阵的作用

   将世界空间中的顶点,转换到相机空间中。使渲染的场景能够以相机的视角进行展示。
   相机矩阵实际是特殊的模型矩阵

2. 决定相机矩阵的因素

在这里插入图片描述

   影响相机空间的因素有三个
   ① 相机的位置(e):相机空间原点的位置。该位置默认与世界空间原点重合,即(0, 0, 0)。

   ② 相机的视线:即图中 − f ⃗ -\vec{f} f 方向。
   默认情况下,相机空间的 r ⃗ \vec{r} r 和世界空间 +X 轴重合, u ⃗ \vec{u} u 和世界空间 +Y 轴重合, f ⃗ \vec{f} f 和世界空间 +Z 轴重合;
   由于相机的视线为 − f ⃗ -\vec{f} f 方向,所以在相机空间中,所有可见顶点的z值都是负数

   ③ 相机的上方向 u ⃗ \vec{u} u
   综上,通过相机的位置和三轴方向,能够确认相机空间。

3. 相机三轴方向推导

影响相机矩阵的因素
   使用from指定相机在世界空间的位置;
   使用to指定相机视线终点在世界空间的位置;
   使用up指定相机的上方。
   将from,up,to执行一定的数学计算,就可确定相机空间的三轴的方向。
   forward向量(相机+z/+f轴):

vec3 forward = normalize(from - to)

   right向量(相机+x/+r轴):不管forward如何变化,forward必然和世界空间的up(0, 1, 0)在同一个平面中,因此可以通过下式求出相机的right:

vec3 worldUp = normalize(vec3(0, 1, 0));
vec3 right = normalize(crossProduct(worldUp, forward));

   up向量(相机+y/+u轴):right、up和forward满足右手法则,因此通过矩阵叉乘,就能求得up向量,注意叉乘的顺序:

vec3 up = normalize(crossProduct(forward, right));

   综上,求得了相机三轴在世界空间中的方向。

4. 坐标转换公式

   正交矩阵的所有列(行)向量构成了一个标准正交基(Orthonormal Bases),它的列向量(列主序)是两两垂直的单位向量。
   标准正交基可以视为对坐标系的描述:在标准参考系下,同一向量 v ⃗ \vec{v} v ,在不同坐标基下,有不同的坐标。比如, v ⃗ \vec{v} v 在坐标基 R R R下,坐标为 v ⃗ ′ \vec{v}' v ,在坐标基 Q Q Q下,坐标为 v ⃗ ′ ′ \vec{v}'' v ′′
v ⃗ = R v ⃗ ′ = Q v ⃗ ′ ′ \vec{v}=R\vec{v}'=Q\vec{v}'' v =Rv =Qv ′′
   有如下的示例:
( 1 2 6 ) = ( 1 0 0 0 1 0 0 0 1 ) ( 1 2 6 ) = ( 0 0 1 1 0 0 0 1 0 ) ( 2 6 1 ) \begin{pmatrix}1 \\ 2 \\ 6 \end{pmatrix} = \begin{pmatrix}1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix}1 \\ 2 \\ 6 \end{pmatrix} = \begin{pmatrix}0 & 0 & 1 \\ 1 & 0 & 0 \\ 0 & 1 & 0 \end{pmatrix} \begin{pmatrix}2 \\ 6 \\ 1 \end{pmatrix} 126 = 100010001 126 = 010001100 261
   上述例子中, ( 1 0 0 0 1 0 0 0 1 ) \begin{pmatrix}1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} 100010001 是正交基 R R R,同时也是通用的标准参考系,三轴分别为 ( 1 , 0 , 0 ) (1, 0, 0) (1,0,0) ( 0 , 1 , 0 ) (0, 1, 0) (0,1,0) ( 0 , 0 , 1 ) (0, 0, 1) (0,0,1)
    ( 0 0 1 1 0 0 0 1 0 ) \begin{pmatrix} 0 & 0 & 1 \\ 1 & 0 & 0 \\ 0 & 1 & 0 \end{pmatrix} 010001100 是正交基 Q Q Q ( 2 6 1 ) \begin{pmatrix}2 \\ 6 \\ 1 \end{pmatrix} 261 v ⃗ \vec{v} v 在正交基 Q Q Q下的坐标 v ⃗ ′ ′ \vec{v}'' v ′′

   可以看到,若某一坐标空间和标准参考系有相同的正交基,那么该坐标空间的正交基就是单位矩阵,因此有:
v ⃗ = R v ⃗ ′ \vec{v}=R\vec{v}' v =Rv
   所以得到坐标转换公式
v ⃗ ′ = R − 1 v ⃗ \vec{v}'=R^{-1}\vec{v} v =R1v
   由于R是正交矩阵,正交矩阵的逆矩阵等于其转置,故有:
v ⃗ ′ = R T v ⃗ \vec{v}'=R^{T}\vec{v} v =RTv

5. 相机矩阵推导

   由第3小节《相机三轴方向推导》可以得到相机三轴(right、up和forward)在世界空间中的信息。
   这三个两两垂直的单位列向量构成了一个正交基 R c a m = ( r ⃗ u ⃗ f ⃗ ) R_{cam} =\begin{pmatrix}\vec{r} & \vec{u} & \vec{f} \end{pmatrix} Rcam=(r u f ),该正交基描述的正是相机空间坐标系。
   由第4小节内容可知,应用坐标转换公式,有:
v ⃗ ′ = R c a m T v ⃗ \vec{v}'=R_{cam}^{T}\vec{v} v =RcamTv
   由于相机可能不在世界坐标的原点,因此还需要考虑相机的位移 T T T:在旋转前还需执行逆向移动。
v ⃗ ′ = R c a m T T c a m − 1 v ⃗ \vec{v}'=R_{cam}^{T}T_{cam}^{-1}\vec{v} v =RcamTTcam1v
   综上,将世界空间的点变换到相机空间的矩阵为:
R = R c a m T T c a m − 1 R = R_{cam}^{T}T_{cam}^{-1} R=RcamTTcam1
   将矩阵展开,有:
R = ( r x r y r z 0 u x u y u z 0 f x f y f z 0 0 0 0 1 ) ( 1 0 0 − T x 0 1 0 − T y 0 0 1 − T z 0 0 0 1 ) R =\begin{pmatrix}r_{x} & r_{y} & r_{z} & 0 \\u_{x} & u_{y} & u_{z} & 0 \\ f_{x} & f_{y} & f_{z} & 0 \\ 0 & 0 & 0 & 1\end{pmatrix}\begin{pmatrix}1 & 0 & 0 & -T_{x} \\ 0 & 1 & 0 & -T_{y}\\ 0 & 0 & 1 & -T{z}\\0 & 0 & 0 & 1\end{pmatrix} R= rxuxfx0ryuyfy0rzuzfz00001 100001000010TxTyTz1
   下图借鉴自popy007大佬的文章,很清晰的说明了这个过程:
相机变换
   图中黑色的正交基是通用的标准的参考系,红色的正交基是相机空间的坐标基。
   步骤① 和步骤②先后将相机旋转、移动到指定姿态和位置,如图3所示。
   此时对世界空间中所有的几何物体先后执行逆平移、逆旋转后,世界空间的所有几何体就被转换到了相机空间。

6. 参考

  1. mathematics-physics-for-computer-graphics/lookat-function
  2. 推导相机矩阵
  3. GAMES101-现代计算机图形学入门-闫令琪
;