Static Batching

Unity offers a second batching mechanism through Static Batching. The purpose of this feature is to grant us a way to batch nonidentical meshes of any size into a single batch with a similar goal and methodology to Dynamic Batching, but solving the problem for a different set of conditions. The essential difference between the two batching methods is that Static Batching occurs during application initialization, whereas Dynamic Batching takes place at runtime. We therefore have a lot more control over when and where Static Batching takes place.

Note

Static Batching is available in all editions of Unity 5, but only in the Pro Edition of Unity 4. Unity 4 Free users will need to upgrade to the Pro Edition to make use of this feature.

The Static Batching system has its own set of requirements:

  • As the name implies, the meshes must be flagged as Static
  • Additional memory must be set aside for each mesh being statically batched
  • The mesh instances can come from any source mesh, but they must share the same Material

Let's cover each of these requirements in more detail.

The Static flag

Static Batching can only be applied to objects with the Static flag enabled or, more specifically, the Batching Static sub flag (also known as StaticEditorFlags). Clicking on the down arrow next to the Static option for a GameObject will reveal a dropdown of these StaticEditorFlags, which can alter the object's behavior for various Static processes.

The Static flag

Memory requirements

The additional memory requirement for Static Batching will vary depending on the amount of replication occurring within the batched meshes. Static Batching works by combining all flagged meshes into a single, large mesh, and passing it into the rendering system through a single Draw Call. If all of the meshes being statically batched are unique, then this would cost us no additional memory usage compared to rendering the objects normally, as the same amount of memory space is required to store the meshes.

However, statically batched duplicates cost us additional memory equal to the number of meshes multiplied by the size of the original mesh. Ordinarily, rendering one, ten, or a million clones of the same object costs us the same amount of memory, because they're all referencing the same mesh data. The only difference is the transform of each object. But, because Static Batching needs to copy the data into a large buffer, complete with its transform data, this referencing is lost, and a new duplicate of the original mesh is copied into the buffer with a hard-coded transform position, regardless of whether the same mesh has already been copied in.

Therefore, using Static Batching to render 1,000 identical tree objects will cost us 1,000 times more memory than rendering the same objects normally, because each tree must be copied into the Static Batching buffer as a unique set of vertex data. This causes some significant memory consumption and performance issues if Static Batching is not used wisely.

Material references

Finally, we already know about sharing material references as a means of reducing Render State changes, so this requirement is fairly obvious. However, sometimes we're statically batching meshes that require multiple materials. In which case, all meshes using a different material will be grouped together in their own static batch, and again for each unique material being used.

The downside to this design feature is that, at best, Static Batching can only render all of the static meshes using a number of Draw Calls equal to the number of materials they need. But, the benefit is that we can control which meshes get batched together using different materials, effectively forcing it to start a new static batch through some cunning material duplication. This will become clear after we cover some of the Static Batching system's caveats.

Static Batching caveats

The Static Batching system is not without its drawbacks. Because of how it approaches the batching solution, by combining meshes into a single greater mesh, the Static Batching system has a few caveats that we need to be aware of. These concerns range from minor inconveniences to major drawbacks depending on the Scene:

  • Draw Call savings are not immediately visible from the Stats window until runtime
  • Static objects should not be introduced to the Scene at runtime
  • Statically batched meshes cannot be moved from their original starting transform
  • If any one of the statically batched meshes is visible, then the entire group will be rendered

Edit Mode debugging of Static Batching

Trying to determine the overall effect that Static Batching is having on our Scene can be a little tricky since nothing is being Statically Batched while in Edit Mode. All of the magic happens during Scene initialization, which can make it difficult to determine what benefits Static Batching is actually providing. This is especially true if we leave implementing this feature until late in the project lifecycle, where we can spend a lot of time launching, tweaking, and relaunching our Scene to ensure we're getting the Draw Call savings we're expecting. Consequently, it is best to start working on Static Batching optimization early in the process of building a new Scene.

Avoiding instantiating static meshes at runtime

New static objects introduced into the Scene will not be automatically combined into any existing batch by the Static Batching system. To do so would cause an enormous runtime overhead between recalculating the mesh and synchronizing with the rendering system, so Unity does not even attempt to do it. This restriction means we should not attempt to dynamically instantiate the statically batched content. All meshes we wish to statically batch should be present in the original Scene file.

Note

Dynamic instantiation of objects can be a costly action in its own right. We will cover solutions to that problem in Chapter 7, Masterful Memory Management.

As with the previous caveat, statically batched meshes should not be moved after they have been batched, since doing so would generate a tremendous CPU overhead. The Static Batching system has already taken the original data and combined it into a new mesh object. Moving the original meshes is both impossible while the Static flag is enabled, and not even recognized by the Unity system if the flag is disabled and the object's transform is changed.

Visibility and rendering

The final caveat is perhaps the most important. If even a single vertex of a Statically Batched mesh is visible to the Camera, then the whole mesh will be pushed into the rendering system and processed in its entirely. We need to be smart about how we use Static Batching and optimize its usage to prevent us rendering a gigantic mesh each and every frame!

For example, if we have a Scene with many rooms connected together which all share the same Material, then enabling Static Batching for every room object will cause every single room to be rendered even if only a single room is visible, and even if the player is staring straight into a wall. Such Scenes would fare better using Occlusion Culling (explored in Chapter 6, Dynamic Graphics) to prevent nonvisible rooms from being rendered.

Meanwhile, large outdoor scenes will find it useful to duplicate Materials. This is a useful trick to force similar objects to be statically batched into different groups. Assigning identical, but duplicate Materials to different sections of the world will render them the same; however, they will be grouped separately. This would increase the number of Draw Calls, but allow us to reuse the same Texture, Material, and Shader files for the entire Scene.

Duplicating Materials can become a bit of a chore from the maintenance perspective, since any changes made to one Material must also be made to the others. Hypothetically, we might think we can accomplish this through Script by attaching a Component that automatically duplicates a Material and assigns it to the mesh during Scene initialization. Unfortunately, Static Batching happens too early in the initialization process for us to intercept through a custom Component such as this, so the task must be done through the Editor (a good opportunity to make use of Editor scripts).

Static Batching summary

Static Batching is a powerful, but dangerous tool. If we don't use it wisely, we can very easily inflict performance losses via memory consumption and rendering costs on our application. It also takes a good amount of manual tweaking and configuration. However, it does have a significant advantage: it can be used on object sets of any size. There is essentially no limit as far as Static Batching is concerned.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.195.34