Is there any reason why OpenGL performs primitives' clipping in clip coordinates? Can it be at least theoretically done in normalized device coordinates?
2 Answers
The space after clip space is normalized device coordinate space, which is obtained by dividing clip.xyz by clip.w. If W is zero... oops.
Oh sure, you could put a conditional test to see if W is zero or very close to zero. Or you can just do the clipping math in clip space and never have to worry about it. No post-clipping vertex can have a W of zero, because the clip box for each vertex is based on being in the closed range (-W, W). And if W is 0, then the closed range is an empty set, and thus the vertex is not on that range.
Also, negative values of W are outside of the clipping space. The closed range (-W, W) is inverted where W is negative, but the meaning of the range itself is not. Consider a W of -1; the range becomes (1, -1). There are no numbers that are simultaneously greater than 1 and less than -1. Therefore that space is empty.
And yet, division by a negative W can still land NDC points in the [-1, 1] NDC-space range, where they will not be clipped if you didn't clip them beforehand.
- 9,161
- 14
- 23
-
3Also, W < 0 for points behind the camera. So if you divide by W first, you then cannot tell whether a point/primitive was behind the camera or in front of it. – Nathan Reed Nov 26 '17 at 03:05
-
1Last fact seems most important to me – Nolan Nov 28 '17 at 12:46
-
But I doubt it's true. Could you prove it or provide an example? – Nolan Nov 28 '17 at 14:44
-
@Nolan: The point (0, 0, 0, -1). Divide by -1, and it's in the [-1, 1] range. But it can't be in the range of [1, -1], since that is an empty set. – Nicol Bolas Nov 28 '17 at 15:10
-
You can't get point (0, 0, 0, -1) after multiplying by the projection matrix. It requires initial point have w coordinate equal 0 or have weird projection planes like negative near or far behind near. – Nolan Nov 28 '17 at 16:50
-
@Nolan: Nowhere in OpenGL is there an assumption that `gl_Position` can only arise by "multiplying by a projection matrix". The specification must deal with *all* possible values, not just the ones that come about through the usual means. – Nicol Bolas Nov 28 '17 at 16:53
-
Also I would argue this point must be clipped. You can multiply (0,0,0,-1) by (-1) and get (0,0,0,1) which denotes same point in 3D but shouldn't be clipped according to its w coordinate. – Nolan Nov 28 '17 at 17:04
-
@Nolan: But it cannot be clipped in NDC space, because in NDC space, the point is just (0, 0, 0). Remember: NDC is 3D space, not 4D. So it cannot tell the difference between a clip-space (0, 0, 0, 1) and (0, 0, 0, -1). The former should not be clipped; the latter should. NDC space can't tell the difference. This is why clipping is done in clip-space; because it has sufficient information to do it correctly. – Nicol Bolas Nov 28 '17 at 17:06
-
Let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/69391/discussion-between-nolan-and-nicol-bolas). – Nolan Nov 28 '17 at 17:08
Clipping could be done in normalised device coordinates as all primitives with z-coordinates outside -1 to 1 are outside the clipping planes. However, there is no reason not to do it in clip coordinates by considering z-coordinates from -w to w.
Theoretically it possible. However it seems there is performance increase when doing the clipping in clip coordinates. By first comparing z-coordinates before perspective division it saves time by not computing perspective division for the clipped primitives. This means less division operations. This favourable as floating point division can take a few processing cycles.
Refer also to the answer in this related question
- 1,032
- 5
- 11