Is it better to have your game character as a one-piece skeletal mesh or built up from separated meshes in terms of rendering performance? It seems like UE suggests to build a character up from several meshes using the socket attaching functionality on one side. On the other side, one would say that more meshes are more draw calls, which takes the performance down rapidly.
In our game, we don’t have the option to “pre-make” the player’s character, because we want to give player the ability to build up their armor and weapons from many various pieces, as many as it would be insane amount of work (and insane increase on the game’s file size) to pre-make a character variations for all the equipment combinations. We also want to make the world open, with a lot of players (around 300 players visible at peaks), so there were several concerns about rendering performance in our team.
As UE doesn’t offer any way to merge meshes at run-time currently, we were asking… How big difference is it to have one character built up from e.g. 10 meshes (10 draw calls?) and having character built up from just one mesh (1 draw call?)? Is it a difference big enough to investigate any way to merge meshes at runtime (according to player’s current equipment constitution)? Can UE even render 300 players at once on some average hardware and at some reasonable frame rate or is it sci-fi?
We believe we can keep our characters and equipment at under 20 000 triangles per simultaneous display (simply, 1 player = 20k tris). To perform a simple test, I’ve made two sphere meshes, one with 2 000 tris, one with 20 000 tris and a simple material with 100% metallic to involve reflections. Then I’ve made two actor blueprints, one of them contained the 20k sphere and the second one contained 10 times the 2k sphere. I’ve also added spinning of all the spheres on Event Tick, so besides that the spheres were “Movable”, they were actually moving. I put them in scene and watched the average FPS on my quite average gaming rig I’d say: Haswell i5, 4 cores, 3.4 GHz, 8GB RAM, nVidia GTX 560 Ti.
20k tris, 1 draw call, avg. frame rate: 110.996 (100%) (screenshot)
20k tris, 10 draw calls, avg. frame rate: 97.597 (87.9%) (screenshot)
Performance difference: approx. -12%
Then I have added Levels of Detail to the spheres: LOD0 20k (100%), LOD1 10k (50%), LOD2 3k (15%), LOD3 1k (5%). And finally I have distributed 300 copies of both 1 and 10 draw call versions in two maps. When performing this test, instead of watching all 300 spheres from far away (and seeing just the LOD3), I tried to move and turn around in between the spheres as a regular player would do in a crowd of other players.
300 draw calls total (1 per “player”), avg. frame rate: 99.674 (100%) (screenshot)
3000 draw calls total (10 per “player”), avg. frame rate: 47.157 (47.3%) (screenshot)
Performance difference: approx. -53%
How accurate do you think such a test is? Please share your opinions.
Currently, we are rather a small team and considering development of some real-time mesh merging mechanism is probably out of our available resources for now. We will go the way of building up a character from many “draw calls”. 47 frames per second is a low frame rate, but one needs to keep in mind that there are reserves, which you might count with if you are wondering about the right solution for your game:
- Apparently, LODs increase performance several times more than draw calls decrease performance, you better worry about precisely setup LODs. Earlier I tried putting just 32 characters in a scence, each character had 10 mannequins duplicated within (1 mannequin is around 40k tris) and my frame rate dropped to 14.
- In our game, a player will be able to see 300 players at once in very, very critical situations, if at all. 99% of time it will be up to 60 players around at once.
- All these tests were performed with “Epic” rendering settings, you can give your players the ability to scale down their rendering quality, you can even allow them to switch to Unlit rendering mode. Gamers used to top quality rendering are usually equipped with better hardware than mine is.
On the other side, there are normally other objects to render in a scene than just the players and player characters might have more sophisticated materials to render than I used, which is not a subject to 1 vs 10 draw call test, so I used just a very simple material.
Although building up the character from many separate meshes is the only way to go for us at the moment, we will be most likely considering the other option in future again, if Epic won’t add such a feature faster.
Here’s the download link to my test UE project for this (UE 4.9), so you can easily edit stuff and perform a more accurate test if you like: Test.zip