Homogeneous divides

I have a question about homogeneous coordinates in OpenGL. I’m sorry if this shouldn’t be posted under “advanced”, but it’s hard for me to tell.

Is it true that the projection matrix defined by a call to glFrustum will only work for vertices of the form [x y z 1]^T ?

The reason it seems to me this must be so is that it seems to me the projection matrices defined by glFrustum would not project points correctly without w = 1. Roughly speaking (ignoring normalised device coordinates and any handedness changes) let’s take an example. Consider the centre of projection at (0, 0, -1) and the viewplane along the Z=0 plane, the x coordinate of a point [x y z w]^T should be projected (into 2D) as x / (w * ((z / w) + 1)) = x / (z + w), whereas the projection matrices defined by glFrustum will set the w coordinate of such a point to -z, hence after the perspective divide the 2d coordinate will be (again roughly speaking) x / -z. What happened to the original w ?!?

Where am I wrong here?

If I am correct, does this mean that before applying the projection matrix to vertices a vertex [x y z w]^T is projected to [x y z 1]^T ? Then the projection matrix is applied, and clipping occurs to the “image space” cube in projective space against 7 clipping planes. And finally the perspective division is done.

The final thing confusing me is that in the OpenGL spec. it says OpenGL may not handle clip-coordinates with w < 0 correctly…how can this be right? Any point behind the viewer in 3D will be transformed to a 4D point with w < 0 after the projection matrix is applied. Or do I misunderstand what they mean by a clip-coordinate?

I’d be really grateful if someone could clear this up for me. Thanks for reading!

I didn’t go through your math, but I looked at glFrustum, and it looks like the input w coordinate ends up in the output z coordinate. After perspective division and near/far clip, things seem that they should just work out.

I think the w<0 restriction refers to vertices that should appear in the clip volume after the division. An example would be a triangle with “external” vertices, such as those used in projected shadow volumes. Basically, it lets you avoid handling a bizarro case where triangles wrap clear around the clip volume and wrap through to the other side with the opposite winding.

I started writing an explanation and realized it would take too long, and be too hard to understand with just text. You may want to check out Marc Olano’s homogeneous rasterization paper. Google it.


does this mean that before applying the projection matrix to vertices a vertex [x y z w]^T is projected to [x y z 1]^T ?
Obviously, that is not the case. Not sure about your math though.
w=0 allows to specify a coordinate at infinity, for example it can be used to represent the horizon, the stars, etc.
Like the w=0 needed for a parallel infinite light.

Specifying a vertex with w=0 doesn’t mean that w=0 in clip-space. And the w<0 case doesn’t include w=0.