ShaderMaterial Recompile: Fragment Code Updates, but New Uniforms Are Ignored

I am trying to create a dynamic ShaderMaterial that allows both the fragment shader source and the set of uniforms to be modified at runtime. Defining the uniforms in the constructor works correctly, but I have not been able to update the uniform list dynamically after instantiation.

Working demo (click on the sphere) : A ShaderMaterial where uniforms declared in the constructor update correctly when the shader is recompiled.

However, the next playground shows the issue: when the uniforms are not declared in the constructor, I cannot add them later at runtime:

Broken demo: A ShaderMaterial whose fragment code updates, but where dynamically adding uniforms fails.

I attempted the following:

this.options.uniforms = ['worldViewProjection', 'plane'];

and:

this.getEffect().uniforms = ['worldViewProjection', 'plane'];

prior to recompilation, but neither approach succeeded.

Is there a supported way to update uniforms dynamically?

Update on the investigation: it doesn’t seem to be an issue with the uniform declaration, as I can see the uniform in Spector. It’s more likely related to actually setting the uniform…

This is not supported (and we can’t allow it, because an effect can be shared by multiple materials).

A material (effect) is defined, among others, by the list of uniforms. If the list changes, a new effect must be created. You should simply create a new instance of the material with the new uniform list / shader code.

1 Like