The grouped sprite component is in 4.8 now and out of experimental, so you should be able to check them out in 4.8 preview 3. Here are some numbers with a test that I think approximates yours.
I have two test cases, 5K elements using a large sprite and 100K using a smaller sprite (spatially), as at 100K at the large sprite ended up GPU bound due to overdraw.
100K grouped instances:
- 5K large separate components - 85 ms render thread time, 5001 draw calls
- 5K large instances on a grouped sprite component - 1.9 ms render thread time, 2 draw calls
- 100K small separate components - Got tired of waiting for stats after a few minutes
- 100K small instances on a grouped sprite component - 1.85 ms render thread time, 2 draw calls (as long as the group isn’t dynamic, RT time is now constant, only GPU time increases as the # of sprites increases)
Note: Unfortunately I wasn’t able to do much about the cache uniform expressions overhead when using loose sprites it isn’t possible to safely make a persistent override proxy if the game code is using a MID, but grouped sprites dramatically reduce the # of components typically necessary, and should help quite a bit there.
Working with groups is pretty simple:
- You can build them programmatically like a UInstancedStaticMeshComponent works, but they have fewer limitations (you can mix/match sprites and materials in one, it will generate additional draw calls as necessary)
- You can convert selections in the level editor into a grouped component using the Merge button in the details panel if all selected items are sprite actors, or the right-click context menu if the selection is mixed (it will leave non-sprite objects alone but delete sprite actors, replacing them with a merged actor).
- You can split a sprite group back into separate actors if you need to move/reposition something, and can then re-merge them.
- You can sort them based on the rendering project settings TranslucencySortAxis, so that batches that contain translucent sprites render as expected.
Note: All sprites in a group will be drawn as one or a few draw calls (the mininum required given the materials and textures). This means that:
- Culling will be done as a whole unit. Either all instances are drawn or none of the instances are drawn. You probably don’t want to group sprites from opposite ends of the map together.
- Sorting will be done as a whole unit. If you have some translucent foreground sprites and some translucent background sprites, you probably don’t want to group them together. With the sort button they’ll sort correctly relative to each other, but a translucent player in the mid-ground can’t pass in between the two of them, it’ll either draw in front of both or behind both. These kinds of sorting issues only apply to Translucent materials, Masked materials don’t have the same issues but they only work for binary (0 or 1) opacity.
Cheers,
Michael Noland