One of the recent additions to our tool chain is the ability to create texture atlases.
Texture Atlasing is a concept whereby you place multiple textures into a single bigger texture or textures so that you drastically reduce your texture binding and swaps during the rendering of a complex scene.
Atlasing has existed for a while and has been used on many older games as a primary technique — the Quake games for example started using atlasing for a level’s lightmap information. We have recently been looking into this technique because we have increased our texture usage, plus atlasing has a lot of benefits on devices such as the iPhone where texture bandwidth is limited.
Previously we had been using a limited form of a texture atlas for our UI elements in our games. Here is an example of the atlas for the Air Cadets UI artwork.
As you can see we used a 1024×1024 texture which contains every button, character and element seen throughout the games’ menus and HUD. This atlas was created manually and we had to store image positions and dimensions in a spreadsheet which then was used to create the correct UV coordinates for the in game buttons/images. Although it worked, it was terribly slow for both of us and meant changes to the menu artwork caused many headaches!
For the current project we need to take advantage of atlasing for the main level scenes because our texture usage has drastically increased. After some research, I found that nVidia had released a command line driven tool back in 2004 that had various features to create an atlas automatically and output a useful text-based file (.TAI Texture Atlas Information file) that listed the original texture, its new atlas file and the UV offsets of the position in the atlas (see links at the bottom of this page).
After a few tests and most importantly having the source code to the tool, it looked like the perfect option to get this working within our pipeline with a few changes to help us make sure everything would work on the final iPod/iPhone hardware.
The route I chose was to create a new maya ‘command’ plug-in that would externally call the command line tool with the scene textures, read the created TAI file, then use the new offsets to update all the UV coordinates for the scene. After some testing and custom changes to the nVidia tool, we can now generate atlases efficiently and have all our geometry updated in maya referencing the atlas with the correct texture coordinates.
This now has multiple uses across everything we do as we can decide to place multiple similar objects into an atlas or keep them separate. For example, if we have a scene that contains various prefab objects like tables, chairs, cups or other general incidental items (and we know that these items are going to have a high probability of always being drawn together even if they are separate models) we can simply put all their textures into the same atlas thus cutting down multiple texture swaps when the renderer is drawing these objects.
Once we iron out the few remaining bugs – and once we have got all of its features documented – we hope to release the maya tool at some point in the not-too-distant future.
The Pros and Cons of Atlasing
I’ve been quite positive about atlasing so far, however I should probably make a rundown of all the pros and cons so you can judge for yourself if this would be useful to projects you might be working on or if you are just researching the technique.
Texture batching / Speed
Mentioned throughout this post, this is pretty much your main benefit. It is not guaranteed to give you a speed up, but with good render ordering it most likely will. For iPhone if you make your atlas a PVR texture as well, you will see much better bandwidth usage.
No power of two limitation within the atlas
With an atlas you get the benefit of placing non-power of two textures into a large power of two atlas – thus allowing much greater freedom creating odd texture shapes and UV setups.
Multiple use – UI elements, UV Animations
You can use the atlas in various forms as mentioned earlier: Air Cadets placed all UI elements into an atlas; you could also (for example) have a waterfall texture animation in your game that uses separate textures for each frame — if you place all the animation frames into an atlas all you have to do is perform UV coordinate shifts on a single atlas.
Image assets easier to manage
Having all your texture information in a single big texture can make life a little simpler for art changes as everything is there in a single image resource for tweaks throughout development.
Mipmapping and Filtering
Since all your textures are tightly packed, if your UVs are right on the edge of an image within the atlas and you want some sort of mipmap filtering on the atlas to smooth out pixelation, then when the image is mipmapped and using as an example, bilinear filtering — since it uses nearest neighbour you’ll potentially get pixels bleeding from unrelated textures which will look jarring in the final render. A solution to this can be to shift your UVs away from the exact edge of the image or make the image bigger itself inside the atlas with extra pixels so there is a safety border between two images.
Limited texture wrapping / Texture tricks (rotate/scale) will not work
Since your UVs are all referencing the same texture, you are pretty much limited to the (GL_)REPEAT texture wrapping mode. It also means if you were using various texture matrix tricks to increase the repetition or to rotate/scale a texture image you become incredibly limited to small changes, otherwise you will see the surrounding images in the atlas.
Moving/changing images within the atlas can be restrictive
The main point of creating an atlas is to pack as many images into a single texture as possible. Problems may arise when you decide that you want to remove an image from the atlas, which leaves a large wasteful hole that you don’t want. Simply moving the other images about in an image editor is no good as this breaks your UV values for the images that you move. I’d always recommend doing atlasing at a late stage in level creation so you can make more of a correct judgement on what images should be atlased on what objects.
I know this post is a bit text heavy, but I hope it provides some information to those looking into this technique. We’ve found this system to very beneficial in our current game as it allows us to push the uniqueness of an environment by using more textures than we could have previously. As mentioned, we hope to release our which you might find useful, so watch this space. As ever comments, corrections or any other information is always welcome.