Symptoms:
- I am drawing a lot of objects, and the game is running slow.
- I see a high CPU overhead.
Cause:
Every object visible in a scene is sent by Unity to the GPU to be drawn, using the select graphics API for the current platform. Drawing objects can be expensive if you have a lot of them in your scenes. In that case, the requests made to the GPU will be very high. These are usually called draw calls.
In modern hardware, draw calls are very cheap. However, the problem with draw calls is the changes that the renderer (render states) has to go through when drawing objects. These changes are related to the configuration that the GPU needs to use to render a given object. For instance, the object we want to render from the scene uses the material, textures, and shaders. When these settings don't change between draw calls, the draw call takes little time to execute compared to when the settings change.
Suppose there are a lot of objects that do not share the same material, texture, shader, etc. In that case, the Renderer has to change its state to draw the next object, and the draw calls become expensive and take more time to execute.
Resolution:
It is important to know what draw calls are and what batches are.
A draw call is a call to the graphics API to draw objects (e.g., draw a triangle), while a batch is a group of draw calls to be drawn together.
Batching objects together minimizes the state changes needed to draw each object inside the batch. Doing this, in turn, leads to improved performance by reducing the CPU cost of rendering the objects.
Unity groups the objects in batches to be drawn in two ways; Dynamic Batching and Static Batching. Only objects that share properties like textures or materials can be batched together.
Static batching is the recommended technique for objects that do not move since it can quickly render them. This method has a memory trade-off, as the batched meshes are combined into a single larger mesh. The resulting mesh is the union of all the smaller individual static meshes in the scene that meet the criteria to be batched together.
To use static batching, you need your objects to be static. You can do this by marking them as Static in the inspector.
On the other hand, Dynamic batching tries to optimize how non-static objects are rendered by transforming their vertices on the CPU, grouping many similar vertices together, and drawing them all in one go. It's limited to small meshes, as batching larger meshes dynamically is more expensive than not batching them.
More Information