3

I have a mesh to render with OpenGL. What I want is to render its edges, but only the ones of the un-occluded faces. However, I realize that this is not possible with only:

glEnable(GL_DEPTH_TEST);    // Enable depth test
glDepthFunc(GL_LEQUAL);     // Accept fragment if it closer to the camera than the former one
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

since there is no depth information in-between the edges, so the edges of the occluded triangles are still rendered.

A work around is to draw the triangles with GL_FILL first in background color (in my case, white), and then draw the edges separately. But doing so results in artifacts similar to the z-fighting phenomenon, i.e., some edges seem thinner than others or even vanish, as shown below

enter image description here

On the left is what I have, and on the right is what I desire (viewed in MeshLab). Since depth test of triangles seems to be unavoidable in this case, I guess I am also asking:

How can I draw edges over triangles without the z-fighting artifacts?

Note that face culling is not useful, as it only eliminates faces facing backward, but cannot deal with occlusion.

ihdv
  • 1,927
  • 2
  • 13
  • 29
  • set [`glPolygonOffset`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glPolygonOffset.xhtml) for the 1st pass. – Rabbid76 Nov 08 '21 at 10:43
  • 1
    @Rabbid76 Thanks! It's exactly what I need, and it seems to be the standard solution – ihdv Nov 08 '21 at 12:29

1 Answers1

4

Set a polygon offset for the first pass with glPolygonOffset:

glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1, 1);

Disable the polygon offset for the 2nd pass:

glDisable(GL_POLYGON_OFFSET_FILL);

Polygon fill offset manipulates the depth of a fragment by a minimum amount. This results in the depth of the fragments in the first pass being a small amount greater than the depth of the same fragments in the second pass. This is how you get rid of the deep conflict.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174