Multiple static mesh material slots with material instances vs one material slot with texture performance

Hi,

I am currently working on a material system for my game, and I am deciding whether I should use multiple materials on a static mesh, where each material will be the instance of same master material, but will have just different color parameter, or whether I should have just one material slot with one material, where the paint color is stored in either a texture or vertex color.

The former would make the workflow much cleaner and flexible. I am already aware there is performance cost for each material slot on a static mesh, but what I do not know is if that cost is same also if all the material slots are occupied by an instance of the same master material, instead of being unique materials.

Does anyone have experience with this?

Thanks

1 Like

I would make a master material and instance the slots then you can just change parameters values to get your changes. Changing scalar parameters is cheaper then replacing the whole material. Your just changing a var not a utexture.

I am aware of that. What I don’t know is how much is the performance hit reduced compared to having all materials unique, instead of instance, and if that performance gain is similar to having just one material slot.

For example, I would like to see stats like this:
5 Material slots with unique materials: X amount of milliseconds
5 Material slots with instances of same master material: Y amount of milliseconds
One material slot: Z amount of milliseconds

I know what the possibilities are. I am just wondering if someone actually ever measured the performance.

I never have checked that out, I always use instances , so i can change what i need when i need it during play.
If you go try it both ways and check each, then you will know.

First. An instance doesn’t mean you can directly change the values during runtime.
You have to set that up in blueprint with a dynamic material instance.

Second.
You always use instances because that’s just how unreal likes things.

Third.
It depends on what the mesh is for.

Each material slot is a draw call.

If your mesh happens once - say a character - 20 materials on it, however heavy, will only be 20 drawcalls, which can be manageable.

If the mesh happens infinitely - say foliage - having more than 1 slot will degrade performance by multiplying the number of drawcalls required to render.

The MS and all the other stuff is just BS when someone else tells you theirs.
You have to bench it on your project in your target system, on your target scene, or it won’t ever mean a thing.

The base cost is also pointless because it’s very variable. It’s not a situation where addition/subtraction and multiplication/division work like regular algebra. It’s one of those fringe cases where 2 + 2 can equal both 4 and 12 at the same time. Scroodinger like, you won’t know until you bench it…

It is always best to have a single material for the entire mesh, which should be a master material instance, and the mesh has a unique UV mapping, with all maps baked to that particular parameterization.
As @MostHost_LA says, for things like foliage, or modular building blocks, that really matters! (Also, when using instanced meshes, this helps, too.)

Having multiple materials on a static mesh, each of which is an instance, is not as good, but it can be fine, especially for meshes that are a little rarer. The main reason to do this is to support customization, or part swapping – the material slots may all use instances of the same master material, but they have different parameters/maps configured.

Having multiple materials per mesh, with each of them being its own master material (rather than an instance,) is the worst. Unfortunately, a lot of marketplace assets come like this, because this is what happens by default when you export to Unreal using a naive/straight-forward export workflow.
But then again, if there’s only a single instance of that mesh (it’s some kind of hero asset) then there’s not a big difference. Still would be better using instances of the same master material, though, to avoid that shader compilation overhead.

Up to a certain extent i guess.
There’s drawbacks and advantage on this too.

If all you need is to make a material red, for instance. Having a master material that uses textures is completely pointless.
Setting up the master material to not use textures unless requires is better - but having a completely different material for it altogether is better yet.

Best case scenario of this is Textiles (cloth). You can use anything you want on it (provided the proper usage checkbox is checked), but its likely a lot better off with its own dedicated material.

This probably also extends to any material that requires special things
foliage: wind.
Eyes: transparency
Hair cards: a whole different thing.
Etc…

I am aware of those. What I don’t know is if the two draw calls of a single mesh with two materials are equally as expensive if the materials are unique or if they are instance of the same parent material. And if they are not equally expensive, then what is the rough ratio (e.g. how much cheaper the instanced material is)

That makes no sense.
If A costs X why would a copy of A cost Y ?

All an instance is, is quite literally, a copy.

Now, if you create the master material properly with a bunch of switches that cause recompile, and you toggle a bunch of them in a specific instance - then yes, the cost is different because you altered that instance.
But not anymore or any less than the main material, were the same settings to be changed.

It that was true then Epic would not be saying material instances are cheaper to render than unique materials. Instance is not just a copy.

An instance is exactly that.

Where does epic say otherwise, and where does epic say they are cheaper?
Nowhere.

dynamic material instance. do not have to be BP only, you can use c++ to make them. I have made many of them and they work very nice.

Just remember this, what ever you are changing during runtime has to be sent in the packets over the network. the less you send the less the overhead there will be.

Here for example:

If there’s a performance benefit, it’s not significant.

I’m not a graphics engineer so maybe I’m way off but purely from a reasoning standpoint, the fact that changing a parent material means recompiling every single material instance would seem to indicate to me that they are basically just copies…

Regardless, it’s clear that material instances are not like mesh instances, you’re not going to see a reduction in drawcalls so any performance gain has to come from somewhere else, and where that would be I’m not sure.

This is one of those “at scale, it matters, and in a single instance, you can’t measure a difference” problems.

Switching shader-program has a cost. Switching parameters for a shader-program (textures, colors) has less of a cost, by some fraction that’s not measurable for 10 meshes when you run at 30 fps, and may be quite measurable if you have 100,000 meshes and try to run at 240 fps.

Not switching at all has the least cost, because then the engine may be able to combine multiple items into a single operation using instancing, in theory. If you want to assure that combination, use one of the instanced-meshes actors.

There are two other costs of unique materials:

  • The shader program RAM / cache on the card usage, similar to icache usage on a CPU. Smaller is faster, and makes it less likely that the system falls off some particular performance stairstep
  • The workflow in the editor is slower the more different unique shaders you use, and this goes up with combinatorics (e g, used-with-landscape, used-with-skins, used-with-static-lighting, …)

The reason all this is so hard to say hard and fast things about, is that it’s often not the case that any one change has a noticeable impact, until one of them ends up pushing you over some particular limit on some particular hardware, at which point that particular hardware starts running slower. If you want to “be fatty while developing, and fix up only what you need at the end,” then you will have an essentially insurmountable hardware/software/asset/level combinatorics explosion to contend with. Thus, it’s generally better to make it a habit to always do the good thing – it’s not premature optimization, it’s “doing your job well and not ignoring what you know will happen in the future.”

1 Like

In my particular case I am deciding whether units and buildings in my RTS game should have one or multiple materials. The former should be supposedly faster, but the latter makes content creation much faster and workflow much cleaner.

I’ll ask on that topic directly.
He’s obviously 1000% wrong.

The same material will cost the same amount. Period.

That said.
Going from multiple materials to one texture isn’t complicated.
Your model is already unwrapped.

Add a UV from the existing one (preserve you work)
Pack the UV, move the areas around and scale it to taste.
Bake a color map from the materials.
Plug it into whatever you use - mixer, substance painter, etc. And they’ll produce the single texture for you.

It’s not nearly as simple :slight_smile:

True, but that’s also why they call us 3D artists?
I hate messing with UVs as much as the next guy trust me…

There are a number of workflows that use a tool of some sort to bake the mesh to a single material as part of exporting for the engine. There’s a variety of tools and paths to make this happen automatically, or semi-automatically – which one works for you (if any) depends on your specific tools and needs.

Then again, if you want to support team decals and individual unit damage, you may end up with some solution that requires multiple materials anyway for technical reasons.
In general, I’d expect CPU and pathfinding and simulation to be a harder cap on unit count in an RTS, than the difference between 1 and 2 material (instances) per unit mesh.
Also, if your meshes support articulation (aiming cannons or whatnot) then each mesh piece has a cost, in addition to each additional material.

If you’re targeting mass market Android phones, it’s probably best to bite the bullet and bake everything to a single material slot. If you’re targeting PC with add-in graphics cards, perhaps the incentive to do so is less direct. And if you’re an alone creator, do whatever it takes to ship the game ahead of any other particular criteria. “Shipping one game” vs “being too locked up in all the technical mintuae and shipping zero games” is a much bigger difference than “shipping a game that runs well on a GeForce GTX 970” versus “shipping a game that runs well on an Intel Iris 600.”