From e81d6ae79b9c0dc334ab930447929c96440320a0 Mon Sep 17 00:00:00 2001 From: Ingun Jon Date: Sat, 11 Jun 2022 10:10:50 +0900 Subject: [PATCH 1/7] depthpeeling example --- examples/files.json | 3 +- examples/webgl_depth_peeling.html | 333 ++++++++++++++++++++++++++++++ 2 files changed, 335 insertions(+), 1 deletion(-) create mode 100644 examples/webgl_depth_peeling.html diff --git a/examples/files.json b/examples/files.json index 0be062a5ee4388..aac794802e2415 100644 --- a/examples/files.json +++ b/examples/files.json @@ -223,7 +223,8 @@ "webgl_video_kinect", "webgl_video_panorama_equirectangular", "webgl_water", - "webgl_water_flowmap" + "webgl_water_flowmap", + "webgl_depth_peeling" ], "webgl / nodes": [ "webgl_materials_instance_uniform_nodes", diff --git a/examples/webgl_depth_peeling.html b/examples/webgl_depth_peeling.html new file mode 100644 index 00000000000000..de96cba1ad1b30 --- /dev/null +++ b/examples/webgl_depth_peeling.html @@ -0,0 +1,333 @@ + + + + three.js webgl - geometry - cube + + + + + + + + + + + + + + + From 177016f1cbd5cbf4f8c851b005f46e1e46b70ae5 Mon Sep 17 00:00:00 2001 From: Ingun Jon Date: Sat, 11 Jun 2022 10:16:10 +0900 Subject: [PATCH 2/7] ok I just realized a problem it gets darker as depth grows --- examples/webgl_depth_peeling.html | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/webgl_depth_peeling.html b/examples/webgl_depth_peeling.html index de96cba1ad1b30..8ddf834a9690e5 100644 --- a/examples/webgl_depth_peeling.html +++ b/examples/webgl_depth_peeling.html @@ -235,7 +235,7 @@ Depth: 3, }; init(); - function init() { + async function init() { const renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); @@ -281,7 +281,7 @@ ) ); - const texture = new THREE.TextureLoader().load( + const texture = await new THREE.TextureLoader().loadAsync( 'textures/sprite0.png' ); const plane = new THREE.Mesh( @@ -323,8 +323,13 @@ animate(); const gui = new GUI(); - gui.add( AppState, 'Enabled' ); - gui.add( AppState, 'Depth' ).min( 1 ).max( 5 ).step( 1 ); + gui.add( AppState, 'Enabled' ).onChange( animate ); + gui.add( AppState, 'Depth' ).min( 1 ).max( 5 ).step( 1 ).onChange( v => { + + dp.setDepth( v ); + animate(); + + } ); } From 8052bf3c73f5e48df3f095e41d73f5efe40a491f Mon Sep 17 00:00:00 2001 From: Ingun Jon Date: Sun, 12 Jun 2022 13:13:49 +0900 Subject: [PATCH 3/7] use over composite --- examples/webgl_depth_peeling.html | 170 ++++++++++++------------------ 1 file changed, 68 insertions(+), 102 deletions(-) diff --git a/examples/webgl_depth_peeling.html b/examples/webgl_depth_peeling.html index 8ddf834a9690e5..269d396e39d0b0 100644 --- a/examples/webgl_depth_peeling.html +++ b/examples/webgl_depth_peeling.html @@ -25,40 +25,23 @@ import * as THREE from 'three'; import { OrbitControls } from './jsm/controls/OrbitControls.js'; import { FullScreenQuad } from './jsm/postprocessing/Pass.js'; + import { CopyShader } from './jsm/shaders/CopyShader.js'; import { GUI } from './jsm/libs/lil-gui.module.min.js'; - export class DepthPeeling { + class DepthPeeling { globalUniforms; - underCompositeMaterial = new THREE.ShaderMaterial( { - vertexShader: ` - varying vec2 vUv; - void main() { - vUv = uv; - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); - }`, - fragmentShader: ` - uniform sampler2D tDst; - uniform sampler2D tSrc; - varying vec2 vUv; - void main() { - vec4 d = texture2D(tDst, vUv); - vec4 s = texture2D(tSrc, vUv); - vec3 c = d.a * d.xyz + (1.-d.a)*s.a*s.xyz; - float a = s.a - s.a*d.a + d.a; - gl_FragColor = vec4(c, a); - // gl_FragColor = s; - }`, - uniforms: { - tDst: { value: null }, - tSrc: { value: null }, - }, - } ); - ping; - pong; - depth; + layers = []; + depth = 3; one = new THREE.DataTexture( new Uint8Array( [ 1, 1, 1, 1 ] ), 1, 1 ); - quad = new FullScreenQuad( this.underCompositeMaterial ); + quad = new FullScreenQuad( + new THREE.ShaderMaterial( { + ...CopyShader, + transparent: true, + depthTest: false, + depthWrite: false, + } ) + ); screenSize = new THREE.Vector2(); originalClearColor = new THREE.Color(); ownScene = new THREE.Scene(); @@ -70,17 +53,10 @@ uReciprocalScreenSize: { value: new THREE.Vector2( 1, 1 ) }, }; - const makeRenderTargetTuple = () => [ - new THREE.WebGLRenderTarget( p.width, p.height, { - depthTexture: new THREE.DepthTexture( p.width, p.height ), - } ), - new THREE.WebGLRenderTarget( p.width, p.height ), - ]; - this.ping = makeRenderTargetTuple(); - this.pong = makeRenderTargetTuple(); - this.depth = p.depth; + this.setScreenSize( p.width, p.height ); + this.setDepth( p.depth ); - } + } add( sceneGraph ) { @@ -125,23 +101,21 @@ } - } ); + } ); this.ownScene.add( clonedScene ); - } + } - render( - renderer, - camera, - renderTarget - ) { + render( renderer, camera ) { const originalRenderTarget = renderer.getRenderTarget(); + const originalAutoClear = renderer.autoClear; + renderer.autoClear = false; renderer.getSize( this.screenSize ); if ( - this.screenSize.width !== this.ping[ 0 ].width || - this.screenSize.height !== this.ping[ 0 ].height + this.screenSize.width !== this.layers[ 0 ].width || + this.screenSize.height !== this.layers[ 0 ].height ) this.setScreenSize( this.screenSize.width, this.screenSize.height ); const width = this.screenSize.width; @@ -151,78 +125,69 @@ 1 / height ); - const [ layerA, compositeA ] = this.ping; - const [ layerB, compositeB ] = this.pong; renderer.getClearColor( this.originalClearColor ); - renderer.setClearColor( 0x000000, 0 ); - renderer.setRenderTarget( layerA ); - renderer.clear(); - renderer.setRenderTarget( compositeA ); - renderer.clear(); + renderer.setClearColor( 0x000000 ); - const [ , finalComposite ] = new Array( this.depth ).fill( 0 ).reduce( - ( - [ prevDepth, prevComposite ], - _, - idx - ) => { - - const otherLayer = prevDepth === layerA ? layerB : layerA; - const otherComposite = - prevComposite === compositeA ? compositeB : compositeA; - this.globalUniforms.uPrevDepthTexture.value = - idx === 0 ? this.one : prevDepth.depthTexture; - renderer.setRenderTarget( otherLayer ); - renderer.clear(); - renderer.render( this.ownScene, camera ); - - renderer.setRenderTarget( - idx < this.depth - 1 - ? otherComposite // If it's not the final step then proceed ping-ponging - : renderTarget // If it's the final step, and if renderTarget is given, - ? renderTarget // ... then render to the given render Target - : renderTarget === undefined // if render targen is undefined, - ? otherComposite // ... then keep ping-ponging - : null // or render to the main frame buffer - ); - renderer.clear(); - this.underCompositeMaterial.uniforms.tDst.value = prevComposite.texture; - this.underCompositeMaterial.uniforms.tSrc.value = otherLayer.texture; - this.underCompositeMaterial.uniformsNeedUpdate = true; - this.quad.render( renderer ); - return [ otherLayer, otherComposite ]; - - }, - [ layerA, compositeA ] - ); + this.layers.reduceRight( ( prevDepth, layer ) => { + + this.globalUniforms.uPrevDepthTexture.value = prevDepth; + renderer.setRenderTarget( layer ); + renderer.clear(); + renderer.render( this.ownScene, camera ); + return layer.depthTexture; + + }, this.one ); renderer.setRenderTarget( originalRenderTarget ); + renderer.setClearColor( this.originalClearColor ); + renderer.clear(); - return finalComposite; + for ( const layer of this.layers ) { - } + this.quad.material.uniforms.tDiffuse.value = + layer.texture; + this.quad.material.needsUpdate = true; + this.quad.render( renderer ); + + } + + renderer.autoClear = originalAutoClear; + + } getDepth() { return this.depth; - } + } setDepth( depth ) { + while ( depth < this.layers.length ) this.layers.pop()?.dispose(); + + while ( this.layers.length < depth ) + this.layers.push( + new THREE.WebGLRenderTarget( this.screenSize.width, this.screenSize.height, { + depthTexture: new THREE.DepthTexture( + this.screenSize.width, + this.screenSize.height + ), + } ) + ); + this.depth = depth; - } + } setScreenSize( width, height ) { - ( this.globalUniforms.uReciprocalScreenSize.value ).set( + this.globalUniforms.uReciprocalScreenSize.value.set( 1 / width, 1 / height ); - [ this.ping, this.pong ].forEach( ( [ rtWithDepth, rtWithoutDepth ] ) => { - rtWithDepth.setSize( width, height ); - rtWithoutDepth.setSize( width, height ); - rtWithDepth.depthTexture.dispose(); - rtWithDepth.depthTexture = new THREE.DepthTexture( width, height ); + this.layers.forEach( ( rt ) => { + + rt.setSize( width, height ); + rt.depthTexture.dispose(); + rt.depthTexture = new THREE.DepthTexture( width, height ); } ); @@ -230,6 +195,7 @@ } + const AppState = { Enabled: true, Depth: 3, @@ -238,7 +204,7 @@ async function init() { const renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio( window.devicePixelRatio ); + // renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); @@ -311,7 +277,7 @@ dp.add( scene ); const animate = () => requestAnimationFrame( () => - AppState.Enabled ? dp.render( renderer, camera, null ) : renderer.render( scene, camera ) + AppState.Enabled ? dp.render( renderer, camera ) : renderer.render( scene, camera ) ); From 5267480adb569aa45ff69c192ea5288c55972187 Mon Sep 17 00:00:00 2001 From: Ingun Jon Date: Sun, 12 Jun 2022 16:23:17 +0900 Subject: [PATCH 4/7] pixel ratio --- examples/webgl_depth_peeling.html | 63 +++++++++++++------------------ 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/examples/webgl_depth_peeling.html b/examples/webgl_depth_peeling.html index 269d396e39d0b0..c99443027d6a6a 100644 --- a/examples/webgl_depth_peeling.html +++ b/examples/webgl_depth_peeling.html @@ -28,9 +28,13 @@ import { CopyShader } from './jsm/shaders/CopyShader.js'; import { GUI } from './jsm/libs/lil-gui.module.min.js'; - class DepthPeeling { + export class DepthPeeling { + + globalUniforms = { + uPrevDepthTexture: { value: null }, + uReciprocalScreenSize: { value: new THREE.Vector2( 1, 1 ) }, + }; - globalUniforms; layers = []; depth = 3; one = new THREE.DataTexture( new Uint8Array( [ 1, 1, 1, 1 ] ), 1, 1 ); @@ -43,17 +47,12 @@ } ) ); screenSize = new THREE.Vector2(); + pixelRatio = 1; originalClearColor = new THREE.Color(); ownScene = new THREE.Scene(); constructor( p ) { - this.globalUniforms = { - uPrevDepthTexture: { value: null }, - uPrevColorTexture: { value: null }, - uReciprocalScreenSize: { value: new THREE.Vector2( 1, 1 ) }, - }; - - this.setScreenSize( p.width, p.height ); + this.setScreenSize( p.width, p.height, p.pixelRatio ); this.setDepth( p.depth ); } @@ -87,7 +86,7 @@ // --- DEPTH PEELING SHADER CHUNK (START) (peeling) vec2 screenPos = gl_FragCoord.xy * uReciprocalScreenSize; float prevDepth = texture2D(uPrevDepthTexture,screenPos).x; - if( prevDepth + 0.00001 >= gl_FragCoord.z ) + if( prevDepth >= gl_FragCoord.z ) discard; // --- DEPTH PEELING SHADER CHUNK (END) } @@ -111,19 +110,6 @@ const originalRenderTarget = renderer.getRenderTarget(); const originalAutoClear = renderer.autoClear; renderer.autoClear = false; - renderer.getSize( this.screenSize ); - - if ( - this.screenSize.width !== this.layers[ 0 ].width || - this.screenSize.height !== this.layers[ 0 ].height - ) - this.setScreenSize( this.screenSize.width, this.screenSize.height ); - const width = this.screenSize.width; - const height = this.screenSize.height; - this.globalUniforms.uReciprocalScreenSize.value = new THREE.Vector2( - 1 / width, - 1 / height - ); renderer.getClearColor( this.originalClearColor ); renderer.setClearColor( 0x000000 ); @@ -163,39 +149,44 @@ while ( depth < this.layers.length ) this.layers.pop()?.dispose(); + const w = this.screenSize.width * this.pixelRatio; + const h = this.screenSize.height * this.pixelRatio; while ( this.layers.length < depth ) this.layers.push( - new THREE.WebGLRenderTarget( this.screenSize.width, this.screenSize.height, { - depthTexture: new THREE.DepthTexture( - this.screenSize.width, - this.screenSize.height - ), + new THREE.WebGLRenderTarget( w, h, { + depthTexture: new THREE.DepthTexture( w, h ), + // samples: 2, } ) ); this.depth = depth; } - setScreenSize( width, height ) { + setScreenSize( width, height, pixelRatio ) { + this.screenSize.set( width, height ); + this.pixelRatio = pixelRatio; + const w = width * pixelRatio; + const h = height * pixelRatio; this.globalUniforms.uReciprocalScreenSize.value.set( - 1 / width, - 1 / height + 1 / w, + 1 / h ); this.layers.forEach( ( rt ) => { - rt.setSize( width, height ); + rt.setSize( w, h ); rt.depthTexture.dispose(); - rt.depthTexture = new THREE.DepthTexture( width, height ); + rt.depthTexture = new THREE.DepthTexture( w, h ); } ); - } + } } + const AppState = { Enabled: true, Depth: 3, @@ -204,7 +195,7 @@ async function init() { const renderer = new THREE.WebGLRenderer(); - // renderer.setPixelRatio( window.devicePixelRatio ); + renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); @@ -273,7 +264,7 @@ .rotateY( - 2 * Math.PI * ( 1 / 10 ) ); scene.add( plane2 ); - const dp = new DepthPeeling( { depth: AppState.Depth, width: window.innerWidth, height: window.innerHeight } ); + const dp = new DepthPeeling( { depth: AppState.Depth, width: window.innerWidth, height: window.innerHeight, pixelRatio: renderer.getPixelRatio() } ); dp.add( scene ); const animate = () => requestAnimationFrame( () => From 95d6fe3f487acd724d50b992d37927916b4065f8 Mon Sep 17 00:00:00 2001 From: Ingun Jon Date: Sun, 12 Jun 2022 16:26:08 +0900 Subject: [PATCH 5/7] depth peeling make screenshiot --- examples/screenshots/webgl_depth_peeling.jpg | Bin 0 -> 14705 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/screenshots/webgl_depth_peeling.jpg diff --git a/examples/screenshots/webgl_depth_peeling.jpg b/examples/screenshots/webgl_depth_peeling.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0f712b651952cbd6637624155cf3720425310b7a GIT binary patch literal 14705 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 Avj6}9 literal 0 HcmV?d00001 From 8375e211fc4f0d12d8059ac35d5a7d2ad7eb71b8 Mon Sep 17 00:00:00 2001 From: Ingun Jon Date: Sun, 12 Jun 2022 16:30:09 +0900 Subject: [PATCH 6/7] window resizing --- examples/webgl_depth_peeling.html | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/webgl_depth_peeling.html b/examples/webgl_depth_peeling.html index c99443027d6a6a..640c06fda6e096 100644 --- a/examples/webgl_depth_peeling.html +++ b/examples/webgl_depth_peeling.html @@ -288,6 +288,16 @@ } ); + window.addEventListener( 'resize', () => { + + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + + renderer.setSize( window.innerWidth, window.innerHeight ); + dp.setScreenSize( window.innerWidth, window.innerHeight, renderer.getPixelRatio() ); + + } ); + } From 3b175dfddbcfa493863c6c794d61f24cb42f2513 Mon Sep 17 00:00:00 2001 From: Ingun Jon Date: Tue, 14 Jun 2022 08:05:38 +0900 Subject: [PATCH 7/7] don't use DepthPeeling class --- examples/webgl_depth_peeling.html | 271 +++++++++++++----------------- 1 file changed, 119 insertions(+), 152 deletions(-) diff --git a/examples/webgl_depth_peeling.html b/examples/webgl_depth_peeling.html index 640c06fda6e096..a969b96e0e55af 100644 --- a/examples/webgl_depth_peeling.html +++ b/examples/webgl_depth_peeling.html @@ -28,180 +28,105 @@ import { CopyShader } from './jsm/shaders/CopyShader.js'; import { GUI } from './jsm/libs/lil-gui.module.min.js'; - export class DepthPeeling { - - globalUniforms = { - uPrevDepthTexture: { value: null }, - uReciprocalScreenSize: { value: new THREE.Vector2( 1, 1 ) }, - }; - - layers = []; - depth = 3; - one = new THREE.DataTexture( new Uint8Array( [ 1, 1, 1, 1 ] ), 1, 1 ); - quad = new FullScreenQuad( - new THREE.ShaderMaterial( { - ...CopyShader, - transparent: true, - depthTest: false, - depthWrite: false, - } ) - ); - screenSize = new THREE.Vector2(); - pixelRatio = 1; - originalClearColor = new THREE.Color(); - ownScene = new THREE.Scene(); - constructor( p ) { - - this.setScreenSize( p.width, p.height, p.pixelRatio ); - this.setDepth( p.depth ); - - } + const renderer = new THREE.WebGLRenderer(); + const scene = new THREE.Scene(); + const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); - add( sceneGraph ) { - - const clonedScene = sceneGraph.clone( true ); - clonedScene.traverse( ( obj ) => { + const globalUniforms = { + uPrevDepthTexture: { value: null }, + uReciprocalScreenSize: { value: new THREE.Vector2( 1, 1 ) }, + }; + const layers = []; + const one = new THREE.DataTexture( new Uint8Array( [ 1, 1, 1, 1 ] ), 1, 1 ); + const quad = new FullScreenQuad( + new THREE.ShaderMaterial( { + ...CopyShader, + transparent: true, + depthTest: false, + depthWrite: false, + } ) + ); + let depthPeelingScene = new THREE.Scene(); - if ( obj instanceof THREE.Mesh && obj.material instanceof THREE.Material ) { + const AppState = { + Enabled: true, + Depth: 3, + }; - const clonedMaterial = obj.material.clone(); - clonedMaterial.blending = THREE.NoBlending; - clonedMaterial.onBeforeCompile = ( shader ) => { + function resizeLayers( width, height, pixelRatio ) { - shader.uniforms.uReciprocalScreenSize = - this.globalUniforms.uReciprocalScreenSize; - shader.uniforms.uPrevDepthTexture = - this.globalUniforms.uPrevDepthTexture; - shader.fragmentShader = ` -// --- DEPTH PEELING SHADER CHUNK (START) (uniform definition) -uniform vec2 uReciprocalScreenSize; -uniform sampler2D uPrevDepthTexture; -// --- DEPTH PEELING SHADER CHUNK (END) - ${shader.fragmentShader} - `; - //peel depth - shader.fragmentShader = shader.fragmentShader.replace( - /}$/gm, - ` -// --- DEPTH PEELING SHADER CHUNK (START) (peeling) - vec2 screenPos = gl_FragCoord.xy * uReciprocalScreenSize; - float prevDepth = texture2D(uPrevDepthTexture,screenPos).x; - if( prevDepth >= gl_FragCoord.z ) - discard; -// --- DEPTH PEELING SHADER CHUNK (END) -} - ` - ); + const w = width * pixelRatio; + const h = height * pixelRatio; + globalUniforms.uReciprocalScreenSize.value.set( + 1 / w, + 1 / h + ); - }; + layers.forEach( ( rt ) => { - obj.material = clonedMaterial; - obj.material.needsUpdate = true; + rt.setSize( w, h ); + rt.depthTexture.dispose(); + rt.depthTexture = new THREE.DepthTexture( w, h ); - } + } ); - } ); - this.ownScene.add( clonedScene ); + } - } + function resizeDepth( width, height, pixelRatio, depth ) { - render( renderer, camera ) { + while ( depth < layers.length ) layers.pop()?.dispose(); - const originalRenderTarget = renderer.getRenderTarget(); - const originalAutoClear = renderer.autoClear; - renderer.autoClear = false; + const w = width * pixelRatio; + const h = height * pixelRatio; + while ( layers.length < depth ) + layers.push( + new THREE.WebGLRenderTarget( w, h, { + depthTexture: new THREE.DepthTexture( w, h ), + } ) + ); - renderer.getClearColor( this.originalClearColor ); - renderer.setClearColor( 0x000000 ); + } - this.layers.reduceRight( ( prevDepth, layer ) => { + function peelDepth( renderer, camera ) { - this.globalUniforms.uPrevDepthTexture.value = prevDepth; - renderer.setRenderTarget( layer ); - renderer.clear(); - renderer.render( this.ownScene, camera ); - return layer.depthTexture; + const originalRenderTarget = renderer.getRenderTarget(); + const originalAutoClear = renderer.autoClear; + renderer.autoClear = false; - }, this.one ); + layers.reduceRight( ( prevDepth, layer ) => { - renderer.setRenderTarget( originalRenderTarget ); - renderer.setClearColor( this.originalClearColor ); + globalUniforms.uPrevDepthTexture.value = prevDepth; + renderer.setRenderTarget( layer ); renderer.clear(); + renderer.render( depthPeelingScene, camera ); + return layer.depthTexture; - for ( const layer of this.layers ) { + }, one ); - this.quad.material.uniforms.tDiffuse.value = - layer.texture; - this.quad.material.needsUpdate = true; - this.quad.render( renderer ); + renderer.setRenderTarget( originalRenderTarget ); + renderer.clear(); - } + for ( const layer of layers ) { - renderer.autoClear = originalAutoClear; - - } - getDepth() { - - return this.depth; - - } - setDepth( depth ) { - - while ( depth < this.layers.length ) this.layers.pop()?.dispose(); - - const w = this.screenSize.width * this.pixelRatio; - const h = this.screenSize.height * this.pixelRatio; - while ( this.layers.length < depth ) - this.layers.push( - new THREE.WebGLRenderTarget( w, h, { - depthTexture: new THREE.DepthTexture( w, h ), - // samples: 2, - } ) - ); - - this.depth = depth; - - } - setScreenSize( width, height, pixelRatio ) { - - this.screenSize.set( width, height ); - this.pixelRatio = pixelRatio; - const w = width * pixelRatio; - const h = height * pixelRatio; - this.globalUniforms.uReciprocalScreenSize.value.set( - 1 / w, - 1 / h - ); + quad.material.uniforms.tDiffuse.value = + layer.texture; + quad.material.needsUpdate = true; + quad.render( renderer ); - this.layers.forEach( ( rt ) => { - - rt.setSize( w, h ); - rt.depthTexture.dispose(); - rt.depthTexture = new THREE.DepthTexture( w, h ); - - } ); + } - } + renderer.autoClear = originalAutoClear; } + init().then( animate ); - - const AppState = { - Enabled: true, - Depth: 3, - }; - init(); async function init() { - const renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); - const scene = new THREE.Scene(); - const width = window.innerWidth, height = window.innerHeight; - const camera = new THREE.PerspectiveCamera( 75, width / height, 0.1, 1000 ); camera.position.z = 5; renderer.shadowMap.enabled = true; @@ -264,26 +189,60 @@ .rotateY( - 2 * Math.PI * ( 1 / 10 ) ); scene.add( plane2 ); - const dp = new DepthPeeling( { depth: AppState.Depth, width: window.innerWidth, height: window.innerHeight, pixelRatio: renderer.getPixelRatio() } ); - dp.add( scene ); - const animate = () => - requestAnimationFrame( () => - AppState.Enabled ? dp.render( renderer, camera ) : renderer.render( scene, camera ) - ); + depthPeelingScene = scene.clone( true ); + + resizeLayers( window.innerWidth, window.innerHeight, renderer.getPixelRatio() ); + resizeDepth( window.innerWidth, window.innerHeight, renderer.getPixelRatio(), AppState.Depth ); + + depthPeelingScene.traverse( ( obj ) => { + + if ( obj instanceof THREE.Mesh && obj.material instanceof THREE.Material ) { + + const clonedMaterial = obj.material.clone(); + clonedMaterial.blending = THREE.NoBlending; + clonedMaterial.onBeforeCompile = ( shader ) => { + + shader.uniforms.uReciprocalScreenSize = globalUniforms.uReciprocalScreenSize; + shader.uniforms.uPrevDepthTexture = globalUniforms.uPrevDepthTexture; + shader.fragmentShader = ` +// --- DEPTH PEELING SHADER CHUNK (START) (uniform definition) +uniform vec2 uReciprocalScreenSize; +uniform sampler2D uPrevDepthTexture; +// --- DEPTH PEELING SHADER CHUNK (END) + ${shader.fragmentShader} + `; + //peel depth + shader.fragmentShader = shader.fragmentShader.replace( + /}$/gm, + ` +// --- DEPTH PEELING SHADER CHUNK (START) (peeling) + vec2 screenPos = gl_FragCoord.xy * uReciprocalScreenSize; + float prevDepth = texture2D(uPrevDepthTexture,screenPos).x; + if( prevDepth >= gl_FragCoord.z ) + discard; +// --- DEPTH PEELING SHADER CHUNK (END) +} + ` + ); + + }; + + obj.material = clonedMaterial; + obj.material.needsUpdate = true; + } + + } ); const orbit = new OrbitControls( camera, renderer.domElement ); orbit.update(); orbit.addEventListener( 'change', animate ); - - animate(); - const gui = new GUI(); gui.add( AppState, 'Enabled' ).onChange( animate ); gui.add( AppState, 'Depth' ).min( 1 ).max( 5 ).step( 1 ).onChange( v => { - dp.setDepth( v ); + resizeDepth( window.innerWidth, window.innerHeight, renderer.getPixelRatio(), v ); animate(); } ); @@ -294,12 +253,20 @@ camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); - dp.setScreenSize( window.innerWidth, window.innerHeight, renderer.getPixelRatio() ); + resizeLayers( window.innerWidth, window.innerHeight, renderer.getPixelRatio() ); + animate(); } ); } + function animate() { + + requestAnimationFrame( () => + AppState.Enabled ? peelDepth( renderer, camera ) : renderer.render( scene, camera ) + ); + + }