Time. Months. Maybe years. You have spent your time (a lot of time) in order to create your game. Small or big, it doesn't matter. It's your game, and now you want to share it with the whole world—and maybe become famous and rich*. It's perfect: the art is good, and you are very proud of your idea inside the game. Your game.
But there is one last issue that you must resolve before the release. No, not a simple issue. The issue: the frame rate of your game is low. Very low. And that means only one thing: you need to find a way to fix it. You must. And you have no idea how.
Don't panic: there is a simple trick that can help you. It's called a "Texture Atlas".
* If you become rich thanks to this article, please remember me. Thank you so much!
What's a Texture Atlas?
If you are approaching the development of a 3D video game for the first time, you’ll begin to discover that 3D graphics are composed of several parts: 3D meshes, textures, particle systems, and many other elements that are usually drawn on the screen 30 times per second (in slang: 30 fps) during the rendering process, making the game’s world varied and lively.
Believe it or not, the first 3D video games I saw in my life had none of these elements. They were composed only of lines that formed objects or elements in 3D wireframe.
Writing this is definitely making me feel old.
Back to us (indeed, to you) and to the important things, today we'll talk about the textures of the user interface (UI hereinafter) and, by extension, about all textures in the game.
In a 3D game, the UI is usually made of 3D elements (such as planes or boxes) with textures.
We mentioned before the rendering process: it’s the operation by which the elements in memory are physically drawn on the screen. It’s among the most complex and expensive processes that occur in a real-time 3D game. Then, any expedient to reduce the time taken by this process is welcome; less time spent in the rendering phase means a higher frame rate (i.e. if you reach the 60 fps you can render the image twice and then think of developing your game also for VR), or more screen elements (and then a richer game, more animated, more beautiful).
One of the means used to reduce the duration of the rendering process is a Texture Atlas: it’s nothing more than an image that contains many textures.
Note: As mentioned in the previous paragraph, this article will discuss the Texture Atlas applied to the UI. However, many of the concepts explained here can also be applied to 3D models and their textures.
A Texture Atlas, we said, is a collection of textures inside a single image.
An Atlas is usually associated with a file descriptor, which indicates to the game where a texture is (in certain x and y coordinates), in order to retrieve it.
Depending on the system that you will use to generate and manage the Atlas, you will have more or less options, such as the distance between the images that compose it (reducing the risk of artifacts on the edges of the texture, caused by an overlap of two elements), or the ability to rotate the elements to optimize the space inside the Atlas (more optimized space means more images inside the same Atlas).
Different Ways to Create a Texture Atlas
There are different ways to create an Atlas. A complete development environment usually allows the internal management of the Atlas; there are also many external tools that provide a lot of additional options.
The choice of which system to use obviously depends on your personal preferences. Here we explain two of them: Sprite Packer, internal to Unity, and TexturePacker (a standalone tool, for a fee).
To open Sprite Packer, choose from the menu Window > Sprite Packer.
The management is really easy: the button Pack is used to create one or more Atlases (it depends on the number of your images and on the Atlas dimension that you want to use).
Now you can select an image to see where it is in the Atlas. If you add or remove images from your project, you must use the button Repack, to update the Atlas.
In order to configure the Sprite Packer, you can choose from the menu Edit > Project Settings > Editor; here you can disable the Atlas, activate it only for the game built, or always turn it on.
For more information about Sprite Packer, you can check the official guide.
Texture Packer is a standalone tool used to manage Atlas.
You can add one or more folders from your project and Texture Packer will create the Atlas.
After that, you can choose the data format for the export. As you can see, there is also the option "JSON for Unity". This means that you can export your Atlas for your Unity project. But, in order to use them together, you must install a free editor extension from the asset store.
For more information about Texture Packer, you can check the official guide.
Why Is It Important to Use a Texture Atlas?
But why is it so important to collect multiple images into a single larger one?
Let's go back for a moment to the rendering process: if every element of the UI has a separate texture, it is drawn with a separated "draw call." This means that if in our interface we have the icon of hearts (representing the player’s energy) and the icon of the coins collected, we will have two draw calls.
Each draw call takes some time to complete, making the rendering process longer and longer. If there are five UI elements, instead of two as in the example above, there are five draw calls.
Do you begin to see the point?
More draw calls -> more time during the rendering phase -> less fps - > game with a low frame rate (with some frame drops) or fewer elements on the screen (then visually poor).
Wasting draw calls this way, unless there are special reasons, doesn’t really make sense, especially for the UI.
In fact, all the textures in an Atlas will be rendered together, in a single pass.
In conclusion, especially if you're developing a game on a platform where performance is really important (such as a mobile platform):
- You must pay attention to the number of draw calls: more draw calls means a higher rendering time (and a higher rendering time means the risk of having a low frame rate).
- Generally, every object with a different texture can generate a single draw call (it's a generic statement: there are some exceptions, especially in the case of 3D objects).
- One way to lower the number of draw calls is to use a Texture Atlas.
- A Texture Atlas is basically a big texture with a group of different textures.
- All objects that use the same Texture Atlas generate a single draw call.
- Especially for the UI textures, the use of a Texture Atlas is a must-have to improve the performance of your project.
And... may the force be with you. And your code. Always.