12
votes

According to a number sources NDC differs from clip space in that NDC is just clip space AFTER division by the W component. Primitives are clipped in clip space, which in OpenGL is -1 to 1 along X, Y, and Z axes (Edit: this is wrong, see answer). In other words, clip space is a cube. Clipping is done within this cube. If it falls inside, it's visible, if it falls outside, it's not visible.

So let's take this simple example, we're looking from the top down on a viewing frustum, down the negative Y axis. The HALFFOV is 45 degrees, which means the NEAR and the RIGHT are both the same (in this case length 2). The example point is (6, 0, -7).

enter image description here

Now, here is the perspective projection matrix:

enter image description here

For simplicity we'll use an aspect ratio of 1:1. So:

RIGHT = 2
LEFT = -2
TOP = 2
BOTTOM = -2
NEAR = 2
FAR = 8

So filling in our values we get a projection matrix of:

enter image description here

Now we add the homogenous W to our point, which was (6, 0, -7), and get get (6, 0, -7, 1).

Now we multiply our matrix with our point, which results in (6, 0, 6.29, 7). This point now (the point after being multiplied by the projection matrix, is supposed to lie in "clip space". Supposedly the clipping is done at this stage, figuring out whether a point lies inside or outside the clipping cube, and supposedly BEFORE division with W. Here is how it looks in "clip space":

enter image description here

From the sources I've seen the clipping is done at this stage, as it looks as above, BEFORE dividing by W. If you divide by W NOW, the point ends up in the right area of the clip space cube. This is why I don't understand why everyone says that perspective division is done AFTER the clipping space. In this space, prior to perspective division the point lies completely outside and would be judged to be outside the clipping space, and not visible. However after the perspective division, division by W, here is how it looks:

enter image description here

Now the point lies within the clip space cube, and can be judged to be inside, and visible. This is why I think perspective division is done BEFORE clipping, because if clipping space is in -1 to +1 in each axis, and the clipping stage checks against these dimensions, for a point to be inside this cube it must have already undergone division by W, otherwise almost ANY point lies outside the clipping space cube and is never visible.

So why does everyone say that first comes clipping space which is a result of the projection matrix, and ONLY then there is perspective division (division by W) which results in NDC?

1
I learned a lot just from the question itself.v.shashenko

1 Answers

16
votes

In clip space, clipping is not done against a unit cube. It is done against a cube with side-length w. Points are inside the visible area if each of their x,y,z coordinate is smaller than their w coordinate.

In the example you have, the point [6, 0, 6.29, 7] is visible because all three coordinates (x,y,z) are smaller than 7.

Note, that for points inside the visible area, this is exactly equivalent to testing x/w < 1. The problems start with points in-front of the far-plane since they might get projected to the visible area by the homogeneous divide because their w-value is negative. As we all know, dividing by a negative number in an inequality would switch the operator, which is impracticable on hardware.

Further readings:
OpenGL sutherland-hodgman polygon clipping algorithm in homogeneous coordinates
Why clipping should be done in CCS, not NDCS
Why does GL divide gl_Position by W for you rather than letting you do it yourself?