Is there any way to bind ShaderMaterial uniforms per mesh?

I’m trying to bind ShaderMaterial uniforms to specific values per mesh.

Initially it seemed like calling set uniform method at onBindObservable would be the way, but because ShaderMaterial calls onBindObservable after it has applied the specified uniform values it only makes the next rendered meshes use the desired value.

Then I was thinking that maybe I could set the values on the “effect” directly, but that wouldn’t work when the material can have multiple effects for different attribute combinations.

Here is a Playground test case. It generates random colors for each mesh and tries to apply them on material bind:

Any suggestions how to make this work without having to inject custom code to Babylon.js function prototypes?

Would that be the expected behavior? ShaderMaterial bind per mesh values | Babylon.js Playground (babylonjs-playground.com)

Yes that is correct indeed. :+1:

I suppose that means that getEffect() when called in onBindObservable always returns the active effect for rendering, even if shaderMaterial internally has multiple effects or even material override active?

Looks good though. I created a test that better matches my use case of render target + material override and it still seems to be working: https://www.babylonjs-playground.com/#HP8QPZ#3

I’m still not sure if there is any documentation that getEffect() is guaranteed to return the active effect in onBindObservable, but at least it “seems” to work so I’ll take it. Hopefully it doesn’t break in the future. :slight_smile:

yup getEffect in onBind will be all good even in the future.