Dear Three.js community,
I am encountering an issue where a transmission material reflects its own geometry when side: THREE.DoubleSide
is used. Here’s the relevant part of my material configuration:
roughnessMap: environmentTexture,
roughness: .1,
transmission: 1,
ior: 1.33,
thickness: 2.5,
side: THREE.DoubleSide,
This setup causes the object to reflect itself, which is not the desired effect.
I’ve consulted GPT, and it suggested using a technique called “Dual Depth Peeling”. I’ve also looked at the rendering part of the meshTransmissionMaterial
example in drei-vanilla, which seems to render the front and back faces separately before combining them (though I don’t fully understand the specifics).
Could anyone please advise on a better way to prevent a transmission material from self-reflecting when using DoubleSide
, either by improving upon the meshTransmissionMaterial
approach or suggesting an alternative technique?
// runs on every frame
animateLoop((time: number) => {
meshTransmissionMaterial.time = time * 0.001
for (const mesh of transmissionMeshes) {
if (meshTransmissionMaterial.buffer === fboMain.texture) {
// Save defaults
oldTone = state.gl.toneMapping
oldBg = state.scene.background
oldSide = mesh.material.side
// Switch off tonemapping lest it double tone maps
// Save the current background and set the HDR as the new BG
// Use discardMaterial, the parent will be invisible, but it's shadows will still be cast
state.gl.toneMapping = THREE.NoToneMapping
mesh.material = discardMaterial
if (mtmParams.backside) {
// Render into the backside buffer
state.gl.setRenderTarget(fboBack)
state.gl.render(state.scene, state.camera)
// And now prepare the material for the main render using the backside buffer
mesh.material = meshTransmissionMaterial
mesh.material.buffer = fboBack.texture
mesh.material.thickness = mtmParams.backsideThickness
mesh.material.side = THREE.BackSide
}
// Render into the main buffer
state.gl.setRenderTarget(fboMain)
state.gl.render(state.scene, state.camera)
mesh.material = meshTransmissionMaterial
mesh.material.thickness = mtmParams.thickness
mesh.material.side = oldSide
mesh.material.buffer = fboMain.texture
// Set old state back
state.scene.background = oldBg
state.gl.setRenderTarget(null)
state.gl.toneMapping = oldTone
}
}
})