@react-three/postprocessing 2.1.5 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -30,7 +30,7 @@ Postprocessing also supports srgb-encoding out of the box, as well as WebGL2 MSA
30
30
 
31
31
  #### What does it look like?
32
32
 
33
- Well, you can do pretty much anything, but here's an example combining a couple of effects ([live demo](https://codesandbox.io/s/react-postprocessing-dof-blob-pqrpl?)).
33
+ Here's an example combining a couple of effects ([live demo](https://codesandbox.io/s/react-postprocessing-dof-blob-pqrpl?)).
34
34
 
35
35
  <a href="https://codesandbox.io/s/react-postprocessing-dof-blob-pqrpl?" target="_blank" rel="noopener">
36
36
  <img src="bubbles.jpg" alt="Bubbles Demo" />
@@ -56,7 +56,70 @@ function App() {
56
56
  }
57
57
  ```
58
58
 
59
- #### Documentation
59
+ ## Documentation
60
+
61
+ #### EffectComposer
62
+
63
+ The EffectComposer is must wrap all your effects. It will manage them for you.
64
+
65
+ ```jsx
66
+ <EffectComposer
67
+ enabled?: boolean
68
+ children: JSX.Element | JSX.Element[]
69
+ depthBuffer?: boolean
70
+ disableNormalPass?: boolean
71
+ stencilBuffer?: boolean
72
+ autoClear?: boolean
73
+ multisampling?: number
74
+ frameBufferType?: TextureDataType
75
+ renderPriority?: number
76
+ camera?: THREE.Camera
77
+ scene?: THREE.Scene
78
+ >
79
+ ```
80
+
81
+ #### Selection/Select
82
+
83
+ Some effects, like Outline or SelectiveBloom can select specific objects. To manage this in a declarative scene with just references can be messy, so we have two components that help you.
84
+
85
+ ```jsx
86
+ <Selection
87
+ children: JSX.Element | JSX.Element[]
88
+ enabled?: boolean
89
+ >
90
+
91
+ <Select
92
+ children: JSX.Element | JSX.Element[]
93
+ enabled?: boolean
94
+ >
95
+ ```
96
+
97
+ You wrap everything into a selection, and then select object or groups. Effects working with selections will acknowledge the selections.
98
+
99
+ ```jsx
100
+ <Selection>
101
+ <EffectComposer autoclear={false}>
102
+ <Outline blur edgeStrength={100} />
103
+ </EffectComposer>
104
+ <Select enabled>
105
+ <mesh />
106
+ </Select>
107
+ </Selection>
108
+ ```
109
+
110
+ Selection can be nested and group multiple object, higher up selection take precence over lower ones. The following for instance will select everything. Remove the outmost `enabled` and only the two mesh group is selected. You can flip the selections or bind them to interactions and state.
111
+
112
+ ```jsx
113
+ <Select enabled>
114
+ <Select enabled>
115
+ <mesh />
116
+ <mesh />
117
+ </Select>
118
+ <Select>
119
+ <mesh />
120
+ </Select>
121
+ </Select>
122
+ ```
60
123
 
61
124
  - [react-postprocessing exports](https://github.com/pmndrs/react-postprocessing/blob/master/api.md)
62
125
  - [postprocessing docs](https://vanruesc.github.io/postprocessing/public/docs/)
@@ -9,6 +9,7 @@ export declare const EffectComposerContext: React.Context<{
9
9
  scene: THREE.Scene;
10
10
  }>;
11
11
  export declare type EffectComposerProps = {
12
+ enabled?: boolean;
12
13
  children: JSX.Element | JSX.Element[];
13
14
  depthBuffer?: boolean;
14
15
  disableNormalPass?: boolean;
@@ -20,5 +21,4 @@ export declare type EffectComposerProps = {
20
21
  camera?: THREE.Camera;
21
22
  scene?: THREE.Scene;
22
23
  };
23
- declare const EffectComposer: React.MemoExoticComponent<React.ForwardRefExoticComponent<EffectComposerProps & React.RefAttributes<unknown>>>;
24
- export default EffectComposer;
24
+ export declare const EffectComposer: React.MemoExoticComponent<React.ForwardRefExoticComponent<EffectComposerProps & React.RefAttributes<unknown>>>;
@@ -0,0 +1,16 @@
1
+ import * as THREE from 'three';
2
+ import React from 'react';
3
+ export declare type Api = {
4
+ selected: THREE.Object3D[];
5
+ select: React.Dispatch<React.SetStateAction<THREE.Object3D[]>>;
6
+ enabled: boolean;
7
+ };
8
+ export declare type SelectApi = JSX.IntrinsicElements['group'] & {
9
+ enabled?: boolean;
10
+ };
11
+ export declare const selectionContext: React.Context<Api>;
12
+ export declare function Selection({ children, enabled }: {
13
+ enabled?: boolean;
14
+ children: React.ReactNode;
15
+ }): JSX.Element;
16
+ export declare function Select({ enabled, children, ...props }: SelectApi): JSX.Element;
@@ -1,13 +1,14 @@
1
1
  import { OutlineEffect } from 'postprocessing';
2
2
  import React, { MutableRefObject } from 'react';
3
3
  import { Object3D } from 'three';
4
+ import { BlendFunction } from 'postprocessing';
4
5
  declare type ObjectRef = MutableRefObject<Object3D>;
5
6
  export declare type OutlineProps = ConstructorParameters<typeof OutlineEffect>[2] & Partial<{
6
7
  selection: Object3D | Object3D[] | ObjectRef | ObjectRef[];
7
8
  selectionLayer: number;
8
9
  }>;
9
10
  export declare const Outline: React.ForwardRefExoticComponent<Partial<{
10
- blendFunction: import("postprocessing").BlendFunction;
11
+ blendFunction: BlendFunction;
11
12
  patternTexture: number;
12
13
  edgeStrength: number;
13
14
  pulseSpeed: number;
package/dist/index.cjs.js CHANGED
@@ -10,6 +10,8 @@ var _extends = require('@babel/runtime/helpers/extends');
10
10
  var _construct = require('@babel/runtime/helpers/construct');
11
11
  var fiber = require('@react-three/fiber');
12
12
  var threeStdlib = require('three-stdlib');
13
+ var mergeRefs = require('react-merge-refs');
14
+ var without = require('lodash-es/without');
13
15
 
14
16
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
15
17
 
@@ -36,8 +38,10 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
36
38
  var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
37
39
  var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends);
38
40
  var _construct__default = /*#__PURE__*/_interopDefaultLegacy(_construct);
41
+ var mergeRefs__default = /*#__PURE__*/_interopDefaultLegacy(mergeRefs);
42
+ var without__default = /*#__PURE__*/_interopDefaultLegacy(without);
39
43
 
40
- var _excluded$6 = ["blendFunction", "opacity"];
44
+ var _excluded$7 = ["blendFunction", "opacity"];
41
45
 
42
46
  var isRef = function isRef(ref) {
43
47
  return !!ref.current;
@@ -54,7 +58,7 @@ var wrapEffect = function wrapEffect(effectImpl, defaultBlendMode) {
54
58
  return /*#__PURE__*/React.forwardRef(function Wrap(_ref, ref) {
55
59
  var blendFunction = _ref.blendFunction,
56
60
  opacity = _ref.opacity,
57
- props = _objectWithoutPropertiesLoose__default["default"](_ref, _excluded$6);
61
+ props = _objectWithoutPropertiesLoose__default["default"](_ref, _excluded$7);
58
62
 
59
63
  var effect = React.useMemo(function () {
60
64
  return new effectImpl(props);
@@ -125,6 +129,8 @@ var EffectComposer = /*#__PURE__*/React__default["default"].memo( /*#__PURE__*/R
125
129
  var children = _ref.children,
126
130
  camera = _ref.camera,
127
131
  scene = _ref.scene,
132
+ _ref$enabled = _ref.enabled,
133
+ enabled = _ref$enabled === void 0 ? true : _ref$enabled,
128
134
  _ref$renderPriority = _ref.renderPriority,
129
135
  renderPriority = _ref$renderPriority === void 0 ? 1 : _ref$renderPriority,
130
136
  _ref$autoClear = _ref.autoClear,
@@ -151,7 +157,7 @@ var EffectComposer = /*#__PURE__*/React__default["default"].memo( /*#__PURE__*/R
151
157
  var effectComposer = new postprocessing.EffectComposer(gl, {
152
158
  depthBuffer: depthBuffer,
153
159
  stencilBuffer: stencilBuffer,
154
- multisampling: threeStdlib.isWebGL2Available() ? multisampling : 0,
160
+ multisampling: multisampling > 0 && threeStdlib.isWebGL2Available() ? multisampling : 0,
155
161
  frameBufferType: frameBufferType
156
162
  }); // Add render pass
157
163
 
@@ -175,8 +181,11 @@ var EffectComposer = /*#__PURE__*/React__default["default"].memo( /*#__PURE__*/R
175
181
  return composer == null ? void 0 : composer.setSize(size.width, size.height);
176
182
  }, [composer, size]);
177
183
  fiber.useFrame(function (_, delta) {
178
- return void (gl.autoClear = autoClear, composer.render(delta));
179
- }, renderPriority);
184
+ if (enabled) {
185
+ gl.autoClear = autoClear;
186
+ composer.render(delta);
187
+ }
188
+ }, enabled ? renderPriority : 0);
180
189
  var group = React.useRef(null);
181
190
  React.useLayoutEffect(function () {
182
191
  var effectPass;
@@ -212,13 +221,12 @@ var EffectComposer = /*#__PURE__*/React__default["default"].memo( /*#__PURE__*/R
212
221
  ref: group
213
222
  }, children));
214
223
  }));
215
- var EffectComposer$1 = EffectComposer;
216
224
 
217
- var _excluded$5 = ["target", "depthTexture"];
225
+ var _excluded$6 = ["target", "depthTexture"];
218
226
  var DepthOfField = /*#__PURE__*/React.forwardRef(function DepthOfField(_ref, ref) {
219
227
  var target = _ref.target,
220
228
  depthTexture = _ref.depthTexture,
221
- props = _objectWithoutPropertiesLoose__default["default"](_ref, _excluded$5);
229
+ props = _objectWithoutPropertiesLoose__default["default"](_ref, _excluded$6);
222
230
 
223
231
  var _useContext = React.useContext(EffectComposerContext),
224
232
  camera = _useContext.camera;
@@ -243,11 +251,11 @@ var DepthOfField = /*#__PURE__*/React.forwardRef(function DepthOfField(_ref, ref
243
251
 
244
252
  var DotScreen = wrapEffect(postprocessing.DotScreenEffect);
245
253
 
246
- var _excluded$4 = ["active"];
254
+ var _excluded$5 = ["active"];
247
255
  var Glitch = /*#__PURE__*/React.forwardRef(function Glitch(_ref, ref) {
248
256
  var _ref$active = _ref.active,
249
257
  active = _ref$active === void 0 ? true : _ref$active,
250
- props = _objectWithoutPropertiesLoose__default["default"](_ref, _excluded$4);
258
+ props = _objectWithoutPropertiesLoose__default["default"](_ref, _excluded$5);
251
259
 
252
260
  var delay = useVector2(props, 'delay');
253
261
  var duration = useVector2(props, 'duration');
@@ -283,10 +291,10 @@ var GodRays = /*#__PURE__*/React.forwardRef(function GodRays(props, ref) {
283
291
  });
284
292
  });
285
293
 
286
- var _excluded$3 = ["size"];
294
+ var _excluded$4 = ["size"];
287
295
  var Grid = /*#__PURE__*/React.forwardRef(function Grid(_ref, ref) {
288
296
  var size = _ref.size,
289
- props = _objectWithoutPropertiesLoose__default["default"](_ref, _excluded$3);
297
+ props = _objectWithoutPropertiesLoose__default["default"](_ref, _excluded$4);
290
298
 
291
299
  var effect = React.useMemo(function () {
292
300
  return new postprocessing.GridEffect(props);
@@ -305,23 +313,90 @@ var HueSaturation = wrapEffect(postprocessing.HueSaturationEffect);
305
313
 
306
314
  var Noise = wrapEffect(postprocessing.NoiseEffect, postprocessing.BlendFunction.COLOR_DODGE);
307
315
 
316
+ var _excluded$3 = ["enabled", "children"];
317
+ var selectionContext = /*#__PURE__*/React.createContext(null);
318
+ function Selection(_ref) {
319
+ var children = _ref.children,
320
+ _ref$enabled = _ref.enabled,
321
+ enabled = _ref$enabled === void 0 ? true : _ref$enabled;
322
+
323
+ var _useState = React.useState([]),
324
+ selected = _useState[0],
325
+ select = _useState[1];
326
+
327
+ var value = React.useMemo(function () {
328
+ return {
329
+ selected: selected,
330
+ select: select,
331
+ enabled: enabled
332
+ };
333
+ }, [selected, select, enabled]);
334
+ return /*#__PURE__*/React__default["default"].createElement(selectionContext.Provider, {
335
+ value: value
336
+ }, children);
337
+ }
338
+ function Select(_ref2) {
339
+ var _ref2$enabled = _ref2.enabled,
340
+ enabled = _ref2$enabled === void 0 ? false : _ref2$enabled,
341
+ children = _ref2.children,
342
+ props = _objectWithoutPropertiesLoose__default["default"](_ref2, _excluded$3);
343
+
344
+ var group = React.useRef(null);
345
+ var api = React.useContext(selectionContext);
346
+ React.useEffect(function () {
347
+ if (api && enabled) {
348
+ var changed = false;
349
+ var current = [];
350
+ group.current.traverse(function (o) {
351
+ o.type === 'Mesh' && current.push(o);
352
+ if (api.selected.indexOf(o) === -1) changed = true;
353
+ });
354
+
355
+ if (changed) {
356
+ api.select(function (state) {
357
+ return [].concat(state, current);
358
+ });
359
+ return function () {
360
+ api.select(function (state) {
361
+ return without__default["default"].apply(void 0, [state].concat(current));
362
+ });
363
+ };
364
+ }
365
+ }
366
+ }, [enabled, children]);
367
+ return /*#__PURE__*/React__default["default"].createElement("group", _extends__default["default"]({
368
+ ref: group
369
+ }, props), children);
370
+ }
371
+
308
372
  var _excluded$2 = ["selection", "selectionLayer", "blendFunction", "patternTexture", "edgeStrength", "pulseSpeed", "visibleEdgeColor", "hiddenEdgeColor", "width", "height", "kernelSize", "blur", "xRay"];
309
- var Outline = /*#__PURE__*/React.forwardRef(function Outline(_ref, ref) {
373
+ var Outline = /*#__PURE__*/React.forwardRef(function Outline(_ref, forwardRef) {
310
374
  var _ref$selection = _ref.selection,
311
375
  selection = _ref$selection === void 0 ? [] : _ref$selection,
312
376
  _ref$selectionLayer = _ref.selectionLayer,
313
377
  selectionLayer = _ref$selectionLayer === void 0 ? 10 : _ref$selectionLayer,
314
- blendFunction = _ref.blendFunction,
315
- patternTexture = _ref.patternTexture,
316
- edgeStrength = _ref.edgeStrength,
317
- pulseSpeed = _ref.pulseSpeed,
318
- visibleEdgeColor = _ref.visibleEdgeColor,
319
- hiddenEdgeColor = _ref.hiddenEdgeColor,
320
- width = _ref.width,
321
- height = _ref.height,
322
- kernelSize = _ref.kernelSize,
323
- blur = _ref.blur,
324
- xRay = _ref.xRay;
378
+ _ref$blendFunction = _ref.blendFunction,
379
+ blendFunction = _ref$blendFunction === void 0 ? postprocessing.BlendFunction.SCREEN : _ref$blendFunction,
380
+ _ref$patternTexture = _ref.patternTexture,
381
+ patternTexture = _ref$patternTexture === void 0 ? null : _ref$patternTexture,
382
+ _ref$edgeStrength = _ref.edgeStrength,
383
+ edgeStrength = _ref$edgeStrength === void 0 ? 1 : _ref$edgeStrength,
384
+ _ref$pulseSpeed = _ref.pulseSpeed,
385
+ pulseSpeed = _ref$pulseSpeed === void 0 ? 0 : _ref$pulseSpeed,
386
+ _ref$visibleEdgeColor = _ref.visibleEdgeColor,
387
+ visibleEdgeColor = _ref$visibleEdgeColor === void 0 ? 0xffffff : _ref$visibleEdgeColor,
388
+ _ref$hiddenEdgeColor = _ref.hiddenEdgeColor,
389
+ hiddenEdgeColor = _ref$hiddenEdgeColor === void 0 ? 0xffffff : _ref$hiddenEdgeColor,
390
+ _ref$width = _ref.width,
391
+ width = _ref$width === void 0 ? postprocessing.Resizer.AUTO_SIZE : _ref$width,
392
+ _ref$height = _ref.height,
393
+ height = _ref$height === void 0 ? postprocessing.Resizer.AUTO_SIZE : _ref$height,
394
+ _ref$kernelSize = _ref.kernelSize,
395
+ kernelSize = _ref$kernelSize === void 0 ? postprocessing.KernelSize.VERY_SMALL : _ref$kernelSize,
396
+ _ref$blur = _ref.blur,
397
+ blur = _ref$blur === void 0 ? false : _ref$blur,
398
+ _ref$xRay = _ref.xRay,
399
+ xRay = _ref$xRay === void 0 ? true : _ref$xRay;
325
400
  _objectWithoutPropertiesLoose__default["default"](_ref, _excluded$2);
326
401
 
327
402
  var _useContext = React.useContext(EffectComposerContext),
@@ -354,10 +429,26 @@ var Outline = /*#__PURE__*/React.forwardRef(function Outline(_ref, ref) {
354
429
  React.useEffect(function () {
355
430
  effect.selectionLayer = selectionLayer;
356
431
  }, [effect, selectionLayer]);
432
+ var api = React.useContext(selectionContext);
433
+ var ref = React.useRef();
434
+ React.useEffect(function () {
435
+ if (api && api.enabled) {
436
+ var _api$selected;
437
+
438
+ var _effect = ref.current;
439
+
440
+ if ((_api$selected = api.selected) != null && _api$selected.length) {
441
+ _effect.selection.set(api.selected);
442
+
443
+ return function () {
444
+ return void _effect.selection.clear();
445
+ };
446
+ }
447
+ }
448
+ }, [api]);
357
449
  return /*#__PURE__*/React__default["default"].createElement("primitive", {
358
- ref: ref,
359
- object: effect,
360
- dispose: null
450
+ ref: mergeRefs__default["default"]([ref, forwardRef]),
451
+ object: effect
361
452
  });
362
453
  });
363
454
 
@@ -386,7 +477,7 @@ var removeLight = function removeLight(light, effect) {
386
477
  return light.layers.disable(effect.selection.layer);
387
478
  };
388
479
 
389
- var SelectiveBloom = /*#__PURE__*/React.forwardRef(function SelectiveBloom(_ref, ref) {
480
+ var SelectiveBloom = /*#__PURE__*/React.forwardRef(function SelectiveBloom(_ref, forwardRef) {
390
481
  var _ref$selection = _ref.selection,
391
482
  selection = _ref$selection === void 0 ? [] : _ref$selection,
392
483
  _ref$selectionLayer = _ref.selectionLayer,
@@ -442,8 +533,25 @@ var SelectiveBloom = /*#__PURE__*/React.forwardRef(function SelectiveBloom(_ref,
442
533
  };
443
534
  }
444
535
  }, [effect, lights, selectionLayer]);
536
+ var api = React.useContext(selectionContext);
537
+ var ref = React.useRef();
538
+ React.useEffect(function () {
539
+ if (api && api.enabled) {
540
+ var _api$selected;
541
+
542
+ var _effect = ref.current;
543
+
544
+ if ((_api$selected = api.selected) != null && _api$selected.length) {
545
+ _effect.selection.set(api.selected);
546
+
547
+ return function () {
548
+ return void _effect.selection.clear();
549
+ };
550
+ }
551
+ }
552
+ }, [api]);
445
553
  return /*#__PURE__*/React__default["default"].createElement("primitive", {
446
- ref: ref,
554
+ ref: mergeRefs__default["default"]([ref, forwardRef]),
447
555
  object: effect,
448
556
  dispose: null
449
557
  });
@@ -558,7 +666,7 @@ exports.ColorDepth = ColorDepth;
558
666
  exports.Depth = Depth;
559
667
  exports.DepthOfField = DepthOfField;
560
668
  exports.DotScreen = DotScreen;
561
- exports.EffectComposer = EffectComposer$1;
669
+ exports.EffectComposer = EffectComposer;
562
670
  exports.EffectComposerContext = EffectComposerContext;
563
671
  exports.Glitch = Glitch;
564
672
  exports.GodRays = GodRays;
@@ -571,9 +679,12 @@ exports.Pixelation = Pixelation;
571
679
  exports.SMAA = SMAA;
572
680
  exports.SSAO = SSAO;
573
681
  exports.Scanline = Scanline;
682
+ exports.Select = Select;
683
+ exports.Selection = Selection;
574
684
  exports.SelectiveBloom = SelectiveBloom;
575
685
  exports.Sepia = Sepia;
576
686
  exports.ShockWave = ShockWave;
577
687
  exports.Texture = Texture;
578
688
  exports.ToneMapping = ToneMapping;
579
689
  exports.Vignette = Vignette;
690
+ exports.selectionContext = selectionContext;
package/dist/index.d.ts CHANGED
@@ -23,4 +23,5 @@ export * from './effects/ToneMapping';
23
23
  export * from './effects/Vignette';
24
24
  export * from './effects/ShockWave';
25
25
  export * from './effects/LUT';
26
- export { default as EffectComposer, EffectComposerContext } from './EffectComposer';
26
+ export * from './Selection';
27
+ export * from './EffectComposer';
package/dist/index.js CHANGED
@@ -1,9 +1,12 @@
1
- import { BlendFunction, BloomEffect, BrightnessContrastEffect, ChromaticAberrationEffect, ColorAverageEffect, ColorDepthEffect, DepthEffect, EffectComposer as EffectComposer$2, RenderPass, NormalPass, EffectPass, DepthOfFieldEffect, DotScreenEffect, GlitchEffect, GlitchMode, GodRaysEffect, GridEffect, HueSaturationEffect, NoiseEffect, OutlineEffect, PixelationEffect, ScanlineEffect, SelectiveBloomEffect, SepiaEffect, SSAOEffect, SMAAPreset, EdgeDetectionMode, SMAAImageLoader, SMAAEffect, TextureEffect, ToneMappingEffect, VignetteEffect, ShockWaveEffect, LUTEffect } from 'postprocessing';
2
- import React, { forwardRef, useMemo, useLayoutEffect, createContext, useRef, useImperativeHandle, useContext, useEffect } from 'react';
1
+ import { BlendFunction, BloomEffect, BrightnessContrastEffect, ChromaticAberrationEffect, ColorAverageEffect, ColorDepthEffect, DepthEffect, EffectComposer as EffectComposer$1, RenderPass, NormalPass, EffectPass, DepthOfFieldEffect, DotScreenEffect, GlitchEffect, GlitchMode, GodRaysEffect, GridEffect, HueSaturationEffect, NoiseEffect, Resizer, KernelSize, OutlineEffect, PixelationEffect, ScanlineEffect, SelectiveBloomEffect, SepiaEffect, SSAOEffect, SMAAPreset, EdgeDetectionMode, SMAAImageLoader, SMAAEffect, TextureEffect, ToneMappingEffect, VignetteEffect, ShockWaveEffect, LUTEffect } from 'postprocessing';
2
+ import React, { forwardRef, useMemo, useLayoutEffect, createContext, useRef, useImperativeHandle, useContext, useState, useEffect } from 'react';
3
3
  import * as THREE from 'three';
4
4
  import { Vector2, Vector3, TextureLoader, sRGBEncoding, RepeatWrapping } from 'three';
5
5
  import { useThree, useFrame, useLoader } from '@react-three/fiber';
6
6
  import { isWebGL2Available } from 'three-stdlib';
7
+ import mergeRefs from 'react-merge-refs';
8
+ import _extends from '@babel/runtime/helpers/esm/extends';
9
+ import without from 'lodash-es/without';
7
10
 
8
11
  const isRef = ref => !!ref.current;
9
12
 
@@ -83,6 +86,7 @@ const EffectComposer = /*#__PURE__*/React.memo( /*#__PURE__*/forwardRef((_ref, r
83
86
  children,
84
87
  camera,
85
88
  scene,
89
+ enabled = true,
86
90
  renderPriority = 1,
87
91
  autoClear = true,
88
92
  depthBuffer,
@@ -101,10 +105,10 @@ const EffectComposer = /*#__PURE__*/React.memo( /*#__PURE__*/forwardRef((_ref, r
101
105
  camera = camera || defaultCamera;
102
106
  const [composer, normalPass] = useMemo(() => {
103
107
  // Initialize composer
104
- const effectComposer = new EffectComposer$2(gl, {
108
+ const effectComposer = new EffectComposer$1(gl, {
105
109
  depthBuffer,
106
110
  stencilBuffer,
107
- multisampling: isWebGL2Available() ? multisampling : 0,
111
+ multisampling: multisampling > 0 && isWebGL2Available() ? multisampling : 0,
108
112
  frameBufferType
109
113
  }); // Add render pass
110
114
 
@@ -120,7 +124,12 @@ const EffectComposer = /*#__PURE__*/React.memo( /*#__PURE__*/forwardRef((_ref, r
120
124
  return [effectComposer, pass];
121
125
  }, [camera, gl, depthBuffer, stencilBuffer, multisampling, frameBufferType, scene, disableNormalPass]);
122
126
  useLayoutEffect(() => composer == null ? void 0 : composer.setSize(size.width, size.height), [composer, size]);
123
- useFrame((_, delta) => void (gl.autoClear = autoClear, composer.render(delta)), renderPriority);
127
+ useFrame((_, delta) => {
128
+ if (enabled) {
129
+ gl.autoClear = autoClear;
130
+ composer.render(delta);
131
+ }
132
+ }, enabled ? renderPriority : 0);
124
133
  const group = useRef(null);
125
134
  useLayoutEffect(() => {
126
135
  let effectPass;
@@ -152,7 +161,6 @@ const EffectComposer = /*#__PURE__*/React.memo( /*#__PURE__*/forwardRef((_ref, r
152
161
  ref: group
153
162
  }, children));
154
163
  }));
155
- var EffectComposer$1 = EffectComposer;
156
164
 
157
165
  const DepthOfField = /*#__PURE__*/forwardRef(function DepthOfField(_ref, ref) {
158
166
  let {
@@ -236,21 +244,67 @@ const HueSaturation = wrapEffect(HueSaturationEffect);
236
244
 
237
245
  const Noise = wrapEffect(NoiseEffect, BlendFunction.COLOR_DODGE);
238
246
 
239
- const Outline = /*#__PURE__*/forwardRef(function Outline(_ref, ref) {
247
+ const selectionContext = /*#__PURE__*/createContext(null);
248
+ function Selection(_ref) {
249
+ let {
250
+ children,
251
+ enabled = true
252
+ } = _ref;
253
+ const [selected, select] = useState([]);
254
+ const value = useMemo(() => ({
255
+ selected,
256
+ select,
257
+ enabled
258
+ }), [selected, select, enabled]);
259
+ return /*#__PURE__*/React.createElement(selectionContext.Provider, {
260
+ value: value
261
+ }, children);
262
+ }
263
+ function Select(_ref2) {
264
+ let {
265
+ enabled = false,
266
+ children,
267
+ ...props
268
+ } = _ref2;
269
+ const group = useRef(null);
270
+ const api = useContext(selectionContext);
271
+ useEffect(() => {
272
+ if (api && enabled) {
273
+ let changed = false;
274
+ const current = [];
275
+ group.current.traverse(o => {
276
+ o.type === 'Mesh' && current.push(o);
277
+ if (api.selected.indexOf(o) === -1) changed = true;
278
+ });
279
+
280
+ if (changed) {
281
+ api.select(state => [...state, ...current]);
282
+ return () => {
283
+ api.select(state => without(state, ...current));
284
+ };
285
+ }
286
+ }
287
+ }, [enabled, children]);
288
+ return /*#__PURE__*/React.createElement("group", _extends({
289
+ ref: group
290
+ }, props), children);
291
+ }
292
+
293
+ const Outline = /*#__PURE__*/forwardRef(function Outline(_ref, forwardRef) {
240
294
  let {
241
295
  selection = [],
242
296
  selectionLayer = 10,
243
- blendFunction,
244
- patternTexture,
245
- edgeStrength,
246
- pulseSpeed,
247
- visibleEdgeColor,
248
- hiddenEdgeColor,
249
- width,
250
- height,
251
- kernelSize,
252
- blur,
253
- xRay,
297
+ blendFunction = BlendFunction.SCREEN,
298
+ patternTexture = null,
299
+ edgeStrength = 1,
300
+ pulseSpeed = 0,
301
+ visibleEdgeColor = 0xffffff,
302
+ hiddenEdgeColor = 0xffffff,
303
+ width = Resizer.AUTO_SIZE,
304
+ height = Resizer.AUTO_SIZE,
305
+ kernelSize = KernelSize.VERY_SMALL,
306
+ blur = false,
307
+ xRay = true,
254
308
  ...props
255
309
  } = _ref;
256
310
  const {
@@ -279,10 +333,23 @@ const Outline = /*#__PURE__*/forwardRef(function Outline(_ref, ref) {
279
333
  useEffect(() => {
280
334
  effect.selectionLayer = selectionLayer;
281
335
  }, [effect, selectionLayer]);
336
+ const api = useContext(selectionContext);
337
+ const ref = useRef();
338
+ useEffect(() => {
339
+ if (api && api.enabled) {
340
+ var _api$selected;
341
+
342
+ const effect = ref.current;
343
+
344
+ if ((_api$selected = api.selected) != null && _api$selected.length) {
345
+ effect.selection.set(api.selected);
346
+ return () => void effect.selection.clear();
347
+ }
348
+ }
349
+ }, [api]);
282
350
  return /*#__PURE__*/React.createElement("primitive", {
283
- ref: ref,
284
- object: effect,
285
- dispose: null
351
+ ref: mergeRefs([ref, forwardRef]),
352
+ object: effect
286
353
  });
287
354
  });
288
355
 
@@ -306,7 +373,7 @@ const addLight = (light, effect) => light.layers.enable(effect.selection.layer);
306
373
 
307
374
  const removeLight = (light, effect) => light.layers.disable(effect.selection.layer);
308
375
 
309
- const SelectiveBloom = /*#__PURE__*/forwardRef(function SelectiveBloom(_ref, ref) {
376
+ const SelectiveBloom = /*#__PURE__*/forwardRef(function SelectiveBloom(_ref, forwardRef) {
310
377
  let {
311
378
  selection = [],
312
379
  selectionLayer = 10,
@@ -351,8 +418,22 @@ const SelectiveBloom = /*#__PURE__*/forwardRef(function SelectiveBloom(_ref, ref
351
418
  return () => lights.forEach(light => removeLight(resolveRef(light), effect));
352
419
  }
353
420
  }, [effect, lights, selectionLayer]);
421
+ const api = useContext(selectionContext);
422
+ const ref = useRef();
423
+ useEffect(() => {
424
+ if (api && api.enabled) {
425
+ var _api$selected;
426
+
427
+ const effect = ref.current;
428
+
429
+ if ((_api$selected = api.selected) != null && _api$selected.length) {
430
+ effect.selection.set(api.selected);
431
+ return () => void effect.selection.clear();
432
+ }
433
+ }
434
+ }, [api]);
354
435
  return /*#__PURE__*/React.createElement("primitive", {
355
- ref: ref,
436
+ ref: mergeRefs([ref, forwardRef]),
356
437
  object: effect,
357
438
  dispose: null
358
439
  });
@@ -454,4 +535,4 @@ const LUT = /*#__PURE__*/forwardRef(function LUT(_ref, ref) {
454
535
  });
455
536
  });
456
537
 
457
- export { Bloom, BrightnessContrast, ChromaticAberration, ColorAverage, ColorDepth, Depth, DepthOfField, DotScreen, EffectComposer$1 as EffectComposer, EffectComposerContext, Glitch, GodRays, Grid, HueSaturation, LUT, Noise, Outline, Pixelation, SMAA, SSAO, Scanline, SelectiveBloom, Sepia, ShockWave, Texture, ToneMapping, Vignette };
538
+ export { Bloom, BrightnessContrast, ChromaticAberration, ColorAverage, ColorDepth, Depth, DepthOfField, DotScreen, EffectComposer, EffectComposerContext, Glitch, GodRays, Grid, HueSaturation, LUT, Noise, Outline, Pixelation, SMAA, SSAO, Scanline, Select, Selection, SelectiveBloom, Sepia, ShockWave, Texture, ToneMapping, Vignette, selectionContext };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/postprocessing",
3
- "version": "2.1.5",
3
+ "version": "2.2.1",
4
4
  "description": "postprocessing wrapper for React and @react-three/fiber",
5
5
  "keywords": [
6
6
  "postprocessing",
@@ -38,6 +38,7 @@
38
38
  "typegen": "tsc --emitDeclarationOnly || true"
39
39
  },
40
40
  "dependencies": {
41
+ "lodash-es": "^4.17.21",
41
42
  "postprocessing": "^6.24.1",
42
43
  "react-merge-refs": "^1.1.0",
43
44
  "three-stdlib": "^2.8.6"