1 | ( function () {
|
2 |
|
3 | |
4 |
|
5 |
|
6 |
|
7 | class BokehPass extends THREE.Pass {
|
8 |
|
9 | constructor( scene, camera, params ) {
|
10 |
|
11 | super();
|
12 | this.scene = scene;
|
13 | this.camera = camera;
|
14 | const focus = params.focus !== undefined ? params.focus : 1.0;
|
15 | const aspect = params.aspect !== undefined ? params.aspect : camera.aspect;
|
16 | const aperture = params.aperture !== undefined ? params.aperture : 0.025;
|
17 | const maxblur = params.maxblur !== undefined ? params.maxblur : 1.0;
|
18 |
|
19 | const width = params.width || window.innerWidth || 1;
|
20 | const height = params.height || window.innerHeight || 1;
|
21 | this.renderTargetDepth = new THREE.WebGLRenderTarget( width, height, {
|
22 | minFilter: THREE.NearestFilter,
|
23 | magFilter: THREE.NearestFilter
|
24 | } );
|
25 | this.renderTargetDepth.texture.name = 'BokehPass.depth';
|
26 |
|
27 | this.materialDepth = new THREE.MeshDepthMaterial();
|
28 | this.materialDepth.depthPacking = THREE.RGBADepthPacking;
|
29 | this.materialDepth.blending = THREE.NoBlending;
|
30 |
|
31 | if ( THREE.BokehShader === undefined ) {
|
32 |
|
33 | console.error( 'THREE.BokehPass relies on THREE.BokehShader' );
|
34 |
|
35 | }
|
36 |
|
37 | const bokehShader = THREE.BokehShader;
|
38 | const bokehUniforms = THREE.UniformsUtils.clone( bokehShader.uniforms );
|
39 | bokehUniforms[ 'tDepth' ].value = this.renderTargetDepth.texture;
|
40 | bokehUniforms[ 'focus' ].value = focus;
|
41 | bokehUniforms[ 'aspect' ].value = aspect;
|
42 | bokehUniforms[ 'aperture' ].value = aperture;
|
43 | bokehUniforms[ 'maxblur' ].value = maxblur;
|
44 | bokehUniforms[ 'nearClip' ].value = camera.near;
|
45 | bokehUniforms[ 'farClip' ].value = camera.far;
|
46 | this.materialBokeh = new THREE.ShaderMaterial( {
|
47 | defines: Object.assign( {}, bokehShader.defines ),
|
48 | uniforms: bokehUniforms,
|
49 | vertexShader: bokehShader.vertexShader,
|
50 | fragmentShader: bokehShader.fragmentShader
|
51 | } );
|
52 | this.uniforms = bokehUniforms;
|
53 | this.needsSwap = false;
|
54 | this.fsQuad = new THREE.FullScreenQuad( this.materialBokeh );
|
55 | this._oldClearColor = new THREE.Color();
|
56 |
|
57 | }
|
58 |
|
59 | render( renderer, writeBuffer, readBuffer
|
60 |
|
61 | ) {
|
62 |
|
63 |
|
64 | this.scene.overrideMaterial = this.materialDepth;
|
65 | renderer.getClearColor( this._oldClearColor );
|
66 | const oldClearAlpha = renderer.getClearAlpha();
|
67 | const oldAutoClear = renderer.autoClear;
|
68 | renderer.autoClear = false;
|
69 | renderer.setClearColor( 0xffffff );
|
70 | renderer.setClearAlpha( 1.0 );
|
71 | renderer.setRenderTarget( this.renderTargetDepth );
|
72 | renderer.clear();
|
73 | renderer.render( this.scene, this.camera );
|
74 |
|
75 | this.uniforms[ 'tColor' ].value = readBuffer.texture;
|
76 | this.uniforms[ 'nearClip' ].value = this.camera.near;
|
77 | this.uniforms[ 'farClip' ].value = this.camera.far;
|
78 |
|
79 | if ( this.renderToScreen ) {
|
80 |
|
81 | renderer.setRenderTarget( null );
|
82 | this.fsQuad.render( renderer );
|
83 |
|
84 | } else {
|
85 |
|
86 | renderer.setRenderTarget( writeBuffer );
|
87 | renderer.clear();
|
88 | this.fsQuad.render( renderer );
|
89 |
|
90 | }
|
91 |
|
92 | this.scene.overrideMaterial = null;
|
93 | renderer.setClearColor( this._oldClearColor );
|
94 | renderer.setClearAlpha( oldClearAlpha );
|
95 | renderer.autoClear = oldAutoClear;
|
96 |
|
97 | }
|
98 |
|
99 | }
|
100 |
|
101 | THREE.BokehPass = BokehPass;
|
102 |
|
103 | } )();
|