openglmatrixglslglm-mathprojection-matrix

How to change ortho matrix size in shader


I tried scaling orthogonal projection matrix but it seems it doesn't scale its dimensions.I am using orthogonal projection for directional lighting. But if the main camera is above ground I want to make my ortho matrix range bigger.

For example if camera is zero , orho matrix is glm::ortho(-10.0f , 10.0f , -10.0f , 10.0f , 0.01f, 4000.0f)

but if camera goes 400 in y direction i want this matrix to be like glm::ortho(-410.0f , 410.0f , -410.0f , 410.0f , 0.01f, 4000.0f)

but I want to do this in the shader with matrix multiplication or addition


Solution

  • The Orthographic Projection matrix can be computed by:

    r = right, l = left, b = bottom, t = top, n = near, f = far
    
    X:    2/(r-l)         0               0               0
    y:    0               2/(t-b)         0               0
    z:    0               0               -2/(f-n)        0
    t:    -(r+l)/(r-l)    -(t+b)/(t-b)    -(f+n)/(f-n)    1
    

    In glsl, for instance:

    float l = -410.0f;
    float r =  410.0f;
    float b = -410.0f;
    float t =  410.0f;
    float n =  0.01f;
    float f =  4000.0f;
    
    mat4 projection = mat4(
        vec4(2.0/(r-l),     0.0,          0.0,         0.0),
        vec4(0.0,           2.0/(t-b),    0.0,         0.0),
        vec4(0.0,           0.0,         -2.0/(f-n),   0.0),
        vec4(-(r+l)/(r-l), -(t+b)/(t-b), -(f+n)/(f-n), 1.0)
    );
    

    Furthermore you can scale the orthographic projection matrix:

    c++

    glm::mat4 ortho = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 0.01f, 4000.0f);
    
    float scale = 10.0f / 410.0f;
    glm::mat4 scale_mat = glm::scale(glm::mat4(1.0f), glm::vec3(scale, scale, 1.0f));
    glm::mat4 ortho_new = ortho * scale_mat;
    

    glsl

    float scale = 10.0 / 410.0;
    mat4 scale_mat = mat4(
        vec4(scale, 0.0,   0.0, 0.0),
        vec4(0.0,   scale, 0.0, 0.0),
        vec4(0.0,   0.0,   1.0, 0.0),
        vec4(0.0,   0.0,   0.0, 1.0)
    );
    
    mat4 ortho_new = ortho * scale_mat;