GODELEV commited on
Commit
a8fb436
·
verified ·
1 Parent(s): ab613d9

Upload 12 files

Browse files
vendor/three/build/three.core.js ADDED
The diff for this file is too large to render. See raw diff
 
vendor/three/build/three.module.js ADDED
The diff for this file is too large to render. See raw diff
 
vendor/three/examples/jsm/postprocessing/EffectComposer.js ADDED
@@ -0,0 +1,365 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ HalfFloatType,
3
+ NoBlending,
4
+ Timer,
5
+ Vector2,
6
+ WebGLRenderTarget
7
+ } from 'three';
8
+ import { CopyShader } from '../shaders/CopyShader.js';
9
+ import { ShaderPass } from './ShaderPass.js';
10
+ import { ClearMaskPass, MaskPass } from './MaskPass.js';
11
+
12
+ /**
13
+ * Used to implement post-processing effects in three.js.
14
+ * The class manages a chain of post-processing passes to produce the final visual result.
15
+ * Post-processing passes are executed in order of their addition/insertion.
16
+ * The last pass is automatically rendered to screen.
17
+ *
18
+ * This module can only be used with {@link WebGLRenderer}.
19
+ *
20
+ * ```js
21
+ * const composer = new EffectComposer( renderer );
22
+ *
23
+ * // adding some passes
24
+ * const renderPass = new RenderPass( scene, camera );
25
+ * composer.addPass( renderPass );
26
+ *
27
+ * const glitchPass = new GlitchPass();
28
+ * composer.addPass( glitchPass );
29
+ *
30
+ * const outputPass = new OutputPass()
31
+ * composer.addPass( outputPass );
32
+ *
33
+ * function animate() {
34
+ *
35
+ * composer.render(); // instead of renderer.render()
36
+ *
37
+ * }
38
+ * ```
39
+ *
40
+ * @three_import import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
41
+ */
42
+ class EffectComposer {
43
+
44
+ /**
45
+ * Constructs a new effect composer.
46
+ *
47
+ * @param {WebGLRenderer} renderer - The renderer.
48
+ * @param {WebGLRenderTarget} [renderTarget] - This render target and a clone will
49
+ * be used as the internal read and write buffers. If not given, the composer creates
50
+ * the buffers automatically.
51
+ */
52
+ constructor( renderer, renderTarget ) {
53
+
54
+ /**
55
+ * The renderer.
56
+ *
57
+ * @type {WebGLRenderer}
58
+ */
59
+ this.renderer = renderer;
60
+
61
+ this._pixelRatio = renderer.getPixelRatio();
62
+
63
+ if ( renderTarget === undefined ) {
64
+
65
+ const size = renderer.getSize( new Vector2() );
66
+ this._width = size.width;
67
+ this._height = size.height;
68
+
69
+ renderTarget = new WebGLRenderTarget( this._width * this._pixelRatio, this._height * this._pixelRatio, { type: HalfFloatType } );
70
+ renderTarget.texture.name = 'EffectComposer.rt1';
71
+
72
+ } else {
73
+
74
+ this._width = renderTarget.width;
75
+ this._height = renderTarget.height;
76
+
77
+ }
78
+
79
+ this.renderTarget1 = renderTarget;
80
+ this.renderTarget2 = renderTarget.clone();
81
+ this.renderTarget2.texture.name = 'EffectComposer.rt2';
82
+
83
+ /**
84
+ * A reference to the internal write buffer. Passes usually write
85
+ * their result into this buffer.
86
+ *
87
+ * @type {WebGLRenderTarget}
88
+ */
89
+ this.writeBuffer = this.renderTarget1;
90
+
91
+ /**
92
+ * A reference to the internal read buffer. Passes usually read
93
+ * the previous render result from this buffer.
94
+ *
95
+ * @type {WebGLRenderTarget}
96
+ */
97
+ this.readBuffer = this.renderTarget2;
98
+
99
+ /**
100
+ * Whether the final pass is rendered to the screen (default framebuffer) or not.
101
+ *
102
+ * @type {boolean}
103
+ * @default true
104
+ */
105
+ this.renderToScreen = true;
106
+
107
+ /**
108
+ * An array representing the (ordered) chain of post-processing passes.
109
+ *
110
+ * @type {Array<Pass>}
111
+ */
112
+ this.passes = [];
113
+
114
+ /**
115
+ * A copy pass used for internal swap operations.
116
+ *
117
+ * @private
118
+ * @type {ShaderPass}
119
+ */
120
+ this.copyPass = new ShaderPass( CopyShader );
121
+ this.copyPass.material.blending = NoBlending;
122
+
123
+ /**
124
+ * The internal timer for managing time data.
125
+ *
126
+ * @private
127
+ * @type {Timer}
128
+ */
129
+ this.timer = new Timer();
130
+
131
+ }
132
+
133
+ /**
134
+ * Swaps the internal read/write buffers.
135
+ */
136
+ swapBuffers() {
137
+
138
+ const tmp = this.readBuffer;
139
+ this.readBuffer = this.writeBuffer;
140
+ this.writeBuffer = tmp;
141
+
142
+ }
143
+
144
+ /**
145
+ * Adds the given pass to the pass chain.
146
+ *
147
+ * @param {Pass} pass - The pass to add.
148
+ */
149
+ addPass( pass ) {
150
+
151
+ this.passes.push( pass );
152
+ pass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );
153
+
154
+ }
155
+
156
+ /**
157
+ * Inserts the given pass at a given index.
158
+ *
159
+ * @param {Pass} pass - The pass to insert.
160
+ * @param {number} index - The index into the pass chain.
161
+ */
162
+ insertPass( pass, index ) {
163
+
164
+ this.passes.splice( index, 0, pass );
165
+ pass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );
166
+
167
+ }
168
+
169
+ /**
170
+ * Removes the given pass from the pass chain.
171
+ *
172
+ * @param {Pass} pass - The pass to remove.
173
+ */
174
+ removePass( pass ) {
175
+
176
+ const index = this.passes.indexOf( pass );
177
+
178
+ if ( index !== - 1 ) {
179
+
180
+ this.passes.splice( index, 1 );
181
+
182
+ }
183
+
184
+ }
185
+
186
+ /**
187
+ * Returns `true` if the pass for the given index is the last enabled pass in the pass chain.
188
+ *
189
+ * @param {number} passIndex - The pass index.
190
+ * @return {boolean} Whether the pass for the given index is the last pass in the pass chain.
191
+ */
192
+ isLastEnabledPass( passIndex ) {
193
+
194
+ for ( let i = passIndex + 1; i < this.passes.length; i ++ ) {
195
+
196
+ if ( this.passes[ i ].enabled ) {
197
+
198
+ return false;
199
+
200
+ }
201
+
202
+ }
203
+
204
+ return true;
205
+
206
+ }
207
+
208
+ /**
209
+ * Executes all enabled post-processing passes in order to produce the final frame.
210
+ *
211
+ * @param {number} deltaTime - The delta time in seconds. If not given, the composer computes
212
+ * its own time delta value.
213
+ */
214
+ render( deltaTime ) {
215
+
216
+ // deltaTime value is in seconds
217
+
218
+ this.timer.update();
219
+
220
+ if ( deltaTime === undefined ) {
221
+
222
+ deltaTime = this.timer.getDelta();
223
+
224
+ }
225
+
226
+ const currentRenderTarget = this.renderer.getRenderTarget();
227
+
228
+ let maskActive = false;
229
+
230
+ for ( let i = 0, il = this.passes.length; i < il; i ++ ) {
231
+
232
+ const pass = this.passes[ i ];
233
+
234
+ if ( pass.enabled === false ) continue;
235
+
236
+ pass.renderToScreen = ( this.renderToScreen && this.isLastEnabledPass( i ) );
237
+ pass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime, maskActive );
238
+
239
+ if ( pass.needsSwap ) {
240
+
241
+ if ( maskActive ) {
242
+
243
+ const context = this.renderer.getContext();
244
+ const stencil = this.renderer.state.buffers.stencil;
245
+
246
+ //context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );
247
+ stencil.setFunc( context.NOTEQUAL, 1, 0xffffffff );
248
+
249
+ this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime );
250
+
251
+ //context.stencilFunc( context.EQUAL, 1, 0xffffffff );
252
+ stencil.setFunc( context.EQUAL, 1, 0xffffffff );
253
+
254
+ }
255
+
256
+ this.swapBuffers();
257
+
258
+ }
259
+
260
+ if ( MaskPass !== undefined ) {
261
+
262
+ if ( pass instanceof MaskPass ) {
263
+
264
+ maskActive = true;
265
+
266
+ } else if ( pass instanceof ClearMaskPass ) {
267
+
268
+ maskActive = false;
269
+
270
+ }
271
+
272
+ }
273
+
274
+ }
275
+
276
+ this.renderer.setRenderTarget( currentRenderTarget );
277
+
278
+ }
279
+
280
+ /**
281
+ * Resets the internal state of the EffectComposer.
282
+ *
283
+ * @param {WebGLRenderTarget} [renderTarget] - This render target has the same purpose like
284
+ * the one from the constructor. If set, it is used to setup the read and write buffers.
285
+ */
286
+ reset( renderTarget ) {
287
+
288
+ if ( renderTarget === undefined ) {
289
+
290
+ const size = this.renderer.getSize( new Vector2() );
291
+ this._pixelRatio = this.renderer.getPixelRatio();
292
+ this._width = size.width;
293
+ this._height = size.height;
294
+
295
+ renderTarget = this.renderTarget1.clone();
296
+ renderTarget.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );
297
+
298
+ }
299
+
300
+ this.renderTarget1.dispose();
301
+ this.renderTarget2.dispose();
302
+ this.renderTarget1 = renderTarget;
303
+ this.renderTarget2 = renderTarget.clone();
304
+
305
+ this.writeBuffer = this.renderTarget1;
306
+ this.readBuffer = this.renderTarget2;
307
+
308
+ }
309
+
310
+ /**
311
+ * Resizes the internal read and write buffers as well as all passes. Similar to {@link WebGLRenderer#setSize},
312
+ * this method honors the current pixel ration.
313
+ *
314
+ * @param {number} width - The width in logical pixels.
315
+ * @param {number} height - The height in logical pixels.
316
+ */
317
+ setSize( width, height ) {
318
+
319
+ this._width = width;
320
+ this._height = height;
321
+
322
+ const effectiveWidth = this._width * this._pixelRatio;
323
+ const effectiveHeight = this._height * this._pixelRatio;
324
+
325
+ this.renderTarget1.setSize( effectiveWidth, effectiveHeight );
326
+ this.renderTarget2.setSize( effectiveWidth, effectiveHeight );
327
+
328
+ for ( let i = 0; i < this.passes.length; i ++ ) {
329
+
330
+ this.passes[ i ].setSize( effectiveWidth, effectiveHeight );
331
+
332
+ }
333
+
334
+ }
335
+
336
+ /**
337
+ * Sets device pixel ratio. This is usually used for HiDPI device to prevent blurring output.
338
+ * Setting the pixel ratio will automatically resize the composer.
339
+ *
340
+ * @param {number} pixelRatio - The pixel ratio to set.
341
+ */
342
+ setPixelRatio( pixelRatio ) {
343
+
344
+ this._pixelRatio = pixelRatio;
345
+
346
+ this.setSize( this._width, this._height );
347
+
348
+ }
349
+
350
+ /**
351
+ * Frees the GPU-related resources allocated by this instance. Call this
352
+ * method whenever the composer is no longer used in your app.
353
+ */
354
+ dispose() {
355
+
356
+ this.renderTarget1.dispose();
357
+ this.renderTarget2.dispose();
358
+
359
+ this.copyPass.dispose();
360
+
361
+ }
362
+
363
+ }
364
+
365
+ export { EffectComposer };
vendor/three/examples/jsm/postprocessing/MaskPass.js ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Pass } from './Pass.js';
2
+
3
+ /**
4
+ * This pass can be used to define a mask during post processing.
5
+ * Meaning only areas of subsequent post processing are affected
6
+ * which lie in the masking area of this pass. Internally, the masking
7
+ * is implemented with the stencil buffer.
8
+ *
9
+ * ```js
10
+ * const maskPass = new MaskPass( scene, camera );
11
+ * composer.addPass( maskPass );
12
+ * ```
13
+ *
14
+ * @augments Pass
15
+ * @three_import import { MaskPass } from 'three/addons/postprocessing/MaskPass.js';
16
+ */
17
+ class MaskPass extends Pass {
18
+
19
+ /**
20
+ * Constructs a new mask pass.
21
+ *
22
+ * @param {Scene} scene - The 3D objects in this scene will define the mask.
23
+ * @param {Camera} camera - The camera.
24
+ */
25
+ constructor( scene, camera ) {
26
+
27
+ super();
28
+
29
+ /**
30
+ * The scene that defines the mask.
31
+ *
32
+ * @type {Scene}
33
+ */
34
+ this.scene = scene;
35
+
36
+ /**
37
+ * The camera.
38
+ *
39
+ * @type {Camera}
40
+ */
41
+ this.camera = camera;
42
+
43
+ /**
44
+ * Overwritten to perform a clear operation by default.
45
+ *
46
+ * @type {boolean}
47
+ * @default true
48
+ */
49
+ this.clear = true;
50
+
51
+ /**
52
+ * Overwritten to disable the swap.
53
+ *
54
+ * @type {boolean}
55
+ * @default false
56
+ */
57
+ this.needsSwap = false;
58
+
59
+ /**
60
+ * Whether to inverse the mask or not.
61
+ *
62
+ * @type {boolean}
63
+ * @default false
64
+ */
65
+ this.inverse = false;
66
+
67
+ }
68
+
69
+ /**
70
+ * Performs a mask pass with the configured scene and camera.
71
+ *
72
+ * @param {WebGLRenderer} renderer - The renderer.
73
+ * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
74
+ * destination for the pass.
75
+ * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
76
+ * previous pass from this buffer.
77
+ * @param {number} deltaTime - The delta time in seconds.
78
+ * @param {boolean} maskActive - Whether masking is active or not.
79
+ */
80
+ render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
81
+
82
+ const context = renderer.getContext();
83
+ const state = renderer.state;
84
+
85
+ // don't update color or depth
86
+
87
+ state.buffers.color.setMask( false );
88
+ state.buffers.depth.setMask( false );
89
+
90
+ // lock buffers
91
+
92
+ state.buffers.color.setLocked( true );
93
+ state.buffers.depth.setLocked( true );
94
+
95
+ // set up stencil
96
+
97
+ let writeValue, clearValue;
98
+
99
+ if ( this.inverse ) {
100
+
101
+ writeValue = 0;
102
+ clearValue = 1;
103
+
104
+ } else {
105
+
106
+ writeValue = 1;
107
+ clearValue = 0;
108
+
109
+ }
110
+
111
+ state.buffers.stencil.setTest( true );
112
+ state.buffers.stencil.setOp( context.REPLACE, context.REPLACE, context.REPLACE );
113
+ state.buffers.stencil.setFunc( context.ALWAYS, writeValue, 0xffffffff );
114
+ state.buffers.stencil.setClear( clearValue );
115
+ state.buffers.stencil.setLocked( true );
116
+
117
+ // draw into the stencil buffer
118
+
119
+ renderer.setRenderTarget( readBuffer );
120
+ if ( this.clear ) renderer.clear();
121
+ renderer.render( this.scene, this.camera );
122
+
123
+ renderer.setRenderTarget( writeBuffer );
124
+ if ( this.clear ) renderer.clear();
125
+ renderer.render( this.scene, this.camera );
126
+
127
+ // unlock color and depth buffer and make them writable for subsequent rendering/clearing
128
+
129
+ state.buffers.color.setLocked( false );
130
+ state.buffers.depth.setLocked( false );
131
+
132
+ state.buffers.color.setMask( true );
133
+ state.buffers.depth.setMask( true );
134
+
135
+ // only render where stencil is set to 1
136
+
137
+ state.buffers.stencil.setLocked( false );
138
+ state.buffers.stencil.setFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1
139
+ state.buffers.stencil.setOp( context.KEEP, context.KEEP, context.KEEP );
140
+ state.buffers.stencil.setLocked( true );
141
+
142
+ }
143
+
144
+ }
145
+
146
+ /**
147
+ * This pass can be used to clear a mask previously defined with {@link MaskPass}.
148
+ *
149
+ * ```js
150
+ * const clearPass = new ClearMaskPass();
151
+ * composer.addPass( clearPass );
152
+ * ```
153
+ *
154
+ * @augments Pass
155
+ */
156
+ class ClearMaskPass extends Pass {
157
+
158
+ /**
159
+ * Constructs a new clear mask pass.
160
+ */
161
+ constructor() {
162
+
163
+ super();
164
+
165
+ /**
166
+ * Overwritten to disable the swap.
167
+ *
168
+ * @type {boolean}
169
+ * @default false
170
+ */
171
+ this.needsSwap = false;
172
+
173
+ }
174
+
175
+ /**
176
+ * Performs the clear of the currently defined mask.
177
+ *
178
+ * @param {WebGLRenderer} renderer - The renderer.
179
+ * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
180
+ * destination for the pass.
181
+ * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
182
+ * previous pass from this buffer.
183
+ * @param {number} deltaTime - The delta time in seconds.
184
+ * @param {boolean} maskActive - Whether masking is active or not.
185
+ */
186
+ render( renderer /*, writeBuffer, readBuffer, deltaTime, maskActive */ ) {
187
+
188
+ renderer.state.buffers.stencil.setLocked( false );
189
+ renderer.state.buffers.stencil.setTest( false );
190
+
191
+ }
192
+
193
+ }
194
+
195
+ export { MaskPass, ClearMaskPass };
vendor/three/examples/jsm/postprocessing/OutputPass.js ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ ColorManagement,
3
+ RawShaderMaterial,
4
+ UniformsUtils,
5
+ LinearToneMapping,
6
+ ReinhardToneMapping,
7
+ CineonToneMapping,
8
+ AgXToneMapping,
9
+ ACESFilmicToneMapping,
10
+ NeutralToneMapping,
11
+ CustomToneMapping,
12
+ SRGBTransfer
13
+ } from 'three';
14
+ import { Pass, FullScreenQuad } from './Pass.js';
15
+ import { OutputShader } from '../shaders/OutputShader.js';
16
+
17
+ /**
18
+ * This pass is responsible for including tone mapping and color space conversion
19
+ * into your pass chain. In most cases, this pass should be included at the end
20
+ * of each pass chain. If a pass requires sRGB input (e.g. like FXAA), the pass
21
+ * must follow `OutputPass` in the pass chain.
22
+ *
23
+ * The tone mapping and color space settings are extracted from the renderer.
24
+ *
25
+ * ```js
26
+ * const outputPass = new OutputPass();
27
+ * composer.addPass( outputPass );
28
+ * ```
29
+ *
30
+ * @augments Pass
31
+ * @three_import import { OutputPass } from 'three/addons/postprocessing/OutputPass.js';
32
+ */
33
+ class OutputPass extends Pass {
34
+
35
+ /**
36
+ * Constructs a new output pass.
37
+ */
38
+ constructor() {
39
+
40
+ super();
41
+
42
+ /**
43
+ * This flag indicates that this is an output pass.
44
+ *
45
+ * @type {boolean}
46
+ * @readonly
47
+ * @default true
48
+ */
49
+ this.isOutputPass = true;
50
+
51
+ /**
52
+ * The pass uniforms.
53
+ *
54
+ * @type {Object}
55
+ */
56
+ this.uniforms = UniformsUtils.clone( OutputShader.uniforms );
57
+
58
+ /**
59
+ * The pass material.
60
+ *
61
+ * @type {RawShaderMaterial}
62
+ */
63
+ this.material = new RawShaderMaterial( {
64
+ name: OutputShader.name,
65
+ uniforms: this.uniforms,
66
+ vertexShader: OutputShader.vertexShader,
67
+ fragmentShader: OutputShader.fragmentShader
68
+ } );
69
+
70
+ // internals
71
+
72
+ this._fsQuad = new FullScreenQuad( this.material );
73
+
74
+ this._outputColorSpace = null;
75
+ this._toneMapping = null;
76
+
77
+ }
78
+
79
+ /**
80
+ * Performs the output pass.
81
+ *
82
+ * @param {WebGLRenderer} renderer - The renderer.
83
+ * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
84
+ * destination for the pass.
85
+ * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
86
+ * previous pass from this buffer.
87
+ * @param {number} deltaTime - The delta time in seconds.
88
+ * @param {boolean} maskActive - Whether masking is active or not.
89
+ */
90
+ render( renderer, writeBuffer, readBuffer/*, deltaTime, maskActive */ ) {
91
+
92
+ this.uniforms[ 'tDiffuse' ].value = readBuffer.texture;
93
+ this.uniforms[ 'toneMappingExposure' ].value = renderer.toneMappingExposure;
94
+
95
+ // rebuild defines if required
96
+
97
+ if ( this._outputColorSpace !== renderer.outputColorSpace || this._toneMapping !== renderer.toneMapping ) {
98
+
99
+ this._outputColorSpace = renderer.outputColorSpace;
100
+ this._toneMapping = renderer.toneMapping;
101
+
102
+ this.material.defines = {};
103
+
104
+ if ( ColorManagement.getTransfer( this._outputColorSpace ) === SRGBTransfer ) this.material.defines.SRGB_TRANSFER = '';
105
+
106
+ if ( this._toneMapping === LinearToneMapping ) this.material.defines.LINEAR_TONE_MAPPING = '';
107
+ else if ( this._toneMapping === ReinhardToneMapping ) this.material.defines.REINHARD_TONE_MAPPING = '';
108
+ else if ( this._toneMapping === CineonToneMapping ) this.material.defines.CINEON_TONE_MAPPING = '';
109
+ else if ( this._toneMapping === ACESFilmicToneMapping ) this.material.defines.ACES_FILMIC_TONE_MAPPING = '';
110
+ else if ( this._toneMapping === AgXToneMapping ) this.material.defines.AGX_TONE_MAPPING = '';
111
+ else if ( this._toneMapping === NeutralToneMapping ) this.material.defines.NEUTRAL_TONE_MAPPING = '';
112
+ else if ( this._toneMapping === CustomToneMapping ) this.material.defines.CUSTOM_TONE_MAPPING = '';
113
+
114
+ this.material.needsUpdate = true;
115
+
116
+ }
117
+
118
+ //
119
+
120
+ if ( this.renderToScreen === true ) {
121
+
122
+ renderer.setRenderTarget( null );
123
+ this._fsQuad.render( renderer );
124
+
125
+ } else {
126
+
127
+ renderer.setRenderTarget( writeBuffer );
128
+ if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
129
+ this._fsQuad.render( renderer );
130
+
131
+ }
132
+
133
+ }
134
+
135
+ /**
136
+ * Frees the GPU-related resources allocated by this instance. Call this
137
+ * method whenever the pass is no longer used in your app.
138
+ */
139
+ dispose() {
140
+
141
+ this.material.dispose();
142
+ this._fsQuad.dispose();
143
+
144
+ }
145
+
146
+ }
147
+
148
+ export { OutputPass };
vendor/three/examples/jsm/postprocessing/Pass.js ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ BufferGeometry,
3
+ Float32BufferAttribute,
4
+ OrthographicCamera,
5
+ Mesh
6
+ } from 'three';
7
+
8
+ /**
9
+ * Abstract base class for all post processing passes.
10
+ *
11
+ * This module is only relevant for post processing with {@link WebGLRenderer}.
12
+ *
13
+ * @abstract
14
+ * @three_import import { Pass } from 'three/addons/postprocessing/Pass.js';
15
+ */
16
+ class Pass {
17
+
18
+ /**
19
+ * Constructs a new pass.
20
+ */
21
+ constructor() {
22
+
23
+ /**
24
+ * This flag can be used for type testing.
25
+ *
26
+ * @type {boolean}
27
+ * @readonly
28
+ * @default true
29
+ */
30
+ this.isPass = true;
31
+
32
+ /**
33
+ * If set to `true`, the pass is processed by the composer.
34
+ *
35
+ * @type {boolean}
36
+ * @default true
37
+ */
38
+ this.enabled = true;
39
+
40
+ /**
41
+ * If set to `true`, the pass indicates to swap read and write buffer after rendering.
42
+ *
43
+ * @type {boolean}
44
+ * @default true
45
+ */
46
+ this.needsSwap = true;
47
+
48
+ /**
49
+ * If set to `true`, the pass clears its buffer before rendering
50
+ *
51
+ * @type {boolean}
52
+ * @default false
53
+ */
54
+ this.clear = false;
55
+
56
+ /**
57
+ * If set to `true`, the result of the pass is rendered to screen. The last pass in the composers
58
+ * pass chain gets automatically rendered to screen, no matter how this property is configured.
59
+ *
60
+ * @type {boolean}
61
+ * @default false
62
+ */
63
+ this.renderToScreen = false;
64
+
65
+ }
66
+
67
+ /**
68
+ * Sets the size of the pass.
69
+ *
70
+ * @abstract
71
+ * @param {number} width - The width to set.
72
+ * @param {number} height - The height to set.
73
+ */
74
+ setSize( /* width, height */ ) {}
75
+
76
+ /**
77
+ * This method holds the render logic of a pass. It must be implemented in all derived classes.
78
+ *
79
+ * @abstract
80
+ * @param {WebGLRenderer} renderer - The renderer.
81
+ * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
82
+ * destination for the pass.
83
+ * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
84
+ * previous pass from this buffer.
85
+ * @param {number} deltaTime - The delta time in seconds.
86
+ * @param {boolean} maskActive - Whether masking is active or not.
87
+ */
88
+ render( /* renderer, writeBuffer, readBuffer, deltaTime, maskActive */ ) {
89
+
90
+ console.error( 'THREE.Pass: .render() must be implemented in derived pass.' );
91
+
92
+ }
93
+
94
+ /**
95
+ * Frees the GPU-related resources allocated by this instance. Call this
96
+ * method whenever the pass is no longer used in your app.
97
+ *
98
+ * @abstract
99
+ */
100
+ dispose() {}
101
+
102
+ }
103
+
104
+ // Helper for passes that need to fill the viewport with a single quad.
105
+
106
+ const _camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
107
+
108
+ // https://github.com/mrdoob/three.js/pull/21358
109
+
110
+ class FullscreenTriangleGeometry extends BufferGeometry {
111
+
112
+ constructor() {
113
+
114
+ super();
115
+
116
+ this.setAttribute( 'position', new Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );
117
+ this.setAttribute( 'uv', new Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );
118
+
119
+ }
120
+
121
+ }
122
+
123
+ const _geometry = new FullscreenTriangleGeometry();
124
+
125
+
126
+ /**
127
+ * This module is a helper for passes which need to render a full
128
+ * screen effect which is quite common in context of post processing.
129
+ *
130
+ * The intended usage is to reuse a single full screen quad for rendering
131
+ * subsequent passes by just reassigning the `material` reference.
132
+ *
133
+ * This module can only be used with {@link WebGLRenderer}.
134
+ *
135
+ * @augments Mesh
136
+ * @three_import import { FullScreenQuad } from 'three/addons/postprocessing/Pass.js';
137
+ */
138
+ class FullScreenQuad {
139
+
140
+ /**
141
+ * Constructs a new full screen quad.
142
+ *
143
+ * @param {?Material} material - The material to render te full screen quad with.
144
+ */
145
+ constructor( material ) {
146
+
147
+ this._mesh = new Mesh( _geometry, material );
148
+
149
+ }
150
+
151
+ /**
152
+ * Frees the GPU-related resources allocated by this instance. Call this
153
+ * method whenever the instance is no longer used in your app.
154
+ */
155
+ dispose() {
156
+
157
+ this._mesh.geometry.dispose();
158
+
159
+ }
160
+
161
+ /**
162
+ * Renders the full screen quad.
163
+ *
164
+ * @param {WebGLRenderer} renderer - The renderer.
165
+ */
166
+ render( renderer ) {
167
+
168
+ renderer.render( this._mesh, _camera );
169
+
170
+ }
171
+
172
+ /**
173
+ * The quad's material.
174
+ *
175
+ * @type {?Material}
176
+ */
177
+ get material() {
178
+
179
+ return this._mesh.material;
180
+
181
+ }
182
+
183
+ set material( value ) {
184
+
185
+ this._mesh.material = value;
186
+
187
+ }
188
+
189
+ }
190
+
191
+ export { Pass, FullScreenQuad };
vendor/three/examples/jsm/postprocessing/RenderPass.js ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ Color
3
+ } from 'three';
4
+ import { Pass } from './Pass.js';
5
+
6
+ /**
7
+ * This class represents a render pass. It takes a camera and a scene and produces
8
+ * a beauty pass for subsequent post processing effects.
9
+ *
10
+ * ```js
11
+ * const renderPass = new RenderPass( scene, camera );
12
+ * composer.addPass( renderPass );
13
+ * ```
14
+ *
15
+ * @augments Pass
16
+ * @three_import import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
17
+ */
18
+ class RenderPass extends Pass {
19
+
20
+ /**
21
+ * Constructs a new render pass.
22
+ *
23
+ * @param {Scene} scene - The scene to render.
24
+ * @param {Camera} camera - The camera.
25
+ * @param {?Material} [overrideMaterial=null] - The override material. If set, this material is used
26
+ * for all objects in the scene.
27
+ * @param {?(number|Color|string)} [clearColor=null] - The clear color of the render pass.
28
+ * @param {?number} [clearAlpha=null] - The clear alpha of the render pass.
29
+ */
30
+ constructor( scene, camera, overrideMaterial = null, clearColor = null, clearAlpha = null ) {
31
+
32
+ super();
33
+
34
+ /**
35
+ * The scene to render.
36
+ *
37
+ * @type {Scene}
38
+ */
39
+ this.scene = scene;
40
+
41
+ /**
42
+ * The camera.
43
+ *
44
+ * @type {Camera}
45
+ */
46
+ this.camera = camera;
47
+
48
+ /**
49
+ * The override material. If set, this material is used
50
+ * for all objects in the scene.
51
+ *
52
+ * @type {?Material}
53
+ * @default null
54
+ */
55
+ this.overrideMaterial = overrideMaterial;
56
+
57
+ /**
58
+ * The clear color of the render pass.
59
+ *
60
+ * @type {?(number|Color|string)}
61
+ * @default null
62
+ */
63
+ this.clearColor = clearColor;
64
+
65
+ /**
66
+ * The clear alpha of the render pass.
67
+ *
68
+ * @type {?number}
69
+ * @default null
70
+ */
71
+ this.clearAlpha = clearAlpha;
72
+
73
+ /**
74
+ * Overwritten to perform a clear operation by default.
75
+ *
76
+ * @type {boolean}
77
+ * @default true
78
+ */
79
+ this.clear = true;
80
+
81
+ /**
82
+ * If set to `true`, only the depth can be cleared when `clear` is to `false`.
83
+ *
84
+ * @type {boolean}
85
+ * @default false
86
+ */
87
+ this.clearDepth = false;
88
+
89
+ /**
90
+ * Overwritten to disable the swap.
91
+ *
92
+ * @type {boolean}
93
+ * @default false
94
+ */
95
+ this.needsSwap = false;
96
+
97
+ /**
98
+ * This flag indicates that this pass renders the scene itself.
99
+ *
100
+ * @type {boolean}
101
+ * @readonly
102
+ * @default true
103
+ */
104
+ this.isRenderPass = true;
105
+
106
+ this._oldClearColor = new Color();
107
+
108
+ }
109
+
110
+ /**
111
+ * Performs a beauty pass with the configured scene and camera.
112
+ *
113
+ * @param {WebGLRenderer} renderer - The renderer.
114
+ * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
115
+ * destination for the pass.
116
+ * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
117
+ * previous pass from this buffer.
118
+ * @param {number} deltaTime - The delta time in seconds.
119
+ * @param {boolean} maskActive - Whether masking is active or not.
120
+ */
121
+ render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
122
+
123
+ const oldAutoClear = renderer.autoClear;
124
+ renderer.autoClear = false;
125
+
126
+ let oldClearAlpha, oldOverrideMaterial;
127
+
128
+ if ( this.overrideMaterial !== null ) {
129
+
130
+ oldOverrideMaterial = this.scene.overrideMaterial;
131
+
132
+ this.scene.overrideMaterial = this.overrideMaterial;
133
+
134
+ }
135
+
136
+ if ( this.clearColor !== null ) {
137
+
138
+ renderer.getClearColor( this._oldClearColor );
139
+ renderer.setClearColor( this.clearColor, renderer.getClearAlpha() );
140
+
141
+ }
142
+
143
+ if ( this.clearAlpha !== null ) {
144
+
145
+ oldClearAlpha = renderer.getClearAlpha();
146
+ renderer.setClearAlpha( this.clearAlpha );
147
+
148
+ }
149
+
150
+ if ( this.clearDepth == true ) {
151
+
152
+ renderer.clearDepth();
153
+
154
+ }
155
+
156
+ renderer.setRenderTarget( this.renderToScreen ? null : readBuffer );
157
+
158
+ if ( this.clear === true ) {
159
+
160
+ // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
161
+ renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
162
+
163
+ }
164
+
165
+ renderer.render( this.scene, this.camera );
166
+
167
+ // restore
168
+
169
+ if ( this.clearColor !== null ) {
170
+
171
+ renderer.setClearColor( this._oldClearColor );
172
+
173
+ }
174
+
175
+ if ( this.clearAlpha !== null ) {
176
+
177
+ renderer.setClearAlpha( oldClearAlpha );
178
+
179
+ }
180
+
181
+ if ( this.overrideMaterial !== null ) {
182
+
183
+ this.scene.overrideMaterial = oldOverrideMaterial;
184
+
185
+ }
186
+
187
+ renderer.autoClear = oldAutoClear;
188
+
189
+ }
190
+
191
+ }
192
+
193
+ export { RenderPass };
vendor/three/examples/jsm/postprocessing/ShaderPass.js ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ ShaderMaterial,
3
+ UniformsUtils
4
+ } from 'three';
5
+ import { Pass, FullScreenQuad } from './Pass.js';
6
+
7
+ /**
8
+ * This pass can be used to create a post processing effect
9
+ * with a raw GLSL shader object. Useful for implementing custom
10
+ * effects.
11
+ *
12
+ * ```js
13
+ * const fxaaPass = new ShaderPass( FXAAShader );
14
+ * composer.addPass( fxaaPass );
15
+ * ```
16
+ *
17
+ * @augments Pass
18
+ * @three_import import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js';
19
+ */
20
+ class ShaderPass extends Pass {
21
+
22
+ /**
23
+ * Constructs a new shader pass.
24
+ *
25
+ * @param {Object|ShaderMaterial} [shader] - A shader object holding vertex and fragment shader as well as
26
+ * defines and uniforms. It's also valid to pass a custom shader material.
27
+ * @param {string} [textureID='tDiffuse'] - The name of the texture uniform that should sample
28
+ * the read buffer.
29
+ */
30
+ constructor( shader, textureID = 'tDiffuse' ) {
31
+
32
+ super();
33
+
34
+ /**
35
+ * The name of the texture uniform that should sample the read buffer.
36
+ *
37
+ * @type {string}
38
+ * @default 'tDiffuse'
39
+ */
40
+ this.textureID = textureID;
41
+
42
+ /**
43
+ * The pass uniforms.
44
+ *
45
+ * @type {?Object}
46
+ */
47
+ this.uniforms = null;
48
+
49
+ /**
50
+ * The pass material.
51
+ *
52
+ * @type {?ShaderMaterial}
53
+ */
54
+ this.material = null;
55
+
56
+ if ( shader instanceof ShaderMaterial ) {
57
+
58
+ this.uniforms = shader.uniforms;
59
+
60
+ this.material = shader;
61
+
62
+ } else if ( shader ) {
63
+
64
+ this.uniforms = UniformsUtils.clone( shader.uniforms );
65
+
66
+ this.material = new ShaderMaterial( {
67
+
68
+ name: ( shader.name !== undefined ) ? shader.name : 'unspecified',
69
+ defines: Object.assign( {}, shader.defines ),
70
+ uniforms: this.uniforms,
71
+ vertexShader: shader.vertexShader,
72
+ fragmentShader: shader.fragmentShader
73
+
74
+ } );
75
+
76
+ }
77
+
78
+ // internals
79
+
80
+ this._fsQuad = new FullScreenQuad( this.material );
81
+
82
+ }
83
+
84
+ /**
85
+ * Performs the shader pass.
86
+ *
87
+ * @param {WebGLRenderer} renderer - The renderer.
88
+ * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
89
+ * destination for the pass.
90
+ * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
91
+ * previous pass from this buffer.
92
+ * @param {number} deltaTime - The delta time in seconds.
93
+ * @param {boolean} maskActive - Whether masking is active or not.
94
+ */
95
+ render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
96
+
97
+ if ( this.uniforms[ this.textureID ] ) {
98
+
99
+ this.uniforms[ this.textureID ].value = readBuffer.texture;
100
+
101
+ }
102
+
103
+ this._fsQuad.material = this.material;
104
+
105
+ if ( this.renderToScreen ) {
106
+
107
+ renderer.setRenderTarget( null );
108
+ this._fsQuad.render( renderer );
109
+
110
+ } else {
111
+
112
+ renderer.setRenderTarget( writeBuffer );
113
+ // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
114
+ if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
115
+ this._fsQuad.render( renderer );
116
+
117
+ }
118
+
119
+ }
120
+
121
+ /**
122
+ * Frees the GPU-related resources allocated by this instance. Call this
123
+ * method whenever the pass is no longer used in your app.
124
+ */
125
+ dispose() {
126
+
127
+ this.material.dispose();
128
+
129
+ this._fsQuad.dispose();
130
+
131
+ }
132
+
133
+ }
134
+
135
+ export { ShaderPass };
vendor/three/examples/jsm/postprocessing/UnrealBloomPass.js ADDED
@@ -0,0 +1,524 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ AdditiveBlending,
3
+ Color,
4
+ HalfFloatType,
5
+ MeshBasicMaterial,
6
+ ShaderMaterial,
7
+ UniformsUtils,
8
+ Vector2,
9
+ Vector3,
10
+ WebGLRenderTarget
11
+ } from 'three';
12
+ import { Pass, FullScreenQuad } from './Pass.js';
13
+ import { CopyShader } from '../shaders/CopyShader.js';
14
+ import { LuminosityHighPassShader } from '../shaders/LuminosityHighPassShader.js';
15
+
16
+ /**
17
+ * This pass is inspired by the bloom pass of Unreal Engine. It creates a
18
+ * mip map chain of bloom textures and blurs them with different radii. Because
19
+ * of the weighted combination of mips, and because larger blurs are done on
20
+ * higher mips, this effect provides good quality and performance.
21
+ *
22
+ * When using this pass, tone mapping must be enabled in the renderer settings.
23
+ *
24
+ * Reference:
25
+ * - [Bloom in Unreal Engine](https://docs.unrealengine.com/latest/INT/Engine/Rendering/PostProcessEffects/Bloom/)
26
+ *
27
+ * ```js
28
+ * const resolution = new THREE.Vector2( window.innerWidth, window.innerHeight );
29
+ * const bloomPass = new UnrealBloomPass( resolution, 1.5, 0.4, 0.85 );
30
+ * composer.addPass( bloomPass );
31
+ * ```
32
+ *
33
+ * @augments Pass
34
+ * @three_import import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
35
+ */
36
+ class UnrealBloomPass extends Pass {
37
+
38
+ /**
39
+ * Constructs a new Unreal Bloom pass.
40
+ *
41
+ * @param {Vector2} [resolution] - The effect's resolution.
42
+ * @param {number} [strength=1] - The Bloom strength.
43
+ * @param {number} radius - The Bloom radius.
44
+ * @param {number} threshold - The luminance threshold limits which bright areas contribute to the Bloom effect.
45
+ */
46
+ constructor( resolution, strength = 1, radius, threshold ) {
47
+
48
+ super();
49
+
50
+ /**
51
+ * The Bloom strength.
52
+ *
53
+ * @type {number}
54
+ * @default 1
55
+ */
56
+ this.strength = strength;
57
+
58
+ /**
59
+ * The Bloom radius. Must be in the range `[0,1]`.
60
+ *
61
+ * @type {number}
62
+ */
63
+ this.radius = radius;
64
+
65
+ /**
66
+ * The luminance threshold limits which bright areas contribute to the Bloom effect.
67
+ *
68
+ * @type {number}
69
+ */
70
+ this.threshold = threshold;
71
+
72
+ /**
73
+ * The effect's resolution.
74
+ *
75
+ * @type {Vector2}
76
+ * @default (256,256)
77
+ */
78
+ this.resolution = ( resolution !== undefined ) ? new Vector2( resolution.x, resolution.y ) : new Vector2( 256, 256 );
79
+
80
+ /**
81
+ * The effect's clear color
82
+ *
83
+ * @type {Color}
84
+ * @default (0,0,0)
85
+ */
86
+ this.clearColor = new Color( 0, 0, 0 );
87
+
88
+ /**
89
+ * Overwritten to disable the swap.
90
+ *
91
+ * @type {boolean}
92
+ * @default false
93
+ */
94
+ this.needsSwap = false;
95
+
96
+ // internals
97
+
98
+ // render targets
99
+ this.renderTargetsHorizontal = [];
100
+ this.renderTargetsVertical = [];
101
+ this.nMips = 5;
102
+ let resx = Math.round( this.resolution.x / 2 );
103
+ let resy = Math.round( this.resolution.y / 2 );
104
+
105
+ this.renderTargetBright = new WebGLRenderTarget( resx, resy, { type: HalfFloatType } );
106
+ this.renderTargetBright.texture.name = 'UnrealBloomPass.bright';
107
+ this.renderTargetBright.texture.generateMipmaps = false;
108
+
109
+ for ( let i = 0; i < this.nMips; i ++ ) {
110
+
111
+ const renderTargetHorizontal = new WebGLRenderTarget( resx, resy, { type: HalfFloatType } );
112
+
113
+ renderTargetHorizontal.texture.name = 'UnrealBloomPass.h' + i;
114
+ renderTargetHorizontal.texture.generateMipmaps = false;
115
+
116
+ this.renderTargetsHorizontal.push( renderTargetHorizontal );
117
+
118
+ const renderTargetVertical = new WebGLRenderTarget( resx, resy, { type: HalfFloatType } );
119
+
120
+ renderTargetVertical.texture.name = 'UnrealBloomPass.v' + i;
121
+ renderTargetVertical.texture.generateMipmaps = false;
122
+
123
+ this.renderTargetsVertical.push( renderTargetVertical );
124
+
125
+ resx = Math.round( resx / 2 );
126
+
127
+ resy = Math.round( resy / 2 );
128
+
129
+ }
130
+
131
+ // luminosity high pass material
132
+
133
+ const highPassShader = LuminosityHighPassShader;
134
+ this.highPassUniforms = UniformsUtils.clone( highPassShader.uniforms );
135
+
136
+ this.highPassUniforms[ 'luminosityThreshold' ].value = threshold;
137
+ this.highPassUniforms[ 'smoothWidth' ].value = 0.01;
138
+
139
+ this.materialHighPassFilter = new ShaderMaterial( {
140
+ uniforms: this.highPassUniforms,
141
+ vertexShader: highPassShader.vertexShader,
142
+ fragmentShader: highPassShader.fragmentShader
143
+ } );
144
+
145
+ // gaussian blur materials
146
+
147
+ this.separableBlurMaterials = [];
148
+ // These sizes have been changed to account for the altered coefficients-calculation to avoid blockiness,
149
+ // while retaining the same blur-strength. For details see https://github.com/mrdoob/three.js/pull/31528
150
+ const kernelSizeArray = [ 6, 10, 14, 18, 22 ];
151
+ resx = Math.round( this.resolution.x / 2 );
152
+ resy = Math.round( this.resolution.y / 2 );
153
+
154
+ for ( let i = 0; i < this.nMips; i ++ ) {
155
+
156
+ this.separableBlurMaterials.push( this._getSeparableBlurMaterial( kernelSizeArray[ i ] ) );
157
+
158
+ this.separableBlurMaterials[ i ].uniforms[ 'invSize' ].value = new Vector2( 1 / resx, 1 / resy );
159
+
160
+ resx = Math.round( resx / 2 );
161
+
162
+ resy = Math.round( resy / 2 );
163
+
164
+ }
165
+
166
+ // composite material
167
+
168
+ this.compositeMaterial = this._getCompositeMaterial( this.nMips );
169
+ this.compositeMaterial.uniforms[ 'blurTexture1' ].value = this.renderTargetsVertical[ 0 ].texture;
170
+ this.compositeMaterial.uniforms[ 'blurTexture2' ].value = this.renderTargetsVertical[ 1 ].texture;
171
+ this.compositeMaterial.uniforms[ 'blurTexture3' ].value = this.renderTargetsVertical[ 2 ].texture;
172
+ this.compositeMaterial.uniforms[ 'blurTexture4' ].value = this.renderTargetsVertical[ 3 ].texture;
173
+ this.compositeMaterial.uniforms[ 'blurTexture5' ].value = this.renderTargetsVertical[ 4 ].texture;
174
+ this.compositeMaterial.uniforms[ 'bloomStrength' ].value = strength;
175
+ this.compositeMaterial.uniforms[ 'bloomRadius' ].value = 0.1;
176
+
177
+ const bloomFactors = [ 1.0, 0.8, 0.6, 0.4, 0.2 ];
178
+ this.compositeMaterial.uniforms[ 'bloomFactors' ].value = bloomFactors;
179
+ this.bloomTintColors = [ new Vector3( 1, 1, 1 ), new Vector3( 1, 1, 1 ), new Vector3( 1, 1, 1 ), new Vector3( 1, 1, 1 ), new Vector3( 1, 1, 1 ) ];
180
+ this.compositeMaterial.uniforms[ 'bloomTintColors' ].value = this.bloomTintColors;
181
+
182
+ // blend material
183
+
184
+ this.copyUniforms = UniformsUtils.clone( CopyShader.uniforms );
185
+
186
+ this.blendMaterial = new ShaderMaterial( {
187
+ uniforms: this.copyUniforms,
188
+ vertexShader: CopyShader.vertexShader,
189
+ fragmentShader: CopyShader.fragmentShader,
190
+ premultipliedAlpha: true,
191
+ blending: AdditiveBlending,
192
+ depthTest: false,
193
+ depthWrite: false,
194
+ transparent: true
195
+ } );
196
+
197
+ this._oldClearColor = new Color();
198
+ this._oldClearAlpha = 1;
199
+
200
+ this._basic = new MeshBasicMaterial();
201
+
202
+ this._fsQuad = new FullScreenQuad( null );
203
+
204
+ }
205
+
206
+ /**
207
+ * Frees the GPU-related resources allocated by this instance. Call this
208
+ * method whenever the pass is no longer used in your app.
209
+ */
210
+ dispose() {
211
+
212
+ for ( let i = 0; i < this.renderTargetsHorizontal.length; i ++ ) {
213
+
214
+ this.renderTargetsHorizontal[ i ].dispose();
215
+
216
+ }
217
+
218
+ for ( let i = 0; i < this.renderTargetsVertical.length; i ++ ) {
219
+
220
+ this.renderTargetsVertical[ i ].dispose();
221
+
222
+ }
223
+
224
+ this.renderTargetBright.dispose();
225
+
226
+ //
227
+
228
+ for ( let i = 0; i < this.separableBlurMaterials.length; i ++ ) {
229
+
230
+ this.separableBlurMaterials[ i ].dispose();
231
+
232
+ }
233
+
234
+ this.compositeMaterial.dispose();
235
+ this.blendMaterial.dispose();
236
+ this._basic.dispose();
237
+
238
+ //
239
+
240
+ this._fsQuad.dispose();
241
+
242
+ }
243
+
244
+ /**
245
+ * Sets the size of the pass.
246
+ *
247
+ * @param {number} width - The width to set.
248
+ * @param {number} height - The height to set.
249
+ */
250
+ setSize( width, height ) {
251
+
252
+ let resx = Math.round( width / 2 );
253
+ let resy = Math.round( height / 2 );
254
+
255
+ this.renderTargetBright.setSize( resx, resy );
256
+
257
+ for ( let i = 0; i < this.nMips; i ++ ) {
258
+
259
+ this.renderTargetsHorizontal[ i ].setSize( resx, resy );
260
+ this.renderTargetsVertical[ i ].setSize( resx, resy );
261
+
262
+ this.separableBlurMaterials[ i ].uniforms[ 'invSize' ].value = new Vector2( 1 / resx, 1 / resy );
263
+
264
+ resx = Math.round( resx / 2 );
265
+ resy = Math.round( resy / 2 );
266
+
267
+ }
268
+
269
+ }
270
+
271
+ /**
272
+ * Performs the Bloom pass.
273
+ *
274
+ * @param {WebGLRenderer} renderer - The renderer.
275
+ * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
276
+ * destination for the pass.
277
+ * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
278
+ * previous pass from this buffer.
279
+ * @param {number} deltaTime - The delta time in seconds.
280
+ * @param {boolean} maskActive - Whether masking is active or not.
281
+ */
282
+ render( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
283
+
284
+ renderer.getClearColor( this._oldClearColor );
285
+ this._oldClearAlpha = renderer.getClearAlpha();
286
+ const oldAutoClear = renderer.autoClear;
287
+ renderer.autoClear = false;
288
+
289
+ renderer.setClearColor( this.clearColor, 0 );
290
+
291
+ if ( maskActive ) renderer.state.buffers.stencil.setTest( false );
292
+
293
+ // Render input to screen
294
+
295
+ if ( this.renderToScreen ) {
296
+
297
+ this._fsQuad.material = this._basic;
298
+ this._basic.map = readBuffer.texture;
299
+
300
+ renderer.setRenderTarget( null );
301
+ renderer.clear();
302
+ this._fsQuad.render( renderer );
303
+
304
+ }
305
+
306
+ // 1. Extract Bright Areas
307
+
308
+ this.highPassUniforms[ 'tDiffuse' ].value = readBuffer.texture;
309
+ this.highPassUniforms[ 'luminosityThreshold' ].value = this.threshold;
310
+ this._fsQuad.material = this.materialHighPassFilter;
311
+
312
+ renderer.setRenderTarget( this.renderTargetBright );
313
+ renderer.clear();
314
+ this._fsQuad.render( renderer );
315
+
316
+ // 2. Blur All the mips progressively
317
+
318
+ let inputRenderTarget = this.renderTargetBright;
319
+
320
+ for ( let i = 0; i < this.nMips; i ++ ) {
321
+
322
+ this._fsQuad.material = this.separableBlurMaterials[ i ];
323
+
324
+ this.separableBlurMaterials[ i ].uniforms[ 'colorTexture' ].value = inputRenderTarget.texture;
325
+ this.separableBlurMaterials[ i ].uniforms[ 'direction' ].value = UnrealBloomPass.BlurDirectionX;
326
+ renderer.setRenderTarget( this.renderTargetsHorizontal[ i ] );
327
+ renderer.clear();
328
+ this._fsQuad.render( renderer );
329
+
330
+ this.separableBlurMaterials[ i ].uniforms[ 'colorTexture' ].value = this.renderTargetsHorizontal[ i ].texture;
331
+ this.separableBlurMaterials[ i ].uniforms[ 'direction' ].value = UnrealBloomPass.BlurDirectionY;
332
+ renderer.setRenderTarget( this.renderTargetsVertical[ i ] );
333
+ renderer.clear();
334
+ this._fsQuad.render( renderer );
335
+
336
+ inputRenderTarget = this.renderTargetsVertical[ i ];
337
+
338
+ }
339
+
340
+ // Composite All the mips
341
+
342
+ this._fsQuad.material = this.compositeMaterial;
343
+ this.compositeMaterial.uniforms[ 'bloomStrength' ].value = this.strength;
344
+ this.compositeMaterial.uniforms[ 'bloomRadius' ].value = this.radius;
345
+ this.compositeMaterial.uniforms[ 'bloomTintColors' ].value = this.bloomTintColors;
346
+
347
+ renderer.setRenderTarget( this.renderTargetsHorizontal[ 0 ] );
348
+ renderer.clear();
349
+ this._fsQuad.render( renderer );
350
+
351
+ // Blend it additively over the input texture
352
+
353
+ this._fsQuad.material = this.blendMaterial;
354
+ this.copyUniforms[ 'tDiffuse' ].value = this.renderTargetsHorizontal[ 0 ].texture;
355
+
356
+ if ( maskActive ) renderer.state.buffers.stencil.setTest( true );
357
+
358
+ if ( this.renderToScreen ) {
359
+
360
+ renderer.setRenderTarget( null );
361
+ this._fsQuad.render( renderer );
362
+
363
+ } else {
364
+
365
+ renderer.setRenderTarget( readBuffer );
366
+ this._fsQuad.render( renderer );
367
+
368
+ }
369
+
370
+ // Restore renderer settings
371
+
372
+ renderer.setClearColor( this._oldClearColor, this._oldClearAlpha );
373
+ renderer.autoClear = oldAutoClear;
374
+
375
+ }
376
+
377
+ // internals
378
+
379
+ _getSeparableBlurMaterial( kernelRadius ) {
380
+
381
+ const coefficients = [];
382
+ const sigma = kernelRadius / 3;
383
+
384
+ for ( let i = 0; i < kernelRadius; i ++ ) {
385
+
386
+ coefficients.push( 0.39894 * Math.exp( - 0.5 * i * i / ( sigma * sigma ) ) / sigma );
387
+
388
+ }
389
+
390
+ return new ShaderMaterial( {
391
+
392
+ defines: {
393
+ 'KERNEL_RADIUS': kernelRadius
394
+ },
395
+
396
+ uniforms: {
397
+ 'colorTexture': { value: null },
398
+ 'invSize': { value: new Vector2( 0.5, 0.5 ) }, // inverse texture size
399
+ 'direction': { value: new Vector2( 0.5, 0.5 ) },
400
+ 'gaussianCoefficients': { value: coefficients } // precomputed Gaussian coefficients
401
+ },
402
+
403
+ vertexShader: /* glsl */`
404
+
405
+ varying vec2 vUv;
406
+
407
+ void main() {
408
+
409
+ vUv = uv;
410
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
411
+
412
+ }`,
413
+
414
+ fragmentShader: /* glsl */`
415
+
416
+ #include <common>
417
+
418
+ varying vec2 vUv;
419
+
420
+ uniform sampler2D colorTexture;
421
+ uniform vec2 invSize;
422
+ uniform vec2 direction;
423
+ uniform float gaussianCoefficients[KERNEL_RADIUS];
424
+
425
+ void main() {
426
+
427
+ float weightSum = gaussianCoefficients[0];
428
+ vec3 diffuseSum = texture2D( colorTexture, vUv ).rgb * weightSum;
429
+
430
+ for ( int i = 1; i < KERNEL_RADIUS; i ++ ) {
431
+
432
+ float x = float( i );
433
+ float w = gaussianCoefficients[i];
434
+ vec2 uvOffset = direction * invSize * x;
435
+ vec3 sample1 = texture2D( colorTexture, vUv + uvOffset ).rgb;
436
+ vec3 sample2 = texture2D( colorTexture, vUv - uvOffset ).rgb;
437
+ diffuseSum += ( sample1 + sample2 ) * w;
438
+
439
+ }
440
+
441
+ gl_FragColor = vec4( diffuseSum, 1.0 );
442
+
443
+ }`
444
+ } );
445
+
446
+ }
447
+
448
+ _getCompositeMaterial( nMips ) {
449
+
450
+ return new ShaderMaterial( {
451
+
452
+ defines: {
453
+ 'NUM_MIPS': nMips
454
+ },
455
+
456
+ uniforms: {
457
+ 'blurTexture1': { value: null },
458
+ 'blurTexture2': { value: null },
459
+ 'blurTexture3': { value: null },
460
+ 'blurTexture4': { value: null },
461
+ 'blurTexture5': { value: null },
462
+ 'bloomStrength': { value: 1.0 },
463
+ 'bloomFactors': { value: null },
464
+ 'bloomTintColors': { value: null },
465
+ 'bloomRadius': { value: 0.0 }
466
+ },
467
+
468
+ vertexShader: /* glsl */`
469
+
470
+ varying vec2 vUv;
471
+
472
+ void main() {
473
+
474
+ vUv = uv;
475
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
476
+
477
+ }`,
478
+
479
+ fragmentShader: /* glsl */`
480
+
481
+ varying vec2 vUv;
482
+
483
+ uniform sampler2D blurTexture1;
484
+ uniform sampler2D blurTexture2;
485
+ uniform sampler2D blurTexture3;
486
+ uniform sampler2D blurTexture4;
487
+ uniform sampler2D blurTexture5;
488
+ uniform float bloomStrength;
489
+ uniform float bloomRadius;
490
+ uniform float bloomFactors[NUM_MIPS];
491
+ uniform vec3 bloomTintColors[NUM_MIPS];
492
+
493
+ float lerpBloomFactor( const in float factor ) {
494
+
495
+ float mirrorFactor = 1.2 - factor;
496
+ return mix( factor, mirrorFactor, bloomRadius );
497
+
498
+ }
499
+
500
+ void main() {
501
+
502
+ // 3.0 for backwards compatibility with previous alpha-based intensity
503
+ vec3 bloom = 3.0 * bloomStrength * (
504
+ lerpBloomFactor( bloomFactors[ 0 ] ) * bloomTintColors[ 0 ] * texture2D( blurTexture1, vUv ).rgb +
505
+ lerpBloomFactor( bloomFactors[ 1 ] ) * bloomTintColors[ 1 ] * texture2D( blurTexture2, vUv ).rgb +
506
+ lerpBloomFactor( bloomFactors[ 2 ] ) * bloomTintColors[ 2 ] * texture2D( blurTexture3, vUv ).rgb +
507
+ lerpBloomFactor( bloomFactors[ 3 ] ) * bloomTintColors[ 3 ] * texture2D( blurTexture4, vUv ).rgb +
508
+ lerpBloomFactor( bloomFactors[ 4 ] ) * bloomTintColors[ 4 ] * texture2D( blurTexture5, vUv ).rgb
509
+ );
510
+
511
+ float bloomAlpha = max( bloom.r, max( bloom.g, bloom.b ) );
512
+ gl_FragColor = vec4( bloom, bloomAlpha );
513
+
514
+ }`
515
+ } );
516
+
517
+ }
518
+
519
+ }
520
+
521
+ UnrealBloomPass.BlurDirectionX = new Vector2( 1.0, 0.0 );
522
+ UnrealBloomPass.BlurDirectionY = new Vector2( 0.0, 1.0 );
523
+
524
+ export { UnrealBloomPass };
vendor/three/examples/jsm/shaders/CopyShader.js ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @module CopyShader
3
+ * @three_import import { CopyShader } from 'three/addons/shaders/CopyShader.js';
4
+ */
5
+
6
+ /**
7
+ * Full-screen copy shader pass.
8
+ *
9
+ * @constant
10
+ * @type {ShaderMaterial~Shader}
11
+ */
12
+ const CopyShader = {
13
+
14
+ name: 'CopyShader',
15
+
16
+ uniforms: {
17
+
18
+ 'tDiffuse': { value: null },
19
+ 'opacity': { value: 1.0 }
20
+
21
+ },
22
+
23
+ vertexShader: /* glsl */`
24
+
25
+ varying vec2 vUv;
26
+
27
+ void main() {
28
+
29
+ vUv = uv;
30
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
31
+
32
+ }`,
33
+
34
+ fragmentShader: /* glsl */`
35
+
36
+ uniform float opacity;
37
+
38
+ uniform sampler2D tDiffuse;
39
+
40
+ varying vec2 vUv;
41
+
42
+ void main() {
43
+
44
+ vec4 texel = texture2D( tDiffuse, vUv );
45
+ gl_FragColor = opacity * texel;
46
+
47
+
48
+ }`
49
+
50
+ };
51
+
52
+ export { CopyShader };
vendor/three/examples/jsm/shaders/LuminosityHighPassShader.js ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ Color
3
+ } from 'three';
4
+
5
+ /**
6
+ * @module LuminosityHighPassShader
7
+ * @three_import import { LuminosityHighPassShader } from 'three/addons/shaders/LuminosityHighPassShader.js';
8
+ */
9
+
10
+ /**
11
+ * Luminosity high pass shader.
12
+ *
13
+ * @constant
14
+ * @type {ShaderMaterial~Shader}
15
+ */
16
+ const LuminosityHighPassShader = {
17
+
18
+ name: 'LuminosityHighPassShader',
19
+
20
+ uniforms: {
21
+
22
+ 'tDiffuse': { value: null },
23
+ 'luminosityThreshold': { value: 1.0 },
24
+ 'smoothWidth': { value: 1.0 },
25
+ 'defaultColor': { value: new Color( 0x000000 ) },
26
+ 'defaultOpacity': { value: 0.0 }
27
+
28
+ },
29
+
30
+ vertexShader: /* glsl */`
31
+
32
+ varying vec2 vUv;
33
+
34
+ void main() {
35
+
36
+ vUv = uv;
37
+
38
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
39
+
40
+ }`,
41
+
42
+ fragmentShader: /* glsl */`
43
+
44
+ uniform sampler2D tDiffuse;
45
+ uniform vec3 defaultColor;
46
+ uniform float defaultOpacity;
47
+ uniform float luminosityThreshold;
48
+ uniform float smoothWidth;
49
+
50
+ varying vec2 vUv;
51
+
52
+ void main() {
53
+
54
+ vec4 texel = texture2D( tDiffuse, vUv );
55
+
56
+ float v = luminance( texel.xyz );
57
+
58
+ vec4 outputColor = vec4( defaultColor.rgb, defaultOpacity );
59
+
60
+ float alpha = smoothstep( luminosityThreshold, luminosityThreshold + smoothWidth, v );
61
+
62
+ gl_FragColor = mix( outputColor, texel, alpha );
63
+
64
+ }`
65
+
66
+ };
67
+
68
+ export { LuminosityHighPassShader };
vendor/three/examples/jsm/shaders/OutputShader.js ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @module OutputShader
3
+ * @three_import import { OutputShader } from 'three/addons/shaders/OutputShader.js';
4
+ */
5
+
6
+ /**
7
+ * Performs tone mapping and color space conversion for
8
+ * FX workflows.
9
+ *
10
+ * Used by {@link OutputPass}.
11
+ *
12
+ * @constant
13
+ * @type {ShaderMaterial~Shader}
14
+ */
15
+ const OutputShader = {
16
+
17
+ name: 'OutputShader',
18
+
19
+ uniforms: {
20
+
21
+ 'tDiffuse': { value: null },
22
+ 'toneMappingExposure': { value: 1 }
23
+
24
+ },
25
+
26
+ vertexShader: /* glsl */`
27
+ precision highp float;
28
+
29
+ uniform mat4 modelViewMatrix;
30
+ uniform mat4 projectionMatrix;
31
+
32
+ attribute vec3 position;
33
+ attribute vec2 uv;
34
+
35
+ varying vec2 vUv;
36
+
37
+ void main() {
38
+
39
+ vUv = uv;
40
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
41
+
42
+ }`,
43
+
44
+ fragmentShader: /* glsl */`
45
+
46
+ precision highp float;
47
+
48
+ uniform sampler2D tDiffuse;
49
+
50
+ #include <tonemapping_pars_fragment>
51
+ #include <colorspace_pars_fragment>
52
+
53
+ varying vec2 vUv;
54
+
55
+ void main() {
56
+
57
+ gl_FragColor = texture2D( tDiffuse, vUv );
58
+
59
+ // tone mapping
60
+
61
+ #ifdef LINEAR_TONE_MAPPING
62
+
63
+ gl_FragColor.rgb = LinearToneMapping( gl_FragColor.rgb );
64
+
65
+ #elif defined( REINHARD_TONE_MAPPING )
66
+
67
+ gl_FragColor.rgb = ReinhardToneMapping( gl_FragColor.rgb );
68
+
69
+ #elif defined( CINEON_TONE_MAPPING )
70
+
71
+ gl_FragColor.rgb = CineonToneMapping( gl_FragColor.rgb );
72
+
73
+ #elif defined( ACES_FILMIC_TONE_MAPPING )
74
+
75
+ gl_FragColor.rgb = ACESFilmicToneMapping( gl_FragColor.rgb );
76
+
77
+ #elif defined( AGX_TONE_MAPPING )
78
+
79
+ gl_FragColor.rgb = AgXToneMapping( gl_FragColor.rgb );
80
+
81
+ #elif defined( NEUTRAL_TONE_MAPPING )
82
+
83
+ gl_FragColor.rgb = NeutralToneMapping( gl_FragColor.rgb );
84
+
85
+ #elif defined( CUSTOM_TONE_MAPPING )
86
+
87
+ gl_FragColor.rgb = CustomToneMapping( gl_FragColor.rgb );
88
+
89
+ #endif
90
+
91
+ // color space
92
+
93
+ #ifdef SRGB_TRANSFER
94
+
95
+ gl_FragColor = sRGBTransferOETF( gl_FragColor );
96
+
97
+ #endif
98
+
99
+ }`
100
+
101
+ };
102
+
103
+ export { OutputShader };