Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 382
user1175938 Avatar asked Jan 29 '12 22:01

user1175938


2 Answers

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.

like image 58
SigTerm Avatar answered Sep 20 '22 16:09

SigTerm


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?

According to this link: http://www-01.ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.opengl/doc/openglrf/glDepthFunc.htm%23b5afa88027vbia,

The glDepthFunc subroutine specifies the function used to compare each incoming pixel z value with the z value present in the depth buffer." It is also stated that: "GL_LESS Passes if the incoming z value is less than the stored z value.

Here: the z value is distance from camera to the object. This results in the closer object to be drawn on the screen. This is also explained here: http://www.glprogramming.com/red/chapter10.html

I quote from the last link:

Depth Buffer

The depth buffer stores a depth value for each pixel. As described in "A Hidden-Surface Removal Survival Kit" in Chapter 5, depth is usually measured in terms of distance to the eye, so pixels with larger depth-buffer values are overwritten by pixels with smaller values. This is just a useful convention, however, and the depth buffer's behavior can be modified as described in "Depth Test." The depth buffer is sometimes called the z buffer (the z comes from the fact that x and y values measure horizontal and vertical displacement on the screen, and the z value measures distance perpendicular to the screen).

like image 40
Jamil Avatar answered Sep 16 '22 16:09

Jamil