# CustomMaterial with different textures

**URL:** <https://forum.babylonjs.com/t/custommaterial-with-different-textures/22059>\
**Category:** Questions\
**Tags:** material\
**Created:** [July 1, 2021, 12:11pm UTC](https://forum.babylonjs.com/t/custommaterial-with-different-textures/22059 "2021-07-01T12:11:18Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![JSa](https://avatars.discourse-cdn.com/v4/letter/j/f04885/32.png) [@JSa](https://forum.babylonjs.com/u/JSa)\
**Post date:** [July 1, 2021, 12:11pm UTC](https://forum.babylonjs.com/t/custommaterial-with-different-textures/22059/1 "2021-07-01T12:11:18Z")

</div>

Hi!

What could go wrong with the scenario below?

I have a code that works like this:

- Load a mesh
- Create new **StandardMaterial** and apply it to mesh

I have about 100 meshes and each have unique diffureTexture. Performance is good.

Then, the next version is this:

- Load a mesh
- Create new **CustomMaterial** and apply it to mesh

This time the performance gets very bad… it seems that CustomMaterial gets recompiled all the time or something.

I find many threads about cloning CustomMaterial already etc. but still could not find this exact issue. My initial idea was that plain CustomMaterial without any customization would be just like StandardMaterial… 🤔

Could I somehow clone the CustomMaterial and change the diffuseTexture only without recompiling the whole shader?

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [July 1, 2021, 1:16pm UTC](https://forum.babylonjs.com/t/custommaterial-with-different-textures/22059/2 "2021-07-01T13:16:11Z")

</div>

It should definitely be possible to cache the shader and reuse the effect. Could you provide a quick repro in the playground I am worried we might have a cache issue ?

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [July 1, 2021, 2:56pm UTC](https://forum.babylonjs.com/t/custommaterial-with-different-textures/22059/3 "2021-07-01T14:56:09Z")

</div>

Maybe that can help:

> [@Multiple materials with same shader settings](https://forum.babylonjs.com/t/multiple-materials-with-same-shader-settings/20645/2):
>
> It can’t really be optimized as you really need 50 different materials here. Because you are using a CustomMaterial, it will also create 50 shaders (effects), even if the code is the same. If you wanted to optimize the number of effects created (that would not change the rendering performance, only the memory used and the compilation time), you would need to create your material as a node material instead: @Deltakosh has recently added an optimization where you can reuse the same node material …

---

<div class="post-metadata">

**Author:** ![JSa](https://avatars.discourse-cdn.com/v4/letter/j/f04885/32.png) [@JSa](https://forum.babylonjs.com/u/JSa)\
**Post date:** [July 2, 2021, 8:02am UTC](https://forum.babylonjs.com/t/custommaterial-with-different-textures/22059/4 "2021-07-02T08:02:39Z")

</div>

Here you go ( using my existing test-bench, it seems to catch multitude of bugs easily 😃 ):

CustomMaterial, this uses 50% of CPU all the time and even FPS drops to 30fps when zooming:  
[https://playground.babylonjs.com/#U2KKMK#167](https://playground.babylonjs.com/#U2KKMK#167)

Same with StandardMaterial, no problems here:  
[https://playground.babylonjs.com/#U2KKMK#166](https://playground.babylonjs.com/#U2KKMK#166)

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [July 2, 2021, 9:11am UTC](https://forum.babylonjs.com/t/custommaterial-with-different-textures/22059/5 "2021-07-02T09:11:12Z")

</div>

You should not create new materials continously but create a pool beforehands and get one from it when needed:

[https://playground.babylonjs.com/#U2KKMK#170](https://playground.babylonjs.com/#U2KKMK#170)

---

<div class="post-metadata">

**Author:** ![JSa](https://avatars.discourse-cdn.com/v4/letter/j/f04885/32.png) [@JSa](https://forum.babylonjs.com/u/JSa)\
**Post date:** [July 2, 2021, 10:27am UTC](https://forum.babylonjs.com/t/custommaterial-with-different-textures/22059/6 "2021-07-02T10:27:38Z")

</div>

Hmm… I am wondering how StandardMaterial handles this “out-of-the-box” without any performance hit?

For CustomMaterial to be as effective should it somehow cache the internal shaders globally instead of always recompiling them? I feel uncomfortable that just changing the material color would lead into implementing a pool etc.

I am also thinking this workaround: Should I just inherit my own material from StandardMaterial and change the shader code there?

Or 2nd idea: Could I create uniforms for material color and texturemap and use only single instance of CustomMaterial? For color I think I know how to do this but not for diffuseTexture… _Edit:_ This seems to be difficult as CustomMaterial returns undefined for getEffect()… At least it seems that I totally misunderstand StandardMaterial and CustomMaterial relationship by just trying to use intuition 😉

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [July 2, 2021, 10:59am UTC](https://forum.babylonjs.com/t/custommaterial-with-different-textures/22059/7 "2021-07-02T10:59:04Z")

</div>

> [@JSa](#):
>
> I am wondering how StandardMaterial handles this “out-of-the-box” without any performance hit?

You will still have some perf hit because there’s a creation of a material each frame, so some GC will kick in at some times. It’s not as bad as with a `CustomMaterial` because the `StandardMaterial` is able to reuse an existing effect and not create a new one each time, something the `CustomMaterial` can’t do currently.

> [@JSa](#):
>
> Should I just inherit my own material from StandardMaterial and change the shader code there?

That’s basically what `CustomMaterial` is doing.

> [@JSa](#):
>
> Could I create uniforms for material color and texturemap and use only single instance of CustomMaterial?

You can do something like that, but it is not really supported as the `_uniformBuffer` variable is not exposed:

> **[Babylon.js Playground](https://playground.babylonjs.com/#U2KKMK%23177)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL 3D scenes

---

<div class="post-metadata">

**Author:** ![JSa](https://avatars.discourse-cdn.com/v4/letter/j/f04885/32.png) [@JSa](https://forum.babylonjs.com/u/JSa)\
**Post date:** [July 2, 2021, 11:01am UTC](https://forum.babylonjs.com/t/custommaterial-with-different-textures/22059/8 "2021-07-02T11:01:25Z")

</div>

> [@Evgeni\_Popov](#):
>
> You can do something like that, but it is not really supported as the `_uniformBuffer` variable is not exposed:
> 
> [https://playground.babylonjs.com/#U2KKMK#177](https://playground.babylonjs.com/#U2KKMK#177)

Thank you! 🙂 This is just what I am looking for! I would be very happy to see this part of exposed API as well. I find it very usefull.

And about this:  
const mat = new BABYLON.CustomMaterial(); **// can also use StandardMaterial for that matter, no need for a CustomMaterial as no shader code is modified**

… I do need to modify the shader in the real use case. That’s the exact reason to do this with CustomMaterial. 🙂
