Is there any way to speed up node material cloning process?

Hi everyone!

Sorry in advance if this topic is a bit nitpicky… Because it is :smiley:

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:

  1. When the game boots, load the necessery load materials (json format).
  2. 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.
  3. 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;

  1. 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


    Without cloning, it is

    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.

  2. 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:

    What is this?

    There is some additional processing happening for the node materials, so it seems to hog the process even further :nerd_face: 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

Does this one big mesh has all the materilas which were cloned?

1 Like

The combined mesh uses the same one texture, so combining them should be safe :slight_smile: So it uses only single material in the end

Then do you need node material along the way? Also I’m really intrigued why you need to clone the materials. You should not have to.

Can you repro in the PG?

1 Like

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)

Here is almost the newest version of the main shader I use: Babylon.js Node Material Editor

I think you have seen this before in some coloring issue thread :slight_smile:

I kind of wonder if making all the things in the same shader has been a bad idea?

Just a shot in the dark: how big are these cloud textures? And are they cloned as well if they come from a string srouce?

1 Like

I see. If you can provide a repro of your use case I can look at the cloning loop to see if I can improve it

1 Like

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 :slight_smile:

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.

Can you double check, please? I made this playground: Babylon.js 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).

2 Likes