skip to Main Content

Whenever I draw a texture that has alpha around the edges (it is anti-aliased by photoshop), these edges become dark. I have endlessly messed around with texture filters and blend modes but have had no success.

Here is what I mean:

minFilter: Linear magFilter: Linear

Circle on yellow background
Red background

minFilter: MipMapLinearNearest magFilter: Linear

enter image description here
enter image description here

minFilter: MipMapLinearLinear magFilter: Linear

enter image description here
enter image description here

As you can see, changing the filter on the libGDX Texture Packer makes a big difference with how things look, but alphas are still dark.

I have tried manually setting the texture filter in libgdx with:

texture.setFilter(minFilter, magFilter);

But that does not work.

I have read that downscaling with a linear filter causes the alpha pixels to default to black? If this is the case, how can I avoid it?

I have also tried changing the blend mode: glBlend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_APHA) makes no difference. glBlend(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) removes alpha altogether so that doesn’t work.

I do NOT want to set my minFilter to Nearest because it makes things look terribly pixellated. I have tried every other combination of texture filters but everything results in the same black/dark edges/outline effect.

2

Answers


  1. I have read that downscaling with a linear filter causes the alpha pixels to default to black?

    This is not necessarily true; it depends on what colour Photoshop decided to put in the fully transparent pixels. Apparently this is black in your case.

    The problem occurs because the GPU is interpolating between two neighbouring pixels, one of which is fully transparent (with all colour channels set to zero as well). Let’s say that the other pixel is bright red:

    (255,   0,   0, 255)  // Bright red, fully opaque
    (  0,   0,   0,   0)  // Black, fully transparent
    

    Interpolating with a 50/50 ratio gives:

    (128,   0,   0, 128)
    

    This is a half-opaque dark red pixel, which explains the dark fringes you’re seeing.

    There are two possible solutions.

    1. Add bleeds to transparent regions

    Make sure that the fully transparent pixels have the right colour assigned to them; essentially “bleed” the colour from the nearest non-transparent pixel into adjacent fully transparent pixels. I’m not sure Photoshop can do this, but the libGDX TexturePacker can; see the bleed and bleedIterations settings. You need to be careful to set bleedIterations high enough, and add enough padding for the bleed to expand into, for your particular level of downscaling.

    Now the example comes out like this:

    (255,   0,   0, 255)
    (255,   0,   0,   0)  // Red bled into the transparent region
    

    Interpolation now gives a bright red transparent pixel, as desired:

    (255,   0,   0, 128)
    

    2. Use premultiplied alpha

    This is less finicky to get right, but it helps to know exactly what you’re doing. Again TexturePacker has you covered, with the premultipliedAlpha setting. This is OpenGL blend mode glBlend(GL_ONE, GL_ONE_MINUS_SRC_ALPHA).

    The numbers in the example don’t change; this is still the pixel that comes out:

    (128,   0,   0, 128)
    

    However, this is no longer interpreted as “half-transparent dark red”, but rather as “add some red, and remove some background”. More generally, with premultiplied alpha, the colour channels are not “which colour to blend in” but “how much colour to add”.

    Note that a pixel like (255, 0, 0, 0) can no longer exist in the source texture: because the alpha is premultiplied, an alpha of zero automatically means that all colour channels must be zero as well. (If you want to get really fancy, you can even use such pixels to apply additive blending in the same render pass and the same texture as regular blending!)

    Further reading on premultiplied alpha:

    Login or Signup to reply.
  2. I was able to resolve this issue by changing filtering on texture packer pro from Linear to MipMapenter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search