【问题标题】:Decompose projection matrix44 to left, right, bottom, top, near and far boundary values将投影矩阵44分解为左、右、下、上、近、远边界值
【发布时间】:2012-05-31 08:52:22
【问题描述】:

谁能帮我从投影矩阵 44 中获取左、右、下、上、近和远边界值?

【问题讨论】:

    标签: android opengl-es qcar-sdk


    【解决方案1】:

    这里是方程系统Christian Rau 的分辨率:

    对于正交矩阵:

    near   =  (1+m34)/m33;
    far    = -(1-m34)/m33;
    bottom =  (1-m24)/m22;
    top    = -(1+m24)/m22;
    left   = -(1+m14)/m11;
    right  =  (1-m14)/m11;
    

    对于透视矩阵:

    near   = m34/(m33-1);
    far    = m34/(m33+1);
    bottom = near * (m23-1)/m22;
    top    = near * (m23+1)/m22;
    left   = near * (m13-1)/m11;
    right  = near * (m13+1)/m11;
    

    您可以将值 m11、m12 等替换为文档中为 glOrthoglFrustum 定义的公式,以检查其是否正确。

    【讨论】:

    • 仅供参考,此答案使用(1 索引)行主矩阵坐标,OpenGL 默认使用列主矩阵。如果不转置坐标,m34 将是一个常量值。
    【解决方案2】:

    首先,您可以查看这些矩阵是如何为对glOrthoglFrustum(或您的框架中的类似函数)的相应调用定义的。接下来的步骤取决于投影的类型,可以是正交投影(例如来自glOrtho)还是透视投影(例如来自glFrustumgluPerspective),这可以通过查看第三列来决定。

    现在对于正交矩阵,很容易得到两个方程:

    right - left = 2 / m11
    right + left = -2 * m14 / m11
    

    从这些你可以很容易地计算出right = (1-m14) / m11left = right - 2/m11(你可以重新检查我在心算过程中犯的任何错误)。其他两对参数也类似(注意m33的符号)。

    对于透视投影,您应该首先使用m33m34 计算nearfar。然后你可以计算right/leftbottom/top 类似于上面的情况,但使用计算出的near 值。

    总而言之,一旦您知道了基于参数的矩阵公式,就真的可以归结为一堆易于求解的简单 2x2 方程组。一个更有趣的问题是,为什么您实际上需要从投影矩阵计算这些参数。如果你真的需要它们,你应该只存储它们(因为你是构造矩阵的人,无论如何)。否则,这听起来像是将 OpenGL 用于更多事情(如场景管理)的另一个实例,而不是它的实际用途,只是一个简单的绘图 API。

    【讨论】:

    • 其实我必须这样做(stackoverflow.com/questions/10810360/…)。帮我实现。
    • @user779554 我对您所说的那些库没有任何经验,但作为您可能不知道的一般信息,您不一定需要提取 @ 的参数从矩阵调用 987654340@ 或 glFrustum 以获得相同的投影矩阵到 OpenGL。您可以直接使用glLoadMatrixglMultMatrix 函数来输入矩阵。不确定这是否是您想要实现的目标,因为我没有完全理解另一个问题。
    【解决方案3】:

    为了将来参考,我在下面复制了 C++ 中近、远等的值,用于具有 0 索引列主要投影矩阵的 OpenGL:

    float near = m_projectionMatrix[3][2] / (m_projectionMatrix[2][2] - 1.0f);
    float far = m_projectionMatrix[3][2] / (m_projectionMatrix[2][2] + 1.0f);
    logStderr(VERBOSE, "near, far %5.2f, %5.2f...\n", near, far);
    
    float nearBottom = near * (m_projectionMatrix[2][1] - 1) / m_projectionMatrix[1][1];
    float nearTop = near * (m_projectionMatrix[2][1] + 1) / m_projectionMatrix[1][1];
    float nearLeft = near * (m_projectionMatrix[2][0] - 1) / m_projectionMatrix[0][0];
    float nearRight = near * (m_projectionMatrix[2][0] + 1) / m_projectionMatrix[0][0];
    logStderr(VERBOSE, "nearLeft, nearRight, nearTop, nearBottom %5.2f, %5.2f, %5.2f, %5.2f...\n", nearLeft, nearRight, nearTop, nearBottom);
    
    float farBottom = far * (m_projectionMatrix[2][1] - 1) / m_projectionMatrix[1][1];
    float farTop = far * (m_projectionMatrix[2][1] + 1) / m_projectionMatrix[1][1];
    float farLeft = far * (m_projectionMatrix[2][0] - 1) / m_projectionMatrix[0][0];
    float farRight = far * (m_projectionMatrix[2][0] + 1) / m_projectionMatrix[0][0];
    logStderr(VERBOSE, "farLeft, farRight, farTop, farBottom %5.2f, %5.2f, %5.2f, %5.2f...\n", farLeft, farRight, farTop, farBottom);
    

    【讨论】:

      猜你喜欢
      • 2019-12-14
      • 2020-10-22
      • 1970-01-01
      • 2019-03-05
      • 2011-08-31
      • 1970-01-01
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多