簡體   English   中英

如何在openGL中使用逆視圖矩陣繪制相機視錐

[英]How to draw camera frustum using inverse view matrix in openGL

我嘗試畫出攝像機視錐,以進行調試。 我可以使用NDC空間通過以下代碼繪制它

Matrix inv = (camera.getViewMatrix() * camera.getProjectionMatrix()).inverse();

Vector4 f[8u] =
{
    // near face
    {1, 1, -1, 1.f},
    {-1, 1, -1, 1.f},
    {1, -1, -1, 1.f},
    {-1, -1, -1, 1.f},

    // far face
    {1, 1, 1, 1.f},
    {-1, 1, 1 , 1.f},
    {1, -1, 1 , 1.f},
    {-1, -1,1, 1.f},
};

Vector3 v[8u];
for (int i = 0; i < 8; i++)
{
    Vector4 ff = inv * f[i];
    v[i].x = ff.x / ff.w;
    v[i].y = ff.y / ff.w;
    v[i].z = ff.z / ff.w;
}

drawLine(v[0], v[1], Color::White);
drawLine(v[0], v[2], Color::White);
drawLine(v[3], v[1], Color::White);
drawLine(v[3], v[2], Color::White);

drawLine(v[4], v[5], Color::White);
drawLine(v[4], v[6], Color::White);
drawLine(v[7], v[5], Color::White);
drawLine(v[7], v[6], Color::White);

drawLine(v[0], v[4], Color::White);
drawLine(v[1], v[5], Color::White);
drawLine(v[3], v[7], Color::White);
drawLine(v[2], v[6], Color::White);

但是,當我嘗試使用反視圖進行繪制時,視錐被拉到相機的后面。

Matrix inv = camera.getViewMatrix().inverse();

float ar = static_cast<float>(800.f / 600.f);
float fov = 60.f;
float near = 0.1f;
float far = 100.f;
float halfHeight = tanf(Deg2Rad * (fov / 2.f));
float halfWidth = halfHeight * ar;

float xn = halfWidth * near;
float xf = halfWidth * far;
float yn = halfHeight * near;
float yf = halfHeight * far;

Vector4 f[8u] =
{
    // near face
    {xn, yn, near, 1.f},
    {-xn, yn, near, 1.f},
    {xn, -yn, near, 1.f},
    {-xn, -yn,near , 1.f},

    // far face
    {xf, yf, far, 1.f},
    {-xf, yf,far , 1.f},
    {xf, -yf,far , 1.f},
    {-xf, -yf,far, 1.f},
};

Vector3 v[8];
for (int i = 0; i < 8; i++)
{
    Vector4 ff = inv * f[i];
    v[i].x = ff.x / ff.w;
    v[i].y = ff.y / ff.w;
    v[i].z = ff.z / ff.w;
}

drawLine(v[0], v[1], Color::White);
drawLine(v[0], v[2], Color::White);
drawLine(v[3], v[1], Color::White);
drawLine(v[3], v[2], Color::White);

drawLine(v[4], v[5], Color::White);
drawLine(v[4], v[6], Color::White);
drawLine(v[7], v[5], Color::White);
drawLine(v[7], v[6], Color::White);

drawLine(v[0], v[4], Color::White);
drawLine(v[1], v[5], Color::White);
drawLine(v[3], v[7], Color::White);
drawLine(v[2], v[6], Color::White);

如您在場景截圖中所見,當我看着場景的中心時,視錐被繪制在相機的后面。

攝像機1的視圖

攝像機2的視圖

計算視圖的代碼

static const float speed = frametime * 10000.f; // TODO add speed variable
Vector2 delta = m_mousePosition - Mouse::getPosition();
m_mousePosition = Mouse::getPosition();

Quaternion q;
Transformable::rotateX(-delta.y * frametime * 100.f);
Transformable::rotateY(delta.x * frametime * 100.f);
q.fromEuler(Transformable::getRotation());
m_direction = m_originDirection.rotate(q).normalize();
m_right = m_originUp.cross(m_direction).normalize();
m_up = m_direction.cross(m_right).normalize();

if (Keyboard::isKeyPress(GLFW_KEY_A))
    Transformable::translate(m_right * frametime * speed);
else if (Keyboard::isKeyPress(GLFW_KEY_D))
    Transformable::translate(-m_right * frametime * speed);
if (Keyboard::isKeyPress(GLFW_KEY_W))
    Transformable::translate(m_direction * frametime * speed);
else if (Keyboard::isKeyPress(GLFW_KEY_S))
    Transformable::translate(-m_direction * frametime * speed);
if (Keyboard::isKeyPress(GLFW_KEY_Q))
    Transformable::translate(-m_up * frametime * speed);
else if (Keyboard::isKeyPress(GLFW_KEY_E))
    Transformable::translate(m_up * frametime * speed);

m_view = Matrix::lookAt(Transformable::getPosition(), Transformable::getPosition() + m_direction, m_up);

和lookAt函數

Matrix Matrix::lookAt(Vector3 const & eye, Vector3 const & center, Vector3 const & up)
{
    Vector3 f = (center - eye).normalize();
    Vector3 u = up;
    u.normalize();
    Vector3 s = f.cross(u).normalize();
    u = s.cross(f);

    Matrix result(s.x, u.x, -f.x, 0.f,
                s.y, u.y, -f.y, 0.f,
                s.z, u.z, -f.z, 0.f,
                -s.dotProduct(eye), -u.dotProduct(eye), f.dotProduct(eye), 1.f);
    return (result);
}

有人知道我的代碼有什么問題嗎? 讓我知道是否缺少信息。

該代碼也在該github上的shadow_map(github.com/jbalestr42/GraphicsEngine)分支中。

設置了經典的OpenGL視圖和投影矩陣,以使視圖空間是右手的,相機朝着-z方向看,而glOrthoglFrustum函數將沿視圖方向的距離解釋為nearfar ,因此視圖空間z坐標遠近飛機中的

z_near = -near
z_far = -far

而您的代碼:

 { // near face {xn, yn, near, 1.f}, {-xn, yn, near, 1.f}, {xn, -yn, near, 1.f}, {-xn, -yn,near , 1.f}, // far face {xf, yf, far, 1.f}, {-xf, yf,far , 1.f}, {xf, -yf,far , 1.f}, {-xf, -yf,far, 1.f}, }; 

只是在+z方向上繪制了平截頭體,這有望在相機后面結束。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM