0
101 Dec 10, 2008 at 23:19

I’ve been trying to understand perspective projection transformation in openGL. Why is it that the z coordinates typically get mapped non-linearly (considering issues with z-fighting), rather than linearly into the canonical view volume? Is it simply because linear mapping can’t be cast nicely by a matrix multiply and a w-divide?

Thanks,
Tobey

#### 7 Replies

0
165 Dec 11, 2008 at 02:37

You can certainly do a linear mapping if you want, using a slightly different than standard projection matrix. However, you put your finger on the issue - z-fighting. You generally want things that are closer to be more sensitive to depth differences than things that are further away, as things that are closer tend to be bigger in screen space. It’s a tradeoff.

0
101 Dec 11, 2008 at 09:20

@Reedbeta

You can certainly do a linear mapping if you want, using a slightly different than standard projection matrix. However, you put your finger on the issue - z-fighting. You generally want things that are closer to be more sensitive to depth differences than things that are further away, as things that are closer tend to be bigger in screen space. It’s a tradeoff.

Z-fighting is not the reason behind the projection matrix being the way that it is. The reason is perspective-correct rasterization. The fact that there is more z precision closer to the camera is simply a benign side effect of the requirement that 1/z be interpolated across a triangle instead of z. For a thorough understanding of all this, I recommend reading Sections 4.4 and 4.5 of my book Mathematics for 3D Game Programming and Computer Graphics.

0
102 Dec 11, 2008 at 09:41

I don’t think you can linearize z-buffer with different projection matrix, but you can do it in vertex shader by multiplying z with w. Anyway, even though this makes z values linear at vertices I believe it makes them non-linear inbetween due to perspective projection, so you would have to do this in pixel shader (i.e. write to oDepth) which would be a performance killer.

0
104 Dec 11, 2008 at 11:03

i just use linear z in my application and it worked fine, but i have a question - is the z value from the projection matrix the 1/z?

cause i dont know either. and what is its purpose, how does the clipper fit into this, because once a vertex is projected how are you supposed
to clip it with the near plane, i did it with a separate transform with the view matrix and clip that first, then do the rest in quick 2d.

0
102 Dec 11, 2008 at 12:23

@rouncer

i just use linear z in my application and it worked fine, but i have a question - is the z value from the projection matrix the 1/z?

I believe you are talking about software rasterizing while everyone else is talking about GPU’s or how GPU transformation is abstracted with OpenGL/D3D. With software rasterizing you can of course do anything you like, e.g. use W-buffer which is linear. The actual z value written to the depth buffer is (a*z’+b)/(c*z’+d), where z’ is the camera space z and a, b, c and d coefficients from the projection matrix (i.e. the coefficients of the bottom right 2x2 matrix of the projection matrix). As you can see, this isn’t linear in relation to the z’, except if c=0, which is orthogonal projection.

0
165 Dec 11, 2008 at 17:42

@elengyel

Z-fighting is not the reason behind the projection matrix being the way that it is. The reason is perspective-correct rasterization.

Ah, yes. You’re right of course - sorry!

0
101 Feb 05, 2009 at 15:58

I know it’s been a while since I asked my initial question, but I was finally able to get elengyel’s book,”Mathematics for 3D Game Programming and Computer Graphics” from my university’s library. It’s great, and concise without sacrificing explanation. Thanks!

-Tobey