为什么我在libGDX中的纹理上获得黑色轮廓/边缘?

时间:2018-01-24 05:58:10

标签: java android opengl-es libgdx photoshop

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

这就是我的意思:

minFilter: Linear magFilter: Linear

Circle on yellow background Red background

minFilter: MipMapLinearNearest magFilter: Linear

enter image description here enter image description here

minFilter: MipMapLinearLinear magFilter: Linear

enter image description here enter image description here

正如您所看到的,更改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,因为它会使事物看起来非常像素化。我已经尝试了其他所有纹理滤镜组合,但所有内容都会产生相同的黑/暗边缘/轮廓效果。

2 个答案:

答案 0 :(得分:5)

  

我已经读过使用线性滤波器进行缩减会导致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

要想做到这一点不那么挑剔,但这有助于确切了解你正在做什么。再次使用premultipliedAlpha设置覆盖了TexturePacker。这是OpenGL混合模式glBlend(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)

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

(128,   0,   0, 128)

然而,这不再被解释为"半透明的暗红色",而是"添加一些红色,并删除一些背景"。更一般地说,对于预乘alpha,颜色通道不是"哪种颜色要混合在"但是"要添加多少颜色"。

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

进一步阅读预乘alpha:

答案 1 :(得分:0)

通过将纹理打包器专业版的过滤从线性更改为 MipMapenter image description here