Think of my question as a more complicated version of this question here:
Three.js, sharing ShaderMaterial between meshes but with different uniform sets
tl;dr: I'm relying on a skin shader from THREE.js r100 to enable subsurface scattering on the meshes to make them appear more realistic but only one of them actually has the proper postprocessing to enable the effects.
The postprocessing effect is desired on all three meshes but only exists on one, the center. You can tell because the lighting looks right, and you can see where light travels "through" the mesh in thinner areas, like on the bottom part of the neck area and the ears (and if you get reaaaallly close it's in the nose too :D ).
Where the code is hosted has some wild things going on to generate the mesh, but that's beside the point, the main problem that I'm having is what you can see, only the center mesh (the one that was first added to the scene) actually has the proper effects applied to its material, the others have cloned versions of that shader but they don't render with the proper post-processing, I have a feeling it's because they're sharing uniforms or something related to that, but I'm not sure how to duplicate it properly. I was wondering how I can fix it? Do I add more render passes?
Is the way to adjust the render passes for the shader materials by adding even more passes relevant to the materials or just merely editing the uniforms (as stated in the linked question)?
I'm a bit lost and I've tried a lot to get this to work (though I'm definitely new to THREE.js post-processing passes), but you're my last hope. To someone experienced with this I feel like the solution will be very straightforward, I have a feeling I'm missing something very basic.
to view the output: https://abrasive-likeable-gateway.glitch.me/index-shader.html
to view the code: https://glitch.com/edit/#!/abrasive-likeable-gateway?path=index-shader.html%3A655%3A0
the filesystem is visible on the left side, you can remix the project on glitch (w/ a free account) to edit the code. I would've used codepen but I didn't want to deal with linking all of the three.js dependencies.
at index-shader.html on line 655 is where the setup begins for postprocessing
and at SS-xfer-placement.js on line 2838 is where rendering happens
in the same document, between lines 1900 - 2048 is the following code, which I suspect is where things are wrong, it looks like this, and imports the mesh, adds a material to it (that was set up in the html file after line 655) and adds it to the scene
the code looks like this:
setTimeout(()=>{
updateFaceParams()
setTimeout(()=>{
console.log(scene)
//send the model from ONE to THREE, init THREE
// document.querySelector("#ONEJS").style.height = "10vh!important;"
// document.querySelector("#ONEJS").style.width = "10vw!important;"
document.querySelector("#ONEJS").style.position = `absolute`
document.querySelector("#ONEJS").style.top = `0px`
document.querySelector("#ONEJS").style.right = `0px`
initTHREE();
let materialClone = window.THREEmaterial.clone()
var facePortion = scene.getObjectByName("face").geometry
console.log("FACE", scene.getObjectByName("face"))
var geometryConvert = convertGeometryToFiveBufferGeometry(facePortion)
var transferMesh = new THREE.Mesh( geometryConvert, window.THREEmaterial );
transferMesh.position.y = - 50;
transferMesh.rotation.y=3*Math.PI
// transferMesh.scale.set( scale, scale, scale );
transferMesh.scale.set(200,200,200)
transferMesh.doubleSided = true;
// console.log(transferMesh)
transferMesh.name = "face"
transferMesh.rotateY(Math.PI/180 * 180);
transferMesh.material.flatShading = false
transferMesh.material.shading = THREE.SmoothShading
THREEscene.add( transferMesh );
// console.log("test",transferMesh)
// console.log(THREEscene)
//
}, 1000)
setTimeout(()=>{
updateFaceParams()
setTimeout(()=>{
var facePortion = scene.getObjectByName("face").geometry
console.log("FACE", scene.getObjectByName("face"))
var geometryConvert = convertGeometryToFiveBufferGeometry(facePortion)
var transferMesh = new THREE.Mesh( geometryConvert, window.THREEmaterial.clone() );
transferMesh.position.y = - 50;
transferMesh.rotation.y=3*Math.PI
// transferMesh.scale.set( scale, scale, scale );
transferMesh.scale.set(200,200,200)
transferMesh.doubleSided = true;
// console.log(transferMesh)
transferMesh.name = "face"
transferMesh.rotateY(Math.PI/180 * 180);
transferMesh.material.flatShading = false
transferMesh.material.shading = THREE.SmoothShading
transferMesh.position.set(transferMesh.position.x+200, transferMesh.position.y, transferMesh.position.z)
THREEscene.add( transferMesh );
var THREErenderModelUV = new THREE.RenderPass( THREEscene,THREEcamera, window.THREEmaterialUV.clone(), new THREE.Color( 0x575757 ) );
THREEcomposer.addPass( THREErenderModelUV );
//TODO: write a stack overflow question about copying shaders!!!
setTimeout(()=>{
updateFaceParams()
setTimeout(()=>{
var facePortion = scene.getObjectByName("face").geometry
console.log("FACE", scene.getObjectByName("face"))
var geometryConvert = convertGeometryToFiveBufferGeometry(facePortion)
var transferMesh = new THREE.Mesh( geometryConvert, window.THREEmaterial.clone() );
// \var transferMesh = new THREE.Mesh( geometryConvert, new THREE.MeshPhongMaterial({color:0xffffff}) );
transferMesh.position.y = - 50;
transferMesh.rotation.y=3*Math.PI
// transferMesh.scale.set( scale, scale, scale );
transferMesh.scale.set(200,200,200)
transferMesh.doubleSided = true;
// console.log(transferMesh)
transferMesh.name = "face"
transferMesh.rotateY(Math.PI/180 * 180);
transferMesh.material.flatShading = false
transferMesh.material.shading = THREE.SmoothShading
transferMesh.position.set(transferMesh.position.x-200, transferMesh.position.y, transferMesh.position.z)
THREEscene.add( transferMesh );
// var THREErenderModelUV = new THREE.RenderPass( THREEscene,THREEcamera, window.THREEmaterialUV.clone(), new THREE.Color( 0x575757 ) );
// THREEcomposer.addPass( THREErenderModelUV );
var THREErenderModelUV = new THREE.RenderPass( THREEscene,THREEcamera, THREEmaterialUV.clone(), new THREE.Color( 0x575757 ) );
// var THREEeffectCopy = new THREE.ShaderPass( THREE.CopyShader );
// var THREEeffectBloom1 = new THREE.BloomPass( 1, 15, 2, 512 );
// var THREEeffectBloom2 = new THREE.BloomPass( 1, 25, 3, 512 );
// var THREEeffectBloom3 = new THREE.BloomPass( 1, 25, 4, 512 );
// THREEeffectBloom1.clear = true;
// THREEeffectBloom2.clear = true;
// THREEeffectBloom3.clear = true;
// THREEeffectCopy.renderToScreen = true;
// //
// var THREEpars = {
// generateMipmaps: true,
// minFilter: THREE.LinearMipmapLinearFilter,
// magFilter: THREE.LinearFilter,
// format: THREE.RGBFormat,
// stencilBuffer: false
// };
// var THREErtwidth = 512;
// var THREErtheight = 512;
//
// THREEcomposer = new THREE.EffectComposer( THREErenderer, new THREE.WebGLRenderTarget( THREErtwidth, THREErtheight, THREEpars ) );
THREEcomposer.addPass( THREErenderModelUV );
console.log(THREEcomposer)
}, 2000)
}, 2000)
}, 2000)
}, 2000)
},1000)
in other areas of the project, I wouldn't recommend looking at since it's really not relevant to this issue, the points that I highlighted are the only areas that deal with rendering, adding the mesh, and applying postprocessing.
the uniforms for the material are set up in the html file "index-shader.html" between lines 655 and 700 which may also be where I'd need to duplicate the uniforms and apply them properly, but I can't seem to figure out how to do that.
Please let me know if you have any help, thank you for reading!