Search code examples
javaopenglmatrixprojectionperspectivecamera

OpenGL Perspective Projection: How to define left and right


How do I set up coordinates for perspective matrix like in orthographic projection for left, right, top and bottom and add in fov and aspect ratio. I have only seen perspective matrix use other arguments in a method without left, right, bottom, top. This is my ortho matrix:

public static Matrix4f Orthographic(float left, float right, float bottom, float top, float near, float far) {
        Matrix4f result = Identity();

        result.elements[0 + 0 * 4] = 2.0f / (right - left);

        result.elements[1 + 1 * 4] = 2.0f / (top - bottom);

        result.elements[2 + 2 * 4] = 2.0f / (near - far);

        result.elements[0 + 3 * 4] = (left + right) / (left - right);
        result.elements[1 + 3 * 4] = (bottom + top) / (bottom - top);
        result.elements[2 + 3 * 4] = (far + near) / (far - near);

        return result;
    }

Now I want to create perspective one with same arguments but with added fov.


Solution

  • At Perspective Projection the projection matrix describes the mapping from 3D points in the world as they are seen from of a pinhole camera, to 2D points of the viewport.
    The eye space coordinates in the camera frustum (a truncated pyramid) are mapped to a cube (the normalized device coordinates).

    The Viewing frustum of a perspective projection can be defined by a by 6 distances.

    In the following distances left, right, bottom and top, are the distances from the center of the view to the side faces of the frustum, on the near plane. near and far specify the distances to the near and far plane of the frustum.

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

    If the projection is symmetric, where the line of sight is axis of symmetry of the view frustum, then the matrix can be simplified and can be specified by an field of view angle (fov_y), an aspect ratio (w / h) an the 2 distances to the near and far plane

    a  = w / h
    ta = tan( fov_y / 2 );
    
    2 * n / (r-l) = 1 / (ta * a)
    2 * n / (t-b) = 1 / ta
    (r+l)/(r-l)   = 0
    (t+b)/(t-b)   = 0
    

    So the symmetrically perspective projection is:

    x:    1/(ta*a)  0      0              0
    y:    0         1/ta   0              0
    z:    0         0     -(f+n)/(f-n)   -1
    t:    0         0     -2*f*n/(f-n)    0