This is the fifth day of my participation in the August More text Challenge. For details, see:August is more challenging

Recommended reading

  • CSDN home page
  • GitHub open source address
  • Unity3D plug-in sharing
  • Jane’s address book
  • My personal blog
  • QQ group: 1040082875

The target

  • Learn how to reduce Draw calls and make your game run more smoothly
  • Despite the simplicity of my graphical interface, why do my games lag so much?
  • Why is my game taking so long to load?
  • Why is switching between interfaces so slow?
  • Why is my game’s FPS so low?
  • I’ve compressed all the textures and sprites! Why the delay?
  • Why is my game still crashing?
  • Why does the battery drain so fast when playing my game?
  • Why is my phone so hot when I’m playing my game?

Let’s face it, we’ve all faced these problems in game development. We’re going to try to analyze new graphics, image compression, new code, does that work? This can waste a lot of time and cost. Eventually, we try some wacky solution or just give up.

Here we will try to minimize our mistakes. I would rather say this is a mistake than this is a mistake.

Before we solve the problem of too many Draw calls, let’s understand what a Draw Call is.

So, what is a Draw Call? Draw Call is a command sent by the CPU to the GPU to render a Mesh. This command only specifies whether a Mesh has been rendered/drawn and does not draw any Material information (bear with me a little longer, buddy, it will get easier to read on, I promise).

After getting the command, GUP gets the render state values (Material, Texture, Shader, etc.) and all the vertex data on your screen is converted into pretty pixels with some code logic (I hope it’s pretty).

The render command basically does a number of small tasks, such as counting thousands of vertices on the screen and drawing thousands of pixels.

Note Each Mesh using a different Material will require a separate Draw Call.

How did Draw Call affect our game? Let’s look at an example to understand it. I’m going to use a simple UI Panel to help you understand this concept more easily.

Step 1: Create the UI according to your idea

I created it like this, as shown below:

As shown above, this is very basic using only a few circles and rectangles.

Sprite, which I use as follows:

Step 2: Check Draw Call

Press the Play button to start the game, and click the “State” button in the top right corner of the game view, as shown below:

You’ll be able to pop up some important data about the graphics rendered during the game’s runtime, as shown below:

For us, the main number is’ Batches’. Reducing the number of ‘Batches’ Batches reduces the number of Draw calls

For those who want to learn more about the “Stats” window, go to the following links to learn more:

Docs.unity3d.com/Manual/Rend…

Step 3: Open the Frame Debugger window

NoteUnity5.0 and above have this function

Unity official document:

With the Frame Debugger, the game pauses and Unity caches the contents of the currently executing Frame, with all Draw Calls you can move forward and backward, allowing you to analyze overhead at the Draw Call level.

For a deeper understanding of Frame Debugger, go to the following link:

Docs.unity3d.com/Manual/Fram…

So let’s click “Enable” to analyze the Draw Call

After clicking ‘Enable’, the program pauses and displays the number of Batches needed to paint the screen, which for my Batches is 10. Yours may not be the same as mine, depending on your screen (in the case of my UI). You can scroll through each Draw Call to see the information generated by each Call.

OK, I can see some Draw Calls, why should I care? As I said before, Draw Calls depend on your computer hardware, although it’s a simple UI, it takes about 10 Draw Calls to complete the screen.

Now imagine, how many Draw Calls would it take in actual game development?

Imagine how many Draw Calls it would take to have thousands of grids per frame!! Therefore, reducing the number of Draw calls will reduce GPU overhead.

“A modern board game can handle around 500-5000 Draw Calls per frame. Mobile devices can only handle around 40-60 Draw Calls, and the latest phones can only handle 120-160 Draw Calls at most.”

So Draw Calls may be a big trouble!! Remember, frame rate is big!!

If your framerate is good, you don’t need to worry about Draw Calls.

The number of Draw Calls severely affects performance and is heavily dependent on the user’s hardware.

Oh… I now know that Draw Calls is the culprit! But are there any good solutions? Fortunately, there is a built-in tool in Unity called “Sprite Packer” to solve our problems.

Unity official document:

“The best way to get the best performance is to package each Sprite into an atlas. Unity provides a Sprite Packer feature to automatically generate the atlas.”

Now let’s simply package a few sprites from the project into an atlas.

Let’s see how much we can cut down on Draw calls.

Step 1: Select the Sprite you want to pack

In fact, you should pack all the sprites on the same screen.

Step 2: Give the package a tag (do the following for each Sprite you want to package together), as shown in the figure below:

In this case, my tag is “MainScreen”, and you can name it whatever you want.

Step 3: Open the Sprite Paker window and finish packing

[img- PumsmlrL-1627867757795] [img- PumsmlrL-1627867757795]

Click the Pack button

This packs all sprites with the Packing Tag set to MainScreen into one atlas.

As shown in the image above, you can use the drop-down menu to find the corresponding atlas.

If some sprites are not packaged into the atlas, they are further packaged into the subatlas.

You can also choose some packaging algorithms.

You can check out the links below to learn more:

Docs.unity3d.com/Manual/Spri…

Step 4: Run the game!!

Have you seen any changes?

[img- Z289Wg8N-1627867757795] My Batches have changed from 10 to 3!! Draw Calls reduced by 7!! This is a 2x performance optimization!! Also reduces the load on the GPU!!

Imagine going from 500 to 200 in the real world. That would be a big increase. Especially for mobile phones.

This gives a huge boost to rendering.

Perks this isn’t real?

It only takes 5 minutes to get it right, so it’s worth it.

In general, rendering is a tedious task, so reducing Draw Calls will reduce the rendering burden. There are some third-party tools like Texture Packer that use advanced packaging algorithms and have an advantage over Unity’s own Sprite Pack.

You can find out more about it through the following links:

Simonschreibt. DE/gat/renderh…

www.codeandweb.com/texturepack…

Docs.unity3d.com/Manual/Opti…