I've been trying to construct a perspective projection matrix myself and finding it extremely difficult.

I realize that a perspective projection matrix is by default a frustum in OpenGL 3.3+ that is transformed into a unit cube and I need to divide x , y and z by -z too project x y z into -z then I need to divide by w after I've done some equations on I believe these values top , bottom , left , right , zFar and ZNear however I don't exactly know what those equations are and I'm not exactly savy in all the maths required to do this persay also I've read that this is not the full perspective projection matrix and I need some kind of clipping planes?

GLfloat x = 1.0-z;
GLfloat y = 1.0-z;
GLfloat z = 1.0-z;

GLfloat projm[16] = {0};

//crazy equations that I don't know with values
//that I don't know where to place exactly:
//top , bottom , left , right , zFar and ZNear 

x / w;
y / w;
z / w;

projm[] ={x, 0.0 , 0.0, 1.0,
          0.0, y , 0.0, 1.0,
          0.0, 0.0, z,  1.0};

I'm very aware of GLM , I'd prefer too do it myself for learning , curosity and potential benefits please be gentle.


OpenGL already handles the division by W part, you don't need to do anything about that.

So, this is what a perspective projection matrix should look like:


FOV is the vertical angle of the frustum.

Near and far are the distance from the camera to the cutting planes. Nothing gets rendered beyond those. Make sure fo set the near plane to a small value, but not too small, or you will lose precision because of how the depth buffer works.

Aspect is the aspect ration of the window (windowWidth/windowHeight)

The best explanation about how all this works I found was on this website (yes it's about webgl, but it can be read without knowledge of it)http://webglfundamentals.org/webgl/lessons/webgl-3d-perspective.html

| improve this answer | |
  • \$\begingroup\$ I'll go through all this and hope I find some use out of it : ) @Bálint \$\endgroup\$ – Dominic Hughes Apr 23 '16 at 17:33
  • \$\begingroup\$ Bálint What is : var f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfViewInRadians); for? Is that too compute the angle of some part of the cone or field of view?. \$\endgroup\$ – Dominic Hughes Apr 23 '16 at 20:53
  • \$\begingroup\$ @DominicHughes I'm not actually sure, simply put fieldOfView / 2 instead of that \$\endgroup\$ – Bálint Apr 23 '16 at 21:02
  • 1
    \$\begingroup\$ I thought it was divide too be honest lol wasn't shore though, sorry for my variable naming errors : <. GLfloat x = screenWidth / screenHeight * tan(FOV / 2); Is that much better? : D \$\endgroup\$ – Dominic Hughes Apr 23 '16 at 21:10
  • 1
    \$\begingroup\$ @DominicHughes -far + near / far - near this is wrong, you divide near with far, thne you add a negative far and subtract near from it, use parentheses \$\endgroup\$ – Bálint Apr 24 '16 at 7:02


Note the perspective projection matrix is a transform like any other. The difference compared to orthogonal matrix is that the xy-displacement is dependent on the z coordinate. If you figure out what a perspective is and have a good idea about what shearing transforms do perspective projection matrices are no magic at all. Good luck!

| improve this answer | |
  • \$\begingroup\$ That doesn't even come close too answering what I asked for but thanks for your mellow helpful tip. Obviously I wouldn't be here if those links were working for me in my honest opinion they are full of abstractions that are hardly explained and they expect way too much infact all tutorials should be written for noobs every time in my opinion. @Andreas \$\endgroup\$ – Dominic Hughes Apr 23 '16 at 9:32
  • \$\begingroup\$ I'll consider making a more "physical" explaination. How familiar are you with matrices? Do you know what happens when multiplying a matrix with a vector? \$\endgroup\$ – Andreas Apr 23 '16 at 10:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.