opengl - 从矩阵获取平截头体的世界坐标

标签 opengl glm-math

我有常用的立方体(-1, -1, -1 到 1, 1, 1)和我的相机矩阵( View 和投影)。 投影矩阵是透视投影。 我想查看给定相机可以看到哪个区域。想象一下,我想像截锥体一样拉伸(stretch)我的立方体,以便我可以看到其他相机的结果。

我的想法:

获取 viewProjectionMatrix 的倒数并将单位立方体坐标与其相乘:

glm::vec4 CubeCoordinates[8]{                                        
    glm::vec4(-1.0f, -1.0f, 1.0f, 1.0f),
    glm::vec4(-1.0f, 1.0f, 1.0f, 1.0f), 
    glm::vec4(1.0f, 1.0f, 1.0f, 1.0f), 
    glm::vec4(1.0f, -1.0f, 1.0f, 1.0f), 
    glm::vec4(-1.0f, -1.0f, -1.0f, 1.0f), 
    glm::vec4(-1.0f, 1.0f, -1.0f, 1.0f), 
    glm::vec4(1.0f, 1.0f, -1.0f, 1.0f), 
    glm::vec4(1.0f, -1.0f, -1.0f, 1.0f) };

glm::mat4 InvertedViewProjectionMatrix = glm::inverse(refCamera.GetViewProjectionMatrix());

for (uint32_t i = 0; i < 8; ++i)
{
    CameraEdgesWorldSpace[i] = InvertedViewProjectionMatrix * CubeCoordinates[i];
}

现在立方体坐标应该位于世界空间中并且看起来像截锥体。 但输出的坐标是错误的。

我可以保证 viewProjectionMatrix 正常工作,因为我像在任何地方一样使用它。

计算有误吗?或者我是否使用了错误的命令来反转矩阵(我是 GLM 的新手)?

最佳答案

投影矩阵将眼睛坐标映射到剪辑坐标。现在,您没有要反投影的剪辑坐标,只有 NDC 坐标。

如何从 NDC 转换为剪辑坐标?好吧,请记住,我们使用的是齐次坐标而不是欧几里得坐标(因此是第四维 w)。齐次坐标恰好对于乘以非零常数而言是不变的。也就是说,对于任何非点,点 (a, b, c, d) 等价于 (k*a, k*b, k*c, k*d) -零k

通过将剪辑坐标乘以1/w,可以将剪辑坐标转换为 NDC。这是乘以一个常数!因此,NDC 本身就是一个有效的剪辑坐标,因此您可以对其进行反向投影。

现在,从齐次坐标到欧几里得坐标总是需要除以w。我们通常在 OpenGL 中不这样做的原因是仿射变换不会影响 w,因此它通常保留 1。但在这种情况下则不然,因为投影矩阵及其逆矩阵都会影响 w 坐标。

因此,正如 BDL 在评论中指出的那样,您缺少了 w 的除法。您需要获取 NDC 坐标中的可见立方体,将它们传递给一系列向后变换,最后除以 w 以转到欧几里得坐标。事实上,您完全可以跳过除以 w,因为您可以简单地保持在齐次坐标中并使用另一个相机的 View 进行渲染。

关于opengl - 从矩阵获取平截头体的世界坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45143729/

相关文章:

c++ - 尝试使用 OpenGL 时出错

c++ - SDL2 : Fast Pixel Manipulation

performance - 为什么是 GLM_CONSTEXPR_SIMD?

c++ - 从不同的库中隐式转换相似类型以在 C++ 中无缝地协同工作

c++ - GLM - 旋转使对象消失

python - 为什么我的渲染图像没有显示我期望使用 gluLookAt 看到的 View ?

opengl - 如何调试 GLSL 着色器?

python - 如何像在 3dsMax 中一样实现相机平移?

c++ - 在 OpenGL 中将矩阵与 vector 对齐

c++ - 设计一个 "renderer",是否有必要使用 OpenGL 以外的 API?