Why is GL_LEQUAL recommended for the GL depth function (and why doesn't it work for me)?

user1175938 picture user1175938 · Jan 29, 2012 · Viewed 11.4k times · Source

On the GL wiki they recommend using GL_LEQUAL for the depth function. Also, the depth function defaults to GL_LESS. When I use either of these functions, I get strange results. In this picture the red square should be in front of the blue one (both squares are the same size): with GL_LESS

However, if I use glClearDepth(0.0) and then glDepthFunc(GL_GREATER), running the otherwise unchanged program I get this: with GL_GREATER

Thinking about it a bit more, it makes sense that GL_LESS would give the results it does: if the incoming depth value is less than the stored one, the fragment is written.

If I positioned my camera at (1, 0, 0) and looked towards (0, 0, 0) I expect an object at (0.5, 0, 0) to be in front of an object at (0, 0, 0). With GL_LESS wouldn't the object at (0, 0, 0) be the one whose fragments are written?

EDIT: Nicol, thanks for mentioning the projection matrix. It seems like it was set incorrectly. I was following your tutorial on arcsynthesis.org for awhile and adapting the code to my own project, but I deviated from your projection matrix and used math described on the glFrustum man page to implement my own version of that function, and then used NeHe's gluPerspective replacement to replace gluPerspective. I don't know why the replacements didn't work because my matrix math is correct (i have checked it against various online calculators). Using your matrix I get the correct result with GL_LESS.

Answer

SigTerm picture SigTerm · Jan 30, 2012

Why is GL_LEQUAL recommended for the GL depth function

Shaders. Multipass alphablended lightning (possibly with bumpmapping). To do that, you'll have to paint same object on same position/depth several time, but with different shader/blending parameters AND depth test should be enabled (depth writing can be disabled after 1st past). GL_LESS will cut out 2nd pass and every pass after that. GL_LEQUAL won't, and lighting will work properly.

GL_LEQUAL will not cause z-fighting by itself, z-fighting happens when you have two almost parallel polygons sharing almost identical location. Effect can be reduced by increasing depth buffer precision. In the past it could have been also reduced by using w-buffer (at least in DirectX), but AFAIK this feature isn't popular anymore.

In this picture the red square should be in front of the blue one (both squares are the same size):

Impossible to answer correctly without source code.