Set a shader uniform / NME input block per mesh

Hi all,
I’m writing a multiplayer game where players all appear on the same screen, to differentiate them i’ve made a node material that takes an input block for the colour and then replaces all the alpha parts of the base colour texture with that colour, resulting in lots of players using the same skin but with different team colours.

my problem is, I’m setting the colour uniform in a material onBindObservable, but all the meshs are coming out the same colour.
I’ve tried to demonstrate the issue here:
https://playground.babylonjs.com/#HMQGLT#49

It doesn’t behave exactly the same as the NME using my GLTF models, but it shows all the boxes the same colour when they should have different colours as set in their metadata and transferred to the shader during the onBind event, if you pan the camera so you don’t see one the others will flip to the next colour in line
I’d appreciate any pointers, is what I’m attempting possible?

1 Like

@Evgeni_Popov might be able to help with this one tomorrow :slight_smile:

2 Likes

You should use material.getEffect() to set the color in the onBindObservable event for the change to be taken into account right away. material.setColor3 will set the new value to be used only for the next frame:

https://playground.babylonjs.com/#HMQGLT#53

However, it’s better for performances to clone the material and set the color value once and for all:

https://playground.babylonjs.com/#HMQGLT#54

1 Like

nice! thanks very much!

“However, it’s better for performances to clone the material”

Does this also apply to dozens/hundreds of boxes and therefore so many materials?
Aren’t materials more performance intensive than this bind call?

PS: How heavy are materials on performance and should the bind call be avoided if possible?

The setColor call leads to an update of the uniform buffer of the material, so a GPU buffer update whereas having different materials won’t (each material has its own uniform buffer). That’s why I said it was better for performances to have different materials (you should also freeze the materials for max perf).

Note that ANGLE may have some optimizations and not generate a GPU buffer update each time in the “setColor by material” case. In any case, you should make some testing to choose between one or the other method.

1 Like