@react-three/postprocessing 2.1.4 → 2.2.0

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>
102
+ <Outline xRay blur edgeStrength={100} width={1000} />
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,18 +313,77 @@ 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,
378
+ _ref$blendFunction = _ref.blendFunction,
379
+ blendFunction = _ref$blendFunction === void 0 ? postprocessing.BlendFunction.ADD : _ref$blendFunction,
315
380
  patternTexture = _ref.patternTexture,
316
381
  edgeStrength = _ref.edgeStrength,
317
382
  pulseSpeed = _ref.pulseSpeed,
318
- visibleEdgeColor = _ref.visibleEdgeColor,
319
- hiddenEdgeColor = _ref.hiddenEdgeColor,
383
+ _ref$visibleEdgeColor = _ref.visibleEdgeColor,
384
+ visibleEdgeColor = _ref$visibleEdgeColor === void 0 ? 0xffffff : _ref$visibleEdgeColor,
385
+ _ref$hiddenEdgeColor = _ref.hiddenEdgeColor,
386
+ hiddenEdgeColor = _ref$hiddenEdgeColor === void 0 ? 0xffffff : _ref$hiddenEdgeColor,
320
387
  width = _ref.width,
321
388
  height = _ref.height,
322
389
  kernelSize = _ref.kernelSize,
@@ -354,10 +421,26 @@ var Outline = /*#__PURE__*/React.forwardRef(function Outline(_ref, ref) {
354
421
  React.useEffect(function () {
355
422
  effect.selectionLayer = selectionLayer;
356
423
  }, [effect, selectionLayer]);
424
+ var api = React.useContext(selectionContext);
425
+ var ref = React.useRef();
426
+ React.useEffect(function () {
427
+ if (api && api.enabled) {
428
+ var _api$selected;
429
+
430
+ var _effect = ref.current;
431
+
432
+ if ((_api$selected = api.selected) != null && _api$selected.length) {
433
+ _effect.selection.set(api.selected);
434
+
435
+ return function () {
436
+ return void _effect.selection.clear();
437
+ };
438
+ }
439
+ }
440
+ }, [api]);
357
441
  return /*#__PURE__*/React__default["default"].createElement("primitive", {
358
- ref: ref,
359
- object: effect,
360
- dispose: null
442
+ ref: mergeRefs__default["default"]([ref, forwardRef]),
443
+ object: effect
361
444
  });
362
445
  });
363
446
 
@@ -386,7 +469,7 @@ var removeLight = function removeLight(light, effect) {
386
469
  return light.layers.disable(effect.selection.layer);
387
470
  };
388
471
 
389
- var SelectiveBloom = /*#__PURE__*/React.forwardRef(function SelectiveBloom(_ref, ref) {
472
+ var SelectiveBloom = /*#__PURE__*/React.forwardRef(function SelectiveBloom(_ref, forwardRef) {
390
473
  var _ref$selection = _ref.selection,
391
474
  selection = _ref$selection === void 0 ? [] : _ref$selection,
392
475
  _ref$selectionLayer = _ref.selectionLayer,
@@ -442,8 +525,25 @@ var SelectiveBloom = /*#__PURE__*/React.forwardRef(function SelectiveBloom(_ref,
442
525
  };
443
526
  }
444
527
  }, [effect, lights, selectionLayer]);
528
+ var api = React.useContext(selectionContext);
529
+ var ref = React.useRef();
530
+ React.useEffect(function () {
531
+ if (api && api.enabled) {
532
+ var _api$selected;
533
+
534
+ var _effect = ref.current;
535
+
536
+ if ((_api$selected = api.selected) != null && _api$selected.length) {
537
+ _effect.selection.set(api.selected);
538
+
539
+ return function () {
540
+ return void _effect.selection.clear();
541
+ };
542
+ }
543
+ }
544
+ }, [api]);
445
545
  return /*#__PURE__*/React__default["default"].createElement("primitive", {
446
- ref: ref,
546
+ ref: mergeRefs__default["default"]([ref, forwardRef]),
447
547
  object: effect,
448
548
  dispose: null
449
549
  });
@@ -558,7 +658,7 @@ exports.ColorDepth = ColorDepth;
558
658
  exports.Depth = Depth;
559
659
  exports.DepthOfField = DepthOfField;
560
660
  exports.DotScreen = DotScreen;
561
- exports.EffectComposer = EffectComposer$1;
661
+ exports.EffectComposer = EffectComposer;
562
662
  exports.EffectComposerContext = EffectComposerContext;
563
663
  exports.Glitch = Glitch;
564
664
  exports.GodRays = GodRays;
@@ -571,9 +671,12 @@ exports.Pixelation = Pixelation;
571
671
  exports.SMAA = SMAA;
572
672
  exports.SSAO = SSAO;
573
673
  exports.Scanline = Scanline;
674
+ exports.Select = Select;
675
+ exports.Selection = Selection;
574
676
  exports.SelectiveBloom = SelectiveBloom;
575
677
  exports.Sepia = Sepia;
576
678
  exports.ShockWave = ShockWave;
577
679
  exports.Texture = Texture;
578
680
  exports.ToneMapping = ToneMapping;
579
681
  exports.Vignette = Vignette;
682
+ 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, 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,16 +244,62 @@ 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,
297
+ blendFunction = BlendFunction.ADD,
244
298
  patternTexture,
245
299
  edgeStrength,
246
300
  pulseSpeed,
247
- visibleEdgeColor,
248
- hiddenEdgeColor,
301
+ visibleEdgeColor = 0xffffff,
302
+ hiddenEdgeColor = 0xffffff,
249
303
  width,
250
304
  height,
251
305
  kernelSize,
@@ -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.4",
3
+ "version": "2.2.0",
4
4
  "description": "postprocessing wrapper for React and @react-three/fiber",
5
5
  "keywords": [
6
6
  "postprocessing",
@@ -38,7 +38,8 @@
38
38
  "typegen": "tsc --emitDeclarationOnly || true"
39
39
  },
40
40
  "dependencies": {
41
- "postprocessing": "^6.24.0",
41
+ "lodash-es": "^4.17.21",
42
+ "postprocessing": "^6.24.1",
42
43
  "react-merge-refs": "^1.1.0",
43
44
  "three-stdlib": "^2.8.6"
44
45
  },