简体   繁体   中英

OpenGL how to properly calculate the camera matrix with GLM

I am working to an OpenGL graphic engine and I'm experiencing a very odd issue. Basically I'm importing (through Assimp) a .DAE scene (made in Cinema4D) which also contains a Camera. The camera is in the origin and rotated 20 degrees to the left and 20 degrees up, so that a section of the cube should appear in the lower right corner of the viewport.

When rendering I first calculate the "global" lookAt matrix, by applying the world transformation matrix of the camera node within the scene graph to the lookAt matrix:

cameraMatrix = transform * glm::lookAt(camera->position, camera->lookAt, camera->upward);

and then use it to calculate the final meshes' modelview matrices:

// mesh.second is the world matrix
mat4 modelvMatrix = renderList->cameraMatrix * mesh.second;

which is then combined with the projection matrix and fed to the shader. However the result (textures are not working yet) seems like "mirrored", as if the transformations were applied conversely:

Doing some math manually using the same transformation matrix :

//cameraMatrix = transform * glm::lookAt(camera->position, camera->lookAt, camera->upward);
cameraMatrix = camera->getCameraMatrix(transform);

mat4 Camera::getCameraMatrix(mat4p transform)
{
    auto invTr = glm::inverseTranspose(mat3(transform));
    auto pos = vec3(transform * vec4(position, 1));
    auto dir = invTr * glm::normalize(lookAt - position);
    auto upw = invTr * upward;
    return glm::lookAt(pos, pos + dir, upw);
}

seems to solve the problem:

However I am not sure if the output is entirely right because it is not perfectly specular to the first image. The local transformation matrix of the camera node is:

mat4x4(
    (0.939693,  0.000000, -0.342020, 0.000000),
    (0.116978,  0.939693,  0.321394, 0.000000),
    (0.321394, -0.342020,  0.883022, 0.000000),
    (0.000000, -0.000000,  0.000000, 1.000000))

How should I properly calculate the camera matrix?

EDIT

I've been asking about the calculus of the matrices:

        mat4 modelvMatrix = renderList->cameraMatrix * mesh.second;
        mat4 renderMatrix = projectionMatrix * modelvMatrix;
        shaderProgram->setMatrix("renderMatrix", renderMatrix);
        mesh.first->render();

and the shader code:

const std::string Source::VertexShader= R"(
    #version 430 core

    layout(location = 0) in vec3 position;
    layout(location = 1) in vec3 normal;
    layout(location = 2) in vec2 vertexTexCoord;

    uniform mat4 renderMatrix;

    out vec2 texCoord;

    void main()
    {
        gl_Position = renderMatrix * vec4(position, 1.0);
        texCoord = vertexTexCoord;
    }
)";


const std::string Source::FragmentShader= R"(
    #version 430 core

    uniform sampler2D sampler;

    in vec2 texCoord;

    out vec3 color;

    void main()
    {
        color = vec3(0.0, 1.0, 0.0);
        //color = texture(sampler, texCoord);
    }
)";

First, this is wrong:

cameraMatrix = transform * glm::lookAt(camera->position, camera->lookAt, camera->upward);

The correct order is as follows:

MVP = P * V * M;

Where P,V,M are projection, view and model matrices respectively.

Also,that expression doesn't make sense because your glm::lookAt already calculates lookAt matrix based on camera's transform.(if we imply that your 'transform' is camera's model matrix)

Now, regarding glm::lookAt() . Don't use it to get view (camera) matrix. While it does return you a matrix that is oriented in a direction you specified, this is not going to be a correct view matrix because the eye position (translation part of this matrix) is not inversed as it should in the case of view matrix.

The simpliest way to get a correct view matrix is to inverse its model matrix.

glm::mat4 V = glm::inverse(M);

That's it. Now you can fetch your 'V' into shader or calculate MVP matrix on CPU.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM