Terathon Software 3D Graphics Library

Modifying the Projection Matrix to Perform Oblique Near-plane Clipping

The following code modifies the OpenGL projection matrix so that the near plane coincides with a given arbitrary plane. The far plane is adjusted so that the resulting view frustum has the best shape possible. This code assumes that the original projection matrix is a perspective projection (standard or infinite). The clipPlane parameter must be in camera-space coordinates, and its w-coordinate must be negative (corresponding to the camera being on the negative side of the plane).

For algorithmic details, see Game Programming Gems 5, Section 2.6.

#include "Vector4D.h"


inline float sgn(float a)
{
    if (a > 0.0F) return (1.0F);
    if (a < 0.0F) return (-1.0F);
    return (0.0F);
}


void ModifyProjectionMatrix(const Vector4D& clipPlane)
{
    float       matrix[16];
    Vector4D    q;

    // Grab the current projection matrix from OpenGL
    glGetFloatv(GL_PROJECTION_MATRIX, matrix);
    
    // Calculate the clip-space corner point opposite the clipping plane
    // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
    // transform it into camera space by multiplying it
    // by the inverse of the projection matrix
    
    q.x = (sgn(clipPlane.x) + matrix[8]) / matrix[0];
    q.y = (sgn(clipPlane.y) + matrix[9]) / matrix[5];
    q.z = -1.0F;
    q.w = (1.0F + matrix[10]) / matrix[14];
    
    // Calculate the scaled plane vector
    Vector4D c = clipPlane * (2.0F / Dot(clipPlane, q));
    
    // Replace the third row of the projection matrix
    matrix[2] = c.x;
    matrix[6] = c.y;
    matrix[10] = c.z + 1.0F;
    matrix[14] = c.w;

    // Load it back into OpenGL
    glMatrixMode(GL_PROJECTION);
    glLoadMatrix(matrix);
}

How to cite this article

Lengyel, Eric. “Modifying the Projection Matrix to Perform Oblique Near-plane Clipping”. Terathon Software 3D Graphics Library, 2004. http://www.terathon.com/code/oblique.html