Instancing Skeletal Meshes

Our project, a simple RTS tower defense-style game, has wave after wave of several enemies that spawn across the map.
These enemies seek out players and try to destroy them, with each wave increasing in difficulty, as well as increasing the number of enemies to spawn.
Well after so many waves, rendering all of these creatures really starts to show a performance impact.
I know you can instance static meshes (which we are doing for other objects), but is there any way to do the same for skeletal meshes?
Please note that I’m not just asking if UE4 currently has this ability, but also if it’s even technically possible via some minor C++ engine tweaks.
And if it’s not even technically possible, what are some good alternatives to improve performance in this scenario?

It is possible. Battlefield 3 actual use instancing for every draw call.
For last game that I worked I coded rendered that batched all rendering data that was needed for all draw calls to huge tbuffer. Then each instanced draw call just say where data start, how much data is used per instance and how many instances there are to render. It’s not super complicated system to do but it would need complete rehaul of current UE4 renderer.

From page 27.

Instancing SKs is not implemented in UE4 (which is big shame). You could have a look at this http://http.developer.nvidia.com/GPUGems3/gpugems3_ch02.html but this requires of big rewrites in skeletal shader and engine pipeline for them.

If you need only a few hundred skeletal meshes, say <500, you don’t need instancing, there are other optimization possibilities in UE4. I use a bunch of them in my RTS project (custom pathfinder, own update loop instead of actor ticking, lower number of bones, lower number of vertices, one material per mesh, simplified materials and effects, well tweaked shadows, proper landscape and model lods, no AO etc.). You can save a lot of performance in this way!

By “custom pathfinder” do you mean you don’t use UE4 AI system ?

Yes, it is written from scratch…

The reason why there isn’t skeletal mesh instancing yet in the engine is that it isn’t just a magic toggle. Instancing requires compromises and different games have different needs, which means different compromises. Also, the only thing instancing does is reduce the number of draw calls: if that isn’t your bottleneck, it won’t help you much.

For example, past some number of characters your animation BP update time will outweight the time spent with drawcalls depending on how complex it is. If you need massive numbers of animated entities you inevitably need to use different, simpler methods for updating their animations.

So, first thing before you consider working on a instancing solution, make sure you profile (Performance and Profiling | Unreal Engine Documentation ) to see exactly what is behind the performance issues. Some suggestions in advance :

  • If it’s animation BPs, make sure all your nodes are using the fast path: Animation Fast Path Optimization | Unreal Engine Documentation

  • If it’s draw calls, first try making sure your characters don’t use more than one material each. For example, instead of using different materials for clothing and skin, pack all into a single one. Each material requires a separate draw call, so a character using three materials means three draw calls.

2 Likes