OpenGL - Question about the usage of glDepthMask

Viewed 14816

I have rendered an objectA in a scene as follows. The scene has many other objects too.

void Draw()
{    
    if( glIsList( displayListID ) )
    {
        glPushAttrib( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ENABLE_BIT );

        glEnable( GL_BLEND );
        glEnable( GL_DEPTH_TEST );
        //glDepthMask( GL_FALSE );
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

        glEnable( GL_LINE_SMOOTH );
        glEnable( GL_POINT_SMOOTH );
        glEnable( GL_POLYGON_SMOOTH );

        glMatrixMode( GL_MODELVIEW ); 

        color.setAlpha(alpha); // set alpha transparent of this objectA
        glCallList( displayListID );

        //glDepthMask( GL_TRUE );
        glDisable( GL_BLEND );  

        glPopAttrib();
    }
}

Now here is the problem,

As shown, I comment out two lines //glDepthMask( GL_FALSE ); //glDepthMask( GL_TRUE );

the scene renders the objectA and other objects correctly in depth. However, the modification of the objectA alpha doesn't work anymore (i.e. color.setAlpha(alpha) ).

If I uncomment the above two lines, then alpha modification is back to work. However, the depth rendering is NOT correct. In other words, sometimes, the objectA should be behind other objects but it looks like the objectA is in front of all objects.

How do I fix this problem?

Thank you

4 Answers

Minor addition to other responses:

Even though visually it makes no difference what order you draw your opaque objects in, you should nevertheless sort them front-to-back to avoid over-draw and take advantage of the depth buffer to avoid pointless pixel shader invocations. This can have a significant performance impact. And even if sorting is slow, you can still bin your objects into near/medium/far groups and draw those in an explicit order.

For instance, in a 3D game, you always want to draw the sky last. Right before that, the landscape. Before that, distant objects. But start with the player or gun. The most stuff you draw first, that's closer, the less stuff you'll draw then overdraw. It's not always possible to do this with overlapping objects, but it's usually good enough.

It isn't necessary to turn of depth buffer writing, if you sort your translucent objects from back to front.
I render translucent objects like that:

  1. Draw all opaque objects, in any order.
  2. Turn on blending.
  3. Draw translucent objects sorted from back to front.

The issue of discarding fragments mentioned by bobobobo arises when you have intersecting polygons. But in this case disabling the depth buffer won't produce a correct result in all cases. At first sight it might look right, but if you look carefully, you will notice incorrect blending order:

Wrong blending

This case has mathematically no solution, since one polygon has to be rasterized before the other. To solve this issue you (or an artist) have to split the polygons at the intersection in a 3D editor (e.g. Blender). So you split your intersecting object into 2 or more and order them appropriately by your sorting algorithm. Than the translucent parts will be rendered in correct order:

Correct blending

Note that depth buffer writing is enabled in the 2nd screenshot!

If you disable the depth buffer you would naturally get the same result, but you don't need it. Indeed, it is easier to see such overlapping issues if the depth buffer writing is not disabled. This is the reason i prefer not to disable it.

Related