I was trying to update shader chunk on the script.
As seen the below code, I’ve changed the shader chunk with a custom shader and also called app-wide shader update.
let fs = this.shader.resource;
for (let i = 0; i < this.materials.length; i++) {
var material = this.materials[i].resource;
material.chunks.lightSpecularBlinnPS = fs;
material.update();
}
const library = this.app.graphicsDevice.getProgramLibrary();
let i, len;
for (i = 0, len = this.app.graphicsDevice.shaders.length; i < len; i++) {
const shader = this.app.graphicsDevice.shaders[i];
library.removeFromCache(shader);
}
this.app.scene.updateShaders = true;
Yeah, last time I had to do this, I made a script asset that is set the Loading Type to ‘After the Engine’ file and overrode the chunk in that so it is effectively a patch
Basically it needs to be done before any material using that chunk compiles its shader. That will happen as soon as any model using that material will start rendering.
A good place is After Engine as Yaustar shared above. Or another way we do often is add a script in the scene root entity (we don’t put render components usually there).
I’ve tried working with the clearVariants() pc.Material method and also clearShaders() on the referenced mesh instances, but that didn’t trigger any update on the material side.
It seems the logic in the engine has changed and the program library is used differently now?
I mean you could use a dirty old trick and temporary change a material property (e.g. reference a channel that you don’t use normally, e.g. add an emissive map). Just for a frame call update, afterwards remove it and call again.
Maybe @mvaligursky has an idea on how to properly do this (force recompile a material shader)?
After I attached the script to the root entity, I called the shader chunk update function initially.
As @Leonidas says, the shader of the material is updated.
Interesting part is once the shader chunk exist on the material, I can update it in realtime. @yaustar Is this expected behavior??
There is no expected behaviour here, as none of this is a public API. We could find some way to do this, but could you please provide the repro project with what you are trying to do? The implementation of this code in the engine is pretty complex, and I’m not sure we can provide suggestions without testing those to see what might work.