mobob
mobob

Reputation: 906

How to stop OpenGL background bleed on transparent textures

I have an iOS OpenGL ES 2.0 3D game and am working to get transparent textures working nicely, in this particular example for a fence.

I'll start with the final result. The bits of green background/clear color are coming through around the edges of the fence - note how it isn't ALL edges and some of it is ok:

Background bleed evidence

The reason for the lack of bleed in the top right is order of operations. As you can see from the following shots, the order of draw includes some buildings that get drawn BEFORE the fence. But most of it is after the fence:

Draw progression with depth

So one solution is to always draw my transparent textured objects last. I would like to explore other solutions, as my pipeline might not always allow this. I'm looking for other suggestions to solve this problem without sorting my draws.

This is likely a depth or blend function, but i've tried a ton of stuff and nothing seems to work (different blend functions, different discard alpha levels, different background colors, different texture settings).

Here are some specifics of my implementation.

In my frag shader I'm throwing out fragments that have transparency - this way they won't render to depth:

lowp vec4 texVal = texture2D(sTexture, texCoord);
if(texVal.w < 0.5)
    discard;

I'm using one giant PVR texture atlas with mipmapping - the texture itself SHOULD just have 0 or 1 for alpha, but something with the blending could be causing this:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

I'm using the following blending when rendering:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Any suggestions to fix this bleed would be great!

EDIT - tried a different min filter for the texture as suggested in the comments, LINEAR/NEAREST, but same result. Note I have also tried NEAREST/NEAREST and no luck:

enter image description here

Upvotes: 4

Views: 3110

Answers (2)

DanP
DanP

Reputation: 187

try increasing the alpha filter limit,

lowp vec4 texVal = texture2D(sTexture, texCoord);
if(texVal.w < 0.9)
    discard;

Upvotes: 1

Leonard
Leonard

Reputation: 668

I know this is an old question but I came across it several times whilst trying to find an answer to my very similar OpenGL issue. Thought I'd share my findings here for anyone with similar. The culprit in my code looked like this:

glClearColor(1, 0, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);

I used a pink transparent colour for ease of visual reference whilst debugging. Despite the fact it was transparent when it was blending between background and the colour of the subject it would bleed in much like the symptoms in the screenshot of the question. What fixed it for me was wrapping this code to mask the glClear step. It looked like this:

glColorMask(false, false, false, true);
glClearColor(1, 0, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
glColorMask(true, true, true, true);

To my knowledge, this means when the clear process kicks in it only operates on the alpha channel. After this is was all re-enabled to continue the process as intended. If someone with a more solid knowledge of OpenGL can explain it better I'd love to hear!

Upvotes: 0

Related Questions