If I create a new material:
const baseMaterial = new BABYLON.PBRMaterial(newName, scene);
and define a customShaderName and processFinalCode in it:
baseMaterial.customShaderNameResolve = (...) => {
console.log('internal customShaderNameResolve called.')
options.processFinalCode = (type, code) => {
console.log('internal processFinalCode called.')
...
And then I call baseMaterial.forceCompilation(mesh, (material)...
The first time I do this, processFinalCode gets called. If I change the scene (like add a scene.environmentTexture and repeat this whole process, processFinalCode gets called again.
If I don’t modify anything in the scene, and call this process, customShaderNameResolve runs, but processFinalCode doesn’t.
In the playground I created, you can see this behavior by clicking “change texture” once, and note it adds an environment, and it logs Internally capturing vertex code. But if you click “change texture” again, it doesn’t log this. https://playground.babylonjs.com/#YPXI4C#142
Babylon is choosing not to recompile the shader, or at least not re-call processFinalCode. What I want to do here in this case is then return the cached GLSL for this material.
I tried looking in BABYLON.Effect.ShadersStore, the only key I see that might be it is defaultPixelShader, but this is not the cached GLSL, this is the unprocessed raw GLSL (like it has #include<__decl__defaultFragment> in it), so it’s not what’s being passed to the GPU for this material.
By the way, I also tried forcing a name change of the internal material by returning a unique name in customShaderNameResolve. But everything I try here fails. It tries to look up the effect in the shader store (I think) by the new name, but I don’t know the GLSL to put in the ShadersStore yet. I thought that if processFinalCode was present, it would ignore the ShadersStore entries. But in the playground you can see if you uncomment line 50, it makes a network call for the ShadersStore entries, but if I put anything in those entries, it also fails to compile.
So I’m trying to figure out, can I either:
- Force a compilation every time by changing the shader’s name in
customShaderNameResolve, or - Can I get the cached GLSL value of the material when it doesn’t compile? Is there some internal cache key I can read the GLSL from, or re-create the cache with the same key that Babylon uses internally? I can guess at it (like base it off the scene env, lights, etc) but I’m guessing Babylon has its own caching mechanism?