Hi, I have a static mesh of a rock in my project. I have reused instances of this same rock in the level design thousands of times. This static mesh rock has a green mossy material as its default material. The asset pack this rock came in has a separate identical copy of the static mesh rock with a snowy texture assigned to it as its default material.
If I plan to use this snowy rock in the level again thousands of times does anyone know what the most efficient approach would be in terms of framerate and overall game performance?
A) Have 5000 of the mossy rock static mesh and another 5000 of the different snowy rock static mesh both in the same level?
B) Delete the snowy static mesh from the content browser. Have 10,000 of the mossy rock static mesh placed in the level, half with the default mossy material and the other half get their material overriden with the snowy rock material. Each set of rocks are on a different sublevel so changing the material on a specific half of the rock meshes is not an issue.
Im not sure whats worse, doubling the number of unique static meshes in the level or having 5000 meshes with overrided default materials. All of this is also utilizing nanite. Any advice here would be greatly appreciated.
Doesn’t really change anything if the end result is the same.
1b rocks of a + 1b rocks of a is just as bad as 2b rocks of only a or 2b rocks of only b.
The only benefit would be to have 1b rocks total, .5b of A and .5b of B.
Instancing works on each material, so having 2 materials means worse performance. True.
But it also doesnt really matter until you get to 40 or 60 unique instances.
Total numbers matter, but they also don’t.
Less is better. Always. For performance.
In the end, the maximum number of instances on screen is handled by the system you use for instancing.
Something like foliage is optimized for it. It groups things so that they share drawcalls automatically.
Something like a custom HISMC is not optimized for loading stuff, so you don’t get extra benefits, but you also dont usually use those systems for 1b instances.
Search online for
Ue4 optimization Intel.
Read their paper where they explain the limits/considerations and options for instancing.
Though dated (I think like 6 or 7 years now) its still verymuch a “baseline” principle/truth/best paractice worth knowinf about.
Hi, thank you for the response. Cutting down the number of static meshes in total isn’t really an option as those are defined by the needs of the level, nanite is also handling the large count of rocks in the environment very well. The rock in question has about 4,000 tri’s. My instinct is having two seperate copies of the rock present in the level, a mossy one and a snowy one, for a unique total of 8,000 tri’s is probably preferable to having only one version of the rock present but then dealing with 5,000 instances having overriden materials. I’m sure on a small scale it would be irrelevant but once there’s thousands of overriden default material slots I’m guessing that might start causing a performance hit.
Wonder what the impact would be if it was one material but mixed perhaps based on world space (you could have a texture to decide which texture slots to mix internally in the material node)
The impact is minimal, but that doesn’t mean you shouldn’t set up benckmarks to get ypur baselines.
Everything you do - in any engine - should be based on performance testing first.
If more people followed that simple rule, you’d see a lot better videogames out there…
Overriding instance materials doesn’t really cost all that much. Its just the same as it being a completely different material/object.
Shader tricks like perInstanceRandom cost less.
So you could hook that into a syatem to decide how the rock looks but
Once you include both textures in the shader file your memory footprint is larger, which may or may not be a worse hinderance.
You could simply extract a single channel out of the moss, probably green as thats predominant on the moss, and feed that in as follows:
Subtract from green (so green - 1-green). Leaves you with colorless in place of green.
Place in lerp B revirwing this as it was incorreect
Use per instance random to power an alpha value that goes 0 or 1 (in an IF so its clean).
Perinstancerandom - look what it outputs.
Plug into the source of if.
Set values on if.
Use as alpha of lerp.
And now you have a cheaper rock that can sometimes be white where the green is, sometimes white.
If your shader uses world position for defining the moss area you are in a performance trouble situation anyway, so I gave the example assuming moss is just texture.
You can do the same using WPO, the cost is just higher for it…