# My projection matrix for OpenGL fails on non-symmetric boundaries

Assuming my viewing volume has x coordinates varies from l to r, and y varies from top to bottom, and finally z-axis varies n to f, I derived the following projection matrix:

    mat4 projection = {
2n/(r-l), 0,       (r+l)/(r-l), 0,
0,        2n(t-b), (t+b)/(t-b), 0,
0,        0,       (n+f)/(n-f), 2nf/(n-f),
0,        0,       -1,          0


which matches the projection matrix derived here

Plugging in values for my cube coordinates, to be centered in the middle of the screen with Left = -100, Right = 100, Top = 100, Bottom = -100. I have the following vertices positions:

    f32 r =  100;
f32 l = -100;

f32 t =  100;
f32 b = -100;

f32 n = -1;
f32 f = -3;

GLfloat VertexData =
{

//--------- Vertex Positions ---------//
-50.0f,  -50.0f,   1.0f,
+50.0f,  -50.0f,   1.0f,
+50.0f,  +50.0f,   1.0f,
-50.0f,  +50.0f,   1.0f,

-50.0f,  -50.0f,   3.0f,
+50.0f,  -50.0f,   3.0f,
+50.0f,  +50.0f,   3.0f,
-50.0f,  +50.0f,   3.0f,
//-------Other data for texture coordinates------//
};


which produces the expected image and here is my question: if I am using a non-symmetric boundaries (Right != -Left) should not the output image be the same?

I set Right = 100, Left = 0, and I changed vertices positions to be from 25 to 75 ([-50,+50] range with respect to r =100, l = -100 should be equivalent to [+25,+75] with r = 100, l = 0) but the output image does not match Looking at it, it seems like the perspective divide moves further away points to the edge of the screen, instead of the center of the screen.

full source code for this example is available here

Nothing is wrong.

If we suppose n is fixed, then l, r, t, and b control the slope of the sides of the view frustum. When you make l = 0, you are setting that slope to zero, and the left edge of the image corresponds to looking directly along the view direction of the camera. Since you moved the cube too, and the cube is entirely to the right of the viewpoint, your projection is now allowing you a look at the left face of the cube.

What you're doing is effectively the same as cutting off the left half of a normal perspective projection. (Generally, you can arbitrarily skew the view projection frustum without changing its volume by adding the same amount to l and r or to t and b.)

In order to change the coordinate system without changing the projection, you should apply a translation to your view matrix, and leave the projection parameters unchanged.

• After a moment of thinking, I figured it out, basically, dividing by z moves towards the zero, in my case the 0 is no longer the center of the image, but the left edge. May 19 at 21:17