本文将详细介绍OpenGL中的几个坐标系的概念,常见的几种变换,以及视图变换矩阵的推导过程,最后会分析下glm库视图变换矩阵的源码
首先,模型变换(Model),视图变换(View),投影变换(Projection)就是我们常说的三个特殊的矩阵,也经常被统一称为MVP矩阵,要理解他们,我们首先要理解几个坐标系的概念。
右手坐标系
右手坐标系与左手坐标系都是三维笛卡尔坐标系,他们唯一的不同在于z轴的方向,如下图,左边是左手坐标系,右边是右手坐标系
OpenGL中一般用的是右手坐标系
下面的几个坐标系则是在图形的渲染管线中对顶点进行变换所用到的坐标系
1.模型坐标系(Local Space)
模型坐标系(或者叫本地坐标系、局部坐标系,本文后面统一称模型坐标系)顾名思义,就是以物体的正中心为原点的坐标系,通常,我们从三维软件中导出的模型基本是局部坐标系,以模型的中心为原点,其他顶点相对于模型的原点来定义。
但是我们观察一个物体不可能从物体的中心去看它,所以我们需要将它摆放到我们的世界中,因此引入了世界坐标系,而我们的模型变换就是将物体在模型坐标系中的点转换到世界坐标系中。
2. 世界坐标系 (World Space)
世界坐标系就是全局的那个坐标系,我们的物体,以及后面观察物体用到的摄像机全都在世界坐标系中
3. 视图坐标系(View Space)
视图坐标系(或者叫观察者坐标系,本文后面统一称视图坐标系)也就是在世界坐标系中通过假想一个摄像机或者观察者的存在,以摄像机的位置为中心原点,然后从摄像机这个观察者的角度去重新计算世界中的物体相对于摄像机原点的坐标
4. 裁剪坐标系(Clip Space)
不管从哪个角度分析,能观察到的内容都是有限的,可以抽象出一个视锥体代表所观察到的区域,观察到的内容会投影到一块最终的屏幕上,类似于影院最终放映的大屏幕,放映机就是我们观察者的所在的位置,投射出的光线就是我们的视锥体,在视锥体以内的图形最终会被映射到我们的标准化设备坐标系[-1, 1]中,视锥体以外的图形则会被裁减,最终不会出现在我们的屏幕中
坐标系之间的转换
模型变换
模型变换包含三个最基本的变换(平移、旋转、缩放),任何三位空间中位置的移动都可以由这三种变换组合而成
平移
先来看看平移,假设空间中一个物体的坐标为(x,y,z),让它沿x轴,y轴,z轴分别平移一段距离后的坐标为(x + x0, y + y0, z + z0),则由线性代数的知识可以得到
其中就是我们的平移矩阵
旋转
假设固定一个坐标轴不变,将物体绕z轴旋转,则从z轴看过去,就可以简化为二维空间的旋转,推导过程如下
则二维平面中将点 (x0, y0) 绕原点逆时针旋转α角的旋转矩阵为
因此在三维空间中将一个物体沿着z轴逆时针旋转α角,就是z坐标不变,x和y逆时针旋转 α角,旋转矩阵为
同样的,沿着y轴逆时针旋转α角
沿着x轴逆时针旋转α角
缩放
缩放则比较简单,三维空间中将一个物体沿着三个轴分别缩放 sx, sy ,sz倍,则缩放矩阵为
视图变换
准备知识
在推导视图变换的矩阵前,我们得有一个先验知识,那就是旋转矩阵都是正交矩阵,正交矩阵拥有非常多不错的性质,比如
- 正交矩阵的每一列都是单位矩阵,且两两相交
- 正交矩阵的逆等于正交矩阵的转置,且正交的行列式必定为+1或-1
我们也可以简单的证明一下,比如原先物体绕z轴逆时针旋转α的旋转矩阵为
则它的相反变换也就是绕z轴顺时针旋转α(逆时针旋转 -α )的旋转矩阵为
而就是原先的旋转矩阵
的转置,且两个矩阵的行列式都为 1,正交矩阵的性质在我么推导视图变换矩阵的时候特别有用