I've created a isometric tile based game in Libgdx. The textures I'm using are 64x64 and packed using TexturePacker into a TextureAtlas. They are then drawn onto the screen. However, while moving around the pixelated edges of the 64x64 texture flicker and they are distorted, which can be seen in the images below. I have used all filters available in texturepacker, below you can see the results of the Linear and Nearest filters. Apart from flickering, the linear filter adds a black outline to the textures. I would be fine with this if it wasn't for the flickering when the camera moves around.
How the tile should appear:
Linear filtering (You can clearly see the black lines distorting):
Nearest filtering (Harder to see, but the pixelated lines are not straight):
The easiest place to spot it is on the top and bottom of the brown cube. The distortion happens on different places depending on camera movement (this causes flickering).
Anyone know what causes this, or has a possible solution? I'm not sure if any code snippets are needed.
It is also worth mentioning that the camera is set to windowHeight/ppm (ppm = 64) and windowWidth/ppm, then the textures are drawn onto a batch that has its projection matrix set to camera.combined.
Edit: Somehow it's better when reducing the window height from 800 to 710 (nearest):
Turn on the premultiplyAlpha
option in TexturePacker and set setBlendFunction.(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA)
on the SpriteBatch. This should get rid of the flickering black fringing. Basically, when using linear filtering, when the sprite's edges don't exactly line up with the pixels on the screen, the color of the pixel is linearly sampled from an image pixel on the edge of your sprite and an image pixel in the invisible black space (RGBA = 0000) next to it, so the edges can appear darker and more transparent than intended. Pre-multiplying the alpha cures this problem by changing the order of operations of the interpolation. Detailed explanation here and here.
Also, use filterMin
of MipMapLinearNearest
or MipMapLinearLinear
to make sure you aren't getting minifying artifacts. (The first one performs better and the second one looks better at certain zoom levels and should be used if your camera zooms in and out.)
And finally, filterMax
should be Linear
.
Nearest filtering will always produce uneven artifacts if the sprites are not drawn at exactly 1X, 2X, 3X, etc. of their original size, because there will be certain rows and columns of the screen where a pixel in the image is drawn twice.