Instancing and batching: drawing many objects cheaply

The same mesh a thousand times can cost one draw call or a thousand. What decides which.

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.