gluPerspective() matrix

I am a little confused by how the matrix generated by gluPerspective accounts for the ‘w’ component of a given vertex.

Looking up the matrix generated by gluPerspective online, gives me that the matrix has the general form:
| A 0 0 0 |
| 0 B 0 0 |
| 0 0 C D |
| 0 0 -1 0|

Call this matrix M.
The specific values of A,B,C and D are not important for this discussion (I think). Right multiplying this matrix by a 4x1 vector (x,y,z,w) we obtain:

x’ = Ax,
y’ = Bx,
z’ = Cz+Dw
w’ = -z

This relationship puzzles me becuse x’ and y’ do not in any way depend on w.

My understanding was that if w=1/2 for instance, the resulting x’,y’, z’ should be scaled by a factor of 2 after dividing by the w’ component. But this projection transformation seems to have removed the affect of w on x’ and y’, and so they would NOT be multiplied by 2.

Can someone clear this up for me?

The perspective divide (w divide) occurs after applying the projection matrix. That takes care of it.

I am aware that the normalizing comes after the projection matrix, but my point is it will divide by the w component which in this case is (-z) which does not depend on w, and so x and y are not changed by w in any way. Right?

my point is it will divide by the w component which in this case is (-z) which does not depend on w, and so x and y are not changed by w in any way.

Yes, the clip-space X and Y are not affected by the camera-space (pre-transform) W. The larger question is this: why is your camera-space W not 1.0?

Earlier you said:

if w=1/2 for instance, the resulting x’,y’, z’ should be scaled by a factor of 2 after dividing by the w’ component.

That is technically true if your points are in a 4D homogeneous coordinate system. But the standard OpenGL perspective projection matrix expects positions that are in a Cartesian coordinate system (and therefore are not homogeneous). To do a projection from a 4D homogeneous space into another 4D homogeneous space requires a different matrix.

Well that makes sense but then why is it that if I use:

glVertex4f(1,1,1,0.5);

and the projection matrix generated by gluPerspective()

that the resulting point gets scaled by 2?

The larger question is this: why is your camera-space W not 1.0?

My understanding was that this happened frequently, like whenever you called glScalef or used glVertex4f for example… Not so?

My understanding was that this happened frequently, like whenever you called glScalef or used glVertex4f for example.

Scaling matrices scale the positions. They do not affect the W coordinate.

Okay! But then what happens if I say glVertex4f(1,1,1,0.5)? That modifies the w coordinate directly, by my understanding, but even when using gluPerspective, this results in scaling the point by 2 when I try it.

No. What evidence do you have for that?

What you said “originally” is correct:

…But this projection transformation seems to have removed the affect of w on x’ and y’, and so they would NOT be multiplied by 2.

Except that it didn’t “remove” the affect of W on X and Y. It wasn’t designed to do that.

As the above posters have essentially said, the point of this PROJECTION transform is to take 3D orthonormal EYE-SPACE to 4D homogenous CLIP-SPACE. In 3D orthonormal EYE-SPACE, w=1 for all points in space. The PROJECTION matrix assumes it.

However, just playing with this though, if you write out the NDC coordinates of a point as a function of EYE coords (i.e. apply the perspective projection matrix and do the perspective divide), and pretend that EYE-SPACE.w != 1 was valid, you (as you said) see that EYE-SPACE .w plays no role in NDC X and Y, but only in NDC Z. In Z, it functions as a scale factor for EYE-SPACE Z.

My understanding is a bit different: The projection matrix transforms 3d homogenous eye space coordinates to 3d homogenous clip space coordinates.

3d homogenous coordinates have 4 components, but they are only unique modulo a non-zero scaling factor, i.e. (x,y,z,w) and (ax, ay, az, aw) denote the same point for all a != 0.

So (1,1,1,0.5) is indeed the same as (2,2,2,1) and if you apply the projection matrix to both vectors, you’ll see that the result is the same point (though maybe not with the same coordinates).

The homogenous coordinates are later normalized by the “perspective” division (x,y,z,w) -> (x/w,y/w,z/w).

The reason why there is no dependancy on w in standard perspecive matrix is, because it describes a perspective transformation from the origin along the z axis. In orthogonal coordinates this means that the x and y coordinates have to be divided by -z.

If you assume x, y and z are normalized homogenous coordinates, i.e. they are really x/w, y/w and z/w, then you see that the division by -z will indeed not depend on w, as this appears both in the divisor and the dividend: (x/w) / (-z/w) = x/-z.