Sorry in advance if this topic is a bit nitpicky… Because it is
I’m brewing kind of a large game with many node materials. The problem is, most of the meshes require me to clone the material, but the process takes too many milliseconds. If I am to spawn many different enemies for example, and at the same time, this will be a big bottleneck. Also my game initializes around 2 seconds slower when the cloning is on.
So the question is, what could be the cause of the slowdown and is there any way to improve the material cloning process? Do I have to switch to raw shader material for example?
My process currently is following:
When the game boots, load the necessery load materials (json format).
I use LoadAssetContainerAsync to load each model and then replace the material of those models with my giant base node material. I am cloning the original node material per model/node of the model.
When some asset container is needed, I instantiateModelsToScene with cloneMaterials varyingly true/false. I’m afraid I have to use cloning more at some point in the future.
To further show you some usecases;
This is where I need to instantiate asset container that contains the building blocks for my games map. This has currently ~20 mesh pieces. If I instantiateModelToScene with cloneMaterials, it takes quite a bit of time
So around 100ms for 20clones… If I do not clone the materials, I get weird colouring problem. And I have to clone instead of instancing, since I am cloning the meshes further down the road to finally merge them into one big mesh using MergeMeshes.
The worse problem is in my asset container loading function, where I already replace the material loaded in the glb file with the node material. I use material cloning here to ensure that each mesh has a unique node material to minimize side effects.
It takes once again quater of a second to initialize the game’s meshes. This is scary, since it is going to keep increasing in the future… Making the initial load time bigger. I could also skip this phase and just get the node materials on demand in other places, but I think the cloning cost is still a bit too big… ALSO:
There is some additional processing happening for the node materials, so it seems to hog the process even further So in total my models process node materials around 600ms…
So if you have any ideas how to improve or restructure stuff, I am more than glad to hear it! <3
I have some things in the main shader that can be unique to one “entity”. For example;
Dissolving the entity => needs a float value that needs to be unique
“Wobbly” effect which I currently use to move trees/grass patches a bit for “wind” effect. Don’t use this for moving player entities for example.
Possibly some additional grunge texture to add more detail
Possibly some additional cloud textures to add more detail, as in clouds moving in the surface of the ground (and in some cases I have to turn this off)
I made sure I removed all the embedded textures on my game for now, since I also expected they were the primary cause of “slow” cloning… That wasn’t the case
I can create one sure, but maybe on the weekend since I unfortunately must tend to my day job of web programming
Yesterday I also tried to refactor things a bit more on my game code to figure out which models should use the original node material and when to actually clone it. It is pretty error prone however, if I use the original material, since I have to make sure no other piece of code modifies the inputs…
Also by doing the refactoring I noticed something odd with the colors when not cloning the materials and using mergemesh. I will make another question on that as well on the playground.
For a simple material I will get roughly ~4ms (mesh&material cloning) ~50ms (compilation).
For your mega material I will get roughly ~100ms (mesh&material cloning) ~200ms (compilation).
If you could double check the test setup and whether shader compilation time is measured right?
But from a first look, I would say, your material is too big. But it also seems shader compilation just takes a bit longer (50ms or ~3frames for the simple shader).