Decompose the OpenGL projection matrix

Sometimes you need to decompose the OpenGL projection matrix into its original components to adjust some values. Here’s how to do that. I found a thread on stackoverflow on the subject. The formulas there are in row-major format though, but OpenGL is column-major, so they need to be swapped around:

For a perspective matrix:

near   = m43 / (m33 - 1);
far    = m43 / (m33 + 1);
bottom = near * (m32 - 1) / m22;
top    = near * (m32 + 1) / m22;
left   = near * (m31 - 1) / m11;
right  = near * (m31 + 1) / m11;

For an orthographic matrix:

near   =  (1 + m43) / m33;
far    = -(1 - m43) / m33;
bottom =  (1 - m42) / m22;
top    = -(1 + m42) / m22;
left   = -(1 + m41) / m11;
right  =  (1 - m41) / m11;

When you now use a standard C-Array for storage, the indices become:

For the perspective matrix:

GLfloat projection[16];
GLfloat near   = projection[14] / (projection[10] - 1.0f);
GLfloat far    = projection[14] / (projection[10] + 1.0f);
GLfloat bottom = nearPlane * (projection[9] - 1.0f) / projection[5];
GLfloat top    = nearPlane * (projection[9] + 1.0f) / projection[5];
GLfloat left   = nearPlane * (projection[8] - 1.0f) / projection[0];
GLfloat right  = nearPlane * (projection[8] + 1.0f) / projection[0];

For the orthographic matrix:

GLfloat projection[16];
GLfloat near   =  (1.0f + projection[14]) / projection[10];
GLfloat far    = -(1.0f - projection[14]) / projection[10];
GLfloat bottom =  (1.0f - projection[13]) / projection[5];
GLfloat top    = -(1.0f + projection[13]) / projection[5];
GLfloat left   = -(1.0f + projection[12]) / projection[0];
GLfloat right  =  (1.0f - projection[12]) / projection[0];

To calculate a matrix again from those values, use an identity matrix and set:

For a perspective matrix:

matrixProjection[0] = 2.0f * near / (right - left);
matrixProjection[5] = 2.0f * near / (top - bottom);
matrixProjection[8] = (right + left) / (right - left);
matrixProjection[9] = (top + bottom) / (top - bottom);
matrixProjection[10] = -(far + near) / (far - near); 
matrixProjection[11] = -1.0f;
matrixProjection[13] = -(2.0f * far * near) / (far - near);
matrixProjection[15] = 0.0f;

For an orthographic matrix:

matrixProjection[0] = 2.0f / (right - left);
matrixProjection[5] = 2.0f / (top - bottom);
matrixProjection[10] = -2.0f / (far - near);
matrixProjection[12] = -(right + left) / (right - left);
matrixProjection[13] = -(top + bottom) / (top - bottom);
matrixProjection[14] = -(far + near) / (far - near);

If you want even more options, read this.

Published by HorstBaerbel

Software developer by trade and interest, but I venture into the electronics- and diy-world from time to time.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create your website at WordPress.com
Get started
%d bloggers like this: