/** * Depth-of-field post-process with bokeh shader */ THREE.BokehPass = function ( scene, camera, params ) { this.scene = scene; this.camera = camera; var focus = ( params.focus !== undefined ) ? params.focus : 1.0; var aspect = ( params.aspect !== undefined ) ? params.aspect : camera.aspect; var aperture = ( params.aperture !== undefined ) ? params.aperture : 0.025; var maxblur = ( params.maxblur !== undefined ) ? params.maxblur : 1.0; // render targets var width = params.width || window.innerWidth || 1; var height = params.height || window.innerHeight || 1; this.renderTargetColor = new THREE.WebGLRenderTarget( width, height, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat } ); this.renderTargetDepth = this.renderTargetColor.clone(); // depth material this.materialDepth = new THREE.MeshDepthMaterial(); // bokeh material if ( THREE.BokehShader === undefined ) { console.error( "THREE.BokehPass relies on THREE.BokehShader" ); } var bokehShader = THREE.BokehShader; var bokehUniforms = THREE.UniformsUtils.clone( bokehShader.uniforms ); bokehUniforms[ "tDepth" ].value = this.renderTargetDepth; bokehUniforms[ "focus" ].value = focus; bokehUniforms[ "aspect" ].value = aspect; bokehUniforms[ "aperture" ].value = aperture; bokehUniforms[ "maxblur" ].value = maxblur; this.materialBokeh = new THREE.ShaderMaterial({ uniforms: bokehUniforms, vertexShader: bokehShader.vertexShader, fragmentShader: bokehShader.fragmentShader }); this.uniforms = bokehUniforms; this.enabled = true; this.needsSwap = false; this.renderToScreen = false; this.clear = false; }; THREE.BokehPass.prototype = { render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { var composer = THREE.EffectComposer; composer.quad.material = this.materialBokeh; // Render depth into texture this.scene.overrideMaterial = this.materialDepth; renderer.render( this.scene, this.camera, this.renderTargetDepth, true ); // Render bokeh composite this.uniforms[ "tColor" ].value = readBuffer; if ( this.renderToScreen ) { renderer.render( composer.scene, composer.camera ); } else { renderer.render( composer.scene, composer.camera, writeBuffer, this.clear ); } this.scene.overrideMaterial = null; } };