@react-three/postprocessing 2.9.1 → 2.10.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 +25 -96
- package/dist/Autofocus.d.ts +43 -0
- package/dist/effects/ScanlineEffect.d.ts +1 -0
- package/dist/index.cjs +86 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +90 -9
- package/dist/util.d.ts +1 -1
- package/package.json +15 -11
package/README.md
CHANGED
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/@react-three/postprocessing)
|
|
5
5
|
[](https://discord.gg/ZZjjNvJ)
|
|
6
6
|
|
|
7
|
-
`react-postprocessing` is a
|
|
7
|
+
`react-postprocessing` is a
|
|
8
|
+
[postprocessing](https://github.com/pmndrs/postprocessing) wrapper for
|
|
9
|
+
[@react-three/fiber](https://github.com/pmndrs/react-three-fiber). This is not
|
|
10
|
+
(yet) meant for complex orchestration of effects, but can save you
|
|
11
|
+
[hundreds of LOC](https://twitter.com/0xca0a/status/1289501594698960897) for a
|
|
12
|
+
straight forward effects-chain.
|
|
8
13
|
|
|
9
14
|
```bash
|
|
10
15
|
npm install @react-three/postprocessing
|
|
@@ -20,17 +25,29 @@ npm install @react-three/postprocessing
|
|
|
20
25
|
|
|
21
26
|
#### Why postprocessing and not three/examples/jsm/postprocessing?
|
|
22
27
|
|
|
23
|
-
From
|
|
28
|
+
From
|
|
29
|
+
[https://github.com/pmndrs/postprocessing](https://github.com/pmndrs/postprocessing#performance)
|
|
24
30
|
|
|
25
|
-
> This library provides an EffectPass which automatically organizes and merges
|
|
31
|
+
> This library provides an EffectPass which automatically organizes and merges
|
|
32
|
+
> any given combination of effects. This minimizes the amount of render
|
|
33
|
+
> operations and makes it possible to combine many effects without the
|
|
34
|
+
> performance penalties of traditional pass chaining. Additionally, every effect
|
|
35
|
+
> can choose its own blend function.
|
|
26
36
|
>
|
|
27
|
-
> All fullscreen render operations also use a single triangle that fills the
|
|
37
|
+
> All fullscreen render operations also use a single triangle that fills the
|
|
38
|
+
> screen. Compared to using a quad, this approach harmonizes with modern GPU
|
|
39
|
+
> rasterization patterns and eliminates unnecessary fragment calculations along
|
|
40
|
+
> the screen diagonal. This is especially beneficial for GPGPU passes and
|
|
41
|
+
> effects that use complex fragment shaders.
|
|
28
42
|
|
|
29
|
-
Postprocessing also supports srgb-encoding out of the box, as well as WebGL2
|
|
43
|
+
Postprocessing also supports srgb-encoding out of the box, as well as WebGL2
|
|
44
|
+
MSAA (multi sample anti aliasing), which is react-postprocessing's default, you
|
|
45
|
+
get high performance crisp results w/o jagged edges.
|
|
30
46
|
|
|
31
47
|
#### What does it look like?
|
|
32
48
|
|
|
33
|
-
Here's an example combining a couple of effects
|
|
49
|
+
Here's an example combining a couple of effects
|
|
50
|
+
([live demo](https://codesandbox.io/s/react-postprocessing-dof-blob-pqrpl?)).
|
|
34
51
|
|
|
35
52
|
<a href="https://codesandbox.io/s/react-postprocessing-dof-blob-pqrpl?" target="_blank" rel="noopener">
|
|
36
53
|
<img src="bubbles.jpg" alt="Bubbles Demo" />
|
|
@@ -38,7 +55,7 @@ Here's an example combining a couple of effects ([live demo](https://codesandbox
|
|
|
38
55
|
|
|
39
56
|
```jsx
|
|
40
57
|
import React from 'react'
|
|
41
|
-
import {
|
|
58
|
+
import { Bloom, DepthOfField, EffectComposer, Noise, Vignette } from '@react-three/postprocessing'
|
|
42
59
|
import { Canvas } from '@react-three/fiber'
|
|
43
60
|
|
|
44
61
|
function App() {
|
|
@@ -58,93 +75,5 @@ function App() {
|
|
|
58
75
|
|
|
59
76
|
## Documentation
|
|
60
77
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
The EffectComposer 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
|
-
/** For effects that support DepthDownsamplingPass */
|
|
76
|
-
resolutionScale?: number
|
|
77
|
-
renderPriority?: number
|
|
78
|
-
camera?: THREE.Camera
|
|
79
|
-
scene?: THREE.Scene
|
|
80
|
-
>
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
#### Selection/Select
|
|
84
|
-
|
|
85
|
-
Some effects, like Outline or SelectiveBloom can select specific objects. To manage this in a declarative scene with just references can be messy, especially when things have to be grouped. These two components take care of it:
|
|
86
|
-
|
|
87
|
-
```jsx
|
|
88
|
-
<Selection
|
|
89
|
-
children: JSX.Element | JSX.Element[]
|
|
90
|
-
enabled?: boolean
|
|
91
|
-
>
|
|
92
|
-
|
|
93
|
-
<Select
|
|
94
|
-
children: JSX.Element | JSX.Element[]
|
|
95
|
-
enabled?: boolean
|
|
96
|
-
>
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
You wrap everything into a selection, this one holds all the selections. Now you can individually select objects or groups. Effects that support selections (for instance `Outline`) will acknowledge it.
|
|
100
|
-
|
|
101
|
-
```jsx
|
|
102
|
-
<Selection>
|
|
103
|
-
<EffectComposer autoclear={false}>
|
|
104
|
-
<Outline blur edgeStrength={100} />
|
|
105
|
-
</EffectComposer>
|
|
106
|
-
<Select enabled>
|
|
107
|
-
<mesh />
|
|
108
|
-
</Select>
|
|
109
|
-
</Selection>
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
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.
|
|
113
|
-
|
|
114
|
-
```jsx
|
|
115
|
-
<Select enabled>
|
|
116
|
-
<Select enabled>
|
|
117
|
-
<mesh />
|
|
118
|
-
<mesh />
|
|
119
|
-
</Select>
|
|
120
|
-
<Select>
|
|
121
|
-
<mesh />
|
|
122
|
-
</Select>
|
|
123
|
-
</Select>
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
#### Selective bloom
|
|
127
|
-
|
|
128
|
-
Bloom is selective by default, you control it not on the effect pass but on the materials by lifting their colors out of 0-1 range. a `luminanceThreshold` of 1 ensures that ootb nothing will glow, only the materials you pick. For this to work `toneMapped` has to be false on the materials, because it would otherwise clamp colors between 0 and 1 again.
|
|
129
|
-
|
|
130
|
-
```jsx
|
|
131
|
-
<Bloom mipmapBlur luminanceThreshold={1} />
|
|
132
|
-
|
|
133
|
-
// ❌ will not glow, same as RGB [1,0,0]
|
|
134
|
-
<meshStandardMaterial color="red"/>
|
|
135
|
-
|
|
136
|
-
// ✅ will glow, same as RGB [2,0,0]
|
|
137
|
-
<meshStandardMaterial emissive="red" emissiveIntensity={2} toneMapped={false} />
|
|
138
|
-
|
|
139
|
-
// ❌ will not glow, same as RGB [1,0,0]
|
|
140
|
-
<meshBasicMaterial color="red" />
|
|
141
|
-
|
|
142
|
-
// ❌ will not glow, same as RGB [1,0,0], tone-mapping will clamp colors between 0 and 1
|
|
143
|
-
<meshBasicMaterial color={[2,0,0]} />
|
|
144
|
-
|
|
145
|
-
// ✅ will glow, same as RGB [2,0,0]
|
|
146
|
-
<meshBasicMaterial color={[2,0,0]} toneMapped={false} />
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
- [react-postprocessing exports](https://github.com/pmndrs/react-postprocessing/blob/master/api.md)
|
|
78
|
+
- [react-postprocessing docs](https://docs.pmnd.rs/react-postprocessing)
|
|
150
79
|
- [postprocessing docs](https://pmndrs.github.io/postprocessing/public/docs/)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import React, { RefObject } from 'react';
|
|
3
|
+
import { DepthOfFieldEffect } from 'postprocessing';
|
|
4
|
+
import { DepthOfField } from './index';
|
|
5
|
+
export type AutofocusProps = typeof DepthOfField & {
|
|
6
|
+
target?: [number, number, number];
|
|
7
|
+
mouse?: boolean;
|
|
8
|
+
debug?: number;
|
|
9
|
+
manual?: boolean;
|
|
10
|
+
smoothTime?: number;
|
|
11
|
+
};
|
|
12
|
+
export type AutofocusApi = {
|
|
13
|
+
dofRef: RefObject<DepthOfFieldEffect>;
|
|
14
|
+
hitpoint: THREE.Vector3;
|
|
15
|
+
update: (delta: number, updateTarget: boolean) => void;
|
|
16
|
+
};
|
|
17
|
+
export declare const Autofocus: React.ForwardRefExoticComponent<React.ForwardRefExoticComponent<{
|
|
18
|
+
blendFunction?: import("postprocessing").BlendFunction | undefined;
|
|
19
|
+
worldFocusDistance?: number | undefined;
|
|
20
|
+
worldFocusRange?: number | undefined;
|
|
21
|
+
focusDistance?: number | undefined;
|
|
22
|
+
focalLength?: number | undefined;
|
|
23
|
+
focusRange?: number | undefined;
|
|
24
|
+
bokehScale?: number | undefined;
|
|
25
|
+
resolutionScale?: number | undefined;
|
|
26
|
+
resolutionX?: number | undefined;
|
|
27
|
+
resolutionY?: number | undefined;
|
|
28
|
+
width?: number | undefined;
|
|
29
|
+
height?: number | undefined;
|
|
30
|
+
} & Partial<{
|
|
31
|
+
target: import("@react-three/fiber").Vector3;
|
|
32
|
+
depthTexture: {
|
|
33
|
+
texture: THREE.Texture;
|
|
34
|
+
packing: number;
|
|
35
|
+
};
|
|
36
|
+
blur: number;
|
|
37
|
+
}> & React.RefAttributes<DepthOfFieldEffect>> & {
|
|
38
|
+
target?: [number, number, number] | undefined;
|
|
39
|
+
mouse?: boolean | undefined;
|
|
40
|
+
debug?: number | undefined;
|
|
41
|
+
manual?: boolean | undefined;
|
|
42
|
+
smoothTime?: number | undefined;
|
|
43
|
+
} & React.RefAttributes<AutofocusApi>>;
|
package/dist/index.cjs
CHANGED
|
@@ -7,6 +7,7 @@ var THREE = require('three');
|
|
|
7
7
|
var fiber = require('@react-three/fiber');
|
|
8
8
|
var threeStdlib = require('three-stdlib');
|
|
9
9
|
var screenSpaceReflections = require('screen-space-reflections');
|
|
10
|
+
var maath = require('maath');
|
|
10
11
|
|
|
11
12
|
function _interopNamespaceDefault(e) {
|
|
12
13
|
var n = Object.create(null);
|
|
@@ -56,7 +57,9 @@ const useVector2 = (props, key) => {
|
|
|
56
57
|
}, [value]);
|
|
57
58
|
};
|
|
58
59
|
|
|
59
|
-
const Bloom = wrapEffect(postprocessing.BloomEffect, {
|
|
60
|
+
const Bloom = wrapEffect(postprocessing.BloomEffect, {
|
|
61
|
+
blendFunction: postprocessing.BlendFunction.ADD,
|
|
62
|
+
});
|
|
60
63
|
|
|
61
64
|
const BrightnessContrast = wrapEffect(postprocessing.BrightnessContrastEffect);
|
|
62
65
|
|
|
@@ -156,7 +159,13 @@ const EffectComposer = React.memo(React.forwardRef(({ children, camera: _camera,
|
|
|
156
159
|
const DepthOfField = React.forwardRef(function DepthOfField({ target, depthTexture, ...props }, ref) {
|
|
157
160
|
const invalidate = fiber.useThree((state) => state.invalidate);
|
|
158
161
|
const { camera } = React.useContext(EffectComposerContext);
|
|
159
|
-
const effect = React.useMemo(() =>
|
|
162
|
+
const effect = React.useMemo(() => {
|
|
163
|
+
const effect = new postprocessing.DepthOfFieldEffect(camera, props);
|
|
164
|
+
// Temporary fix that restores DOF 6.21.3 behavior, everything since then lets shapes leak through the blur
|
|
165
|
+
const maskMaterial = effect.maskPass.getFullscreenMaterial();
|
|
166
|
+
maskMaterial.maskFunction = postprocessing.MaskFunction.MULTIPLY_RGB_SET_ALPHA;
|
|
167
|
+
return effect;
|
|
168
|
+
}, [camera, props]);
|
|
160
169
|
React.useLayoutEffect(() => {
|
|
161
170
|
if (target && typeof target !== 'number') {
|
|
162
171
|
const vec = target instanceof THREE.Vector3
|
|
@@ -308,7 +317,7 @@ const Pixelation = React.forwardRef(function Pixelation({ granularity = 5 }, ref
|
|
|
308
317
|
return jsxRuntime.jsx("primitive", { ref: ref, object: effect, dispose: null });
|
|
309
318
|
});
|
|
310
319
|
|
|
311
|
-
const Scanline = wrapEffect(postprocessing.ScanlineEffect, { blendFunction: postprocessing.BlendFunction.OVERLAY });
|
|
320
|
+
const Scanline = wrapEffect(postprocessing.ScanlineEffect, { blendFunction: postprocessing.BlendFunction.OVERLAY, density: 1.25 });
|
|
312
321
|
|
|
313
322
|
const addLight = (light, effect) => light.layers.enable(effect.selection.layer);
|
|
314
323
|
const removeLight = (light, effect) => light.layers.disable(effect.selection.layer);
|
|
@@ -356,7 +365,6 @@ const SelectiveBloom = React.forwardRef(function SelectiveBloom({ selection = []
|
|
|
356
365
|
};
|
|
357
366
|
}
|
|
358
367
|
}, [effect, invalidate, lights, selectionLayer]);
|
|
359
|
-
React.useRef();
|
|
360
368
|
React.useEffect(() => {
|
|
361
369
|
var _a;
|
|
362
370
|
if (api && api.enabled) {
|
|
@@ -542,6 +550,80 @@ const SSR = React.forwardRef(function SSR({ ENABLE_BLUR = true, USE_MRT = true,
|
|
|
542
550
|
return jsxRuntime.jsx("primitive", { ref: ref, object: effect, ...props });
|
|
543
551
|
});
|
|
544
552
|
|
|
553
|
+
const Autofocus = React.forwardRef(({ target = undefined, mouse: followMouse = false, debug = undefined, manual = false, smoothTime = 0, ...props }, fref) => {
|
|
554
|
+
const dofRef = React.useRef(null);
|
|
555
|
+
const hitpointRef = React.useRef(null);
|
|
556
|
+
const targetRef = React.useRef(null);
|
|
557
|
+
const scene = fiber.useThree(({ scene }) => scene);
|
|
558
|
+
const pointer = fiber.useThree(({ pointer }) => pointer);
|
|
559
|
+
const { composer, camera } = React.useContext(EffectComposerContext);
|
|
560
|
+
// see: https://codesandbox.io/s/depthpickingpass-x130hg
|
|
561
|
+
const [depthPickingPass] = React.useState(new postprocessing.DepthPickingPass());
|
|
562
|
+
const [copyPass] = React.useState(new postprocessing.CopyPass());
|
|
563
|
+
React.useEffect(() => {
|
|
564
|
+
composer.addPass(depthPickingPass);
|
|
565
|
+
composer.addPass(copyPass);
|
|
566
|
+
return () => {
|
|
567
|
+
composer.removePass(depthPickingPass);
|
|
568
|
+
composer.removePass(copyPass);
|
|
569
|
+
};
|
|
570
|
+
}, [composer, depthPickingPass, copyPass]);
|
|
571
|
+
const [hitpoint] = React.useState(new THREE__namespace.Vector3(0, 0, 0));
|
|
572
|
+
const [ndc] = React.useState(new THREE__namespace.Vector3(0, 0, 0));
|
|
573
|
+
const getHit = React.useCallback(async (x, y) => {
|
|
574
|
+
ndc.x = x;
|
|
575
|
+
ndc.y = y;
|
|
576
|
+
ndc.z = await depthPickingPass.readDepth(ndc);
|
|
577
|
+
ndc.z = ndc.z * 2.0 - 1.0;
|
|
578
|
+
const hit = 1 - ndc.z > 0.0000001; // it is missed if ndc.z is close to 1
|
|
579
|
+
return hit ? ndc.unproject(camera) : false;
|
|
580
|
+
}, [ndc, depthPickingPass, camera]);
|
|
581
|
+
const update = React.useCallback(async (delta, updateTarget = true) => {
|
|
582
|
+
var _a;
|
|
583
|
+
// Update hitpoint
|
|
584
|
+
if (target) {
|
|
585
|
+
hitpoint.set(...target);
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
const { x, y } = followMouse ? pointer : { x: 0, y: 0 };
|
|
589
|
+
const hit = await getHit(x, y);
|
|
590
|
+
if (hit)
|
|
591
|
+
hitpoint.copy(hit);
|
|
592
|
+
}
|
|
593
|
+
// Update target
|
|
594
|
+
if (updateTarget && ((_a = dofRef.current) === null || _a === void 0 ? void 0 : _a.target)) {
|
|
595
|
+
if (smoothTime > 0 && delta > 0) {
|
|
596
|
+
maath.easing.damp3(dofRef.current.target, hitpoint, smoothTime, delta);
|
|
597
|
+
}
|
|
598
|
+
else {
|
|
599
|
+
dofRef.current.target.copy(hitpoint);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}, [target, hitpoint, followMouse, getHit, smoothTime, pointer]);
|
|
603
|
+
fiber.useFrame(async (_, delta) => {
|
|
604
|
+
var _a;
|
|
605
|
+
if (!manual) {
|
|
606
|
+
update(delta);
|
|
607
|
+
}
|
|
608
|
+
if (hitpointRef.current) {
|
|
609
|
+
hitpointRef.current.position.copy(hitpoint);
|
|
610
|
+
}
|
|
611
|
+
if (targetRef.current && ((_a = dofRef.current) === null || _a === void 0 ? void 0 : _a.target)) {
|
|
612
|
+
targetRef.current.position.copy(dofRef.current.target);
|
|
613
|
+
}
|
|
614
|
+
});
|
|
615
|
+
// Ref API
|
|
616
|
+
React.useImperativeHandle(fref, () => ({
|
|
617
|
+
dofRef,
|
|
618
|
+
hitpoint,
|
|
619
|
+
update,
|
|
620
|
+
}), [hitpoint, update]);
|
|
621
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [debug
|
|
622
|
+
? fiber.createPortal(jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("mesh", { ref: hitpointRef, children: [jsxRuntime.jsx("sphereGeometry", { args: [debug, 16, 16] }), jsxRuntime.jsx("meshBasicMaterial", { color: "#00ff00", opacity: 1, transparent: true, depthWrite: false })] }), jsxRuntime.jsxs("mesh", { ref: targetRef, children: [jsxRuntime.jsx("sphereGeometry", { args: [debug / 2, 16, 16] }), jsxRuntime.jsx("meshBasicMaterial", { color: "#00ff00", opacity: 0.5, transparent: true, depthWrite: false })] })] }), scene)
|
|
623
|
+
: null, jsxRuntime.jsx(DepthOfField, { ref: dofRef, ...props, target: hitpoint })] }));
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
exports.Autofocus = Autofocus;
|
|
545
627
|
exports.Bloom = Bloom;
|
|
546
628
|
exports.BrightnessContrast = BrightnessContrast;
|
|
547
629
|
exports.ChromaticAberration = ChromaticAberration;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { BlendFunction, BloomEffect, BrightnessContrastEffect, ChromaticAberrationEffect, ColorAverageEffect, ColorDepthEffect, DepthEffect, EffectComposer as EffectComposer$1, RenderPass, NormalPass, DepthDownsamplingPass, EffectPass, DepthOfFieldEffect, DotScreenEffect, GlitchEffect, GlitchMode, GodRaysEffect, GridEffect, HueSaturationEffect, NoiseEffect, OutlineEffect, PixelationEffect, ScanlineEffect, SelectiveBloomEffect, SepiaEffect, SSAOEffect, SMAAEffect, TextureEffect, ToneMappingEffect, VignetteEffect, ShockWaveEffect, LUT3DEffect, TiltShiftEffect as TiltShiftEffect$1, Effect, EffectAttribute } from 'postprocessing';
|
|
2
|
-
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
import React, { forwardRef, useMemo, createContext, useEffect, useRef, useLayoutEffect, useImperativeHandle, useContext, useState } from 'react';
|
|
1
|
+
import { BlendFunction, BloomEffect, BrightnessContrastEffect, ChromaticAberrationEffect, ColorAverageEffect, ColorDepthEffect, DepthEffect, EffectComposer as EffectComposer$1, RenderPass, NormalPass, DepthDownsamplingPass, EffectPass, DepthOfFieldEffect, MaskFunction, DotScreenEffect, GlitchEffect, GlitchMode, GodRaysEffect, GridEffect, HueSaturationEffect, NoiseEffect, OutlineEffect, PixelationEffect, ScanlineEffect, SelectiveBloomEffect, SepiaEffect, SSAOEffect, SMAAEffect, TextureEffect, ToneMappingEffect, VignetteEffect, ShockWaveEffect, LUT3DEffect, TiltShiftEffect as TiltShiftEffect$1, Effect, EffectAttribute, DepthPickingPass, CopyPass } from 'postprocessing';
|
|
2
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import React, { forwardRef, useMemo, createContext, useEffect, useRef, useLayoutEffect, useImperativeHandle, useContext, useState, useCallback } from 'react';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
5
|
import { HalfFloatType, Vector3, TextureLoader, sRGBEncoding, RepeatWrapping, Uniform } from 'three';
|
|
6
|
-
import { extend, useThree, useFrame, useInstanceHandle, useLoader } from '@react-three/fiber';
|
|
6
|
+
import { extend, useThree, useFrame, useInstanceHandle, useLoader, createPortal } from '@react-three/fiber';
|
|
7
7
|
import { isWebGL2Available } from 'three-stdlib';
|
|
8
8
|
import { SSREffect } from 'screen-space-reflections';
|
|
9
|
+
import { easing } from 'maath';
|
|
9
10
|
|
|
10
11
|
const resolveRef = (ref) => typeof ref === 'object' && ref != null && 'current' in ref ? ref.current : ref;
|
|
11
12
|
let i = 0;
|
|
@@ -36,7 +37,9 @@ const useVector2 = (props, key) => {
|
|
|
36
37
|
}, [value]);
|
|
37
38
|
};
|
|
38
39
|
|
|
39
|
-
const Bloom = wrapEffect(BloomEffect, {
|
|
40
|
+
const Bloom = wrapEffect(BloomEffect, {
|
|
41
|
+
blendFunction: BlendFunction.ADD,
|
|
42
|
+
});
|
|
40
43
|
|
|
41
44
|
const BrightnessContrast = wrapEffect(BrightnessContrastEffect);
|
|
42
45
|
|
|
@@ -136,7 +139,13 @@ const EffectComposer = React.memo(forwardRef(({ children, camera: _camera, scene
|
|
|
136
139
|
const DepthOfField = forwardRef(function DepthOfField({ target, depthTexture, ...props }, ref) {
|
|
137
140
|
const invalidate = useThree((state) => state.invalidate);
|
|
138
141
|
const { camera } = useContext(EffectComposerContext);
|
|
139
|
-
const effect = useMemo(() =>
|
|
142
|
+
const effect = useMemo(() => {
|
|
143
|
+
const effect = new DepthOfFieldEffect(camera, props);
|
|
144
|
+
// Temporary fix that restores DOF 6.21.3 behavior, everything since then lets shapes leak through the blur
|
|
145
|
+
const maskMaterial = effect.maskPass.getFullscreenMaterial();
|
|
146
|
+
maskMaterial.maskFunction = MaskFunction.MULTIPLY_RGB_SET_ALPHA;
|
|
147
|
+
return effect;
|
|
148
|
+
}, [camera, props]);
|
|
140
149
|
useLayoutEffect(() => {
|
|
141
150
|
if (target && typeof target !== 'number') {
|
|
142
151
|
const vec = target instanceof Vector3
|
|
@@ -288,7 +297,7 @@ const Pixelation = forwardRef(function Pixelation({ granularity = 5 }, ref) {
|
|
|
288
297
|
return jsx("primitive", { ref: ref, object: effect, dispose: null });
|
|
289
298
|
});
|
|
290
299
|
|
|
291
|
-
const Scanline = wrapEffect(ScanlineEffect, { blendFunction: BlendFunction.OVERLAY });
|
|
300
|
+
const Scanline = wrapEffect(ScanlineEffect, { blendFunction: BlendFunction.OVERLAY, density: 1.25 });
|
|
292
301
|
|
|
293
302
|
const addLight = (light, effect) => light.layers.enable(effect.selection.layer);
|
|
294
303
|
const removeLight = (light, effect) => light.layers.disable(effect.selection.layer);
|
|
@@ -336,7 +345,6 @@ const SelectiveBloom = forwardRef(function SelectiveBloom({ selection = [], sele
|
|
|
336
345
|
};
|
|
337
346
|
}
|
|
338
347
|
}, [effect, invalidate, lights, selectionLayer]);
|
|
339
|
-
useRef();
|
|
340
348
|
useEffect(() => {
|
|
341
349
|
var _a;
|
|
342
350
|
if (api && api.enabled) {
|
|
@@ -522,4 +530,77 @@ const SSR = forwardRef(function SSR({ ENABLE_BLUR = true, USE_MRT = true, ...pro
|
|
|
522
530
|
return jsx("primitive", { ref: ref, object: effect, ...props });
|
|
523
531
|
});
|
|
524
532
|
|
|
525
|
-
|
|
533
|
+
const Autofocus = forwardRef(({ target = undefined, mouse: followMouse = false, debug = undefined, manual = false, smoothTime = 0, ...props }, fref) => {
|
|
534
|
+
const dofRef = useRef(null);
|
|
535
|
+
const hitpointRef = useRef(null);
|
|
536
|
+
const targetRef = useRef(null);
|
|
537
|
+
const scene = useThree(({ scene }) => scene);
|
|
538
|
+
const pointer = useThree(({ pointer }) => pointer);
|
|
539
|
+
const { composer, camera } = useContext(EffectComposerContext);
|
|
540
|
+
// see: https://codesandbox.io/s/depthpickingpass-x130hg
|
|
541
|
+
const [depthPickingPass] = useState(new DepthPickingPass());
|
|
542
|
+
const [copyPass] = useState(new CopyPass());
|
|
543
|
+
useEffect(() => {
|
|
544
|
+
composer.addPass(depthPickingPass);
|
|
545
|
+
composer.addPass(copyPass);
|
|
546
|
+
return () => {
|
|
547
|
+
composer.removePass(depthPickingPass);
|
|
548
|
+
composer.removePass(copyPass);
|
|
549
|
+
};
|
|
550
|
+
}, [composer, depthPickingPass, copyPass]);
|
|
551
|
+
const [hitpoint] = useState(new THREE.Vector3(0, 0, 0));
|
|
552
|
+
const [ndc] = useState(new THREE.Vector3(0, 0, 0));
|
|
553
|
+
const getHit = useCallback(async (x, y) => {
|
|
554
|
+
ndc.x = x;
|
|
555
|
+
ndc.y = y;
|
|
556
|
+
ndc.z = await depthPickingPass.readDepth(ndc);
|
|
557
|
+
ndc.z = ndc.z * 2.0 - 1.0;
|
|
558
|
+
const hit = 1 - ndc.z > 0.0000001; // it is missed if ndc.z is close to 1
|
|
559
|
+
return hit ? ndc.unproject(camera) : false;
|
|
560
|
+
}, [ndc, depthPickingPass, camera]);
|
|
561
|
+
const update = useCallback(async (delta, updateTarget = true) => {
|
|
562
|
+
var _a;
|
|
563
|
+
// Update hitpoint
|
|
564
|
+
if (target) {
|
|
565
|
+
hitpoint.set(...target);
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
const { x, y } = followMouse ? pointer : { x: 0, y: 0 };
|
|
569
|
+
const hit = await getHit(x, y);
|
|
570
|
+
if (hit)
|
|
571
|
+
hitpoint.copy(hit);
|
|
572
|
+
}
|
|
573
|
+
// Update target
|
|
574
|
+
if (updateTarget && ((_a = dofRef.current) === null || _a === void 0 ? void 0 : _a.target)) {
|
|
575
|
+
if (smoothTime > 0 && delta > 0) {
|
|
576
|
+
easing.damp3(dofRef.current.target, hitpoint, smoothTime, delta);
|
|
577
|
+
}
|
|
578
|
+
else {
|
|
579
|
+
dofRef.current.target.copy(hitpoint);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}, [target, hitpoint, followMouse, getHit, smoothTime, pointer]);
|
|
583
|
+
useFrame(async (_, delta) => {
|
|
584
|
+
var _a;
|
|
585
|
+
if (!manual) {
|
|
586
|
+
update(delta);
|
|
587
|
+
}
|
|
588
|
+
if (hitpointRef.current) {
|
|
589
|
+
hitpointRef.current.position.copy(hitpoint);
|
|
590
|
+
}
|
|
591
|
+
if (targetRef.current && ((_a = dofRef.current) === null || _a === void 0 ? void 0 : _a.target)) {
|
|
592
|
+
targetRef.current.position.copy(dofRef.current.target);
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
// Ref API
|
|
596
|
+
useImperativeHandle(fref, () => ({
|
|
597
|
+
dofRef,
|
|
598
|
+
hitpoint,
|
|
599
|
+
update,
|
|
600
|
+
}), [hitpoint, update]);
|
|
601
|
+
return (jsxs(Fragment, { children: [debug
|
|
602
|
+
? createPortal(jsxs(Fragment, { children: [jsxs("mesh", { ref: hitpointRef, children: [jsx("sphereGeometry", { args: [debug, 16, 16] }), jsx("meshBasicMaterial", { color: "#00ff00", opacity: 1, transparent: true, depthWrite: false })] }), jsxs("mesh", { ref: targetRef, children: [jsx("sphereGeometry", { args: [debug / 2, 16, 16] }), jsx("meshBasicMaterial", { color: "#00ff00", opacity: 0.5, transparent: true, depthWrite: false })] })] }), scene)
|
|
603
|
+
: null, jsx(DepthOfField, { ref: dofRef, ...props, target: hitpoint })] }));
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
export { Autofocus, Bloom, BrightnessContrast, ChromaticAberration, ColorAverage, ColorDepth, Depth, DepthOfField, DotScreen, EffectComposer, EffectComposerContext, Glitch, GodRays, Grid, HueSaturation, LUT, Noise, Outline, Pixelation, SMAA, SSAO, SSR, Scanline, Select, Selection, SelectiveBloom, Sepia, ShockWave, Texture, TiltShift, TiltShift2, TiltShiftEffect, ToneMapping, Vignette, resolveRef, selectionContext, useVector2, wrapEffect };
|
package/dist/util.d.ts
CHANGED
|
@@ -9,5 +9,5 @@ export type EffectProps<T extends EffectConstructor> = ReactThreeFiber.Node<T ex
|
|
|
9
9
|
blendFunction?: BlendFunction;
|
|
10
10
|
opacity?: number;
|
|
11
11
|
};
|
|
12
|
-
export declare const wrapEffect: <T extends EffectConstructor, P extends EffectProps<T>>(effect: T, defaults?: P | undefined) => React.ForwardRefExoticComponent<React.PropsWithoutRef<P> & React.RefAttributes<T>>;
|
|
12
|
+
export declare const wrapEffect: <T extends EffectConstructor, P extends EffectProps<T> = EffectProps<T>>(effect: T, defaults?: P | undefined) => React.ForwardRefExoticComponent<React.PropsWithoutRef<P> & React.RefAttributes<T>>;
|
|
13
13
|
export declare const useVector2: (props: Record<string, unknown>, key: string) => THREE.Vector2;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-three/postprocessing",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.10.0",
|
|
4
4
|
"description": "postprocessing wrapper for React and @react-three/fiber",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"postprocessing",
|
|
@@ -33,7 +33,19 @@
|
|
|
33
33
|
"eslint --fix"
|
|
34
34
|
]
|
|
35
35
|
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"prebuild": "rimraf dist && yarn typegen",
|
|
38
|
+
"build": "rollup -c",
|
|
39
|
+
"prepare": "yarn build",
|
|
40
|
+
"eslint": "eslint . --fix --ext=js,ts,jsx,tsx",
|
|
41
|
+
"eslint:ci": "eslint . --ext=js,ts,jsx,tsx",
|
|
42
|
+
"test": "echo no tests yet",
|
|
43
|
+
"typecheck": "tsc --noEmit --emitDeclarationOnly false --strict --jsx react",
|
|
44
|
+
"typegen": "tsc --emitDeclarationOnly || true",
|
|
45
|
+
"release": "semantic-release"
|
|
46
|
+
},
|
|
36
47
|
"dependencies": {
|
|
48
|
+
"maath": "^0.5.3",
|
|
37
49
|
"postprocessing": "^6.30.2",
|
|
38
50
|
"screen-space-reflections": "2.5.0",
|
|
39
51
|
"three-stdlib": "^2.21.10"
|
|
@@ -63,6 +75,7 @@
|
|
|
63
75
|
"rimraf": "^5.0.0",
|
|
64
76
|
"rollup": "^3.21.0",
|
|
65
77
|
"rollup-plugin-filesize": "^10.0.0",
|
|
78
|
+
"semantic-release": "^21.0.2",
|
|
66
79
|
"three": "^0.151.3",
|
|
67
80
|
"typescript": "^5.0.4"
|
|
68
81
|
},
|
|
@@ -70,14 +83,5 @@
|
|
|
70
83
|
"@react-three/fiber": ">=8.0",
|
|
71
84
|
"react": ">=18.0",
|
|
72
85
|
"three": ">= 0.138.0 < 0.152.0"
|
|
73
|
-
},
|
|
74
|
-
"scripts": {
|
|
75
|
-
"prebuild": "rimraf dist && yarn typegen",
|
|
76
|
-
"build": "rollup -c",
|
|
77
|
-
"eslint": "eslint . --fix --ext=js,ts,jsx,tsx",
|
|
78
|
-
"eslint:ci": "eslint . --ext=js,ts,jsx,tsx",
|
|
79
|
-
"test": "echo no tests yet",
|
|
80
|
-
"typecheck": "tsc --noEmit --emitDeclarationOnly false --strict --jsx react",
|
|
81
|
-
"typegen": "tsc --emitDeclarationOnly || true"
|
|
82
86
|
}
|
|
83
|
-
}
|
|
87
|
+
}
|