我浏览了一些OpenGL学习资源,其中一篇是这篇文章:Modern OpenGL 04-Cameras,Vectors&Input,作者在其中提出了一种构建Camera类的方法,该类可用于导出视图和投影矩阵。

在随附的源代码中,有一个函数将相机的方向作为变换矩阵(永久链接到源代码)返回,该函数的实现方式如下:

glm::mat4 Camera::orientation() const {
    glm::mat4 orientation;
    orientation = glm::rotate(orientation, glm::radians(_verticalAngle), glm::vec3(1,0,0));
    orientation = glm::rotate(orientation, glm::radians(_horizontalAngle), glm::vec3(0,1,0));
    return orientation;
}


如果我想相对于相机所面对的方向平移相机,那么我会假设我可以将方向矩阵乘以平移矢量来获得一个新的矢量,该矢量可以在相机中进行平移相机朝向的方向。

但是,这并不能产生我所期望的结果。在查看了前,上和右轴的派生方式(永久链接到源代码)后:

glm::vec3 Camera::forward() const {
    glm::vec4 forward = glm::inverse(orientation()) * glm::vec4(0,0,-1,1);
    return glm::vec3(forward);
}

glm::vec3 Camera::right() const {
    glm::vec4 right = glm::inverse(orientation()) * glm::vec4(1,0,0,1);
    return glm::vec3(right);
}

glm::vec3 Camera::up() const {
    glm::vec4 up = glm::inverse(orientation()) * glm::vec4(0,1,0,1);
    return glm::vec3(up);
}


我可以看到我需要将平移矢量与方向矩阵的倒数以获得预期的结果,但我不明白为什么。方向不是本文使用的方向吗?如果是这种情况,那为什么我需要求逆?

评论

我猜作者实际上是计算取向的反方向,因为他在Camera :: view然后在Camera :: matrix中调用了这个取向,而没有对其进行转置或反转。并且由于glfwGetCursorPos将为您提供翻转的Y坐标,因此方向的确会巧合地计算方向的倒数。但是X坐标不会翻转,这应该会引起问题,但我无法解释为什么不会。

#1 楼

人们总是会忘记OpenGL中没有“相机”。为了模拟相机,您必须反向移动整个世界。因此,如果您想让相机向下看30度,就可以将整个世界向上移动30度。如果您想将摄像机向左移动,则将整个世界向右移动。这就是为什么您会在翻译向量中使用"-"变量的地方注意到position符号的原因。

因此,openGL中没有单独的“视图”矩阵,因此将模型视图矩阵组合在一起。这就是采取逆运算的原因。由于视图矩阵代表的是相机的前,上和侧面,因此必须取相反的值,因为方向是针对世界而非相机定义的。

评论


$ \ begingroup $
现在,我已经阅读了您的答案,代码变得很有道理了。我有一个预感,就是这样,但还不太清楚。谢谢!在调查问题时,我还偶然发现了这篇文章,该文章更详细地解释了您所写的内容:3dgep.com/understanding-the-view-matrix。也许其他人也会发现它也很有用。
$ \ endgroup $
– MihaiBişog
17年9月6日在16:02



#2 楼

首先,您要讨论矩阵中点的反方向,这是必需的,因为世界变换中的减法逻辑与屏幕旋转直接相关,相反,摄影机运动(您提到的平移)与屏幕位置直接相关围绕投影中心。