Alpha Decal sorting problem

I’m trying to get decals to work properly, but am having some problems. Namely, they z-fight with each other ( I think, heh ).

First I’m rendering down a lightmap, then using DST_COLOR - SRC_COLOR to apply the wall texture. Next, I render the decals using SRC_ALPHA - ONE_MINUS_SRC_ALPHA…polygonOffset enabled, and depthFunc set to GL_LEQUAL.

At first, I thought they were just being rendered in a more-or-less random order every time, but it seems that the problem happens even when I can guarantee that they are rendered in the exact same order.

Options I’ve read about:

Use polygonOffset – actually, I already am doing this but it doesn’t seem to be sufficient.

Use a depthfunc of GL_EQUAL – seems to make the problem worse.

Switch art and blend mode so that you can render the decals using DST_COLOR - SRC_COLOR – This actually does have some promise, but I can’t use this for the blood stains and pools that I need to create…because…they wouldn’t ever show up on a completely green/cyan/blue/black type surface…there has to be at least some red in the texture in order to see anything.

Any help would be greatly appreciated.
Thanks in advance.
El Jefe

[This message has been edited by El Jefe (edited 03-11-2002).]

So the problem is affected by both the depth test and the blending mode?

This may be a dumb question, but I have to ask, do you maybe have your depth reversed? Try using GL_GEQUAL for the depth test and see if it helps. If not, well, a screenshot would be nice for a start.

Yeah, GL_GEQUAL doesn’t seem to work very well at all. I see equally bad artefacting with GL_EQUAL…and GL_LEQUAL mostly works except for random z-fighting. …But I only see the fighting with other decals, not the wall that they are attached to, presumably because of the poly offset I do.

Do I maybe have to ensure that I’m not somehow writing the z-values for the decals when I render them with PolyOffset? Does anyone know if the offset z values calc’d by PolyOffset are the values that get written into the z-buffer or if it only uses the offset values for comparison purposes only? It seems like I’d be screwed if it puts the offset z-values into the z-buffer…

As for the blend mode, if I use DST_COLOR - SRC_COLOR, with appropriate artwork, the problem with z-fighting goes away. So…I suppose I should check to see if the engine I’m using automatically adjusts certain GL states based on the blend mode used…

Hmm, I really don’t have a place to put a screenshot. To be honest though, I’m not sure if it would really capture the problem very well.

If your decals are z-fighting with one another but not the surface they are applied to, then it is obvious you have depth writing enabled when drawing the decals. Disable depth writes (but leave depth testing on) when drawing your decals, that will stop their mutual z-fighting.

Hint: see glDepthMask

[This message has been edited by DFrey (edited 03-11-2002).]

I would just chang the depthfunc to GL_NOTEQUAL. That should work, it worked for my skid marks I draw on the ground.

What does glPolygonOffset do/not do that makes it not work? It seems ideal to solve your problem.

The problem is that part of it is implementation specific.

It’s implementation specific because its inner workings depend on the z buffer depth and format. But that doesn’t matter.

previous thread

Omaha, look at exactly what he said, using glPolygonOffset did stop them from fighting with the surface the decals were being applied to, but glPolygonOffset will not stop decals from fighting against one another if they each have the same offset. That’s why depth writes must be disabled, i.e. masked, when drawing the decals. So that for each decal the same offset works. Otherwise, you would have to continually change the offset for each overlapping decal. Far easier to disable depth writes and be done with it using only a single depth offset for each decal.