像素化纹理过滤失真
Pixelated texture filtering distorted
我在 Libgdx 中创建了一个基于等距图块的游戏。我使用的纹理是 64x64,并使用 TexturePacker 打包到 TextureAtlas 中。然后将它们绘制到屏幕上。然而,当在 64x64 纹理的像素化边缘周围移动时,它们会闪烁并且扭曲,这可以在下图中看到。我已经使用了 texturepacker 中可用的所有过滤器,您可以在下面看到线性和最近过滤器的结果。除了闪烁之外,线性滤镜还为纹理添加了黑色轮廓。如果不是因为相机移动时的闪烁,我会接受这个。
磁贴应如何显示:
线性过滤(你可以清楚地看到黑线扭曲):
最近过滤(较难看清,但像素化线条不直):
最容易发现它的地方是棕色立方体的顶部和底部。失真发生在不同的地方,具体取决于相机的移动(这会导致闪烁)。
有人知道是什么原因造成的,或者有可能的解决方案吗?我不确定是否需要任何代码片段。
还值得一提的是,相机设置为 windowHeight/ppm (ppm = 64) 和 windowWidth/ppm,然后将纹理绘制到投影矩阵设置为 camera.combined.
编辑:将 window 高度从 800 降低到 710(最近)会更好:
打开TexturePacker中的premultiplyAlpha
选项,并在SpriteBatch中设置setBlendFunction.(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA)
。这应该消除闪烁的黑色边缘。基本上,当使用线性过滤时,当精灵的边缘与屏幕上的像素不完全对齐时,像素的颜色是从精灵边缘的图像像素和不可见黑色中的图像像素线性采样的space (RGBA = 0000) 在它旁边,所以边缘看起来比预期的更暗和更透明。预乘 alpha 通过改变插值的操作顺序解决了这个问题。详细解释here and here。
另外,使用 filterMin
或 MipMapLinearNearest
或 MipMapLinearLinear
来确保您没有得到缩小的伪影。 (第一个表现更好,第二个在某些缩放级别下看起来更好,如果您的相机放大和缩小,应该使用。)
最后,filterMax
应该是 Linear
。
如果精灵未按其原始大小的 1X、2X、3X 等精确绘制,则最近的过滤将始终产生不均匀的伪像,因为屏幕的某些行和列会在图像中的像素处出现被画了两次。
我在 Libgdx 中创建了一个基于等距图块的游戏。我使用的纹理是 64x64,并使用 TexturePacker 打包到 TextureAtlas 中。然后将它们绘制到屏幕上。然而,当在 64x64 纹理的像素化边缘周围移动时,它们会闪烁并且扭曲,这可以在下图中看到。我已经使用了 texturepacker 中可用的所有过滤器,您可以在下面看到线性和最近过滤器的结果。除了闪烁之外,线性滤镜还为纹理添加了黑色轮廓。如果不是因为相机移动时的闪烁,我会接受这个。
磁贴应如何显示:
线性过滤(你可以清楚地看到黑线扭曲):
最近过滤(较难看清,但像素化线条不直):
最容易发现它的地方是棕色立方体的顶部和底部。失真发生在不同的地方,具体取决于相机的移动(这会导致闪烁)。
有人知道是什么原因造成的,或者有可能的解决方案吗?我不确定是否需要任何代码片段。
还值得一提的是,相机设置为 windowHeight/ppm (ppm = 64) 和 windowWidth/ppm,然后将纹理绘制到投影矩阵设置为 camera.combined.
编辑:将 window 高度从 800 降低到 710(最近)会更好:
打开TexturePacker中的premultiplyAlpha
选项,并在SpriteBatch中设置setBlendFunction.(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA)
。这应该消除闪烁的黑色边缘。基本上,当使用线性过滤时,当精灵的边缘与屏幕上的像素不完全对齐时,像素的颜色是从精灵边缘的图像像素和不可见黑色中的图像像素线性采样的space (RGBA = 0000) 在它旁边,所以边缘看起来比预期的更暗和更透明。预乘 alpha 通过改变插值的操作顺序解决了这个问题。详细解释here and here。
另外,使用 filterMin
或 MipMapLinearNearest
或 MipMapLinearLinear
来确保您没有得到缩小的伪影。 (第一个表现更好,第二个在某些缩放级别下看起来更好,如果您的相机放大和缩小,应该使用。)
最后,filterMax
应该是 Linear
。
如果精灵未按其原始大小的 1X、2X、3X 等精确绘制,则最近的过滤将始终产生不均匀的伪像,因为屏幕的某些行和列会在图像中的像素处出现被画了两次。