Seams rendering tilemap

Hi I recently started working on a 2d platformer game. I have used 2d opengl before but I had an issue with rendering tilemaps so I stopped working on that project and made a 3d game. After doing some 3d I now went back to 2d and I still have the same issue here is an image:


.
I am using nearest filtering and to create the tilemap I just get coordinates from a texture atlas class and apply them to the quads for each tile and put them into a vbo. The lines only appear if the camera is at certain positions:(no lines in this image)


.
Any help appreciated.

Code for texture atlas:

public class TextureAtlas {
		private float[][] textureCoords;
	
		public TextureAtlas(int width, int height) {
		textureCoords= new float[width * height][];
		float w = (float) 1d/width;
		float h = (float) 1d/height;
		
		int n = 0;
		for(int i = 0;i<height;i++) {
			for(int j = 0; j<width;j++) {
				float offsetX = w*j;
				float offsetY = h*i;
				float[] coords = {
						offsetX,h+offsetY,
						offsetX,offsetY,
						w+offsetX,h+offsetY,
						offsetX,offsetY,
						w+offsetX,h+offsetY,
						w+offsetX,offsetY};
				textureCoords[n] = coords;
				n++;
			}
		}
	}
	public float[] getCoord(int textureNumber) {
		return textureCoords[textureNumber];
	}
}

The lines in the image are part of a tile beside the one you are drawing in the tile sheet (the blue line is the cliff edge). so the problem is edge bleeding, which can be easiest fixed by adding some duplicate pixels padding around each tile in the tile sheet. Its usually more common with linear filtering but I think it can happen even with nearest filtering, due to the camera scaling not matching 1:1 with screen pixel size.

You’ll always have a risk of bleeding when using a tilemap.

  • Linear filtering are inherently problematic, as it means the edge around each tile will read the neighboring tiles.
  • Mipmaps are problematic even without linear filtering if your tile size isn’t a power of two (or if you’ve set the max mipmap level incorrectly).
  • MSAA can cause extrapolation of texture coordinates when the center of a pixel is outside the triangle but one or more of the samples are still covered, which causes bleeding.
  • Even if all the above are disabled, you can still get rare bleeding due to floating point errors. These are more common when your tilemap texture isn’t a power-of-two, but can always occur.

All of the above can be 100% fixed by using a GL_TEXTURE_2D_ARRAY texture instead, with each tile in its own layer. Then you can use linear filtering, mipmaps and MSAA without any issues at all as no filtering will ever occur between texture array layers. If you for some reason don’t want to use 2D texture arrays (there’s really no reason not to use them though; they’re pretty much meant for these cases) and you’re willing to sacrifice linear filtering and mipmaps, simply modifying the texture coordinates to read a slightly smaller area of the texture than the tile can work. So for example, if your tiles are 32x32 pixels big, you can use the texture coordinates (0.1, 0.1) to (31.9, 31.9) or something like that (divided by the texture size of course). You can prevent extrapolation when using MSAA by enabling centroid interpolation of the texture coordinates in your shader.

If you have further questions or want more information about any of this stuff, just ask.

Make sure the image holding your tile-textures is a multiply of 2. (256x256, 512x512, etc)