Instance Batcher is a mesh batching solution that will help you reduce draw calls when using large number of prefab instances, while still allowing for dynamic changes.
You can download the demo here:
You can make a simple test to see if Instance Batcher can run on your target device.
=== Features =======================
Requires almost no change in workflow.
Reduces draw calls by batching larger number of instances of a single mesh, while still allowing dynamic use of individual instances.
No vertex limit on the original mesh (vertex limit of 65534 vertices per Mesh still applies)
Allows dynamic changes to:
-
Transform component
-
MeshRenderer component properties:
-
shadow casting mode
-
receive shadow
-
material
-
shared material
Allows setting per instance color (RGBA).
Dynamic renderer bounds calculation for each batch (render only visible batches).
Changes are applied in LateUpdate.
Modified Standard shaders:
- Metallic and Specular workflow
- Forward and Deferred render path
- Directional, Point and Spot lights (with shadows and cookies)
- using per instance color (for albedo (RGB) and transparency (A))
Easy to use InstanceBatcher_Utils.cginc for adding instancing support to custom shaders:
- Includes basic instructions
- Simple custom shader provided as a sample
Editor Tool for generating Instance Batcher Prefab.
Source code included.
=== Requirements and Limitations ==========
Target device must have support for:
- Shader Model 3.0
- TextureFormat.RGBAFloat
InstanceBatcher_Utils.cginc works only with vertex/fragment shaders.
Does not support per instance culling.
Does not support multiple materials or sub-meshes on a game object with InstanceController component attached.
Does not work with light probes and/or reflection probes.
Does not support SkinnedMeshRenderer
Does not support LOD Group
Modified Standard shaders do not support parallax.
Things that will make instance not batch with others and will create a new batch:
- Each combination of MeshRenderer’s shadow casting mode and receive shadow will create a separate batch.
- MeshRenderer’s material property behaves as normal and will produce a new material, which means that it won’t batch with other instances.
- Adding new instance when the capacity of the largest batch is reached will produce a new batch of smallest capacity.
=====================================
Video showing FPS gain in a dynamic scene (also 2552 draw calls VS 40 draw calls :))
Video showing the simple procedure of making Instance Batcher prefabs using the Editor tool and then creating some instances.
Here are some profiling pictures done to compare Instance Batcher with Dynamic batching. The scene consisted of 16900 game objects, a plane and directional light. All game objects were casting and receiving shadows. There was no dynamic changes being made to the cubes just because the overhead of iterating all 16900 objects would kill the performance (and the point with this profiling was to also show the difference in the “CPU Usage”).
There were two test cases:
- First one was done using cubes, which can take advantage of Dynamic batching.
- The second one was done using spheres. Dynamic batching on spheres does not work since the built-in primitive mesh for sphere has too many vertices.
On the image showing “CPU Usage” the “drawing” process part was selected just to clearly show the biggest difference (since the “Gfx.WaitForPresent” part makes the performance look worse than it really is).
In case you are not sure if using Instance Batcher would benefit your project, don’t hesitate to ask any question. Comments and suggestions are also welcomed ![]()





