Texture Atlas edge artifacts...how to fix?

I have been working on some atlas code, and I have a pretty nice algorithm for building the atlas, not much wasted space, and I compute a texcoord transform for each entry. For now I am just uploading this transform to my vertex shader to doing the multiply there, until I start collapsing objects together.

The problem is that I get some edge artifacts, I tried biasing the transform in by a pixel, to deal with filtering, no difference. Now I also see these artifacts when in clamp texture mode versus repeat, which leads me to believe that this is a content problem, but what should I tell the artist? Any suggestions?

What artifacts exactly do you have? “Bleeding” with other neighbouring texture?
If it is so, than you have not so many opportunities to fix it. It happens because of mip-map’s has averaged texel color value.
You can extrude every texture by repeating it’s neighbor pixels. But it helps only until next mip mess them up.
Or you can pack you textures in a grid with POT boundaries, limiting texture’s maximal LOD - for me, it’s quite good solution, but it makes obkects look sharper at very-very far positions.
Good reading is http://download.nvidia.com/developer/NVTextureSuite/Atlas_Tools/Texture_Atlas_Whitepaper.pdf

I would tell the artist to make the texture seamless or use some tools like sTile for that (http://www.harmware.net/bthumbs.htm).

Well, I got rid of them on the top mip level by replicating the outside edge texels. Unfortunately this makes the atlas far less efficient, as the source textures are power of 2, and the atlas is power of 2, so adding 2 to those makes many of the cells have wasted space.

I have yet to mip separately and build the atlas mips from those, but that’s next.

The easiest way is to use 2d texture arrays (check EXT_texture_array, requires >= gf8)

or u write a very costly shader (for a rather simple operation) that manually trilinear filters between correctly chosen texels.

If you are using Mimpapping you will need to use GL_NEAREST_MIPMAP_LINEAR to get rid of them, unless you are going to do some fancy artwork with borders around each set of textures. I decided that lesser IQ was a better solution. But I ditched this idea altogether now and use texture arrays… So much better! :wink:

Mars, I was thinking that I could just upload xxx textures into an array, and include an index to the correct texture in my VBO, is that what you are referring to? Only trouble is at what point you draw the line in terms of hardware features, yeah?

I decided along time ago, that I am targeting GF8 hardware and above. There are millions of GF8 series cards out, and its time to move on people IMO…

The Texture arrays I am talking about are for GF8 and higher. You can use 3D textures, but if you use mipmapping it will sample between layers.

What I was saying is with GL_NEAREST_MIPMAP_LINEAR and a texture atlas you can get rid of the lines you are seeing, and still have some filtering, just not trilinear or anisotropic filtering… HTH

A large part of the impetus for texture arrays is material batching, especially important with d3d interaction, as indicated by the paper Jackis linked (better in 10, but still fairly hefty).

The situation is much better in OpenGL, but going forward arrays seem like the direction of steepest descent in batch setup overhead, not to mention complexity (my favorite part).

So my method for using texture arrays is pretty much what you would do? Don’t bother atlasing at all, just grab n objects until you have a reasonable vertex buffer size, and draw them together with an array index per vertex?

Atlases are fine, they support any hardware that has fragment shader support. Just a real pain in the ass when it comes to using them to do quality filtering. I guess I don’t see why you couldn’t use a PBO/VBO to keep the textures in and access them, but not sure if that will be any slower or faster than using a texture array… Depending on how many buffer objects you are going to have, you could end up with a lot of glBind* calls vs. one for the texture array…