Reuse compiled shader for material but different texture?

Is it possible to clone / instance a material so that the same shader is reused (and the material isn’t recompiled), but each mesh has a different texture set to it? I’m using PBRCustomMaterial.

Textures are properties of a material, so if you want to have different textures for different meshes, I think you will have to create different instances of the material, one for each different texture.

Right at the start of PBRBaseMaterial.isReadyForSubMesh you have:

        if (subMesh.effect && this.isFrozen) {
            if (this._wasPreviouslyReady) {
                return true;
            }
        }

So if you want to speed things up, you can call freeze() on your material to prevent the engine to recheck / rebuild the effect at each frame.

I don’t know about that, but you look like John Carmack, so maybe you can use some sort of MegaTexture and use uv ranges?

LOL.

@bnolan: has long as you only change the texture of a material, it is not recompiled

Reusing the same material and changing the texture for each mesh will still trigger a full run of isReadyForSubMesh I think, which is quite heavy for PBR materials.

If you want to maximize performance, you should have a different material for each mesh and call freeze() on them.

Ok, I worked out how to reuse the shader. The problem was that my custom shader material was being recompiled for every instance, but re-using the effect totally solved the problem.

Or moved things to a new problem anyway. Hah.

clone () {
  let m = new VoxelMaterial(this.scene)

  m['_prepareEffect'] = () => {
    return this['_activeEffect']
  }

  return m
}
1 Like

It should be interesting to understand why it was recompiled at some points
but anyway congrats :wink:

From now on I will make playground examples to demonstrate all these issues :sweat_smile:

1 Like