I am writing an OpenGL program in C that implements alpha-transparent bill boarding particles that use a PNG (with transparency) as their texture via pnglib. However, I have discovered that a particle's transparent zones will still replace particles called before it that are also behind it. In other words, particles newly called, though transparent in some areas, are completely overlapping some particles called before them when, instead, those previously called particles should be showing through the transparency.
In order to visualize the effect this is having, I am attaching a few images to display the problem:
Initially I am calling the particles from oldest-to-newest:
However when the view is changed, the overlapping effect is apparent:
When I decide to reverse the call order I get the opposite:
I believe that a solution to this would involve calling the particles in order from farthest from the camera to nearest. However, it is pretty computationally heavy to go through each active particle, order them from furthest-to-nearest, and then call each one every display frame. I am hoping to find an easier, more efficient solution. I've already tried my hand with glBlendFunc()
but no sfactor
or dfactor
seems to work.
Draw all non transparent geometry first. Then, before drawing the particles, disable the depth-buffer writes by calling
glDepthMask (GL_FALSE)
That will fix most of the rendering problems.
Sorting the particles by distance from the camera is still a good idea. With todays CPU power that shouldn't be much of a problem.