Instanced vs non-instanced static mesh vs materials

I’m a few weeks into learning Unreal. I am trying to use around 2,000 simple mesh objects (around 20 tris per object) to be the ‘walls’ and ‘floor’ in my project. These objects must be able to move, and I want to assign (simple) materials to these objects dynamically.

I have made an actor blueprint in which I have tried using either AddStaticMeshComponent or AddInstance to make my objects. I can move them as I want, using either SetWorldTransform or UpdateInstanceTransform. I.e., I can copy or instance my simple objects.

If I use the copy method, I can assign to the objects the materials I want, but the FPS drops to an unacceptable rate.

If I use the instance method, the FPS is fine, but I cannot control the material used at the per-instance level.

I have tried reducing the number of objects I move per Tick, but the results don’t look good.

Presumably, I need to get the GPU to do more of this work, but I am not sure how to do this.

Is there a better workflow for doing this sort of thing?

1 Like

Maybe group the objects by their material into different InstancedStaticMeshComponents (ISMC_Red, ISMC_Blue, …). If you change the material for example from red to blue, remove the instance from ISMC_Red and add it to the other group ISMC_Blue.

Thanks for the suggestion, ThiloN1987. I don’t think this will work, though, as I want to do more with materials later on, which means they won’t fall neatly into groups.

I have tried spawning actors containing the static mesh on EventbeginPlay. But this has turned out to be even worse.

This is just floors and walls & around 40K polygons. Is there really no way to make this processes simpler in Unreal?

The problem is the count of draw calls if you have so much separate static meshes. Not the number of polygons. Each static mesh means a draw call. I’ve read in a performance presentation about Robo Recall that they set their limit to about 1000-1500 draw calls. Methods to reduce draw calls are for example merging different static meshes into one or - using instanced static meshes. An instanced static mesh with 2000 instances means only 1 call, not 2000 calls like with separate meshes.

Are the meshes always moving repeatedly the same way, like an animation? Then you could try a skeletal mesh instead and a few materials for all 2000 meshes (combine textures of different meshes into one - you don’t want to use 2000 materials).

Or you force them into groups by putting similar looking cubes into the same instanced static mesh component. I’ve also seen more than 2000 cubes with a good framerate in a particle system (https://www.youtube.com/watch?v=ftIlR_G1HIk), but you will have problems accessing the transform of a specific cube and changing it’s material.

I don’t really see an easy way for that, but I may be wrong. If you describe in more details what you want to do (screenshots how it should look?) maybe someone could help you better.

Thanks again, ThiloN1987.

Just to clarify – “Methods to reduce draw calls are for example merging different static meshes into one or - using instanced static meshes.” – there is no way to assign materials to instances dynamically? That is to say that a draw call is per instance group, and instances with different materials must therefore be in different draw calls? I understand I can get lots of geometry and a high FPS rate with instances, but that this limits the options for materials.

“Are the meshes always moving repeatedly the same way, like an animation?” – they are, to the extent that all that they do can be represented by a single animation curve, i.e. translation on one axis. Bones are a good idea, but I wonder if I would run into problems i) with 2,000 bones and associated bloated functionality for skeletal mesh?

I did consider making a procedurally-generated mesh to make my geometry, and then fudging a bones-like system to move the components. But I haven’t been able to discover yet how to to do this animation at run time, or what penalties I will create, for e.g. with recalculating collision geometry, etc.

On materials… I would like to end up with per-face assignment to a number of materials and textures. For instance, so that the floor/walls geometry can show directional arrows, but which assignments are determined dynamically/procedurally, at run time. Not hundreds of materials/textures, but maybe a few dozen.

I realise that these may be high expectations, perhaps with few off-the-shelf solutions. But it was the first steps I am having trouble with – understanding Unreal’s work flows, etc.

Thanks again for your advice.