如何从视图投影矩阵中检索摄像机的原点/位置? (OpenGL)

问题描述 投票:1回答:2

是否有任何方法可以从视图投影矩阵中检索摄像机的原点/位置? (OpenGL)

我正在尝试绘制相机的视锥,并且在计算FarNear平面的角时没有问题。

但是我不知道如何检索代表相机原点的点。

我原本希望通过乘以同构的剪辑空间坐标来检索此:

glm::vec4(0.f, 0.f, 0.f, 1.f)

但是我有点像是倒置的相机位置。 (在屏幕快照中标记为X)包括下面的所有源代码。

enter image description here

    // Homogeneous points for source cube in clip-space.
    std::array<glm::vec4, 9> corners =
    {
        // Far plane
        glm::vec4(-1.f,-1.f, 1.f, 1.f), // bottom-left
        glm::vec4( 1.f,-1.f, 1.f, 1.f), // bottom-right
        glm::vec4( 1.f, 1.f, 1.f, 1.f), // top-right
        glm::vec4(-1.f, 1.f, 1.f, 1.f), // top-left

        // Near plane
        glm::vec4(-1.f,-1.f,-1.f, 1.f), // bottom-left
        glm::vec4( 1.f,-1.f,-1.f, 1.f), // bottom-right
        glm::vec4( 1.f, 1.f,-1.f, 1.f), // top-right
        glm::vec4(-1.f, 1.f,-1.f, 1.f), // top-left

        // Camera/screen center position.
        glm::vec4(0.f, 0.f, 0.f, 1.f)
    };

    const auto invMatrix(glm::inverse(viewProjectionMatrix));

    for (U32 i = 0; i < corners.size(); i++)
    {
        corners[i] = invMatrix * corners[i]; // 4x4 * 4x1 matrix/vector multiplication.
        corners[i] /= corners[i].w; // Homogeneous to euclidean/cartesian conversion
    }

    // Far plane.
    this->AddLine(corners[0], corners[1], rColor);
    this->AddLine(corners[1], corners[2], rColor);
    this->AddLine(corners[2], corners[3], rColor);
    this->AddLine(corners[3], corners[0], rColor);

    // Near plane.
    this->AddLine(corners[4], corners[5], rColor);
    this->AddLine(corners[5], corners[6], rColor);
    this->AddLine(corners[6], corners[7], rColor);
    this->AddLine(corners[7], corners[4], rColor);

    // Connection from Near rectangle to the Far rectangle.
    this->AddLine(corners[0], corners[4], rColor);
    this->AddLine(corners[1], corners[5], rColor);
    this->AddLine(corners[2], corners[6], rColor);
    this->AddLine(corners[3], corners[7], rColor);

    // X
    this->AddLine(corners[4], corners[8], rColor);
    this->AddLine(corners[5], corners[8], rColor);
    this->AddLine(corners[6], corners[8], rColor);
    this->AddLine(corners[7], corners[8], rColor);
opengl matrix projection projection-matrix frustum
2个回答
1
投票

计算原点的一种可能方法是计算透视投影描述的三个平截头体平面的交集(可能对其应用了任何模型-视图变换)。>>

下面是伪GLSL解决方案:

// Get plane equations of left, right and top frustum planes:
// (Reference: Paper "Fast Extraction of Viewing Frustum Planes from the WorldView-Projection Matrix")
// Note that `m[i]` below means the i-th "row" (as opposed to the i-th column) of matrix `m`
vec4 left  = m[3] + m[0]
vec4 right = m[3] - m[0]
vec4 top   = m[3] - m[1]
// Compute intersection point of these three planes:
vec3 c23 = cross(right.xyz, top.xyz)
vec3 c31 = cross(top.xyz, left.xyz)
vec3 c12 = cross(left.xyz, right.xyz)
vec3 result = -(c23 * left.w + c31 * right.w + c12 * top.w) / dot(left.xyz, c23)

0
投票

[通常,如果您只有一个合成的viewProjection矩阵,则无法从中推导出相机原点。您将需要其他信息。

© www.soinside.com 2019 - 2024. All rights reserved.