# 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;
GLfloat near   = projection / (projection - 1.0f);
GLfloat far    = projection / (projection + 1.0f);
GLfloat bottom = nearPlane * (projection - 1.0f) / projection;
GLfloat top    = nearPlane * (projection + 1.0f) / projection;
GLfloat left   = nearPlane * (projection - 1.0f) / projection;
GLfloat right  = nearPlane * (projection + 1.0f) / projection;``````

For the orthographic matrix:

``````GLfloat projection;
GLfloat near   =  (1.0f + projection) / projection;
GLfloat far    = -(1.0f - projection) / projection;
GLfloat bottom =  (1.0f - projection) / projection;
GLfloat top    = -(1.0f + projection) / projection;
GLfloat left   = -(1.0f + projection) / projection;
GLfloat right  =  (1.0f - projection) / projection;``````

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

For a perspective matrix:

``````matrixProjection = 2.0f * near / (right - left);
matrixProjection = 2.0f * near / (top - bottom);
matrixProjection = (right + left) / (right - left);
matrixProjection = (top + bottom) / (top - bottom);
matrixProjection = -(far + near) / (far - near);
matrixProjection = -1.0f;
matrixProjection = -(2.0f * far * near) / (far - near);
matrixProjection = 0.0f;``````

For an orthographic matrix:

``````matrixProjection = 2.0f / (right - left);
matrixProjection = 2.0f / (top - bottom);
matrixProjection = -2.0f / (far - near);
matrixProjection = -(right + left) / (right - left);
matrixProjection = -(top + bottom) / (top - bottom);
matrixProjection = -(far + near) / (far - near);``````

If you want even more options, read this.