Invalid matrix

I started working on shadow maps for directional lights and for that I need a lookAt matrix, but when I tried to build from an example online tutorial it looked something like this:

enter image description here

It now looks like this: https://media.giphy.com/media/QrMnqBBJZuATu/giphy.gif

I tried several ways to create it, but with no success, I checked if the wrong, cross and translation functions were wrong, but it was not. I've also tried going from column matrices to row matrices, but no luck. Can anyone please point out what I did wrong?

Lookat Matrix Construction:

Center-vector = (0, 0, 0), Up vector = (0, 1, 0)

Matrix4f Matrix4f::lookAt(const Vector3f& position, const Vector3f& center, const Vector3f& up) {
        Matrix4f out(1.0f); 

        Vector3f z = position.substract(center).normalize(); 


        Vector3f y = up;

        Vector3f x = y.cross(z).normalize();

        y = z.cross(x);

        out.mElements[0 * 4 + 0] = x.x;
        out.mElements[0 * 4 + 1] = x.y;
        out.mElements[0 * 4 + 2] = x.z;

        out.mElements[1 * 4 + 0] = y.x;
        out.mElements[1 * 4 + 1] = y.y;
        out.mElements[1 * 4 + 2] = y.z;

        out.mElements[2 * 4 + 0] = z.x;
        out.mElements[2 * 4 + 1] = z.y;
        out.mElements[2 * 4 + 2] = z.z;

        return (out * Matrix4f::translation(Vector3f(-position.x, -position.y, -position.z)));
    }
}

      

Credit for the code: https://stackoverflow.com/users/5577765/rabbid76

This is how I pass the matrix to the shader:

void Shader::setMat4(const char* name, const math::Matrix4f& matrix){
    glUniformMatrix4fv(getUniformLocation(name), 1, GL_TRUE, matrix.mElements);
}

      

After I've calculated the lookAt matrix, I pass it to the vertex shader uniform: view

and calculate a point like this:

gl_Position = projection * view * model * vec4(vertexPosition, 1.0);

      

And this is how matrix multiplication works:

Matrix4f Matrix4f::multiply(const Matrix4f& other) const {
    Matrix4f out;
    for (int y = 0; y < 4; y++) {
        for (int x = 0; x < 4; x++) {
            fl32 o = 0;
            for (int c = 0; c < 4; c++) {
                o += this->mElements[c + y * 4] * other.mElements[x + c * 4];                   }
            out.mElements[x + y * 4] = o;
        }
    }
    return out;
}

      

Edit: Updated image Edit: Added more detailed description

+3


source to share


3 answers


After several attempts to get the lookat matrix I gave up on building the lookat matrix, instead I built the lookat matrix based on the position of the camera and the position that the camera should be looking at, using trigonometric functions I was able to create the result I was looking for.

My current way of plotting a lookat matrix is:



Matrix4f Matrix4f::lookAt(const Vector3f& position, const Vector3f& center) {
        Vector3f deltaVector = (position - center).normalize();

        fl32 yaw = (fl32)radToDeg(atan(deltaVector.x / deltaVector.z));
        fl32 pitch = (fl32)radToDeg(acos(Vector2f(deltaVector.x, deltaVector.z).magnitude()));

        if (deltaVector.z > 0)
            yaw = yaw - 180.0f;

        Matrix4f yRotation = Matrix4f::rotation(Vector3f(0.0f, 1.0f, 0.0f), -yaw);
        Matrix4f xRotation = Matrix4f::rotation(Vector3f(1.0f, 0.0f, 0.0f), pitch);

        Matrix4f translation = Matrix4f::translation(position);

        return (translation * (yRotation * xRotation));
    }

      

+1


source


You need to normalize s before calculating u. I'm not sure if this is the only problem.



+3


source


If your positions ( position

, center

) and the vector up

are in view space, then the Z-axis of the view matrix is ​​the return line of sight, and the Y-axis is the vector up, See the following code:

Matrix4f Matrix4f::lookAt(const Vector3f& position, const Vector3f& center, const Vector3f& up)
{
    Matrix4f out(1.0f); // I suppose this initilizes a 4*4 identity matrix

    // Z-Axis is the line of sight
    Vector3f z = position.substract(center).normalize(); // inverse line of sight

    // Y-Axis is the up vector
    Vector3f y = up;

    // X-Axis is the cross product of Y-Axis and Z-Axis
    Vector3f x = y.cross(z).normalize();

    // orthonormalize the Y-Axis
    y = z.cross( x );

    out.mElements[0*4 + 0] = x.x;
    out.mElements[0*4 + 1] = x.y;
    out.mElements[0*4 + 2] = x.z;

    out.mElements[1*4 + 0] = y.x;
    out.mElements[1*4 + 1] = y.y;
    out.mElements[1*4 + 2] = y.z;

    out.mElements[2*4 + 0] = z.x;
    out.mElements[2*4 + 1] = z.y;
    out.mElements[2*4 + 2] = z.z;

    return (out * Matrix4f::translation(Vector3f(-position.x, -position.y, -position.z)));
}

      

+2


source







All Articles