Search code examples
openglgraphicspyopengldepth-buffer

OpenGL – Get distance to farthest face from camera instead of closest face


I'm using OpenGL (with Python bindings) to render depth maps of models saved as .obj files. The output is a numpy array with the depth to the object at each pixel.

The seemingly relevant parts of the code I'm using look like this:

glDepthFunc(GL_LESS)                # The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST)             # Enables Depth Testing

... load the vertices and triangles, set the camera viewing position ...

depth = np.array(glReadPixels(0, 0, Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT), dtype=np.float32)

I can use this to successfully render depth images of the object.

However, what I want to do is, instead of obtaining the depth of the face closest to the camera along each ray, I want to obtain the depth of the face furthest from the camera. I want faces to be rendered regardless of in which direction they are facing – i.e. I don't want to backface-cull.

I tried to achieve this by modifying the above code like so:

glDisable(GL_CULL_FACE)             # Turn off backface culling
glDepthFunc(GL_GREATER)             # The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST)             # Enables Depth Testing

... load the vertices and triangles, set the camera viewing position ...

depth = np.array(glReadPixels(0, 0, Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT), dtype=np.float32)

However, when I do this I don't get any depth at all rendered. I suspect that this is because I am using GL_DEPTH_COMPONENT to read out the depth, however I am not sure what to change to fix this.

How can I get the depth of the faces furthest from the camera?


Solution

  • Switching the depth test to GL_GREATER in priciple will do the trick, you overlooked just a tiny detail: You need to initialize the depth buffer differently. By default, it will be intialized to 1.0 when clearing the depth buffer, so that GL_LESS comparisions might update it to values smaller than 1.0.

    Now, you want it to work the other way around, so you must intialize it to 0.0. To do so, just add a glClearDepth(0.0f) before the glClear(... | GL_DEPTH_BUFFER_BIT).

    Furthermore, you yourself mention that you don't want backface culling for that. But instead of disabling that you can also switch the face culling around using glCullFace. You probably want GL_FRONT here, as GL_BACK is the default. But disabling it will work too, of course.