矩阵的应用
OpenGL 中常见的矩阵如模型矩阵、视图矩阵、投影矩阵简单笔记。
模型矩阵
模型矩阵是相对于世界坐标系的,包含一系列*移、缩放、旋转的变换信息的矩阵。它与点的位置没有任何关系。基本的模型矩阵有*移矩阵、缩放矩阵、旋转矩阵,模型矩阵左乘模型矩阵,还是模型矩阵。点坐标左乘模型矩阵就能得到最终变换的坐标。因此,多个顶点能共用同一个模型矩阵,一般一个模型里的所有顶点都共用一个模型矩阵。
*移矩阵
\[ \left[
\begin{matrix}
1 & 0 & 0 & X_t \\\\
0 & 1 & 0 & Y_t \\\\
0 & 0 & 1 & Z_t \\\\
0 & 0 & 0 & 1
\end{matrix}
\right]
\]
例如:Vec(2,2,0) 沿着X轴*移3,沿着Y轴*移3,则:
\[\left[
\begin{matrix}
1 & 0 & 0 & 3 \\\\
0 & 1 & 0 & 3 \\\\
0 & 0 & 1 & 0 \\\\
0 & 0 & 0 & 1
\end{matrix}
\right]
\left[
\begin{matrix}
2 \\\\
2 \\\\
0 \\\\
1
\end{matrix}
\right]
=
\left[
\begin{matrix}
5 \\\\
5 \\\\
0 \\\\
1
\end{matrix}
\right]
\]
缩放矩阵
\[\begin{bmatrix}
S_x & 0 & 0 & 0 \\\\
0 & S_y & 0 & 0 \\\\
0 & 0 & S_z & 0 \\\\
0 & 0 & 0 & 1
\end{bmatrix}
\]
旋转矩阵
点绕z轴旋转:
\[\begin{bmatrix}
\cos\theta & -\sin\theta & 0 & 0 \\\\
\sin\theta & \cos\theta & 0 & 0 \\\\
0 & 0 & 1 & 0 \\\\
0 & 0 & 0 & 1
\end{bmatrix}
\]
点绕x轴旋转:
\[\begin{bmatrix}
1 & 0 & 0 & 0 \\\\
0 & \cos\theta & -\sin\theta & 0 \\\\
0 & \sin\theta & \cos\theta & 0 \\\\
0 & 0 & 0 & 1
\end{bmatrix}\]
点绕y轴旋转:
\[\begin{bmatrix}
\cos\theta & 0 & -\sin\theta & 0\\\\
0 & 1 & 0 & 0\\\\
\sin\theta & 0 & \cos\theta & 0 \\\\
0 & 0 & 0 & 1
\end{bmatrix}\]
视图矩阵
概念:视图矩阵是本地坐标系在世界坐标系中的变换的模型矩阵的逆矩阵,因此视图矩阵也是可以分为*移、缩放、旋转的。
好吧,说点人话,一个摄像机,在世界坐标系中,经过模型矩阵M1(模型变换),从原点沿着X轴正方向前进10单位。这时候,摄像机的视图矩阵为M2,而且M2是M1的逆矩阵。M2的几何含义:假设摄像机一直原地不动,而是这个世界以M2为模型矩阵进行变换,往后移动了10个单位,也就是摄像机在世界坐标系下的*移、缩放、旋转等变换的反向过程。
作用:获得相对坐标(本地坐标)。
将视图矩阵左乘一个物体最终的模型矩阵,得到的矩阵就是所谓的“模型视图矩阵”。“模型视图矩阵”左乘一个世界坐标系下的坐标点,得到的是相对于本地坐标系的坐标点。
举个例子:一个摄像机和一个物体,一起同样的速度和方向,从世界坐标系的原点沿着X轴的正方形移动了10个单位。摄像机的视图矩阵左乘物体的模型矩阵(模型视图矩阵)表示的含义可以理解为:世界往X轴的负方向移动了10个单位,然后在沿x轴正方向移动10个单位,因此任何一个坐标点乘以这个模型视图矩阵,都不会发生变化,明显,摄像机和物体相对静止的。
投影矩阵
投影矩阵就是把三维空间投影到二维的空间。方式有正交和透视两种。
正交投影矩阵
- 作用:正交投影矩阵可以把虚拟坐标转换回归一化设备坐标(正交投影矩阵乘以虚拟坐标)。
- 归一化设备坐标:在OpenGL里,一切物体都要映射到X、Y轴和Z轴的[-1,1]范围内,这个范围内的坐标被称为归一化设备坐标,其独立于屏幕实际的尺寸。归一化设备坐标假定坐标空间是个正方形。
- 虚拟坐标空间:为了让屏幕形状考虑进来,把宽和高中较小的一个的范围定在[-1,1]内,另外一个根据屏幕尺寸比例调整为较大的范围。
正交投影矩阵如下:
\[ \left[
\begin{matrix}
\frac{2}{right-left} & 0 & 0 & -\frac{right+left}{right-left} \\\\
0 & \frac{2}{top-bottom} & 0 & -\frac{top+bottom}{top-bottom} \\\\
0 & 0 & -\frac{2}{far-near} & -\frac{far+near}{far-near} \\\\
0 & 0 & 0 & 1
\end{matrix}
\right]
\]
注意:使用的是左手坐标系还是右手坐标系,这两者的Z轴是相反的。
其实在一个顶点着色器的顶点位置(gl_Position)变为归一化设备坐标前,还会做透视除法(xyz都除以w)。
透视投影矩阵
透视投影矩阵最大的作用是产生正确的w值。w值可以理解为距离,w值越大,离中心点越*。
透视投影矩阵
\[ \left[
\begin{matrix}
\frac{α}{width/height} & 0 & 0 & 0 \\\\
0 & α & 0 & 0 \\\\
0 & 0 & -\frac{far+near}{far-near} & -\frac{2\*far\*near}{far-near} \\\\
0 & 0 & -1 & 0
\end{matrix}
\right]
\]
其中α是焦距:
\[α = \frac {1} {tan(FOV/2)}
\]
FOV是相机的垂直视角,而不是水*视角
屏幕宽度
height:屏幕高度
far: 到远处*面的距离(>0 && > near)
near: 到*处*面的距离(>0)
虚拟世界的顶点画到在屏幕上经过的变换过程
变换后的坐标 = 视口矩阵 x 投影矩阵 x 视图矩阵 x 模型矩阵 x 模型点坐标