Reduce Draw Calls
One of the most effective ways to optimize your game's performance is to reduce Draw calls.
Draw calls are the number of times objects or other elements are rendered.
Shortly, the more objects is located, the more draw calls will be.
However, depending on the rendering settings and the properties of the material, draw calls may decreases than the actual number of objects.
We recommend you to refer the Unity, Community, and Forum articles on how to reduce draw calls.
This page contains scripts to compare AnyPortrait's ability to reduce draw calls.
It also describes settings that increase draw calls in certain situations.
If you're using a script, see the Related page.
In Unity, the draw call count is indicated as Batch Count.
Although the two concepts have some processing differences, they are usually about the same value, and two words are often treated as the same.
Please note that these two words are also used as the same words on this page.
How AnyPortrait manages Draw Calls
AnyPortrait's systems offer a variety of features and optimization techniques to reduce draw calls.
1. The cases that the draw call is optimized or not increase
- Draw calls are optimized when the character's meshes are rendered with the same textures and materials.
- Draw calls are reduced when multiple characters are placed in the scene that share a common texture and material.
- Draw calls do not increase even if the character's scale is negative.
- In script functions that change the color or texture of a mesh, if the target is "Image", the draw call is prevented from increasing within the character. However, sharing draw calls with "other characters" will be turned off.
2. The cases that the draw call increases
- Draw calls will increase if meshes have different textures or different materials.
- Draw calls increase if color animation is applied or if you randomly change the color of a particular mesh with a script function.
- Draw calls may increase depending on depth from camera. (Draw calls are reduced only when meshes of the same material are placed in succession.)
- When the clipping mesh is rendered draw calls increases, because is uses the Render Texture.
- If you use a property other than the Shader property used by AnyPortrait, draw calls will increase.
AnyPortait has three draw call optimization steps.
1. Multiple characters are rendered with the minimum draw call
- It is that draw calls are the most optimized stage, and characters sharing the same material are rendered in the same draw call
2. Meshes of a single character are rendered with the minimum draw call
- Draw calls are optimized within a single character. Draw calls are not shared with other characters, but draw calls can be reduced a lot at this stage.
3. A mesh that does not share draw calls exists
- Draw calls increase because some of the meshes of a single character are rendered in the different draw call.
Settings to optimize Draw Calls
The simplest way to check draw calls in Unity is as above.
(1) Select Game screen.
(2) Press the Stats button.
(3) The value of the Batches is the number of draw calls.
The scene above shows a scene where only one character is placed, and the draw call is 6.
There is no Draw call Batching, so all elements are being rendered on each draw call.
Open the Player Settings.
- Open "Edit > Project Settings" in the Unity menu and select the "Player", or
- Select Player Settings from "File > Build Settings" in the Unity menu.
If Dynamic Batching is disabled among the items in Other Settings, draw calls are not optimized.
Turn on Dynamic Batching.
When you run the game, draw calls are reduced from 6 to 2.
(Draw calls are the sum by one background and one character with optimized meshes.)
Comparison of Draw Call changes according to how to set the mesh color
When changing the color of the mesh, the draw calls depend on which method you use.
This is related to AnyPortrait's draw call management.
See the example below to optimize.
The color of a mesh has been changed by a modifier or the "SetMeshColor(string transformName, Color color2X)" function.
In this case, this optimization phase is "lowest stages" that the draw calls are not shared with each meshes.
Draw calls increase to 4 because the color-changed mesh is rendered in separate the draw call.
Using the color animation is a comfortable way to do this, but watch out for increased draw calls.
If the mesh's color returns to the default value as (0.5, 0.5, 0.5, 1.0), draw calls are reduced,
and you can also optimize draw calls by using a function that restores the material settings,
such as "ResetMeshMaterialToBatch(string transformName)".
Let's see what happens if the colors of the all meshes are changed in a batch.
Script functions that changes all the colors of meshes will mainly use two things:
- SetMeshColorAll(Color color2X) : Changes the colors of all meshes regardless of material.
- SetMeshColorAll(string optTextureName, Color color2X) : Changes the colors of the meshes, which are use the common texture, which is the argument.
These functions look almost identical, but there are differences in draw calls depending on how they are handled.
This is the result of using the SetMeshColorAll(Color color2X) function.
This function is same that the "SetMeshColor" function is applied to all meshes in bulk.
Since the SetMeshColor function is a function of the "lowest optimization phase", the mesh no longer shares the material, regardless of color.
Therefore, the value the draw call is 6.
This is the result of using SetMeshColorAll(string optTextureName, Color color2X) function.
Since we have given the name of the image as an argument, this function does not target "mesh", but "image".
Since this function directly change the color of material shared by meshes, all meshes continue to share the same material.
Therefore, this function performs "Draw call optimization in single character" as "intermediate optimization phase".
As a result, the draw calls will remain at the optimized value of 2.
Comparison of Draw Call when multiple characters are placed
Draw calls increase when multiple characters are placed.
When various kinds of objects are placed, the draw calls generally increase by the number of objects.
However, if only characters made with AnyPortrait are placed, the draw calls are greatly reduced if those characters share the same texture and material.
(If conditions are met, the original character does not necessarily need to be duplicated for optimization.)
In the above case, six characters are placed in the scene.
However, with AnyPortrait's "highest optimization phase", you can see that the draw calls are reduced significantly to 2.
If you do not change the color, use the default material properties and use the common texture, the characters created by AnyPortrait recognize each other and optimize draw calls without any extra work.
The screen above shows that one of the six characters is selected and the function SetMeshColorAll(string optTextureName, Color color2X) is applied.
As this function was used earlier, the "intermediate optimization phase", this character no longer shares the material with other characters.
Therefore, the draw calls increase from 2 to 12.
Of course, this value is pretty much less than expected maximum draw call of 31, which is the sum of the total number of meshes(30) and one background(1).
However, it seems to have increased significantly compared to the most optimized value of 2.
This result is due to the "continuous rendering order", one of the conditions under which draw calls are batched and reduced.
See additional explanation below.
Let's see how the characters are placed in the current scene.
The characters above are a bit behind, and characters in the same row have the same Z position.
Since the color has the same Z position as the changed character, the rendering order of the meshes of the different materials is mixed.
As a result, there are many situations where materials are switched while rendering is performed sequentially.
This situation does not effectively reduce draw calls even if several groups of objects share material.
Let's see how the draw calls change by changing the Z position of the characters.
For simplicity, we tried to make sure that the Z positions are not equal but placed back and forth sequentially.
When rendering sequentially according to the Z position, this method prevents the rendering order of the "color-changed characters" meshes and the rendering order of other meshes from being mixed.
The number of draw calls has been greatly reduced from 12 to 4 again.
If you know this principle, you can do a little more optimization.
This time, the "color-changed character" is placed first.
The draw calls are now 3, which is the minimum expected value, because other characters are intentionally placed so that they can be bundled and rendered at once.
This is the most optimized state, but in practice it is difficult to reposition objects to reduce draw calls in the game.
Instead, we recommend organizing your scene in such a way that draw calls are likely to be reduced.
What happens if you apply SetMeshColorAll(string optTextureName, Color color2X) to all characters?
Since this function is a "intermidiate optimization phase", once called, "Draw call optimization is a single character" is retained, but "Draw call optimization with other characters" is no longer performed.
Regardless of the color, the draw calls increase slightly to 7.
A value of 7 means that the Z positions of the characters are properly distributed (background 1 + character 6),
as explained above, if the Z positions are the same and the rendering order overlaps, the worst case draw call may not be optimized.
The screen above shows the characters are placed in the same Z position with other same conditions.
There are no draw call optimizations, reaching 31, which is a maximum.
Draw calls are internal calculation of the Unity engine, so there are many other causes of increase and decrease in addition to the Z position.
Try other ways to optimize drawcalls.
Cases that can increase draw calls
There are many conditions under which draw calls can be increased.
Below we introduce some features of AnyPortrait that increase the draw calls other than the above functions or color modifiers.
If multiple images are used for one character, the draw calls will increase.
It may be effective to use one large image rather than several smaller ones.
(Please check in advance since it may vary depending on the build environment and devices.)
Clipping meshes use the Render Texture technique.
Due to the feature of the render texture technique, the clipping meshes does not share draw calls with other meshes.
Draw calls are increased for both clipping mask meshes and meshes being clipped.
If you set the mesh's Shader Settings to something other than the default, this mesh will not be able to share the material with other meshes.
This mesh is changed to be the "lowest optimization phase".
This is the case if you set the Blend method to a value other than Alpha Blend, or use a Material Set that is different from the default.
Using the custom properties of the material using script functions (such as the SetMeshCustomFloatAll function) or the Add Custom Property function on this screen also causes an increase in draw calls.
If you check in the game, you can see that the draw calls are increased by some meshes.