Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

OpenGL depth testing and blending not working simultaniously

I’m currently writing a gravity-simulation and I have a small problem displaying the particles with OpenGL.

To get "round" particles, I create a small float-array like this:

for (int n = 0; n < 16; n++)
            for (int m = 0; m < 16; m++)
            {
                AlphaData[n * 16 + m] = ((n - 8) * (n - 8) + (m - 8) * (m - 8) < 64);
            }

I then put this in a GL_TEXTURE_2D with format GL_RED. In the fragment shader (via glDrawArraysInstanced), I draw the particles like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

color = vec4(ParticleColor.rgb, texture(Sampler, UV).r);

This works as it should, producing a picture like this (particles enlarged for demonstration):

enter image description here

As you can see, no artifacts. Every particle here is the same size, so every smaller one you see on a "larger" particle is in the background and should not be visible. When I turn on depth-testing with

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

I get something like this:
enter image description here

So for the most part, this looks correct ("smaller" particles being behind the "bigger" ones). But I now have artifacts from the underlying quads. Weirdly not ALL particles have this behavior.

Can anybody tell me, what I’m doing wrong? Or do depth-testing and blending not work nicely together?

I’m not sure, what other code you might need for a diagnosis (everything else seems to work correctly), so just tell me, if you need additional code.

I’m using a perspective projection here (of course for particles in 3D-space).

>Solution :

You’re in a special case where your fragments are either fully opaque or fully transparent, so it’s possible to get depth-testing and blending to work at the same time. The actual problem is, that for depth testing even a fully transparent fragment will store it’s depth value. You can prevent the writing by explicitly discarding the fragment in the shader. Something like:

color = vec4(ParticleColor.rgb, texture(Sampler, UV).r);
if (color.a == 0.0)
    discard;

Note, that conditional branching might introduce some additional overhead, but I wouldn’t expect too many problems in your case.

For the general case with semi-transparent fragments, blending and depth-testing at the same time will not work. In order for blending to produce the correct result, you have to depth sort your geometry prior to rendering and render from back to front.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading