Texture filtering: mipmapped sprite sheets

Beringela comments on my previous post:

"Why don't spritesheets (with an edge around each sprite) and mipmaps go well together and are there any workarounds other than not using spritesheets or not using mipmaps?"

Let's work through an example, which I shall simplify down to one dimension for clarity. Let's say we have two textures, sized 4x1:


and 2x1:


With gutters, we could pack these into a 10x1 sprite sheet:

a A B C D d e E F f

Now let's compute the first mip level:

A (B+C)/2 D E F

Hmm. That does somewhat resemble the original sheet, but it no longer has proper gutters, so filtering will bleed from one sprite to the other.

Real trouble starts with the second mip level:

(A*2 + B + C + D) / 5 (D + E*2 + F*2) / 5

Our second sprite has disappeared entirely! That rightmost pixel includes colors E and F from sprite #2, but also some amount of color D from sprite #1.

And of course the final mip is entirely meaningless:

(A*2 + B + C + D*2 + E*2 + F*2) / 10

There are two ways you can try to make sprite sheets and mipmaps play together:

  • Wishful thinking: include gutters wider than a single pixel, cross your fingers, and hope it turns out ok. Any time you see color bleeding problems, increase the gutter size until they go away.

  • The scientific approach: restrict all sprites in a sheet to be the same size, so you can terminate your mip chain at the point where an individual sprite has reached 1x1. Calculate the gutter size so you will still have an entire pixel gutter at this smallest mip level, with corresponding larger gutters for larger mips. Generate mip images separately for each sprite, rather than for the sheet as a whole, and regenerate the gutter with different colors for each mip. This is a considerable pain, and wastes a lot of memory (you end up with significantly more gutter pixels than actual data!) but it does work.

Personally, I would avoid using mipmaps and sprite sheets at the same time. Sprite sheets are never necessary: they're just an optimization to reduce texture switching. When an optimization ends up causing this amount of trouble, you have to wonder if it's really worth it?

Comments (3)

  1. Jeremi says:

    How would you do if you needed to draw a large part of your terrain in one draw and

    the draw used one texture alias with 32 textures on it??

  2. ShawnHargreaves says:

    > How would you do if you needed to draw a large part of your terrain in one draw and the draw used one texture alias with 32 textures on it??

    I wouldn't use texture atlases at all for terrain rendering.

    Terrain rendering absolutely requires mipmaps, and mipmaps don't play nice with sprite sheets. Just not a good combination.

  3. Dan says:

    If I were looking to use texture atlases for terrain rendering, is there a way to limit the mipmap chain?  It seems like that functionality went away in 4.0

    My atlas is 1024×1024 and each image is 64×64, so if I limit to 4 mipmaps it'll work out fine (if I did my math right).

Skip to main content