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.

This code uses the Vector4D class.

#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);
}

Public Source Code

The following are links to C++ snippets that we've released for various algorithms and techniques pertinent to 3D game programming.

Books by Eric Lengyel
Book

Mathematics for 3D Game Programming & Computer Graphics, Second Edition

This best-selling book teaches the mathematics and rendering techniques that a game programmer needs to develop a professional-quality 3D engine.
Book

The OpenGL Extensions Guide

This is the ultimate extension reference for the serious OpenGL programmer.
Books See all publications by Eric Lengyel

Conference Slides and Articles
GDC07

Projection Matrix Tricks (2007)
(PowerPoint, 3.26 MB)

This presentation examines the inner workings of the perspective projection matrix and discusses several techniques for modifying the properties of the projection matrix to solve specific rendering problems at zero cost.
GDC06

Advanced Light and Shadow Culling Methods (2006)
(PowerPoint, 852 kB)

This presentation focuses primarily on portal systems and describes algorithms and optimizations that can be applied to a graphics engine supporting completely dynamic lighting and shadows.
GDC05

Advanced Stencil Shadow and Penumbral Wedge Rendering (2005)
(PowerPoint, 1.00 MB)

This presentation reviews advanced implementation techniques of the stencil shadow algorithm and focuses on the relatively new method of penumbral wedge rendering used to generate soft-edged shadows.
Gamasutra

The Mechanics of Robust
Stencil Shadows

This article describes the mathematical details of efficient and robust stencil shadow rendering. These techniques are implemented in the C4 Engine.