1、 摄像机/观察空间
以摄像机的视角作为场景原点时场景中所有的顶点坐标:观察矩阵把所有的世界坐标变换为相对于摄像机位置与方向的观察坐标。要定义一个摄像机,需要它在世界空间中的位置、观察的方向、一个指向它右侧的向量以及一个指向它上方的向量。实际上创建了一个三个单位轴相互垂直的、以摄像机的位置为原点的坐标系。
2、 摄像机位置
获取摄像机位置很简单。摄像机位置简单来说就是世界空间中一个指向摄像机位置的向量。
glm::vec3 cameraPos = glm::vec3(0.0f,0.0f,3.0f);
注: z轴是从屏幕指向我们的,如果我们希望摄像机向后移动,我们就沿着z轴的正方向移动。
3、 摄像机方向
摄像机的方向,指的是摄像机指向的方向。根据向量相减得到的向量的方向可以知道,用场景原点减去摄像机位置向量的结果就是摄像机的指向向量。
glm::vec3 cameraTarget = glm::vec3(0.0f,0.0f,0.0f);
glm::vec3 cameraDirection = glm::normalize(cameraPos-cameraTarget);
4、 右轴
一个右向量(Right Vector)代表摄像机空间的x轴的正方向。右向量通过上向量与摄像机指向向量叉乘获得。两个向量叉乘的结果会同时垂直于两向量,因此我们会得到指向x轴正方向的那个向量(如果我们交换两个向量叉乘的顺序就会得到相反的指向x轴负方向的向量):
glm::vec3 up = glm::vec3(0.0f,1.0f,0.0f);
glm::vec3 cameraRight = glm::normalize(glm::cross(up,cameraDirection));
5、 上轴
把右向量和方向向量进行叉乘:
glm::vec3 cameraUp = glm::cross(cameraDirection,cameraRight);
6、 LookAt矩阵
使用矩阵的好处之一是如果你使用3个相互垂直(或非线性)的轴定义了一个坐标空间,你可以用这3个轴外加一个平移向量来创建一个矩阵,并且你可以用这个矩阵乘以任何向量来将其变换到那个坐标空间。上面描述了3个相互垂直的轴和一个定义摄像机空间的位置坐标,现在可以创建LookAt矩阵:
其中R是右向量,U是上向量,D是方向向量,P是摄像机位置。注意,位置向量是相反的,因为我们最终希望把世界平移到与我们自身移动的相反方向。把这个LookAt矩阵作为观察矩阵可以很高效地把所有世界坐标变换到刚刚定义的观察空间。LookAt矩阵就像它的名字表达的那样:它会创建一个看着(Look at)给定目标的观察矩阵。
使用GLM创建LookAt矩阵,把它当作观察矩阵。
glm::mat4 view;
view = glm::lookAt(glm::vec3(0.0f,0.0f,3.0f),
glm::vec3(0.0f,0.0f,0.0f),
glm::vec3(0.0f,1.0f,0.0f));