draw call batching

According to ( Using Instanced Meshes doesn't reduce draw calls - Asset Creation - Epic Developer Community Forums ), UE4 does not support batching draw calls for actors that use the same material.

Eg if we have 100 actors and each actor uses 3 materials (call them A B C), that’s 300 draw calls. All UE4 instancing does is group the order of the draw calls so we do 100 A draws, then 100 B draws, then 100 C draws.

I find this shocking. I would have thought the material system (without instancing) would automatically batch draw calls based on some generic algorithm.

I would’ve expected the above example to be done in 3 draw calls - not 300 draw calls. One draw call for each material. Batching draw calls in this way can be done by batching the vertices into a single vertex buffer per-material.

One concern I read was that this can hurt culling when actors are not in close proximity… But UE4 could solve this as follows. Just have the developer label each actor in a group to be batched. So when I create each of the 300 actors (in the editor, in Blueprints, or in C++ code)… I just assign each actor to a draw batch group. Then for each actor in a particular draw batch group, UE4 will automatically combine the vertices into a single vertex buffer for each material in that draw group.

So if the user assigns all 100 actors to a single draw batch group, then UE4 will do 3 draw calls (one for each material). Or, if the user assigns 50 to group G1 and 50 to group G2… Then UE4 will do 6 draw calls (one per material per group) (each actor has 3 materials).

Or the instancing system could do this? Based on the above link, it sounds like instancing would still do 300 draw calls… It just orders the draw calls so that it does each 100 draws material A, then 100 for material B, then 100 for material C. In other words - instancing does not reduce the number of draw calls.

So my question is… Does UE4 support this? And if not then why the heck not?

Aside - Unity does it, see ( Unity - Manual: Draw call batching )

Currently the only way is to use the merge actor tool to combine actors. It takes some extra time, but than you do have a lot of control.

I’m not sure how the instancing is executed, but I compared a simple scene with a 1000 draw calls on a newer mobile device, with a scene where they were all instanced, which I then compared with a scene where they were all in a single draw call by using the merge actor tool. The conclusion: instancing had about the same performance as merging. So it is definitely a lot better than having it all separated.

My actors are spawned dynamically at run-time in a 26x19 grid. Can I efficiently “use the merge actor tool to combine actors” at run-time in my C++ code? The goal is to spawn 26x19 actors on level begin, and then Destroy() actors gradually as the game continues (I’m basically using actors for fog of war). It’s all the same actor just 26x19 copies of it.

According to ( Using Instanced Meshes doesn't reduce draw calls - Asset Creation - Epic Developer Community Forums ), instancing does not batch draw calls and does not reduce draw calls. Instead, it just sorts the draw calls so that draw calls from the same material happen in a row. Again I’m assuming ( Using Instanced Meshes doesn't reduce draw calls - Asset Creation - Epic Developer Community Forums ) is true, but I’d love to verify it if it’s easy to do somehow?

It might be better to check performance instead of just 1 number: draw calls. Performance is related to too many things. Instancing does boost performance in cases where you need to draw a lot of the same “small” meshes.

The merge actor tool is made for the editor itself. I don’t know what you are trying to drawn, so can’t really help you with how to solve the issue.

Maybe you can try to use this: FMeshBatch | Unreal Engine Documentation

I never used it myself yet, but it looks like this is what it does.