I am rendering a tile map in my MonoGame project using a sprite batch.
Here is the rendering code:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, CameraManager.pInstance.pFinalTransform);
foreach( TmxLayer Layer in mCurrentTileMap.Layers)
{
for (int y = 0; y < mCurrentTileMap.Height; y++)
{
for (int x = 0; x < mCurrentTileMap.Width; x++)
{
TmxLayerTile Tile = Layer.Tiles[mCurrentTileMap.Width * y + x];
int TileID = -1;
Texture2D Texture = FindTileMapTextureForTileID(Tile.Gid, out TileID);
if (TileID > 0)
{
int atlasX = TileID % (Texture.Width / TileSize);
int atlasY = TileID / (Texture.Width / TileSize);
SpriteEffects FX = SpriteEffects.None;
if (Tile.HorizontalFlip)
{
FX = SpriteEffects.FlipHorizontally;
}
SpriteBatch.Draw(Texture, new Vector2(x * TileSize, y * TileSize), new Microsoft.Xna.Framework.Rectangle(atlasX * TileSize, atlasY * TileSize, TileSize, TileSize), Color.White, 0, Vector2.Zero, 1, FX, 0);
}
}
}
}
Here's what I think are the important lines of code:
SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp,
null, null, null, CameraManager.pInstance.pFinalTransform);
SpriteBatch.Draw(Texture, new Vector2(x * TileSize, y * TileSize),
new Microsoft.Xna.Framework.Rectangle(atlasX * TileSize, atlasY * TileSize, TileSize, TileSize),
Color.White, 0, Vector2.Zero, 1, FX, 0);
As you can see, I am using SamplerState.PointClamp
. However, as I move around the world, I see this kind of thing once in a while; below some of the tiles you can see a single line of pixels, which are the pixels below it in the sprite atlas.
Click to enlarge to see issue clearly...
I am pretty sure this is happening because the transform applied to the sprite batch (CameraManager.pInstance.pFinalTransform
) is using floating point percision. If I forcefully clamp the scale portion of that transform to whole numbers, the issues does not occur. However, doing that causes very jittery camera movement (my game is very scaled up so each pixel is about 10 pixels on the monitor), so it is not a good solution.
Any ideas on how this effect can be avoided?
Here is what the source texture sprite sheet looks like, for reference.