I’ve tried to subclass a THREE.StandardMaterial
//something like this not all the code
class BwMaterial extends THREE.StandardMaterial{
constructor(parameters){
super(parameters)
this.onBeforeCompile = shader=>{
shader.uniforms.uBWActive = {value: 0}
shader.fragmentShader = 'uniform float uBWActive;\n' + shader.fragmentShader
shader.fragmentShader = shader.fragmentShader.replace('}$', 'if(uBWActive == 1) { gl_FragColor.xyz = dot(vec3(1.),gl_FragColor.xyz);\n} }\n')
}
}
toggleBW(){
const { uBW } = this.userData.uniforms
uBW.value = uBW.value ? 0 : 1
}
The idea is to extends the StandardMaterial
with a flag that would override the color output with grayscale output. So i’m trying to use this:
https://threejs.org/docs/#api/materials/Material.onBeforeCompile
An optional callback that is executed immediately before the shader program is compiled. This function is called with the shader source code as a parameter. Useful for the modification of built-in materials.
So i am trying to modify a built in material.
myModifiedBuiltInMaterial = new BWMaterial({color:'red'})
//renders red
myModifiedBuiltInMaterial.toggleBW()
//renders grayscale
myCloneMaterial = myModifiedBuiltInMaterial.clone()
myCloneMaterial.color.set(0x00ff00)
//renders blue
myCloneMaterial.toggleBW()
//still renders blue
What am i doing wrong here? I would like to make a modified material and then be able to clone it.
Is this an invalid pattern, what would be three.js’s opinions on how to do this. I like subclassing Material
and Mesh
and such, but it doesn’t seem to like me doing this.
I’m confused with how .clone()
is supposed to work.
In computer science, cloning refers to the making of an exact copy of an object,
But this clone doesn’t seem to make an exact copy of an object.