LibGDX纹理出血问题

时间:2015-09-17 09:33:17

标签: android opengl-es libgdx texturepacker

我是LibGDX的新手并且正在尝试实现视差背景。 一切顺利,直到我遇到这样的问题:滚动背景时我得到一些条纹。你可以在附图中看到它:

Texture Bleeding

所以我深入研究了一个问题,并发现这种纹理出血。但情况是我的纹理已经有[Linear,Nearest]滤镜集,而TexturePacker使用duplicatePadding。实际上,我不知道任何其他方法来解决这个问题。请帮忙!

这是我的一些代码:

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);
        }
    }
}

注意:我现在不使用任何相机进行绘图。我只使用大小为FitViewport的{​​{1}}。此外,即使在FullHD分辨率下,有时也会出现出血。

更新:设置1920x1280过滤器以进行缩小和放大Nearest并禁用抗锯齿解决问题,但最终图像变得太丑了!有没有办法避免禁用抗锯齿?因为没有它,缩小看起来很糟糕。

2 个答案:

答案 0 :(得分:0)

尝试将min和mag过滤器设置为最近

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

在GUI TexturePacker中有一个挤出图形的选项 - 它意味着重复纹理的每个边框像素。然后,您可以将两个过滤器都设置为线性

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

但遗憾的是我无法在您正在使用的TexturePacker.Settings对象中看到此选项。你可以尝试将Linear设置为两者,但我很确定它不会起作用(线性滤波器最接近4个纹素以生成一个,因此它可能仍然会产生问题)。

尝试使用GUI Texturepacker然后使用拉伸选项

答案 1 :(得分:0)

此工件的几个可能原因:

  1. 当精灵分辨率缩小时,填充可能不够大。尝试将纹理打包器的filterMin更改为MipMapLinearNearest。并尝试增加paddingXpaddingY

  2. 的大小
  3. 也许你在精灵的边缘看到暗淡或变亮的像素,因为你没有使用预乘的alpha而你的纹理的背景颜色(其alpha为零)是白色的。尝试设置premultiplyAlpha: true。如果这样做,您还需要将SpriteBatch的混合函数更改为(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA)以正确渲染。

  4. 在绘制时,您似乎将精灵位置和大小四舍五入为整数。这将适用于像素完美游戏,您可以确保精灵以1:1的分辨率精确渲染到屏幕上。但是,一旦屏幕尺寸不完全匹配,您的圆角可能会产生小于1像素宽的间隙,这看起来像半透明像素。