计算相机视图矩阵

Posted

技术标签:

【中文标题】计算相机视图矩阵【英文标题】:Calculating The Camera View Matrix 【发布时间】:2013-11-10 14:22:59 【问题描述】:

我有一个问题,我的相机似乎绕着原点旋转。这让我觉得我的矩阵乘法倒退了。然而,这对我来说似乎是正确的,如果我将其反转,它会解决轨道问题,但我会遇到另一个问题,我认为我的翻译是倒退的。

glm::mat4 Camera::updateDelta(const float *positionVec3, const float *rotationVec3)

    // Rotation Axis
    const glm::vec3 xAxis(1.0f, 0.0f, 0.0f);
    const glm::vec3 yAxis(0.0f, 1.0f, 0.0f);
    const glm::vec3 zAxis(0.0f, 0.0f, 1.0f); // Should this be -1?

    // Accumulate Rotations
    m_rotation.x += rotationVec3[0]; // pitch
    m_rotation.y += rotationVec3[1]; // yaw
    m_rotation.z += rotationVec3[2]; // roll

    // Calculate Rotation
    glm::mat4 rotViewMat;
    rotViewMat = glm::rotate(rotViewMat, m_rotation.x, xAxis);
    rotViewMat = glm::rotate(rotViewMat, m_rotation.y, yAxis);
    rotViewMat = glm::rotate(rotViewMat, m_rotation.z, zAxis);

    // Updated direction vectors
    m_forward = glm::vec3(rotViewMat[0][2], rotViewMat[1][2], rotViewMat[2][2]);
    m_up      = glm::vec3(rotViewMat[0][1], rotViewMat[1][1], rotViewMat[2][1]);
    m_right   = glm::vec3(rotViewMat[0][0], rotViewMat[1][0], rotViewMat[2][0]);

    m_forward = glm::normalize(m_forward);
    m_up      = glm::normalize(m_up);
    m_right   = glm::normalize(m_right);

    // Calculate Position
    m_position += (m_forward * positionVec3[2]);
    m_position += (m_up * positionVec3[1]);
    m_position += (m_right * positionVec3[0]);

    m_position += glm::vec3(positionVec3[0], positionVec3[1], positionVec3[2]);

    glm::mat4 translateViewMat;
    translateViewMat = glm::translate(translateViewMat, m_position);

    // Calculate view matrix.
    //m_viewMat = rotViewMat * translateViewMat;
    m_viewMat = translateViewMat * rotViewMat;

    // Return View Proj
    return m_projMat * m_viewMat;

我在其他任何地方都反向进行矩阵乘法,这给了我正确的答案,但这个函数似乎想要相反。

在计算 3D 空间中的对象位置时,我会这样做

m_worldMat = transMat * rotMat * scale;

按预期工作。

【问题讨论】:

getViewProjMat() 是做什么的? @melake47 它将视图和项目垫相乘。我已经更新了问题。 【参考方案1】:

代码似乎有一些错误。

一:rotViewMat 在初始化前的第一次旋转调用中使用。它最初获得什么价值?是单位矩阵吗?

二:旋转不具有您似乎假设的数学属性。绕 x 旋转,然后绕 y 旋转,然后绕 z 旋转(每个都以恒定速度)与绕任何轴旋转(“轨道”)不同,这是一种奇怪的摆动。由于随后的旋转,例如,您累积的 x 旋转(“俯仰”)实际上可能会导致完全不同方向的运动(考虑当累积的 y 旋转接近 90 度时 x 会发生什么)。另一种说法是旋转是不可交换的,请参阅: https://physics.stackexchange.com/questions/48345/non-commutative-property-of-rotation 和 https://physics.stackexchange.com/questions/10362/how-does-non-commutativity-lead-to-uncertainty/10368#10368。

另请参阅:http://en.wikipedia.org/wiki/Rotation_matrix#Sequential_angles 和 http://en.wikipedia.org/wiki/Euler_angles。由于欧拉角(roll-pitch-yaw)不是向量,因此向它们添加速度向量是没有意义的。

你可能想要的是这个:

glm::mat4 Camera::updateDelta(const float *positionVec3, const float *axisVec3, const float angularVelocity)

...
    glm::mat4 rotViewMat; // initialize to unit matrix
    rotViewMat = glm::rotate(rotViewMat, angularVelocity, axisVec3);
...

【讨论】:

数学库 glm,将垫子初始化为单位矩阵。

以上是关于计算相机视图矩阵的主要内容,如果未能解决你的问题,请参考以下文章

如何计算具有齐次变换矩阵的相机的视角? [PCL]

GLFW - 用鼠标旋转相机的视图矩阵使其旋转

相机/视图矩阵

如何使用立体对合成新的相机视图?

从视图矩阵中清除比例组件。独立于相机的缩放

有没有办法从glm中的视图矩阵中提取变换矩阵?