最近在重温计算机图形学的基础知识,期望能做到温故知新,加深对其的理解,以便能从容应对工作中各种情况。
小弟水平有限,若有不正确之处,欢迎大家批评指正。
相关文章链接:
【计算机图形学基础】线性代数基础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 。
综上,通过相机的位置和三轴方向,能够确认相机空间。
使用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));
综上,求得了相机三轴在世界空间中的方向。
相机在世界空间中位置: e y e eye eye = ( x e y e z e ) T \begin{pmatrix}x_{e} & y_{e} & z_{e}\end{pmatrix}^{T} (xeyeze)T;
相机在世界空间三轴: r ⃗ \vec{r} r、 u ⃗ \vec{u} u 和 f ⃗ \vec{f} f 。
若要把世界空间中的顶点转换到相机空间,需要执行如下步骤:
① 将相机eye位置平移到原点;
② 将 − f ⃗ -\vec{f} −f 旋转到 − Z -Z −Z;
③ 将 u ⃗ \vec{u} u 旋转到 Y Y Y;
④ 将 r ⃗ \vec{r} r 旋转到 X X X。
经过上述步骤后能得到一个复合矩阵,将其应用到世界空间中所有顶点,就可以将这些顶点都转换到相机空间。
步骤①很好完成,但步骤②、③、④比较困难。但是,如线性代数基础中所述,旋转矩阵是正交阵,其逆变换等于转置。
因此,可以考虑将坐标轴 X ⃗ Y ⃗ Z ⃗ \vec{X}\vec{Y}\vec{Z} XYZ旋转到坐标轴 r ⃗ u ⃗ f ⃗ \vec{r}\vec{u}\vec{f} ruf,然后求其逆矩阵。
①中的平移矩阵如下:
T = ( 1 0 0 − x e 0 1 0 − y e 0 0 1 − z e 0 0 0 1 ) T = \begin{pmatrix}1 & 0 & 0 & -x_{e}\\0 &1 & 0 & -y_{e}\\0 & 0 & 1 & -z_{e}\\0 & 0 & 0 & 1\end{pmatrix} T=⎝ ⎛100001000010−xe−ye−ze1⎠ ⎞
将 X ⃗ \vec{X} X = ( 1 0 0 0 ) T \begin{pmatrix}1 & 0 & 0 & 0\end{pmatrix}^{T} (1000)T旋转至 u ⃗ \vec{u} u ⊗ \otimes ⊗ f ⃗ \vec{f} f;
将 Y ⃗ \vec{Y} Y = ( 0 1 0 0 ) T \begin{pmatrix}0 & 1 & 0 & 0\end{pmatrix}^{T} (0100)T旋转至 u ⃗ \vec{u} u;
将 Z ⃗ \vec{Z} Z = ( 0 0 1 0 ) T \begin{pmatrix}0 & 0 & 1 & 0\end{pmatrix}^{T} (0010)T旋转至 f ⃗ \vec{f} f;
上述旋转矩阵 R R R 如下所示:
( x u ⃗ ⊗ f ⃗ x u ⃗ x f ⃗ 0 y u ⃗ ⊗ f ⃗ y u ⃗ y f ⃗ 0 z u ⃗ ⊗ f ⃗ z u ⃗ z f ⃗ 0 0 0 0 1 ) \begin{pmatrix}x_{\vec{u} \otimes \vec{f}} & x_{\vec{u}} & x_{\vec{f}} & 0\\y_{\vec{u} \otimes \vec{f}} & y_{\vec{u}} & y_{\vec{f}} & 0\\z_{\vec{u} \otimes \vec{f}} & z_{\vec{u}} & z_{\vec{f}} & 0\\ 0 & 0 & 0 &1 \end{pmatrix} ⎝ ⎛xu⊗fyu⊗fzu⊗f0xuyuzu0xfyfzf00001⎠ ⎞
可以对矩阵 R R R 进行验证, R R R X ( 1 0 0 0 ) \begin{pmatrix}1 \\ 0 \\ 0 \\0\end{pmatrix} ⎝ ⎛1000⎠ ⎞ = ( x u ⃗ ⊗ f ⃗ y u ⃗ ⊗ f ⃗ z u ⃗ ⊗ f ⃗ 0 ) \begin{pmatrix}x_{\vec{u} \otimes \vec{f}} \\ y_{\vec{u} \otimes \vec{f}} \\ z_{\vec{u} \otimes \vec{f}} \\0\end{pmatrix} ⎝ ⎛xu⊗fyu⊗fzu⊗f0⎠ ⎞
R R R X ( 0 1 0 0 ) \begin{pmatrix}0 \\ 1 \\ 0 \\0\end{pmatrix} ⎝ ⎛0100⎠ ⎞ = ( x u ⃗ y u ⃗ z u ⃗ 0 ) \begin{pmatrix}x_{\vec{u}} \\ y_{\vec{u}} \\ z_{\vec{u}} \\0\end{pmatrix} ⎝ ⎛xuyuzu0⎠ ⎞ R R R X ( 0 0 1 0 ) \begin{pmatrix}0 \\ 0 \\ 1 \\0\end{pmatrix} ⎝ ⎛0010⎠ ⎞ = ( x f ⃗ y f ⃗ z f ⃗ 0 ) \begin{pmatrix}x_{\vec{f}} \\ y_{\vec{f}} \\ z_{\vec{f}} \\0\end{pmatrix} ⎝ ⎛xfyfzf0⎠ ⎞
矩阵 R R R分别乘以 X ⃗ \vec{X} X、 Y ⃗ \vec{Y} Y、 Z ⃗ \vec{Z} Z,得到了它们旋转后的位置。
上述矩阵 R R R 可以理解为:矩阵 R R R 代表了一个变换,将当前 X ⃗ \vec{X} X、 Y ⃗ \vec{Y} Y、 Z ⃗ \vec{Z} Z这组标准正交基转换到一组新的正交基中,这组新的正交基分别为 R c o l 1 R_{col1} Rcol1、 R c o l 2 R_{col2} Rcol2 和 R c o l 3 R_{col3} Rcol3。
现对 R R R求逆,即求转置,有 R − 1 R^{-1} R−1 = R T R^{T} RT:
( x u ⃗ ⊗ f ⃗ y u ⃗ ⊗ f ⃗ z u ⃗ ⊗ f ⃗ 0 x u ⃗ y u ⃗ z u ⃗ 0 x f ⃗ y f ⃗ z f ⃗ 0 0 0 0 1 ) \begin{pmatrix}x_{\vec{u} \otimes \vec{f}} & y_{\vec{u} \otimes \vec{f}} & z_{\vec{u} \otimes \vec{f}} & 0\\x_{\vec{u}} & y_{\vec{u}} & z_{\vec{u}} & 0\\x_{\vec{f}} & y_{\vec{f}} & z_{\vec{f}} & 0\\ 0 & 0 & 0 &1 \end{pmatrix} ⎝ ⎛xu⊗fxuxf0yu⊗fyuyf0zu⊗fzuzf00001⎠ ⎞
综上,相机矩阵 R c a m R_{cam} Rcam是一个复合矩阵,其结果为:
R c a m R_{cam} Rcam = R T R^{T} RT T T T,其中 R T R^{T} RT和 T T T见上述的推导。