diff --git a/src/renderers/TransmissionUtils.js b/src/renderers/TransmissionUtils.js new file mode 100644 index 00000000000000..dcd6f84fa75571 --- /dev/null +++ b/src/renderers/TransmissionUtils.js @@ -0,0 +1,71 @@ +import { CustomBlending } from '../constants.js'; +import { PlaneGeometry } from '../geometries/PlaneGeometry.js'; +import { ShaderMaterial } from '../materials/ShaderMaterial.js'; +import { Mesh } from '../objects/Mesh.js'; + +class CopyColorDepthMaterial extends ShaderMaterial { + + set map( v ) { + + this.uniforms.map.value = v; + + } + + set depthMap( v ) { + + this.uniforms.depthMap.value = v; + + } + + constructor() { + + super( { + + name: 'CopyColorDepthMaterial', + blending: CustomBlending, + + uniforms: { + + 'map': { value: null }, + 'depthMap': { value: null } + + }, + + vertexShader: /* glsl */` + + varying vec2 vUv; + + void main() { + + vUv = uv; + gl_Position = vec4( position.xy, 1.0, 1.0 ); + + } + + `, + + fragmentShader: /* glsl */` + + uniform sampler2D map; + uniform sampler2D depthMap; + + varying vec2 vUv; + + void main() { + + gl_FragColor = texture2D( map, vUv ); + gl_FragDepth = texture2D( depthMap, vUv ).r; + + #include + #include + + } + ` + + } ); + + } + +} + +export const transmissionMesh = new Mesh( new PlaneGeometry( 2, 2 ), new CopyColorDepthMaterial() ); diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index a7a25f0bf195ab..0e5ba0ec295328 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -56,6 +56,8 @@ import { WebGLMaterials } from './webgl/WebGLMaterials.js'; import { WebGLUniformsGroups } from './webgl/WebGLUniformsGroups.js'; import { createCanvasElement, probeAsync } from '../utils.js'; import { ColorManagement } from '../math/ColorManagement.js'; +import { transmissionMesh } from './TransmissionUtils.js'; +import { DepthTexture } from '../textures/DepthTexture.js'; class WebGLRenderer { @@ -1243,6 +1245,19 @@ class WebGLRenderer { if ( _renderBackground ) background.render( scene ); + const transmissionRenderTarget = currentRenderState.state.transmissionRenderTarget[ camera.id ]; + if ( transmissiveObjects.length > 0 ) { + + currentRenderList.opaque.length = 0; + + const geometry = objects.update( transmissionMesh ); + const material = transmissionMesh.material; + material.map = transmissionRenderTarget.texture; + material.depthMap = transmissionRenderTarget.depthTexture; + renderObject( transmissionMesh, scene, camera, geometry, material, null ); + + } + renderScene( currentRenderList, scene, camera ); } @@ -1457,9 +1472,9 @@ class WebGLRenderer { minFilter: LinearMipmapLinearFilter, samples: 4, stencilBuffer: stencil, - resolveDepthBuffer: false, resolveStencilBuffer: false, colorSpace: ColorManagement.workingColorSpace, + depthTexture: new DepthTexture(), } ); // debug