Z values not linear in screen space, but 1/z values are?

Started by
6 comments, last by kloffy 14 years, 1 month ago
I'm writing a software rasterizer. I've got it to the point right now where it can draw unlit, perspective-correct texture mapped, z buffered triangles. I'm doing this because I never have and I feel that if a programmer is going to use an API like OpenGL or DirectX, they should understand what is going on behind the scenes. Anyway, one of the references I'm using is a book from 1995 called "Cutting-Edge 3D Game Programming with C++" by John De Goes. It isn't the best reference to be sure, but he does write a perspective corrected texture mapper and it got me going. One thing he mentions is that z values cannot be interpolated across the polygon because they are not linear in screen space, but 1/z values are. He really doesn't give much of an explanation as to why this is, but since I don't know myself, I am dutifully following this advice. I really do not like not knowing why something is or is not happening in my code. Can someone clarify this for me?

No, I am not a professional programmer. I'm just a hobbyist having fun...

Advertisement
The reason why z is not linear in screenspace is because during perspective projection it is mapped to [-1,1] as follows:



That formula is a result of appling the perspective projection matrix and normalizing the resulting homogenous coordinates. If I'm not mistaken 1/z isn't linear either, though. Maybe you're using a different projection algorithm, or I just fail at math...
The "poor mans projection equation" is something like..

X2d = X3d * A_CONSTANT / Z3d
Y2d = Y3d * A_CONSTANT / Z3d

or...

X = X / Z
Y = Y / Z

so if he's using that, maybe that could explain it

Yes, that is what he's doing in the book.

No, I am not a professional programmer. I'm just a hobbyist having fun...

Hmm... It would seem that 1/z isn't linear either. I checked some dummy non-linear z values by hand (1,2,7,12) and their reciprocals (1,.5,.142,.083) and interpolating the reciprocal provides the wrong values (1,.5415,.31225,.083).

I really don't know what he was talking about.

No, I am not a professional programmer. I'm just a hobbyist having fun...

The reason it is not linear in screenspace is quite easy to see if you look at a 3D line and its corresponding 2D projection. If you partition the 3D line into n equally spaced points, the projections of those points are not equally spaced on the projected line. hence, moving linear on the 2D projected line corresponds to moving nonlinearly on the 3D line.

You can linearly interpolate 1/z in 2D space though, and there is a proof in one of Lamothe's books, and I Believe Eberly's first 3D engine book also proves it or at least gives you the general formula from which you can prove it.
-----Quat
i also began learning 3d graphics programming at a simple software renderer (motivation was the same for me as it is for you - and it really helps a lot!)

anyway - here is a good explanation why 1/z leads to perspective correct interpolation: (sry for this long link)

http://www.google.at/url?sa=t&source=web&ct=res&cd=1&ved=0CA4QFjAA&url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.3.211%26rep%3Drep1%26type%3Dpdf&rct=j&q=Perspective-Correct+Interpolation&ei=fDGMS46UAqGqnQPgyt20BA&usg=AFQjCNGf_uPq-jukiemkeysClwskGAD3UA
Excellent explanation, thank you for the link. (Btw.: you can use regular HTML-tags to create links like Perspective-Correct Interpolation on this board.)

This topic is closed to new replies.

Advertisement