【问题标题】:Get world coordinates of frustum from matrix从矩阵中获取截锥体的世界坐标
【发布时间】:2017-12-21 23:03:46
【问题描述】:

我有通常的立方体(-1、-1、-1 到 1、1、1)和我的相机矩阵(视图和投影)。 投影矩阵是透视投影。 我想看看从给定的相机中可以看到哪个区域。想象一下我想像平截头体一样拉伸我的立方体,这样我就可以看到其他相机的结果。

我的想法:

获取 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 新手)?

【问题讨论】:

  • 您错过了透视划分。在投影(或逆投影)之后,w 坐标将不再为 1。
  • 所以我只需要除以 w 吗?
  • 是的。如果这没有帮助,请添加一个示例,显示相机矩阵中的值以及除法后的结果向量。
  • 我测试过,是的,除以 w 分量是正确的;)非常感谢!

标签: opengl glm-math


【解决方案1】:

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

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

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

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

因此,正如 BDL 在 cmets 中指出的那样,您缺少由 w 进行的除法。您需要在 NDC 坐标中获取可见立方体,将它们通过一系列反向变换,最后除以 w 以转到欧几里得坐标。事实上,您可以跳过w 的除法,因为您可以简单地停留在齐次坐标中并使用另一个摄像机的视图进行渲染。

【讨论】:

    猜你喜欢
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    • 2020-06-28
    相关资源
    最近更新 更多