Draw call batching - Falmouth-Games-Academy/comp350-research-journal GitHub Wiki
To draw a game object the engine issues a draw call to the graphics API. Draw calls are expensive performance wise, the fewer calls the better, which is where batching comes into play. There are two types of batching, dynamic batching (used for small moving objects), and static batching (used for objects which are not moving).
Dynamic batching
Dynamic batching is a Unity feature which can be split into being able to work on Meshes and the other bit being able to do particle systems, line renderers and trail renderers due to it working differently for meshes 1(https://docs.unity3d.com/Manual/DrawCallBatching.html). Dynamic batching tends only to be an advantage if the work required is less than that of doing a draw call. It works by using GameObjects vertices and turns them into world space using the CPU. One of the main factors that depends on the resource requirements is the graphics API that is used by the user. The example listed 1(https://docs.unity3d.com/Manual/DrawCallBatching.html) is how consoles often can't make advantage of using dynamic batching because the call overheard tends to be too low. Dynamic batched objects can be moved around unlike static batching and can also have physics with their own rigid body 2(https://www.unity3dtips.com/unity-batching-dynamic-vs-static/). If you manage to fit all the criteria to do dynamic batching, it is expensive on the CPU side of things so this is good if you don't want to increase the load on the GPU 2(https://www.unity3dtips.com/unity-batching-dynamic-vs-static/).
For meshes dynamic batching is only applied to meshes with less than 900 vertex attributes and less than 300 vertices. GameObjects can't be batched if they use mirroring for any of the transforms. Materials instances have to be the same if they want to be batched together, even if there is a little bit of a difference they can't be batched, the only exception is shadow caster rendering. Lightmaps have an effect on how things are batched because they require more parameters, they need to take lightmap index and offset/scale into account. 1(https://docs.unity3d.com/Manual/DrawCallBatching.html)
For particle systems, line renderers and trail renderers (objects that generate dynamically) works differently. There are 4 steps to how it works for them. Step 1, for all batchable items that are compatible Unity builds it all into 1 large vertex buffer. Step 2 the renderer sets up the material state ready to be batched. Step 3 Unity uses the vertex buffer to bind it to the graphics device (graphics card). Step 4 for each renderer in the batch the vertex buffer is updated by putting the offset into the buffer, and then a new draw call is submitted. This method is close to how Unity does draw calls for static batching 1(https://docs.unity3d.com/Manual/DrawCallBatching.html).
Static batching
Static batching is an optimisation that reduces draw calls for static game objects that share the same material. It works by grouping together the static game objects and building one shared vertex and index buffer for them. Compared to using dynamic batching, it will improve CPU performance since it doesn't transform vertices on the CPU, however, it uses more memory 1(https://docs.unity3d.com/Manual/DrawCallBatching.html). A drawback of static batching is that if any part of the static group of objects is visible the whole group will be rendered, which could impact the performance quite a lot 2(https://www.unity3dtips.com/unity-batching-dynamic-vs-static/). Sometimes static batching is not worth using because the memory cost will be too high, for example making the trees static in a forest level would use a lot of memory 1(https://docs.unity3d.com/Manual/DrawCallBatching.html).
Batch size limitations
In targeting fewer draw calls and larger batch sizes, an optimal batch size for the specific target hardware will be found. This is limited by the segmentation algorithm and the texture resolution both applying to the texture atlas of rendering primitives 3(https://www.researchgate.net/profile/Matthias_Trapp/publication/270901841_Geometry_Batching_Using_Texture-Arrays/links/5506a8f70cf231de0778416a/Geometry-Batching-Using-Texture-Arrays.pdf). At this limit, the effect of batching is negligible as the performance bottleneck is in transferring such large amounts of data from the CPU to the GPU (rather than in the CPU overhead associated with draw calls) 4(http://dcgi.felk.cvut.cz/home/zara/papers/KavanEtAll-I3D08.pdf).
References
[1] https://docs.unity3d.com/Manual/DrawCallBatching.html
[2] https://www.unity3dtips.com/unity-batching-dynamic-vs-static/
[3] Trapp, Matthias, and Jürgen Döllner. "Geometry Batching using Texture-arrays." GRAPP. 2015.
[4] Kavan, Ladislav, et al. "Polypostors: 2D polygonal impostors for 3D crowds." Proceedings of the 2008 symposium on Interactive 3D graphics and games. ACM, 2008.