2

I'm new to LibGDX and was trying to implement parallax background. Everything went good until I faced such issue: I get some stripes when scrolling background. You can see it in attached image:

Texture Bleeding

So I looked deeper into an issue and figured out that this some sort of texture bleeding. But the case is that my textures already have [Linear, Nearest] filter set and TexturePacker uses duplicatePadding. Actually, I don't know any other methods to solve this issue. Please help!

Here's some of my code:

TexturePacker

TexturePacker.Settings settings = new TexturePacker.Settings();
settings.minWidth = 256;
settings.minHeight = 256;
settings.duplicatePadding = true;
TexturePacker.process(settings, "../../design", "./", "textures");

AssetLoader

textureAtlas = new TextureAtlas(Gdx.files.internal("textures.atlas"));

for (int i = 0; i < 2; i++) {
    Background.skies.add(textureAtlas.findRegion("background/sky", i));
    Background.skies.get(i).getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Nearest);
}

for (int i = 0; i < 2; i++) {
    Background.clouds.add(textureAtlas.findRegion("background/cloud", i));
    Background.clouds.get(i).getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Nearest);
}

for (int i = 0; i < 8; i++) {
    Background.cities.add(textureAtlas.findRegion("background/city", i));
    Background.cities.get(i).getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Nearest);
}

Background.moon = textureAtlas.findRegion("background/moon");
Background.forest = textureAtlas.findRegion("background/forest");
Background.road = textureAtlas.findRegion("background/road");

Background.moon.getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Nearest);
Background.forest.getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Nearest);
Background.road.getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Nearest);

BackgroundDrawer

private void drawParallaxTextureList(Batch batch, List<TextureAtlas.AtlasRegion> list,
                                     float moveX, float posY) {
    for (int i = 0; i < list.size(); i++) {
        boolean needDraw = false;

        float shift = GameScreen.VIEWPORT_WIDTH * i;
        float drawX = 0.0f;

        if (shift - moveX <= -(GameScreen.VIEWPORT_WIDTH)) { // If it's behind the screen
            if (i == 0) { // If it's first element
                if (moveX >= GameScreen.VIEWPORT_WIDTH * (list.size() - 1)) { // We need to show first after last
                    needDraw = true;
                    drawX = (GameScreen.VIEWPORT_WIDTH) - (moveX - ((GameScreen
                            .VIEWPORT_WIDTH) * (list.size() - 1)));
                }
            }
        } else if (shift - moveX < (GameScreen.VIEWPORT_WIDTH - 1)) {
            needDraw = true;
            drawX = shift - moveX;
        }

        if (needDraw) {
            batch.draw(list.get(i), (int) drawX, (int) posY);
        }
    }
}

NOTE: I don't use any camera for drawing right now. I only use FitViewport with size of 1920x1280. Also, bleeding sometimes appears even in FullHD resolution.

UPDATE: Setting both Nearest filters for minification and magification with increasing paddingX and disabling antialiasing solved issue, but final image become too ugly! Is there way to avoid disabling antialiasing? Because without it, downscale look awful.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Alviere
  • 403
  • 1
  • 4
  • 14
  • Does disabling antialiasing help if you leave the filter as linear? Why would you use antialiasing in a 2D game anyway? – Tenfour04 Sep 18 '15 at 12:29

2 Answers2

0

Try to set both min and mag filters as Nearest

    .setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);

In GUI TexturePacker there is an option to extrude graphics - it means repeating every of border pixel of texture. Then you can set both filters to Linear

    .setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);

but unfortunately I cannot see this option in the TexturePacker.Settings object you are using. You can try to set Linear to both but I'm pretty sure it won't be working (Linear filter takes nearest 4 texels to generate the one so it will probably still generate issues).

Try to use GUI Texturepacker then with extrude option maybe

m.antkowicz
  • 13,268
  • 18
  • 37
  • 1
    See for update in post, please. Setting both `Nearest` causes awful render quality on downscale. – Alviere Sep 17 '15 at 10:58
  • I can't start this jar I found on google code on my mac. It says `Could not find or load main class texturepacker-gui.jar` – Alviere Sep 17 '15 at 11:32
  • try this - https://www.codeandweb.com/texturepacker/download. Free version should be enough for you since it has all option you need afaik. I'm using paid version and I recommend it – m.antkowicz Sep 17 '15 at 11:36
  • have you set Reduce Border Artifacts option? Please provide a screenshot of your settings in TP – m.antkowicz Sep 17 '15 at 12:38
  • There they are: [one](http://postimg.org/image/6f4c9iin1/) and [two](http://postimg.org/image/sd0t3axnh/) – Alviere Sep 18 '15 at 12:40
  • I will compare it with mine settings when I will be at home but at first - I see that you have **extrude** = 0 when it shoud be 1 or 2, also change **trim mode** to none – m.antkowicz Sep 18 '15 at 12:53
  • Have you tried trim -> none and extrude -> 1 ? Because this is what I have in my TP settings. Everything else is the same as yours – m.antkowicz Sep 18 '15 at 19:46
  • Yes, I tried this and it became better but still had gasps on edges of sprites... :( – Alviere Sep 19 '15 at 09:06
0

A few possible reasons for this artifact:

  1. Maybe the padding is not big enough when the sprite resolution is shrunk down. Try changing your texture packer's filterMin to MipMapLinearNearest. And also try increasing the size of paddingX and paddingY.

  2. Maybe you're seeing dim or brightened pixels at the edge of your sprite because you're not using pre-multiplied alpha and your texture's background color (where its alpha is zero) is white. Try setting premultiplyAlpha: true. If you do this, you need to also change the SpriteBatch's blend function to (GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA) to render properly.

  3. You seem to be rounding your sprite positions and sizes to integers when you draw them. This would work in a pixel perfect game, where you're sure the sprites are being rendered exactly at 1:1 resolution to the screen. But once the screen size does not match exactly, your rounding might produce gaps that are less than 1 pixel wide, which will look like semi-transparent pixels.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • 1: not helping. Helps only with `Nearest` filter. Still have gasps on native resolution but OK on downscale. 2: not helping. 3: has no effect on both native resolution and downscale. – Alviere Sep 18 '15 at 07:22