Android LibGDX纹理出血问题
我是LibGDX新手,当时正试图实现视差背景。 在我遇到这样的问题之前,一切都很顺利:我在滚动背景时出现了一些条纹。您可以在附加的图像中看到它: 所以我深入研究了一个问题,发现这是某种纹理出血。但情况是,我的纹理已经有了[线性,最近的]过滤器集,TexturePacker使用Android LibGDX纹理出血问题,android,opengl-es,libgdx,texturepacker,Android,Opengl Es,Libgdx,Texturepacker,我是LibGDX新手,当时正试图实现视差背景。 在我遇到这样的问题之前,一切都很顺利:我在滚动背景时出现了一些条纹。您可以在附加的图像中看到它: 所以我深入研究了一个问题,发现这是某种纹理出血。但情况是,我的纹理已经有了[线性,最近的]过滤器集,TexturePacker使用duplicatePadding。事实上,我不知道还有什么方法可以解决这个问题。请帮忙 以下是我的一些代码: TexturePacker TexturePacker.Settings settings = new Text
duplicatePadding
。事实上,我不知道还有什么方法可以解决这个问题。请帮忙
以下是我的一些代码:
TexturePacker
TexturePacker.Settings settings = new TexturePacker.Settings();
settings.minWidth = 256;
settings.minHeight = 256;
settings.duplicatePadding = true;
TexturePacker.process(settings, "../../design", "./", "textures");
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);
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);
}
}
}
AssetLoader
TexturePacker.Settings settings = new TexturePacker.Settings();
settings.minWidth = 256;
settings.minHeight = 256;
settings.duplicatePadding = true;
TexturePacker.process(settings, "../../design", "./", "textures");
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);
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);
}
}
}
textureAtlas=新的textureAtlas(Gdx.files.internal(“textures.atlas”);
对于(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);
}
对于(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);
}
对于(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.road=textureAtlas.findRegion(“背景/道路”);
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);
背景抽屉
TexturePacker.Settings settings = new TexturePacker.Settings();
settings.minWidth = 256;
settings.minHeight = 256;
settings.duplicatePadding = true;
TexturePacker.process(settings, "../../design", "./", "textures");
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);
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);
}
}
}
private void DrawParallaXtextRelist(批次、列表、,
浮动移动X、浮动位置Y){
对于(int i=0;i
注意:我现在不使用任何相机进行绘图。我只使用大小为1920x1280的FitViewport
。而且,出血有时甚至在全高清分辨率下也会出现
更新:通过增加
paddingX
和禁用抗锯齿功能,为缩小和成像设置最近的过滤器,解决了问题,但最终图像变得太难看了!有没有办法避免禁用抗锯齿?因为没有它,缩尺看起来很糟糕。尝试将最小和最大过滤器都设置为最近的
.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
在GUI TexturePacker中,有一个挤出图形的选项-它意味着重复纹理的每个边界像素。然后可以将两个过滤器都设置为线性
.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
但不幸的是,我无法在您使用的TexturePacker.Settings对象中看到此选项。您可以尝试将“线性”设置为“两者”,但我很确定它不会起作用(线性过滤器需要最接近的4个texel来生成一个,因此它可能仍然会产生问题)
尝试使用GUI Texturepacker,然后使用“挤出”选项,这可能是造成此工件的一些可能原因:
当精灵分辨率缩小时,可能填充不够大。尝试将纹理打包程序的filterMin
更改为mipmaplinearNet。还可以尝试增大paddingX
和paddingY
的大小
可能您在精灵的边缘看到暗淡或明亮的像素,因为您没有使用预乘alpha,并且纹理的背景色(alpha为零)为白色。尝试设置premultiplyAlpha:true
。如果执行此操作,还需要将SpriteBatch的混合函数更改为(GL20.GL\u ONE,GL20.GL\u ONE\u减去SRC\u ALPHA)
,以正确渲染
绘制精灵时,您似乎正在将精灵的位置和大小舍入为整数。这将适用于像素完美的游戏,在游戏中,您可以确保精灵以1:1的分辨率精确渲染到屏幕上。但一旦屏幕大小不完全匹配,舍入可能会产生小于1像素宽的间隙,看起来像半透明像素
请参阅帖子中的更新。将两个设置为最接近的会在缩小比例时导致糟糕的渲染质量。我无法启动我在mac上的google代码中找到的这个jar。它说无法找到或加载主类texturepacker gui.jar
试试这个-。免费版本对你来说应该足够了,因为它有你需要的所有选项。我使用的是付费版本,我建议您设置减少边界工件选项?请提供您设置的屏幕截图,它们是:和1:没有帮助。仅对最近的过滤器有帮助。在本机分辨率上仍有喘息之声,但在缩小尺度上还行。2:没有帮助。3:对本机分辨率和缩尺都没有影响。如果将过滤器保留为线性,禁用抗锯齿是否有帮助?为什么要在2D游戏中使用抗锯齿?