title: OpenGL(8)之摄像机
date: 2020-07-12 16:37
category: 图形学
tags: opengl
link:OpenGL(8)之摄像机
0.前言
OpenGL本身没有摄像机概念,但是可以通过场景中的所有物体往相反方向移动的方式来模拟摄像机,产生一种我们在移动的感觉,而不是场景在移动。
1.摄像机/观察空间
摄像机/观察空间(Camera/View Space)的概念是观察的以摄像机的视角作为场景原点时,场景中所有的顶点坐标,视图矩阵把所有的世界坐标变换为相对于摄像机位置与方向的视图空间坐标。
定义一个摄像机,需要它在世界空间中的位置,观察方向(摄像机的方向),一个指向其右侧的向量和一个指向其上方的向量。
从上述概念中可得知:摄像机的位置以及摄像机的方向,
- 摄像机的位置
在世界空间中定义一个指向摄像机位置的向量即可,通过GLM的内置函数定义一个位置向量:
glm::vec3 cameraPos = glm::vec3(0.0f,0.0f,3.0f);
- 摄像机方向(z轴)
在OpenGL中使用的是右手坐标系,z轴的正方向是从屏幕指向你的,如果希望摄像机向后移动,
就需要将场景沿着z轴正方向移动;
假设物体的正面朝向z轴正方向(该物体的z方向分量为大于0),那么想用摄像机观察这个物体的正面,需要将摄像机放在物体所在位置沿着z轴正方向平移一段距离(其实这里就是相当于摄像机和物体同时处于z轴正方向,即摄像机前移了),并让摄像机的朝向指向物体的正面。
由于使用的是右手坐标系,所以摄像机的z轴正方向应该是在摄像机的后面,下图摄像机蓝色轴
那么摄像机指向目标的方向向量根据向量减法来求得,需要通过目标的位置向量减去摄像机的位置向量,这个求出来的指向目标的方向向量的方向与摄像机z轴的方向相反,我们需要做出相应的方向向量调整以便构建摄像机的观察坐标系,因此,需要用摄像机的位置向量减去目标的位置向量。
glm::vec3 cameraTarget = glm::vec3(0.0f,0.0f,0.0f);
glm::vec3 cameraDirection = glm::normalize(cameraPos-cameraTarget);
- 右轴的概念(x轴)
右向量代表的是摄像机空间的x轴的正方向。为获取右向量,可通过矩阵的叉乘运算来求的,定义一个上向量,把上向量与第2步求的方向向量(z轴)进行叉乘,结果会同时垂直于两个向量,因此会得到指向x轴正方向的那个向量,(如果交换两个向量叉乘的顺序即z*y会得到相反的指向x轴的向量);
glm::vec3 up = glm::vec3(0.0f,1.0f,0.0f);
glm::vec3 cameraRight = glm::normalize(glm::cross(up,cameraDirection));
- 上轴的概念(y轴)
有了x轴向量和z轴向量,获取一个指向摄像机的正y轴向量就相对简单了,
只需要将右向量和方向向量进行叉乘;
glm::vec3 cmeraUp = glm::cross(cameraDirecton,cameraRight);
2.Look At矩阵
使用该矩阵是为了创建一个观察给定目标的观察矩阵,这样做的好处就是如果是3个相互垂直(非线形)的轴定义了一个坐标空间(就是以摄像机为中心点创建的一个坐标空间),可使用3个轴外加一个平移向量来创建该坐标空间,进行场景中物体的观测,并且还可以利用该矩阵乘以任意向量将该物体变换到这个空间中。
通过3个互相垂直的轴和一个定义的摄像机空间的位置坐标,就可以创建Look At矩阵了。
L o o k A t =