1
\$\begingroup\$

All of a sudden, I started having this problem. I've used libGDX + Photoshop before and never had this problem. One of my textures is showing up with a white border/glow around.

enter image description here

The texture is the black blob on the middle, which is a 256 pixels png with a few black brushstrokes I created with Photoshop, just to test it.

Everything in libGDX is on default. I haven't changed the blending function, I'm just using a SpriteBatch to render the image without any changes.

The weird thing is, some other textures I created with Photoshop, same size, RBG 8 bit color mode (just like my blob image), look fine. These are temporary textures I created by downloading a png from the web, pasting it into Photoshop, applying a solid color overlay effect to it and saving it back as a png.

Any idea what's causing this?

Edit: Here's how I'm loading my textures:

private static Texture createTexture(String fileName, boolean maxQuality, Texture.TextureWrap textureWrap) {
    Texture result = new Texture(Gdx.files.internal(fileName), true);
    result.setFilter(maxQuality ? Texture.TextureFilter.MipMapLinearLinear : Texture.TextureFilter.MipMapLinearNearest, Texture.TextureFilter.Linear); // TODO: Are these the best?
    if(textureWrap != null)
        result.setWrap(textureWrap, textureWrap);
    return result;
}

texture = new TextureRegion(createTexture("data/blob.png"));

I just found out using this technique that the transparent pixels in my texture are white (1, 1, 1, 0). So I'm pretty sure the cause is a combination of this, the linear resizing and probably the blending function. Not sure what's the right way to fix it though. Don't want to change the resizing to nearest.

\$\endgroup\$
4
  • \$\begingroup\$ Is the texture coming from a packed spritesheet? Are you using a TextureAtlas? \$\endgroup\$
    – bornander
    Feb 25, 2016 at 12:26
  • \$\begingroup\$ Probably because you have some alpha blending pixels at the edge of your sprite. \$\endgroup\$
    – jgallant
    Feb 25, 2016 at 12:31
  • \$\begingroup\$ @bornander No atlas. See my edit. \$\endgroup\$
    – Juan
    Feb 25, 2016 at 12:47
  • \$\begingroup\$ Change the pixels to 0,0,0,0. When additive blending is used- the white pixels will be added to the background and result in that white border. \$\endgroup\$
    – Felsir
    Feb 26, 2016 at 8:12

1 Answer 1

2
\$\begingroup\$

So I figured it out and found a couple of ways to solve it.

Cause:

Photoshop, for some reason, will produce white transparent pixels. And when libGDX resizes the pictures it seems to average the pixels, so if a pixel is {1, 1, 1, 0} (transparent white) and another is {1, 0, 0, 1} (red), the average would be {1, .5, .5, .5}, which is a semi transparent mix of white and red and looks whitish on a dark background:

white borders

Solution 1:

One way is to premultiply the image, which turns transparent pixels black, using Texture Packer or some other program. This solves the white border on a dark background problem:

enter image description here

But it'll create another problem when using a bright background. Since the default blending functions are GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA, which tells OpenGL to multiply the source image's value times its alpha and add it to the background's value times one minus the source's alpha, blending a mix or red and transparent black caused by image resizing {.5, 0, 0, .5} with a white background {1, 1, 1, 1} will produce {.75, .5, .5, .75}, which is a mix of red, black and white, and looks like a dark border around the texture:

premultiplied GL_SRC_ALPHA

The solution here is to change the blending functions to GL_ONE and GL_ONE_MINUS_SRC_ALPHA (using setBlendFunction is you're using a SpriteBatch). This tells OpenGL to multiply the source's value by one, which will produce {1, .5, .5, 1}, an actual mix of red and white, when blending the mix of red and transparent black {.5, 0, 0, .5} with the white background {1, 1, 1, 1}:

premultiplied GL_ONE

Solution 2:

What I ended up doing is using Texture Packer to reduce border artifacts. This will replace each transparent pixel with the color of a neighbor non-transparent pixel and will work fine with the default blending function on any background.

The reason I used this solution is simply because I already use the default blending mode on every other place. I guess the way to go is to pick one solution and stick to it.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .