Using texture atlases
Add comment!March 19th, 2010
So a texture is an image that is wrapped around a 3D model to add apparent detail -- but what's a texture atlas? A texture atlas is an image that contains multiple textures. For example, below you can see a character texture on the left, and a texture atlas on the right (with four character textures).
Why use a texture atlas?
There are two main reasons to use a texture atlas. First, it can increase rendering speed by allowing you to batch more objects into a single draw call. For example, if all the plants in the game use just one texture atlas, then you can draw them all at the same time. Otherwise you would have to draw one group of plants, switch texture state, draw another group of plants, and so on.
Second, it allows you to use unusually-shaped textures. Most graphics cards are designed to use textures that are square and have dimensions that are powers of two, such as 256x256, 512x512, and so on. But what if you have a graphic that is 550x130? You would have to put it in the middle of a 1024x1024 texture, and waste all the extra space. Alternately, you could pack a lot of unusually-shaped textures into one square texture atlas, and hardly waste any space at all!
For both of these reasons, the Black Shades iPhone port has all the UI textures in the game on one texture atlas. Here is a small part of it:
How do you create a texture atlas?
To create a texture atlas you just need to combine several textures into one image, and keep track of the coordinates of each subimage. Henry created that Black Shades atlas entirely by hand, moving subimages around and checking pixel positions. However, since then he found an interesting online tool for creating texture atlases, called Zwoptex.
Alternately, you can create them automatically. There are a number of tools that you can use for this, or you can write your own. There is an algorithm with pseudocode here that you could try. In Overgrowth, after calculating shadow maps, they are automatically combined into a texture atlas.
The shadow map atlas is created using an algorithm similar to the one linked earlier, using a greedy algorithm to fill from one corner outwards. However, in the Overgrowth version, the textures are sorted by size. First, it starts at the smallest textures and walks upwards to create a list of the textures that will fit in the atlas. Then it adds the list to the atlas starting at the biggest one to make sure that there are no gaps.
Check out the post on two-part shadow maps if you're wondering why they look like this.
As you can see, the biggest textures can be many times as big as the smallest ones, which is why we have to prioritize the smallest ones if we want to include as many textures as possible.
How do you use a texture atlas?
Texture coordinates are usually relative to the size of the individual texture, with (0,0) corresponding to one corner, and (1,1) corresponding to the opposite corner. But what happens when the texture is added to an atlas? Let's consider three points on our original example, and their corresponding points in the atlas:
Each of the coordinates is scaled by (0.5,0.5) and offset by (0.0,0.5). When creating the atlas you have to keep track of the offset and scale for each texture so that you can access them again later. In Overgrowth, the shadow map offset and scale is applied using the vertex shader so that the same model can be used with multiple shadow map coordinates.
Texture atlas limitations
Texture atlases will not work with tiling textures. Instead of tiling, they will start showing other textures in the atlas, which is almost certainly not what you want. The same is true for models that have texture coordinates outside of the range from 0 to 1, assuming that they will wrap around.
It is also inefficient to use texture atlases if not all of the textures are used at once. For example, if you have all your plants on one texture atlas, and the level only uses one plant, then you are wasting a lot of texture space on the graphics card. The texture atlas should only be used if all or most of the textures are likely to be visible.
However, when used responsibly, the texture atlas is a useful tool in any graphics programmer's toolbox. Do you know of any good tools or algorithms for working with them that I didn't mention?