Say i have something like:
//some chunks i want to override for functionality FOO
const myNormalChunks = {
beginnormal_vertex,
defaultnormal_vertex,
normalmap_pars_fragment,
}
//a version of `MeshStandardMaterial` that does FOO instead of default
class StandardMaterialWithFOO extends THREE.MeshStandardMaterial{
constructor(params){
super(params)
this.onBeforeCompile = shader=> { /*replace chunks by name*/ }
}
}
Now i can use the FOO version of the material. But what if i want to add another version of the MeshStandardMaterial
that does both FOO and BAR?
const BAR_onBeforeCompile = shader => {
/* 1. replace another chunk */
/* 2. add something after beginnormal_vertex */
}
class ShaderMaterialWithFOOandBAR extends StandardMaterialWithFOO {
constructor(params){
super(params)
this.onBeforeCompile = /* ??? */
}
}
- i’m kinda thinking it is possible through some hacking to pipe these callbacks
- this wouldn’t work though, because there is no
#include <some_chunk>
after the firstonBeforeCompile
processes it, and i have no way of knowing what it got replaced with.
The only thing i can think of tackling this is by having some super global like GLSL code with every possible permutation controlled by #ifdef
? But i would prefer not to modify the THREE.ShaderChunk
object globally.
someChunk = `
#ifdef isFOO
/* logic */
#endif
#ifdef isBAR
/* logic */
#endif
`
^ this seems somewhat tedious and prone to error though.
Also having something like:
const mySuperUberOneSizeFitAllOnBeforeCompile = shader =>{
if( isBAR ) {...}
if( isFOO ) {...}
}
Does not work because three.js has a caching mechanism that ignores these conditions. Say if I had 10 materials using this same callback, they would all compile as a single one, randomly selected from that list.
Any advice, ideas?