摄像机/观察空间
程序执行效果
摄像机代码
// 摄像机
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
ourShader.setMat4("view", view);
实际上就是得到一个View Matrix
,这样就可以传送给shader program
用于计算从本地坐标系向投影坐标系、剪裁坐标系进行转换。
glm::lookAt(eye, center, up)
eye实际上就是摄像机的位置
center就是摄像机的方向
up就是上轴
eye -> cameraPos
center -> cameraPos + cameraFront
up -> cameraUp
摄像机的位置很好理解,就是3D空间中的一个点P(Vector3{x, y, z})
那么方向的量就是A(Vector3{x, y, z})到B(Vector3{x, y, z})指向(tail, head指向) [下面的代码叫方向向量不恰当,因为是相反的]
我们将两个点的空间坐标通过向量的标准化
求得方向(空间的点不是向量,和长度一样是标量):
1、cameraPos:
vec3(0.0, 0.0, 3.0);
2、cameraFront:
vec3(0.0, 0.0, -1.0); // z 轴相反的方向为摄像机向前
3、cameraPos - cameraFront:
v1 = vec3(x: 0.0, y: 0.0, z: 3.0) , v2 = vec3(x: 0.0, y: 0.0, z: -1.0)
(v1) + (-v2) = (0.0, 0.0, 3.0 + -0.0, -0.0, 1.0)
(0.0, 0.0, 4.0)
如果是相加的话:
cameraPos - cameraFront = (0.0, 0.0, 2.0)
4、cameraDirection = glm::normalize(cameraPos + cameraFront) // 也可以不用这样,直接将cameraPos + cameraFront作为方向
模等于0的向量成为0向量,模等于1的向量叫做单位向量。注意零向量的方向是任意的。由一个向量v求与它同方向的单位向量过程称为标准化(normalization),这个单位向量成为标准化向量(normalized vector)。
公式:
vector normalize = v|v| (v≠0)
carmeraDirection = (0.0, 0.0, 1.0)
5、cameraUp
右轴:
我们需要的另一个向量是一个右向量(Right Vector),它代表摄像机空间的x轴的正方向。为获取右向量我们需要先使用一个小技巧:先定义一个上向量(Up Vector)。接下来把上向量和第二步得到的方向向量进行叉乘。两个向量叉乘的结果会同时垂直于两向量,因此我们会得到指向x轴正方向的那个向量(如果我们交换两个向量叉乘的顺序就会得到相反的指向x轴负方向的向量):
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 cameraRight = glm::normalize(glm::cross(up, cameraDirection));
现在我们已经有了x轴向量和z轴向量,获取一个指向摄像机的正y轴向量就相对简单了:我们把右向量和方向向量进行叉乘:
glm::vec3 cameraUp = glm::cross(cameraDirection, cameraRight);
cameraUp = cross(cameraDirection, cross(up, cameraDirection))