Unity optimization. Draw calls and sprite atlases.

Shanlogauthier
6 min readJan 24, 2024

--

Today, we will explore three test cases in-depth and discuss the close relationship between Sprite Atlas and Draw calls.

Draw calls

In Unity, a draw call is essentially a command sent from the CPU to the GPU, instructing it to render a specific object or a group of objects within a given scene. This process involves a series of computations and resource allocations on both the CPU and GPU.

When an object with a unique material or shader is introduced into a scene, it typically results in the creation of a draw call. This is because each material or shader requires specific rendering instructions, and Unity generates separate draw calls for objects with distinct rendering properties.

The challenge arises when a scene contains numerous draw calls, as each call introduces a certain level of overhead. This overhead involves the communication between the CPU and GPU, which can become a bottleneck, especially in complex scenes with a high volume of objects. As a result, optimizing draw calls becomes crucial for maintaining a smooth and efficient rendering process.

Sprite atlas

A Sprite Atlas in Unity is a texture that contains multiple individual sprites packed together in a single image. It serves the purpose of optimizing rendering performance by reducing the number of draw calls associated with rendering multiple individual sprites.

By consolidating several sprites into a single texture, Unity can batch them into a single draw call when rendering. This batching minimizes the communication overhead between the CPU and GPU, resulting in improved performance, especially in scenarios where a large number of sprites would otherwise lead to a high draw call count.

In addition to performance benefits, Sprite Atlases also facilitate efficient memory usage, as multiple sprites share the same texture. This can be particularly advantageous in mobile and resource-constrained environments.

Overall, Sprite Atlases are a valuable tool in Unity for optimizing rendering efficiency and enhancing the performance of games and applications with a significant number of sprites.

Test cases

In the following example, we will examine three distinct scenes.

Case 1

The first scene comprises 110 green images and 110 red images, all sourced from a single atlas containing only one red image and one green image.

The images have dimensions of 64 pixels by 64 pixels each.

Case 2

In scenario 2, we have the same set of images as in scenario 1, and additionally, another atlas where the images are of dimensions 64x20 pixels.

Case 3

Lastly, we have a scene containing the same 220 images, but this time, the Sprite atlas is not utilized.

The use of 64x20 images compared to 64x64 is implemented to illustrate the impact on draw calls and rendering efficiency, emphasizing how variations in image dimensions can influence performance in Unity.

Power of 2

Files in Unity are often recommended to have dimensions that are powers of two (e.g., 64x64, 128x128) due to graphics hardware and rendering optimizations. Power-of-two textures are more efficiently processed by GPUs, which can enhance overall performance.

When creating Sprite Atlases, adhering to power-of-two dimensions can lead to better texture compression and mipmap generation, optimizing memory usage. Many GPUs handle power-of-two textures more efficiently, and using them can contribute to smoother rendering and reduced memory overhead.

Combining multiple images into a single texture with power-of-two dimensions allows Unity to leverage these optimizations. This consolidation facilitates efficient batching of sprites, leading to a decreased number of draw calls and improved rendering performance in your Unity project.

On the other hand, forcing using larger files in power of 2 when they could be smaller can result in less efficient space utilization of the atlas. It may lead to increased empty space within the atlas. This unused space reduces the effectiveness of texture packing, diminishing the benefits of sprite batching and potentially wasting GPU memory. Therefore, it’s crucial to be mindful of the atlas size and the dimensions of the individual images. Striking a balance between the dimensions of the images and the overall size of the atlas is essential for maximizing space utilization and optimizing draw calls. Careful consideration of image dimensions and atlas size ensures efficient packing, minimizes wasted space, and contributes to improved performance in Unity projects.

Comparasion

The three images are obtained from the same cell phone. In this case a Pixel 6A. Later we will see examples on another device.
As you can see in case 1 and 2 we obtain 5 draw calls. Let’s keep in mind that all the text, the black bar and the button are also being rendered in these draw calls. If you want to see a cleaner example, I invite you to check out the Github repository to try it. Deleting the UI you can get 1 Draw call.

5 Draw calls is what we get compared to case 3 where we can see that it increases to 58 draw calls.
This is where we can see the true power of the sprite atlas.

Now we can’t see a big difference between case 1 and 2. But let’s go to the depths.

To get this info I used the Unity profiler

Case 1 profiling in Moto g8.

Case 2 profiling in Moto g8

Can you see the difference?

YES! Case 2 is having double peaks in VSync while case 1 is not.

VSync: How much time your application spends per frame waiting for the targetFrameRate or the next VBlank
to sync with. This is according to the QualitySettings.vSyncCount value, the target framerate, or the VSync setting that is the default or enforced maximum of the platform your application is running on. For more information about VSync, see the section in this documentation on Rendering and VSync samples.

This small difference is caused by not using power of 2 images.

Conclusion

This was simply an introduction that I hope will help you manipulate the number of draw calls and help you understand how to optimize your game. Draw calls and Sprite atlases are important.
There is much more to delve into, what happens in 3D? What happens if I move an image in the Z axis? What is the difference between using UI or 2D objects in worlds space?

I will be publishing more related articles soon. Stay tuned!

https://linktr.ee/shanick

--

--