Take the 2-minute tour ×

I'm currently learning OpenGL and haven't been able to find an answer to this question.

After the projection matrix is applied to the view space, the view space is "normalized" so that all the points lie within the range [-1, 1]. This is generally referred to as the "canonical view volume" or "normalized device coordinates".

While I've found plenty of resources telling me about how this happens, I haven't seen anything about why it happens.

What is the purpose of this step?

share|improve this question

6 Answers 6

up vote 7 down vote accepted

The most important is that it converts yours points(vertices) from 3D world space to 2D screen space.

That means that after vertex is multiplied with this matrix X and Y coords are position on the screen (between [-1, 1]) and Z is the depth. Z is used for depth-buffer and identifies how far is vertex (or fragment) from your cameras near plane.

Projection means that vertices which are more near from near plane are more far from middle of the screen -> triangle more near to camera appears to be bigger that one that is far. And this is based on yours field of view - you are entering it in some createProjectionMatrix function or createFrustum. It works that it shears and scales yours camera frustum and vertices in it into unit cube. Values that are greater than 1 and smaller than -1 are not displayed.

Also keeps pixel aspect ratio, so pixel can be sqaure. That is simple. It just shears camera frustum like this: more wider screen -> more vertical shear and vice versa.

Simple answer:
It defines yours camera frustum and is good to:

  • make objects which are near to you look bigger than objects that are far from you.
  • keep pixel aspect ratio - Everybody likes square pixel right? :)
share|improve this answer
I don't see any part where he asks what the projection matrix does. He just seems to wonder what the normalized device coordinates are for. –  Christian Rau Aug 24 '11 at 12:17
The projection matrix defines the camera frustum. But this doesn't explain the reason for having [-1,1] as the canonical viewing volume. Why not have [-100,100] instead? –  bobobobo Dec 1 '12 at 19:45
because 1 is "more common number" than 100 :D (0 is even more common, but cube 0x0x0 is not very interesting...) –  Ivan Kuckir Feb 20 '13 at 22:15

I believe this is because OpenGL can't make assumptions about how the image is to be displayed (aspect ratio or resolution, hardware details, etc). It renders and image into an intermediate form which the operating system or driver or whatever scales to the correct resolution/size.

share|improve this answer
You are not correct when you are speeking about hardware details. There are non. Also if you are writing you own rastarizator on cpu (why to do it? To learn how this stuff works :)) you are using same matrices as on gpu. You are lucky that i still dont have privileques to vote down :) –  Notabene Dec 7 '10 at 23:12
Doesn't it need to know the aspect ratio? From what I understand, it stores the scaling factors for X and Y so that the image will have the correct aspect ratio later on. –  breadjesus Dec 7 '10 at 23:44
Correct me if I am wrong, but he is talking about after you project points, and thus we are talking 2D. If this is the case, then OpenGL doesn't know where on the screen you are putting this image, nor about how it is going to be displayed. It creates an image which is then easy to scale and place correctly, but it does not do that for you. I do agree that hardware details was a bad name for it, I simply meant the above. Also, you can specify a projection matrix with an aspect ratio, but that ratio does not have to be the same as your monitor's. –  Chewy Gumball Dec 8 '10 at 0:21
I have to say that i really enjoy this conversation. You are near to be right. Lets go deeper. There are is no image after multiplacation vertices by projMat. Result is just set of 2D point with depth. Than rastarization begins and it creates images. (if on cpu it would draw lines between triangles verts and fill it (and shade it-whatever) ... on gpu it is performed just before pixel/fragment shader). And aspect ratio puts points which should be "scaled away" to values bigger than 1 or smaller than -1 and they will not be displayed. –  Notabene Dec 8 '10 at 0:44
AHHH! I see the issue here. He said "This is generally referred to as the "canonical view volume" or "normalized device coordinates"." I was answering as if he was asking about normalized device coordinates, however he wasn't actually asking about those at all. They are, in fact, two completely different things and that is why we are at odds here. Perhaps that should be clarified so people don't make the same mistake I did. –  Chewy Gumball Dec 8 '10 at 20:40

I note an answer has already been accepted, but it's generally useful for clipping to have the view frustum transformed into a unit cube.

share|improve this answer
True, i little edited my answer to be more clear about this. –  Notabene Dec 8 '10 at 23:00
By the way a unit cube is a cube of side 1. So the name is inappropriate. It should be called canonical viewing volume instead. –  user18490 Jan 7 at 21:42

I've also been wondering this. There are a couple of things to consider.

First, yes, everything in the world gets transformed to that unit cube [-1,1] centered around the origin. If something isn't in that unit cube then it isn't going to be displayed.

The nice thing about this is now, you can cull triangles pretty easily. (If all 3 vertices of a triangle have x > 1 or x < -1 then that triangle can be culled).

share|improve this answer

This answer is long after the fact, but since I found this on google maybe this will still help someone. I just want to clarify what JasonD and Notabene were saying: It is a lot easier to do clipping calculations (figure out what you should see and what you shouldn't see because of which way you are looking, how far away it is, ect.). Instead of checking if things intersect the planes on the borders of your view frustum, you simply compare the x,y,z of everything to xMax, xMin, yMax, ect. , since you simply have a cube. It is a little more complicated if you want to only have part of something showing, but the math is still better with a unit cube than with a frustum.

A couple things I found misleading in other answers:

-You aren't shearing the sides off of the view frustum, you are sort of warping it into a cube using homogeneous matrix transformations.

-We aren't converting to a 2D screen with this step. This step isn't necessary to do so. Theoretically we could do all our work without converting the frustum to a cube first, which would be more intuitive but harder math - but graphics is all about doing calculations really fast since there are a LOT of calculations per second for the average game/whatever.

More detail: It isn't necessarily a unit cube we are converting to, it just has to be a rectangular box for our max-min calculations to work out. In fact in class we used a box where the camera faces down the z-axis, z goes from 0 to 1, x goes from -1 to 1, and y goes from -1 to 1. In general in math 1, 0, and -1 are good numbers for making calculations easier, I assume that is why we don't go from -100 to 100 or something.

TLDR: It makes clipping easier.

Edit: bobobobo has the gist of it. Everything is triangles, generally :D.

Source: Taking a university graphics class

share|improve this answer
While interesting, it seems like your points are partially true. You are not using an homogeneous matrix, it is just that in clip space, points are defined in homogeneous space. 2) true, in clip space ponts are not yet projected onto the screen. It happens after the perspective divide, though note that this necessarily happens when you go back from clip space back to cartesian space. 3) yes and no. Converting points coordinates to NDC space is still somehow necessary. What's not necessary is the clip space, which is specific to the GPU. ... –  user18490 Jan 7 at 21:40
... It's the clip space stage which is not necessary, not the remapping to the unit cube. Your last assumption is not correct either. You remap to -1 to 1 because it's easier to then go from NDC space to raster space (the viewport transform). It's actually even easier if you the NDC space is in the range [0,1] which is the case for some implementation. At the end it's all maths though, so sure other conventions can be used. see the good scratchapixel website for more details. –  user18490 Jan 7 at 21:41

I would recommend to check the lesson on perspective projection matrix on Scratchapixel


It clearly explains that the why is to warp the view frustum space to a unit cube. Why? Essentially because the process of projecting 3D points on the canvas involved to convert them NDC space which is a space in which points on the screen are remapped in the range [-1,1] (assuming the screen is square). Now we also remap the point Z-coordinate to the range [0,1] (or sometimes [-1,1]) therefore in the end you end up with a cube. The fact is that when points are contained in a cube, it's easier to process them than when they are defined in the view frustrum (which is a strange space, a truncated pyramid). Another reason is that it sorts of bring all sort of projective transformation you can imagine in CG to the same space (the unit cube thingy). So regardless of whether you use a perspective or orthographic projection for example, you end up with a cube in the end, and from there you can apply the same transforms to remap the coordinates to their final position in the image (raster space).

Though maybe you focus too much on the why. The unit cube is really just the result of the process of the mathematics involved or used to project vertices onto a screen and then remap their coordinates to raster space.

share|improve this answer

Your Answer


