Three.js, sharing ShaderMaterial between meshes but with different uniform sets

three.js

Solution

When cloning a `ShaderMaterial`, the attributes and vertex/fragment programs are copied by reference. Only the uniforms are copied by value, which is what you want.

This should work efficiently.

You can prove it to yourself by creating a `ShaderMaterial` and then using `ShaderMaterial.clone()` to clone it for each mesh. Then assign each material unique uniform values.

In the console type "render.info". It should show 1 program.

three.js r.64

Problem

As the title says, I would like to reuse a given ShaderMaterial for different meshes, but with a different set of uniforms for each mesh (in fact, some uniforms may vary between meshes, but not necessarily all of them): is it possible ? It seems a waste of resources to me to have to create a full ShaderMaterial for each mesh in this circumstance, the idea being to have a single vertex/fragment shader program but to configurate it through different uniforms, whose values would change depending on the mesh. If I create a new ShaderMaterial for each mesh, I will end up with a lots of duplications (vertex+fragment programs + all other data members of the Material / ShaderMaterial classes). If the engine was able to call a callback before drawing a mesh, I could change the uniforms and achieve what I want to do. Another possibility would be to have a "LiteShaderMaterial" which would hold a pointer to the shared ShaderMaterial + only the specific uniforms for my mesh. Note that my question is related to this one Many meshes with the same geometry and material, can I change their colors? but is still different, as I'm mostly concerned about the waste of resources - performance wise I don't think it would be a lot different between having multiple ShaderMaterial or a single one, as the engine should be smart enough to note that all materials have the same programs and don't resend them to the gfx card. Thanks

Original source

Related problems