数学基础
计算机图形学中大量使用了数学原理,尤其是矩阵和矩阵代数。
3D图形学中几乎每个方面、每种效果——移动、缩放、透视、纹理、光照、阴影等都在很大程度上以数学方式实现。
矩阵
图形学中大量使用了矩阵相关的操作,特别是变换矩阵、视图矩阵、模型矩阵和投影矩阵以及LookAt矩阵。
1. 变换矩阵
这里的变换矩阵指的是:平移矩阵、旋转矩阵以及缩放矩阵。尽管视图矩阵也是变换矩阵,但是为了因为它在后续会被频繁使用,于是我们给它个机会,独立介绍。
实际上,坐标系的变换可能同时包含旋转、平移和缩放,通过变换矩阵的合成功能,我们可以非常容易得到一个表示连续变换的矩阵。
2. 视图矩阵
在世界坐标系中,我们知道某个点的坐标 P w P_{w} Pw,但是在图形学中我们会构建一个虚拟相机,因此虚拟相机也有一个坐标系,我们需要在世界坐标系和虚拟相机坐标系之间进行变换,从而让虚拟相机观测到 P w P_{w} Pw 在其坐标系中的表示 P c P_{c} Pc 。
这个过程包含两个步骤:
a. 平移:首先将 P w P_{w} Pw 平移,其向量为负的期望相机位置。比如相机位置 C = [ C x , C y . C z ] T C = [C_{x}, C_{y}. C_{z}]^{T} C=[Cx,Cy.Cz]T,那么平移量为 t = [ − C x , − C y . − C z ] T t = [-C_{x}, -C_{y}. -C_{z}]^{T} t=[−Cx,−Cy.−Cz]T。
b. 旋转:将 KaTeX parse error: Expected '}', got 'EOF' at end of input: {P_{w} 旋转,其角度为负的期望相机旋转的欧拉角。原理如平移。
3. 投影矩阵
投影矩阵非常直观,就是将3D场景中的点投影到2D图像平面的变换。在SLAM中用得非常平凡,比如最经典的PNP算法,就是将3D点投影到2D平面构建重投影误差。而这个过程需要用到相机的内部参数,这个参数跟相机本身有关,因此图像学中需要为虚拟相机设置这些参数。
这里涉及到纵横比、视场、投影平面或近裁剪平面、远裁剪平面,即相机的结构,通过这些参数可以比较便捷地构相机参数。
4. LookAt矩阵
这个矩阵表示的是相机的摆放位置、朝向以看的方式。
简单理解:
a. 相机位置;相机摆放在哪里;
b. 看的方式:相机是正着摆放、还是反着摆放,这里需要有一个向量表示摆放的方式。比如人的头,我们通常是正着摆放的,所以提供一个垂直朝上的向量。如果我们歪头,那么向量就是侧的。
c. 朝向:即我们看向的方向。
代码及结果
这一讲中,我们将书中的代码进行整理并修改,使其适用于Linux系统。
详情可以参考代码:cg_book_practice/chapter_3/
这一讲的代码只有一个示例,就是构建了几个变换矩阵。
BUG
1. GLM
课本中提供的代码是直接采用了mat4这个数据类型,实际上笔者写出来发现没有该数据类型。于是通过多次查找发现,其包含于GLM中,需要声明glm头文件,并采用命名空间才可以使用。
glm::vec4 mPointPosition_;
glm::mat4 mProjMatrix_;