By now your world streams, has foliage and blends into the terrain. And you probably placed a few hundred rocks by dragging the same mesh in over and over.
Open stat RHI and look at DrawPrimitive calls. That number is your problem.
Why 800 rocks cost 800 draw calls
Every Static Mesh Actor is an actor: a transform, a component, a scene proxy, and its own trip through the render pipeline. The mesh is identical, the material is identical, and the GPU is told about it 800 separate times.
Instancing collapses that. One component holds one mesh and N transforms. The GPU is told once: draw this, here are the 800 places. Same pixels, a fraction of the CPU cost.
The three ways you already have it
Foliage Mode — already instanced. Anything you paint is instances. This is why painted forests work and dragged-in forests don't.
ISM (InstancedStaticMeshComponent) — you add it to a Blueprint and call Add Instance with a transform. This is the manual one and it's the one you'll use.
HISM (HierarchicalInstancedStaticMeshComponent) — ISM with a hierarchy for culling and LOD.
ISM or HISM? Ask one question
The old rule of thumb was "HISM does per-instance LOD, ISM doesn't, use HISM." That's out of date. ISM supports per-instance LOD now, and the current guidance is roughly:
- HISM — better with thousands of instances that don't move. The static hierarchy makes culling cheap.
- ISM — no static hierarchy, so it culls and LODs each instance on the GPU. That's more flexible for instances that move, but more expensive on low-powered platforms.
- HISM's LOD is per group, not per instance, because it works in clusters. If you need LOD behaviour matching a plain static mesh, HISM won't give you that. HISM is at its best where per-instance LOD doesn't matter — low-triangle meshes.
And the modern shortcut: if your project is Nanite-only, ISM is always the choice — Nanite does its own culling and LOD, so HISM's hierarchy has nothing to add. Use HISM where you have Nanite plus fallback meshes.
Honestly? Try both and profile. Both docs and forums agree the answer depends on your project.
When instancing is the wrong tool
Instances are not actors. That's the whole trade:
- No per-instance Blueprint logic. An instance can't have a script, a component, or an overlap event.
- No per-instance material parameters. Same material, always. Per-instance custom data exists and helps, but it's a float array in the vertex shader, not a material instance.
- Interaction means bookkeeping.
Add Instancereturns an index.Remove Instanceshifts every index above it. Store instance indices in a variable and you have silent, undebuggable corruption the first time one is removed.
So: fence posts, rocks, grass, debris, crates that are just scenery — instance them. Anything the player interacts with individually stays an actor, or you spend a week rebuilding actor semantics on top of an index array.
Making it actually help
Instancing wins on draw calls. It does not automatically win on everything:
- Culling is per component. 5000 instances in one ISM spanning your whole map means you cull all or nothing. Split them into spatial groups — one component per region.
- Distance culling on ISM/HISM has a long history of surprising people. Test it, don't assume the setting does what its name says.
- Overlapping instances hurt if you're on Hardware Ray Tracing Lumen. Lots of intersecting instances degrade the acceleration structure.
stat RHIbefore and after. If DrawPrimitive calls didn't drop, you didn't fix anything and you should find out why now.
Common pitfalls
- Storing an instance index across a Remove Instance. Indices shift. Use a stable ID mapped to an index, and rebuild the map on removal.
- One giant ISM for the whole level. Culling becomes all-or-nothing. Group spatially.
- Instancing things the player interacts with. You'll rebuild actors, worse.
- Expecting per-instance materials. Look at per-instance custom data instead, and know its limits.
- Assuming HISM because a 2020 tutorial said so. Re-check against the current docs — ISM has per-instance LOD now, and Nanite changes the answer entirely.
- Not profiling. "Instancing is faster" is a claim about draw calls, not about your specific scene.
30-second recap
- Every static mesh actor is its own draw call. Instances share one.
- Foliage Mode is already instancing. ISM is the manual version.
- HISM: thousands of non-moving, low-triangle instances. ISM: everything else — and always, if you're Nanite-only.
- Instances have no Blueprint logic, no per-instance materials, and unstable indices after removal.
- Split instances into spatial components or culling is all-or-nothing.
stat RHIis how you know it worked.
Next Sunday: garbage collection — why your game hitches every 60 seconds like clockwork, and the setting that splits it across frames.
— Marco
Comments
Leave a comment