如何消除平铺纹理之间的间隙?

13

我正在使用LibGDX制作一个平台游戏。我在平台上使用正方形瓷砖,但有些瓷砖之间会出现缝隙。当我缩放或移动相机时,这些缝隙的位置也会变化。

更多细节:

  • 瓷砖的大小为32x32,我已经尝试过32x32和64x64两种大小。
  • 瓷砖之间的距离是32像素(例如,第一个瓷砖的坐标为x=0,y=0,第二个瓷砖的坐标为x=32,y=0,以此类推,在x和y方向上都是如此)。
  • 缝隙不是纹理伪影导致的,我已经检查过了。
  • 我使用了TexturePacker并进行了填充。

我最好的猜测是,在将纹理转换为屏幕坐标时存在问题,但我不知道如何修复它,并且我找不到任何解决方案。我已经检查了瓷砖大小和对齐精度,但还是无法解决问题。

是否有人遇到过同样的问题或知道如何解决?

6个回答

12
我通过将TexturePacker.Settings类的duplicatePadding字段设置为true来解决了问题。
示例代码:
import com.badlogic.gdx.tools.texturepacker.TexturePacker;
import com.badlogic.gdx.tools.texturepacker.TexturePacker.Settings;

Settings settings = new Settings();
settings.maxWidth = 1024;
settings.maxHeight = 1024;
settings.duplicatePadding = true;

TexturePacker.process(settings, "source", "destination", "name");

好的,那你实际上该怎么使用这个呢...? “source”、“destination”和“name”应该填什么?? 我相信“source”是指图块集? - SuppressWarnings
你可以用它的许多方式,例如在你的启动器类中,或者像我一样,创建一个新类并在主方法中运行此代码。 "source" 是你的图像所在的位置,"destination" 是你想要的纹理文件所在的位置,"name" 是你给纹理文件命名的名称。 - Nixon
您还可以使用 pack.json 文件代替 Settings 类 - LibGDX 纹理打包文档 - Genhis

6

好的,我来为您翻译!

解决方案称为“边缘填充”。如果您正在使用切片集,则可以保证此方法有效。

个人建议使用Tiled编辑器,它可以让您在切片集中调整边距和间距。唯一的缺点是您需要使用带有以下插件的GIMP图像编辑器:http://registry.gimp.org/node/26044

该插件可让您对切片集应用边缘填充,然后问题就解决了!不再出现难看的伪像。


4

出血

间隙

简单来说,问题可能在于您的过滤器设置不正确,需要设置为NEAREST。

您也可以查看Libgdx上的教程。


3

这被称为“纹理渗透”。您需要给瓷砖添加填充,以便在纹理渗透时,可以收集正确的像素数据来填补间隙。


2

我知道回答这篇文章有点晚了,但当我在寻找解决方案时,我来到了这里。

然而,对于我来说,我发现了一种更简单的方法来消除瓷砖之间随机出现的闪烁或间隙。

我只需对我得到的玩家位置的非常长的小数进行强制转换:

camera.position.set((int)robot.position.x, (int)robot.position.y, 0);

这使得玩家的移动非常奇怪,为了让他再次顺畅地移动,我还在其渲染方法中添加了一个转换:

batcher.draw(robotSprite, (int)robot.position.x, (int)robot.position.y, 16, 16);

看,完美地工作了,对我来说没问题。


0
我会在这里发布我的解决方案以及我在Libgdx中尝试过的关于这个问题的内容。

--

T1. 制作原始精灵表(没有图集文件),将其填充到2。

A1. 如果要重新打包没有图集的精灵表,这是不可能的,即使你找到了一个切片/分割工具,它也应该是一堆需要适当重新打包为TiledMap(.tmx)的图像。

A1(更新)。 @Nine Magics 提供的脚本是最好的方法!(我将其用作我的最终解决方案)

--

T2. 使用由libgdx-nightygdx-toolg提供的TiledMapPacker。 批处理代码应为:

java -classpath "gdx.jar";"gdx-natives.jar";"gdx-backend-lwjgl.jar";"gdx-backend-lwjgl-natives.jar";"gdx-tiled-preprocessor.jar";"extensions/gdx-tools/gdx-tools.jar" com.badlogic.gdx.tiledmappacker.TiledMapPacker "PathToYourProject\android\assets\RawMap" "PathToYourProject\android\assets\Map" --strip-unused

A2. 如果你使用复杂的文件夹路径来分类你的 .png 文件,那么生成的 .tmx 输出可能无法被 Tiled 读取。而且该输出文件可能会由于 AtlasTmxMapLoader 加载失败。

--

T3. 相机位置校正,将相机位置变为整数。代码类似于@Julian或@strangecat在libgdx tiledmap flicker with Nearest filtering中的代码。

A3. 我使用这个解决方案没有问题,并且发布了我的代码与他们不同。

    float cameraX = (int)(mainCamera.position.x * Game.PPM_X) / Game.PPM_X;
    float cameraY = (int)(mainCamera.position.y * Game.PPM_X) / Game.PPM_X;
    float cameraZ = mainCamera.position.z;
    mainCamera.position.set(cameraX, cameraY, cameraZ);

同时使用TmxMapLoader.Parameters进行加载

    TmxMapLoader.Parameters params = new TmxMapLoader.Parameters();
    params.textureMinFilter = Texture.TextureFilter.Linear;
    params.textureMagFilter = Texture.TextureFilter.Nearest;
    params.generateMipMaps = true;
    assetManager.load(TILED_MAP_SETS.FIRST_MAP, TiledMap.class, params);

如果您使用了PPM并且想要逐像素移动,您可以使用此整数校正来进行游戏,如果没有,您可以将位置转换为整数。

我几乎浪费了一整天的时间来解决这个问题,希望这些调查能够帮助每一个游戏开发者 :)

编辑(2018/04/21) 我发现Unity也有同样的问题,但我还没有测试Libgdx是否默认具有2x抗锯齿设置。Libgdx可能会通过关闭抗锯齿来修复此问题,就像Unity一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接