【问题标题】:Why do I get black outlines/edges on a texture in libGDX?为什么我在 libGDX 中的纹理上出现黑色轮廓/边缘?
【发布时间】:2018-01-24 05:58:10
【问题描述】:

每当我绘制边缘周围有 alpha 的纹理时(它已被 Photoshop 消除锯齿),这些边缘就会变暗。我无休止地使用纹理过滤器和混合模式,但没有成功。

这就是我的意思:

minFilter: Linear magFilter: Linear

minFilter: MipMapLinearNearest magFilter: Linear

minFilter: MipMapLinearLinear magFilter: Linear

如您所见,更改 libGDX Texture Packer 上的过滤器会对外观产生很大影响,但 alphas 仍然很暗

我尝试在 libgdx 中手动设置纹理过滤器:

texture.setFilter(minFilter, magFilter);

但这不起作用。

我已经读过使用线性过滤器缩小比例会导致 alpha 像素默认为黑色?如果是这种情况,我该如何避免呢?

我也尝试过更改混合模式:glBlend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_APHA) 没有区别。 glBlend(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) 完全删除了 alpha,所以这不起作用。

我确实想将我的minFilter 设置为Nearest,因为这会使事情看起来非常像素化。我已经尝试过所有其他纹理过滤器组合,但所有结果都会产生相同的黑色/深色边缘/轮廓效果。

【问题讨论】:

  • 如果您使用的是使用 Texture Packer 创建的 TextureAtlas,您可以尝试增加 Sprite 的填充。如果我没记错的话,线性过滤器检查最近的 8 帧以找到最佳像素,它可能会导致它是黑边。我实际上遇到了这个问题,但我不记得我是如何解决的。我要么用 PS 重新制作了精灵,要么改变了 TexturePacker 选项。我总是将 TexturePacker 中的过滤器设置为线性。很抱歉无法发布更明确的答案,我已经有一段时间没有使用 LibGDX

标签: java android opengl-es libgdx photoshop


【解决方案1】:

我已经读过使用线性过滤器缩小比例会导致 alpha 像素默认为黑色?

这不一定是真的;这取决于 Photoshop 决定将什么颜色放入 完全透明 像素中。显然,在你的情况下这是黑色的。

出现问题是因为 GPU 在两个相邻像素之间进行插值,其中一个是完全透明的(所有颜色通道也设置为零)。假设另一个像素是鲜红色:

(255,   0,   0, 255)  // Bright red, fully opaque
(  0,   0,   0,   0)  // Black, fully transparent

以 50/50 的比率进行插值得到:

(128,   0,   0, 128)

这是一个半透明的深红色像素,它解释了你看到的暗条纹。

有两种可能的解决方案。

1。向透明区域添加出血

确保为完全透明的像素分配了正确的颜色;基本上将颜色从最近的非透明像素“渗入”到相邻的完全透明像素中。我不确定 Photoshop 可以做到这一点,但 libGDX TexturePacker 可以;见bleed and bleedIterations settings。您需要小心地将bleedIterations 设置得足够高,添加足够的填充以使出血扩展到您的特定缩小级别。

现在的例子是这样的:

(255,   0,   0, 255)
(255,   0,   0,   0)  // Red bled into the transparent region

插值现在可以根据需要提供明亮的红色透明像素:

(255,   0,   0, 128)

2。使用预乘 alpha

这不那么挑剔,但它有助于准确地知道你在做什么。 TexturePacker 再次为您提供了premultipliedAlpha 设置。这是 OpenGL 混合模式glBlend(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)

示例中的数字不变;这仍然是出来的像素:

(128,   0,   0, 128)

但是,这不再被解释为“半透明的深红色”,而是“添加一些红色,并删除一些背景”。更一般地说,使用预乘 Alpha,颜色通道不是“要混合哪种颜色”,而是“要添加多少颜色”。

请注意,像(255, 0, 0, 0) 这样的像素不能再存在于源纹理中:因为 alpha 是预乘的,所以 alpha 为零自动意味着所有颜色通道也必须为零。 (如果你想变得非常花哨,你甚至可以使用这些像素在与常规混合相同的渲染通道和相同的纹理中应用 additive 混合!)

关于预乘 alpha 的进一步阅读:

【讨论】:

  • 谢谢!事实证明,TexturePacker-GUI 导致了所有问题。在遵循您的第一个建议时,我转而使用命令行 TexturePacker,它可能是最新的。
【解决方案2】:

我能够通过将纹理打包器 pro 上的过滤从线性更改为 MipMap 来解决此问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 2013-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多