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

mat*_*ory 3 java photoshop android opengl-es libgdx

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

这就是我的意思:

minFilter: Linear magFilter: Linear

在黄色背景的圈子 红色背景

minFilter: MipMapLinearNearest magFilter: Linear

在此输入图像描述 在此输入图像描述

minFilter: MipMapLinearLinear magFilter: Linear

在此输入图像描述 在此输入图像描述

正如您所看到的,更改libGDX Texture Packer上的过滤器会对事物的外观产生很大影响,但alpha 仍然很暗.

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

texture.setFilter(minFilter, magFilter);
Run Code Online (Sandbox Code Playgroud)

但这不起作用.

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

我也试过改变混合模式:glBlend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_APHA)没有区别.glBlend(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)完全删除alpha,这样就不起作用了.

希望我的设置minFilterNearest因为它使事情看起来非常像素化.我已经尝试了所有其他纹理滤镜组合,但所有内容都会产生相同的黑/暗边/轮廓效果.

Tho*_*mas 5

我已经读过使用线性滤波器进行缩减会导致alpha像素默认为黑色?

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

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

(255,   0,   0, 255)  // Bright red, fully opaque
(  0,   0,   0,   0)  // Black, fully transparent
Run Code Online (Sandbox Code Playgroud)

以50/50比率插值给出:

(128,   0,   0, 128)
Run Code Online (Sandbox Code Playgroud)

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

有两种可能的解决方案.

1.将出血添加到透明区域

确保完全透明的像素分配了正确的颜色; 基本上将颜色从最近的非透明像素"渗出"到相邻的完全透明像素中.我不确定Photoshop可以做到这一点,但libGDX TexturePacker可以; 看到bleedbleedIterations设置.您需要小心设置bleedIterations足够的高度,为出血量添加足够的填充以扩展到您的特定级别的缩减.

现在这个例子是这样的:

(255,   0,   0, 255)
(255,   0,   0,   0)  // Red bled into the transparent region
Run Code Online (Sandbox Code Playgroud)

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

(255,   0,   0, 128)
Run Code Online (Sandbox Code Playgroud)

2.使用预乘alpha

这样做起来不那么挑剔,但它有助于准确了解你在做什么.再次使用TexturePacker覆盖了premultipliedAlpha设置.这是OpenGL混合模式glBlend(GL_ONE, GL_ONE_MINUS_SRC_ALPHA).

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

(128,   0,   0, 128)
Run Code Online (Sandbox Code Playgroud)

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

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

进一步阅读预乘alpha: