# How to stop NodeMaterial from generating same effects when not needed and save compilation time

**URL:** <https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171>\
**Category:** Questions\
**Tags:** material, node\
**Created:** [April 20, 2021, 9:51pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171 "2021-04-20T21:51:51Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![br-matt](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/br-matt/32/22436_2.png) [@br-matt](https://forum.babylonjs.com/u/br-matt)\
**Post date:** [April 20, 2021, 9:51pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/1 "2021-04-20T21:51:51Z")

</div>

Hello, we are trying to load tens of small PBR meshes a second during runtime that loading ahead of time is not an option. One large bottleneck we are experiencing is during material compilation. The number of meshes that can processed smoothly a second at a time suffer because of it. Doing some research and it seems to be generating the same effect for each mesh.

![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/4/40bef48f7690e23394a603800fa89f86a718a3a2.png)

It’s not required in our case, the best we can tell. What’s the best way to pick a pre-existing effect for a mesh to use and skip this compilation step ? We are cloning and freezing a node material and just swapping textures.

---

<div class="post-metadata">

**Author:** ![br-matt](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/br-matt/32/22436_2.png) [@br-matt](https://forum.babylonjs.com/u/br-matt)\
**Post date:** [April 20, 2021, 10:37pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/2 "2021-04-20T22:37:23Z")

</div>

Ah never-mind… I was digging through the code and found can set `_buildId` on the NodeMaterial to force it.

The API docs say `customShaderNameResolve` [NodeMaterial | Babylon.js Documentation](https://doc.babylonjs.com/typedoc/classes/babylon.nodematerial#customshadernameresolve) is there but I don’t think its implemented in NodeMaterial at all.

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 20, 2021, 11:09pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/3 "2021-04-20T23:09:07Z")

</div>

hey can you share your use case in the PG? You should never have to update the buildId as it is a private

---

<div class="post-metadata">

**Author:** ![br-matt](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/br-matt/32/22436_2.png) [@br-matt](https://forum.babylonjs.com/u/br-matt)\
**Post date:** [April 20, 2021, 11:31pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/4 "2021-04-20T23:31:15Z")

</div>

I will try to put one together. We were looking into NodeMaterial though and here [Babylon.js/nodeMaterial.ts at master · BabylonJS/Babylon.js · GitHub](https://github.com/BabylonJS/Babylon.js/blob/master/src/Materials/Node/nodeMaterial.ts#L1161) is where \_buildId is used. It’s auto incremented up top `this._buildId = NodeMaterial._BuildIdGenerator++` we are cloning a NodeMaterial a hundred or so times for the pool and its incrementing that number and making custom effects for each.

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 20, 2021, 11:35pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/5 "2021-04-20T23:35:38Z")

</div>

ok makes sense (why cloning if you need the same effect?)

---

<div class="post-metadata">

**Author:** ![br-matt](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/br-matt/32/22436_2.png) [@br-matt](https://forum.babylonjs.com/u/br-matt)\
**Post date:** [April 20, 2021, 11:38pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/6 "2021-04-20T23:38:43Z")

</div>

Because we want multiple objects in our scene to use the same NodeMaterial but different textures, without having to recompile for each. Perhaps this is not the best way to go about it ?

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 20, 2021, 11:54pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/7 "2021-04-20T23:54:26Z")

</div>

Nope it makes completely sense  
I should then expose the buildId for you so you do not have to mess with an underscore property

I will make that change for next nightly

---

<div class="post-metadata">

**Author:** ![Valentine](https://avatars.discourse-cdn.com/v4/letter/v/7ab992/32.png) [@Valentine](https://forum.babylonjs.com/u/Valentine)\
**Post date:** [April 20, 2021, 11:59pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/8 "2021-04-20T23:59:30Z")

</div>

Setting the buildId manually seems to solve part of the problem, but we’re unclear how textures get linked to the effect atm. What we see right now is that if we have a single shared effect across multiple nodeMaterials, it looks like they all end up sharing textures - in our situation we’re loading these meshes one after the other, and it looks like whichever mesh loaded last ends up applying its textures to all of the others (or that’s a guess at any rate, all the meshes flicker between different textures all the time, occasionally being correct).

My assumption was that the material stores references to textures, and binds them to the samplers in the cached effect when sending the mesh to the GPU, so it would make sense to have multiple materials with their own textures pointing to a single effect. But maybe that’s not the case? Or did we just screw something up on our end? 😄

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 21, 2021, 12:04am UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/9 "2021-04-21T00:04:27Z")

</div>

Nope it should work as you said.  
Here is a simple example: [Babylon.js Playground (babylonjs-playground.com)](https://www.babylonjs-playground.com/#SZR2Q4)

Two materials (but same effect) with different textures  
You can see that the only updates happening are regarding textures and geometries:

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/7/790f85d8fdde513f70104166b5335f492278c2b0.png)

If you can repro your issue in the Playground I should be able to help further

---

<div class="post-metadata">

**Author:** ![Valentine](https://avatars.discourse-cdn.com/v4/letter/v/7ab992/32.png) [@Valentine](https://forum.babylonjs.com/u/Valentine)\
**Post date:** [April 21, 2021, 12:25am UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/10 "2021-04-21T00:25:54Z")

</div>

I’m not sure what the fancy viewer you’re using to debug is, so I’m going to rely on the console to count how many effects I’ve got 🙂

Your scene checks out:

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/6/641de4ff4b951aa07f385225bb0c455cab5a67f8.png)  
If I go to engine.\_compiledEffects there is just one entry.

This is our situation by default, when we create two nodeMaterials from the same node graph and set different textures on them: [https://www.babylonjs-playground.com/#SZR2Q4#1](https://www.babylonjs-playground.com/#SZR2Q4#1)

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/5/52358c793e4a8b1d5b258c9cb8cab029521e1904.png)

As you can see, default behaviour is this creates two separate effects.

Will try and figure out how to duplicate the cloning + buildId setup in a PG, but this is the crux of it.

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 21, 2021, 12:27am UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/11 "2021-04-21T00:27:11Z")

</div>

I’m using this baby: [SpectorJS - Explore and Troubleshoot your WebGL scenes with ease (babylonjs.com)](https://spector.babylonjs.com/)

I have reproduce your issue there: [Local Reflection Texture Test | Babylon.js Playground](https://playground.babylonjs.com/#RSMKT2#4)

Let me dig into it and find a solution 🙂

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 21, 2021, 12:50am UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/12 "2021-04-21T00:50:03Z")

</div>

Alright people!!

The next nightly (will be live in less than a hour) will let you do this:

```auto
 BABYLON.NodeMaterial.ParseFromSnippetAsync("#PX0637", scene).then(nme_mat => {
        var texture_block = nme_mat.getTextureBlocks()[0];
        texture_block.texture = new BABYLON.Texture("/textures/grass.png");
        box.material = nme_mat;

        var clone = nme_mat.clone("mat2", true);
        box2.material = clone;

        texture_block = clone.getTextureBlocks()[0];
        texture_block.texture = new BABYLON.Texture("/textures/crate.png");
    });

```

The only difference is the 2nd parameter for the clone function. When set to true, it will let you reuse the same effect (until you call build again of course).

So this PG will work (when the PR will be live): [Local Reflection Texture Test | Babylon.js Playground](https://playground.babylonjs.com/#X6RIDH)

Link to the PR: [Nightly by deltakosh · Pull Request #10230 · BabylonJS/Babylon.js (github.com)](https://github.com/BabylonJS/Babylon.js/pull/10230)

Enjoy!

---

<div class="post-metadata">

**Author:** ![Valentine](https://avatars.discourse-cdn.com/v4/letter/v/7ab992/32.png) [@Valentine](https://forum.babylonjs.com/u/Valentine)\
**Post date:** [April 21, 2021, 12:52am UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/13 "2021-04-21T00:52:37Z")

</div>

Wow, that’s efficiency! Thanks, we’ll let you know how that goes 😃

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 21, 2021, 12:58am UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/14 "2021-04-21T00:58:53Z")

</div>

Yes please:)

---

<div class="post-metadata">

**Author:** ![Valentine](https://avatars.discourse-cdn.com/v4/letter/v/7ab992/32.png) [@Valentine](https://forum.babylonjs.com/u/Valentine)\
**Post date:** [April 21, 2021, 6:36pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/15 "2021-04-21T18:36:50Z")

</div>

Working like a dream folks 🙂

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 22, 2021, 4:14pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/17 "2021-04-22T16:14:38Z")

</div>

Lovely!

---

<div class="post-metadata">

**Author:** ![br-matt](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/br-matt/32/22436_2.png) [@br-matt](https://forum.babylonjs.com/u/br-matt)\
**Post date:** [April 22, 2021, 5:41pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/18 "2021-04-22T17:41:53Z")

</div>

Picture is worth a thousand words, not bad performance on the swaps for a 2018 MacBook Pro !

> **[bitstream\_walkthrough.mov (video)](https://drive.google.com/file/d/1Jk0TlnlI58D5un0y4BpqRvH6M1uw-1uT/view?usp=sharing)**
>
> Google Drive file.

Thank you again

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 23, 2021, 4:23pm UTC](https://forum.babylonjs.com/t/how-to-stop-nodematerial-from-generating-same-effects-when-not-needed-and-save-compilation-time/20171/19 "2021-04-23T16:23:58Z")

</div>

Beautiful!
