A draw call is a command to the GPU. Issuing them is CPU work, and a scene bound by draw calls is slow no matter how few triangles it has.
Static batching
Combines separate static meshes sharing a material into one larger mesh at build time. Fast to render, costs memory (the combined mesh is stored), and only works for objects that never move.
Dynamic batching
Combines small moving meshes at runtime. Limited to low vertex counts and has CPU cost of its own — a narrower win than it sounds.
GPU instancing
Draws many copies of the same mesh with the same material in one call, each with its own transform. This is the big one for repeated content: a forest of one tree mesh, a wall of one brick module.
The requirement is that the mesh and material are identical. Per-instance variation has to come through instance data — colour tints, small transform differences — rather than through different materials.
What breaks instancing
- Different materials. The most common cause. Two props identical except for their texture do not instance.
- Different meshes. Even trivially different ones.
- Per-object material property changes made the naive way, which silently creates a material copy per object.
Designing for it
- Build environments from a small set of repeated meshes — this is the real argument for modular kits.
- Share materials aggressively; use atlases to make sharing possible.
- Push variation into instance data and vertex colours rather than into new materials.
For generated assets
Every generated model is unique by nature, which is the opposite of instanceable. A scene dressed with forty individually generated props is forty meshes and forty materials. If a scene needs volume, generate a handful of variants and instance those rather than generating one per placement.