为什么我在 libGDX 中的纹理上变黑 outlines/edges?
Why do I get black outlines/edges on a texture in libGDX?
每当我绘制边缘周围有 alpha 的纹理(它被 photoshop 抗锯齿)时,这些边缘就会变暗。我无休止地使用纹理过滤器和混合模式,但没有成功。
我的意思是:
minFilter: Linear magFilter: Linear
minFilter: MipMapLinearNearest magFilter: Linear
minFilter: MipMapLinearLinear magFilter: Linear
如您所见,更改 libGDX Texture Packer 上的过滤器会对外观产生很大影响,但 alpha 仍然黑暗.
我尝试在 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
,因为它让事情看起来非常像素化。我已经尝试了所有其他的纹理过滤器组合,但所有结果都是相同的 black/dark edges/outline 效果。
I have read that downscaling with a linear filter causes the alpha pixels to default to black?
这不一定是真的;这取决于 Photoshop 决定在 完全透明 像素中放入什么颜色。显然你的情况是黑色的。
出现问题是因为 GPU 正在两个相邻像素之间进行插值,其中一个像素是完全透明的(所有颜色通道也都设置为零)。假设另一个像素是鲜红色:
(255, 0, 0, 255) // Bright red, fully opaque
( 0, 0, 0, 0) // Black, fully transparent
以 50/50 的比率进行插值得到:
(128, 0, 0, 128)
这是一个半不透明的 深红色 像素,这解释了您看到的暗条纹。
有两种可能的解决方案。
1。向透明区域添加出血
确保为完全透明的像素分配了正确的颜色;基本上 "bleed" 从最近的非透明像素到相邻的完全透明像素的颜色。我不确定 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)
但是,这不再被解释为 "half-transparent dark red",而是 "add some red, and remove some background"。更一般地说,对于预乘 alpha,颜色通道不是 "which colour to blend in" 而是 "how much colour to add".
请注意,像 (255, 0, 0, 0)
这样的像素不能再存在于源纹理中:因为 alpha 是预乘的,所以 alpha 为零自动意味着所有颜色通道也必须为零。 (如果你想变得非常花哨,你甚至可以使用这样的像素来应用 additive 混合在相同的渲染通道和相同的纹理中作为常规混合!)
进一步阅读预乘 alpha:
我通过将 Texture Packer Pro 上的过滤从线性更改为 MipMap
解决了这个问题
每当我绘制边缘周围有 alpha 的纹理(它被 photoshop 抗锯齿)时,这些边缘就会变暗。我无休止地使用纹理过滤器和混合模式,但没有成功。
我的意思是:
minFilter: Linear magFilter: Linear
minFilter: MipMapLinearNearest magFilter: Linear
minFilter: MipMapLinearLinear magFilter: Linear
如您所见,更改 libGDX Texture Packer 上的过滤器会对外观产生很大影响,但 alpha 仍然黑暗.
我尝试在 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
,因为它让事情看起来非常像素化。我已经尝试了所有其他的纹理过滤器组合,但所有结果都是相同的 black/dark edges/outline 效果。
I have read that downscaling with a linear filter causes the alpha pixels to default to black?
这不一定是真的;这取决于 Photoshop 决定在 完全透明 像素中放入什么颜色。显然你的情况是黑色的。
出现问题是因为 GPU 正在两个相邻像素之间进行插值,其中一个像素是完全透明的(所有颜色通道也都设置为零)。假设另一个像素是鲜红色:
(255, 0, 0, 255) // Bright red, fully opaque
( 0, 0, 0, 0) // Black, fully transparent
以 50/50 的比率进行插值得到:
(128, 0, 0, 128)
这是一个半不透明的 深红色 像素,这解释了您看到的暗条纹。
有两种可能的解决方案。
1。向透明区域添加出血
确保为完全透明的像素分配了正确的颜色;基本上 "bleed" 从最近的非透明像素到相邻的完全透明像素的颜色。我不确定 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)
但是,这不再被解释为 "half-transparent dark red",而是 "add some red, and remove some background"。更一般地说,对于预乘 alpha,颜色通道不是 "which colour to blend in" 而是 "how much colour to add".
请注意,像 (255, 0, 0, 0)
这样的像素不能再存在于源纹理中:因为 alpha 是预乘的,所以 alpha 为零自动意味着所有颜色通道也必须为零。 (如果你想变得非常花哨,你甚至可以使用这样的像素来应用 additive 混合在相同的渲染通道和相同的纹理中作为常规混合!)
进一步阅读预乘 alpha:
我通过将 Texture Packer Pro 上的过滤从线性更改为 MipMap