@react-three/postprocessing 2.12.4 → 2.13.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/dist/effects/ASCII.d.ts +16 -0
- package/dist/effects/N8AO.d.ts +3 -0
- package/dist/index.cjs +171 -81
- package/dist/index.d.ts +6 -5
- package/dist/index.js +173 -84
- package/package.json +3 -3
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { Effect } from 'postprocessing';
|
|
3
|
+
interface IASCIIEffectProps {
|
|
4
|
+
characters?: string;
|
|
5
|
+
fontSize?: number;
|
|
6
|
+
cellSize?: number;
|
|
7
|
+
color?: string;
|
|
8
|
+
invert?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare class ASCIIEffect extends Effect {
|
|
11
|
+
constructor({ characters, fontSize, cellSize, color, invert, }?: IASCIIEffectProps);
|
|
12
|
+
/** Draws the characters on a Canvas and returns a texture */
|
|
13
|
+
createCharactersTexture(characters: string, fontSize: number): THREE.Texture;
|
|
14
|
+
}
|
|
15
|
+
export declare const ASCII: import("react").ForwardRefExoticComponent<IASCIIEffectProps & import("react").RefAttributes<ASCIIEffect>>;
|
|
16
|
+
export {};
|
package/dist/effects/N8AO.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
import { ReactThreeFiber } from '@react-three/fiber';
|
|
2
3
|
type N8AOProps = {
|
|
3
4
|
aoRadius?: number;
|
|
4
5
|
distanceFalloff?: number;
|
|
@@ -7,6 +8,8 @@ type N8AOProps = {
|
|
|
7
8
|
aoSamples?: number;
|
|
8
9
|
denoiseSamples?: number;
|
|
9
10
|
denoiseRadius?: number;
|
|
11
|
+
color?: ReactThreeFiber.Color;
|
|
12
|
+
screenSpaceRadius?: boolean;
|
|
10
13
|
};
|
|
11
14
|
export declare const N8AO: import("react").ForwardRefExoticComponent<N8AOProps & import("react").RefAttributes<N8AOPostPass>>;
|
|
12
15
|
export {};
|
package/dist/index.cjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var THREE = require('three');
|
|
5
4
|
var React = require('react');
|
|
5
|
+
var THREE = require('three');
|
|
6
6
|
var fiber = require('@react-three/fiber');
|
|
7
7
|
var postprocessing = require('postprocessing');
|
|
8
|
-
var maath = require('maath');
|
|
9
8
|
var threeStdlib = require('three-stdlib');
|
|
10
|
-
var
|
|
9
|
+
var maath = require('maath');
|
|
11
10
|
var screenSpaceReflections = require('screen-space-reflections');
|
|
11
|
+
var n8ao = require('n8ao');
|
|
12
12
|
|
|
13
13
|
function _interopNamespaceDefault(e) {
|
|
14
14
|
var n = Object.create(null);
|
|
@@ -29,6 +29,35 @@ function _interopNamespaceDefault(e) {
|
|
|
29
29
|
|
|
30
30
|
var THREE__namespace = /*#__PURE__*/_interopNamespaceDefault(THREE);
|
|
31
31
|
|
|
32
|
+
const selectionContext = React.createContext(null);
|
|
33
|
+
function Selection({ children, enabled = true }) {
|
|
34
|
+
const [selected, select] = React.useState([]);
|
|
35
|
+
const value = React.useMemo(() => ({ selected, select, enabled }), [selected, select, enabled]);
|
|
36
|
+
return jsxRuntime.jsx(selectionContext.Provider, { value: value, children: children });
|
|
37
|
+
}
|
|
38
|
+
function Select({ enabled = false, children, ...props }) {
|
|
39
|
+
const group = React.useRef(null);
|
|
40
|
+
const api = React.useContext(selectionContext);
|
|
41
|
+
React.useEffect(() => {
|
|
42
|
+
if (api && enabled) {
|
|
43
|
+
let changed = false;
|
|
44
|
+
const current = [];
|
|
45
|
+
group.current.traverse((o) => {
|
|
46
|
+
o.type === 'Mesh' && current.push(o);
|
|
47
|
+
if (api.selected.indexOf(o) === -1)
|
|
48
|
+
changed = true;
|
|
49
|
+
});
|
|
50
|
+
if (changed) {
|
|
51
|
+
api.select((state) => [...state, ...current]);
|
|
52
|
+
return () => {
|
|
53
|
+
api.select((state) => state.filter((selected) => !current.includes(selected)));
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}, [enabled, children, api]);
|
|
58
|
+
return (jsxRuntime.jsx("group", { ref: group, ...props, children: children }));
|
|
59
|
+
}
|
|
60
|
+
|
|
32
61
|
const EffectComposerContext = React.createContext(null);
|
|
33
62
|
const EffectComposer = React.memo(React.forwardRef(({ children, camera: _camera, scene: _scene, resolutionScale, enabled = true, renderPriority = 1, autoClear = true, depthBuffer, disableNormalPass, stencilBuffer, multisampling = 8, frameBufferType = THREE.HalfFloatType, }, ref) => {
|
|
34
63
|
const { gl, scene: defaultScene, camera: defaultCamera, size } = fiber.useThree();
|
|
@@ -120,6 +149,35 @@ const EffectComposer = React.memo(React.forwardRef(({ children, camera: _camera,
|
|
|
120
149
|
return (jsxRuntime.jsx(EffectComposerContext.Provider, { value: state, children: jsxRuntime.jsx("group", { ref: group, children: children }) }));
|
|
121
150
|
}));
|
|
122
151
|
|
|
152
|
+
const resolveRef = (ref) => typeof ref === 'object' && ref != null && 'current' in ref ? ref.current : ref;
|
|
153
|
+
let i = 0;
|
|
154
|
+
const components = new WeakMap();
|
|
155
|
+
const wrapEffect = (effect, defaults) =>
|
|
156
|
+
/* @__PURE__ */ React.forwardRef(function Effect({ blendFunction = defaults === null || defaults === void 0 ? void 0 : defaults.blendFunction, opacity = defaults === null || defaults === void 0 ? void 0 : defaults.opacity, ...props }, ref) {
|
|
157
|
+
let Component = components.get(effect);
|
|
158
|
+
if (!Component) {
|
|
159
|
+
const key = `@react-three/postprocessing/${effect.name}-${i++}`;
|
|
160
|
+
fiber.extend({ [key]: effect });
|
|
161
|
+
components.set(effect, (Component = key));
|
|
162
|
+
}
|
|
163
|
+
const camera = fiber.useThree((state) => state.camera);
|
|
164
|
+
const args = React.useMemo(() => { var _a, _b; return [...((_a = defaults === null || defaults === void 0 ? void 0 : defaults.args) !== null && _a !== void 0 ? _a : []), ...((_b = props.args) !== null && _b !== void 0 ? _b : [{ ...defaults, ...props }])]; },
|
|
165
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
166
|
+
[JSON.stringify(props)]);
|
|
167
|
+
return (jsxRuntime.jsx(Component, { camera: camera, "blendMode-blendFunction": blendFunction, "blendMode-opacity-value": opacity, ...props, ref: ref, args: args }));
|
|
168
|
+
});
|
|
169
|
+
const useVector2 = (props, key) => {
|
|
170
|
+
const value = props[key];
|
|
171
|
+
return React.useMemo(() => {
|
|
172
|
+
if (typeof value === 'number')
|
|
173
|
+
return new THREE__namespace.Vector2(value, value);
|
|
174
|
+
else if (value)
|
|
175
|
+
return new THREE__namespace.Vector2(...value);
|
|
176
|
+
else
|
|
177
|
+
return new THREE__namespace.Vector2();
|
|
178
|
+
}, [value]);
|
|
179
|
+
};
|
|
180
|
+
|
|
123
181
|
const DepthOfField = React.forwardRef(function DepthOfField({ target, depthTexture, ...props }, ref) {
|
|
124
182
|
const invalidate = fiber.useThree((state) => state.invalidate);
|
|
125
183
|
const { camera } = React.useContext(EffectComposerContext);
|
|
@@ -224,35 +282,6 @@ const Autofocus = React.forwardRef(({ target = undefined, mouse: followMouse = f
|
|
|
224
282
|
: null, jsxRuntime.jsx(DepthOfField, { ref: dofRef, ...props, target: hitpoint })] }));
|
|
225
283
|
});
|
|
226
284
|
|
|
227
|
-
const resolveRef = (ref) => typeof ref === 'object' && ref != null && 'current' in ref ? ref.current : ref;
|
|
228
|
-
let i = 0;
|
|
229
|
-
const components = new WeakMap();
|
|
230
|
-
const wrapEffect = (effect, defaults) =>
|
|
231
|
-
/* @__PURE__ */ React.forwardRef(function Effect({ blendFunction = defaults === null || defaults === void 0 ? void 0 : defaults.blendFunction, opacity = defaults === null || defaults === void 0 ? void 0 : defaults.opacity, ...props }, ref) {
|
|
232
|
-
let Component = components.get(effect);
|
|
233
|
-
if (!Component) {
|
|
234
|
-
const key = `@react-three/postprocessing/${effect.name}-${i++}`;
|
|
235
|
-
fiber.extend({ [key]: effect });
|
|
236
|
-
components.set(effect, (Component = key));
|
|
237
|
-
}
|
|
238
|
-
const camera = fiber.useThree((state) => state.camera);
|
|
239
|
-
const args = React.useMemo(() => { var _a, _b; return [...((_a = defaults === null || defaults === void 0 ? void 0 : defaults.args) !== null && _a !== void 0 ? _a : []), ...((_b = props.args) !== null && _b !== void 0 ? _b : [{ ...defaults, ...props }])]; },
|
|
240
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
241
|
-
[JSON.stringify(props)]);
|
|
242
|
-
return (jsxRuntime.jsx(Component, { camera: camera, "blendMode-blendFunction": blendFunction, "blendMode-opacity-value": opacity, ...props, ref: ref, args: args }));
|
|
243
|
-
});
|
|
244
|
-
const useVector2 = (props, key) => {
|
|
245
|
-
const value = props[key];
|
|
246
|
-
return React.useMemo(() => {
|
|
247
|
-
if (typeof value === 'number')
|
|
248
|
-
return new THREE__namespace.Vector2(value, value);
|
|
249
|
-
else if (value)
|
|
250
|
-
return new THREE__namespace.Vector2(...value);
|
|
251
|
-
else
|
|
252
|
-
return new THREE__namespace.Vector2();
|
|
253
|
-
}, [value]);
|
|
254
|
-
};
|
|
255
|
-
|
|
256
285
|
const Bloom = wrapEffect(postprocessing.BloomEffect, {
|
|
257
286
|
blendFunction: postprocessing.BlendFunction.ADD,
|
|
258
287
|
});
|
|
@@ -313,35 +342,6 @@ const HueSaturation = wrapEffect(postprocessing.HueSaturationEffect);
|
|
|
313
342
|
|
|
314
343
|
const Noise = wrapEffect(postprocessing.NoiseEffect, { blendFunction: postprocessing.BlendFunction.COLOR_DODGE });
|
|
315
344
|
|
|
316
|
-
const selectionContext = React.createContext(null);
|
|
317
|
-
function Selection({ children, enabled = true }) {
|
|
318
|
-
const [selected, select] = React.useState([]);
|
|
319
|
-
const value = React.useMemo(() => ({ selected, select, enabled }), [selected, select, enabled]);
|
|
320
|
-
return jsxRuntime.jsx(selectionContext.Provider, { value: value, children: children });
|
|
321
|
-
}
|
|
322
|
-
function Select({ enabled = false, children, ...props }) {
|
|
323
|
-
const group = React.useRef(null);
|
|
324
|
-
const api = React.useContext(selectionContext);
|
|
325
|
-
React.useEffect(() => {
|
|
326
|
-
if (api && enabled) {
|
|
327
|
-
let changed = false;
|
|
328
|
-
const current = [];
|
|
329
|
-
group.current.traverse((o) => {
|
|
330
|
-
o.type === 'Mesh' && current.push(o);
|
|
331
|
-
if (api.selected.indexOf(o) === -1)
|
|
332
|
-
changed = true;
|
|
333
|
-
});
|
|
334
|
-
if (changed) {
|
|
335
|
-
api.select((state) => [...state, ...current]);
|
|
336
|
-
return () => {
|
|
337
|
-
api.select((state) => state.filter((selected) => !current.includes(selected)));
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}, [enabled, children, api]);
|
|
342
|
-
return (jsxRuntime.jsx("group", { ref: group, ...props, children: children }));
|
|
343
|
-
}
|
|
344
|
-
|
|
345
345
|
const Outline = React.forwardRef(function Outline({ selection = [], selectionLayer = 10, blendFunction, patternTexture, edgeStrength, pulseSpeed, visibleEdgeColor, hiddenEdgeColor, width, height, kernelSize, blur, xRay, ...props }, forwardRef) {
|
|
346
346
|
const invalidate = fiber.useThree((state) => state.invalidate);
|
|
347
347
|
const { scene, camera } = React.useContext(EffectComposerContext);
|
|
@@ -509,26 +509,6 @@ const SSAO = React.forwardRef(function SSAO(props, ref) {
|
|
|
509
509
|
return jsxRuntime.jsx("primitive", { ref: ref, object: effect, dispose: null });
|
|
510
510
|
});
|
|
511
511
|
|
|
512
|
-
const N8AO = React.forwardRef(({ quality, aoRadius = 5, aoSamples = 16, denoiseSamples = 4, denoiseRadius = 12, distanceFalloff = 1, intensity = 1, }, ref) => {
|
|
513
|
-
const { camera, scene } = fiber.useThree();
|
|
514
|
-
const effect = React.useMemo(() => new n8ao.N8AOPostPass(scene, camera), []);
|
|
515
|
-
React.useLayoutEffect(() => {
|
|
516
|
-
Object.assign(effect.configuration, {
|
|
517
|
-
aoRadius,
|
|
518
|
-
distanceFalloff,
|
|
519
|
-
intensity,
|
|
520
|
-
aoSamples,
|
|
521
|
-
denoiseSamples,
|
|
522
|
-
denoiseRadius,
|
|
523
|
-
});
|
|
524
|
-
}, [aoRadius, distanceFalloff, intensity, aoSamples, denoiseSamples, denoiseRadius]);
|
|
525
|
-
React.useLayoutEffect(() => {
|
|
526
|
-
if (quality)
|
|
527
|
-
effect.setQualityMode(quality.charAt(0).toUpperCase() + quality.slice(1));
|
|
528
|
-
}, [quality]);
|
|
529
|
-
return jsxRuntime.jsx("primitive", { ref: ref, object: effect });
|
|
530
|
-
});
|
|
531
|
-
|
|
532
512
|
const SMAA = wrapEffect(postprocessing.SMAAEffect);
|
|
533
513
|
|
|
534
514
|
const Texture = React.forwardRef(function Texture({ textureSrc, texture, ...props }, ref) {
|
|
@@ -645,6 +625,93 @@ class TiltShiftEffect extends postprocessing.Effect {
|
|
|
645
625
|
}
|
|
646
626
|
const TiltShift2 = wrapEffect(TiltShiftEffect, { blendFunction: postprocessing.BlendFunction.NORMAL });
|
|
647
627
|
|
|
628
|
+
const fragment = `
|
|
629
|
+
uniform sampler2D uCharacters;
|
|
630
|
+
uniform float uCharactersCount;
|
|
631
|
+
uniform float uCellSize;
|
|
632
|
+
uniform bool uInvert;
|
|
633
|
+
uniform vec3 uColor;
|
|
634
|
+
|
|
635
|
+
const vec2 SIZE = vec2(16.);
|
|
636
|
+
|
|
637
|
+
vec3 greyscale(vec3 color, float strength) {
|
|
638
|
+
float g = dot(color, vec3(0.299, 0.587, 0.114));
|
|
639
|
+
return mix(color, vec3(g), strength);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
vec3 greyscale(vec3 color) {
|
|
643
|
+
return greyscale(color, 1.0);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
|
|
647
|
+
vec2 cell = resolution / uCellSize;
|
|
648
|
+
vec2 grid = 1.0 / cell;
|
|
649
|
+
vec2 pixelizedUV = grid * (0.5 + floor(uv / grid));
|
|
650
|
+
vec4 pixelized = texture2D(inputBuffer, pixelizedUV);
|
|
651
|
+
float greyscaled = greyscale(pixelized.rgb).r;
|
|
652
|
+
|
|
653
|
+
if (uInvert) {
|
|
654
|
+
greyscaled = 1.0 - greyscaled;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
float characterIndex = floor((uCharactersCount - 1.0) * greyscaled);
|
|
658
|
+
vec2 characterPosition = vec2(mod(characterIndex, SIZE.x), floor(characterIndex / SIZE.y));
|
|
659
|
+
vec2 offset = vec2(characterPosition.x, -characterPosition.y) / SIZE;
|
|
660
|
+
vec2 charUV = mod(uv * (cell / SIZE), 1.0 / SIZE) - vec2(0., 1.0 / SIZE) + offset;
|
|
661
|
+
vec4 asciiCharacter = texture2D(uCharacters, charUV);
|
|
662
|
+
|
|
663
|
+
asciiCharacter.rgb = uColor * asciiCharacter.r;
|
|
664
|
+
asciiCharacter.a = pixelized.a;
|
|
665
|
+
outputColor = asciiCharacter;
|
|
666
|
+
}
|
|
667
|
+
`;
|
|
668
|
+
class ASCIIEffect extends postprocessing.Effect {
|
|
669
|
+
constructor({ characters = ` .:,'-^=*+?!|0#X%WM@`, fontSize = 54, cellSize = 16, color = '#ffffff', invert = false, } = {}) {
|
|
670
|
+
const uniforms = new Map([
|
|
671
|
+
['uCharacters', new THREE.Uniform(new THREE.Texture())],
|
|
672
|
+
['uCellSize', new THREE.Uniform(cellSize)],
|
|
673
|
+
['uCharactersCount', new THREE.Uniform(characters.length)],
|
|
674
|
+
['uColor', new THREE.Uniform(new THREE.Color(color))],
|
|
675
|
+
['uInvert', new THREE.Uniform(invert)],
|
|
676
|
+
]);
|
|
677
|
+
super('ASCIIEffect', fragment, { uniforms });
|
|
678
|
+
const charactersTextureUniform = this.uniforms.get('uCharacters');
|
|
679
|
+
if (charactersTextureUniform) {
|
|
680
|
+
charactersTextureUniform.value = this.createCharactersTexture(characters, fontSize);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
/** Draws the characters on a Canvas and returns a texture */
|
|
684
|
+
createCharactersTexture(characters, fontSize) {
|
|
685
|
+
const canvas = document.createElement('canvas');
|
|
686
|
+
const SIZE = 1024;
|
|
687
|
+
const MAX_PER_ROW = 16;
|
|
688
|
+
const CELL = SIZE / MAX_PER_ROW;
|
|
689
|
+
canvas.width = canvas.height = SIZE;
|
|
690
|
+
const texture = new THREE.CanvasTexture(canvas, undefined, THREE.RepeatWrapping, THREE.RepeatWrapping, THREE.NearestFilter, THREE.NearestFilter);
|
|
691
|
+
const context = canvas.getContext('2d');
|
|
692
|
+
if (!context) {
|
|
693
|
+
throw new Error('Context not available');
|
|
694
|
+
}
|
|
695
|
+
context.clearRect(0, 0, SIZE, SIZE);
|
|
696
|
+
context.font = `${fontSize}px arial`;
|
|
697
|
+
context.textAlign = 'center';
|
|
698
|
+
context.textBaseline = 'middle';
|
|
699
|
+
context.fillStyle = '#fff';
|
|
700
|
+
for (let i = 0; i < characters.length; i++) {
|
|
701
|
+
const char = characters[i];
|
|
702
|
+
const x = i % MAX_PER_ROW;
|
|
703
|
+
const y = Math.floor(i / MAX_PER_ROW);
|
|
704
|
+
context.fillText(char, x * CELL + CELL / 2, y * CELL + CELL / 2);
|
|
705
|
+
}
|
|
706
|
+
texture.needsUpdate = true;
|
|
707
|
+
return texture;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
const ASCII = React.forwardRef(({ characters = ` .:,'-^=*+?!|0#X%WM@`, fontSize = 54, cellSize = 16, color = '#ffffff', invert = false }, fref) => {
|
|
711
|
+
const effect = React.useMemo(() => new ASCIIEffect({ characters, fontSize, cellSize, color, invert }), [characters, fontSize, cellSize, color, invert]);
|
|
712
|
+
return jsxRuntime.jsx("primitive", { ref: fref, object: effect });
|
|
713
|
+
});
|
|
714
|
+
|
|
648
715
|
const SSR = React.forwardRef(function SSR({ ENABLE_BLUR = true, USE_MRT = true, ...props }, ref) {
|
|
649
716
|
const { invalidate } = fiber.useThree();
|
|
650
717
|
const { scene, camera } = React.useContext(EffectComposerContext);
|
|
@@ -666,6 +733,29 @@ const SSR = React.forwardRef(function SSR({ ENABLE_BLUR = true, USE_MRT = true,
|
|
|
666
733
|
return jsxRuntime.jsx("primitive", { ref: ref, object: effect, ...props });
|
|
667
734
|
});
|
|
668
735
|
|
|
736
|
+
const N8AO = React.forwardRef(({ screenSpaceRadius, quality, aoRadius = 5, aoSamples = 16, denoiseSamples = 4, denoiseRadius = 12, distanceFalloff = 1, intensity = 1, color, }, ref) => {
|
|
737
|
+
const { camera, scene } = fiber.useThree();
|
|
738
|
+
const effect = React.useMemo(() => new n8ao.N8AOPostPass(scene, camera), []);
|
|
739
|
+
React.useLayoutEffect(() => {
|
|
740
|
+
fiber.applyProps(effect.configuration, {
|
|
741
|
+
color,
|
|
742
|
+
aoRadius,
|
|
743
|
+
distanceFalloff,
|
|
744
|
+
intensity,
|
|
745
|
+
aoSamples,
|
|
746
|
+
denoiseSamples,
|
|
747
|
+
denoiseRadius,
|
|
748
|
+
screenSpaceRadius,
|
|
749
|
+
});
|
|
750
|
+
}, [screenSpaceRadius, color, aoRadius, distanceFalloff, intensity, aoSamples, denoiseSamples, denoiseRadius]);
|
|
751
|
+
React.useLayoutEffect(() => {
|
|
752
|
+
if (quality)
|
|
753
|
+
effect.setQualityMode(quality.charAt(0).toUpperCase() + quality.slice(1));
|
|
754
|
+
}, [quality]);
|
|
755
|
+
return jsxRuntime.jsx("primitive", { ref: ref, object: effect });
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
exports.ASCII = ASCII;
|
|
669
759
|
exports.Autofocus = Autofocus;
|
|
670
760
|
exports.Bloom = Bloom;
|
|
671
761
|
exports.BrightnessContrast = BrightnessContrast;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export * from './Selection';
|
|
2
|
+
export * from './EffectComposer';
|
|
3
|
+
export * from './util';
|
|
1
4
|
export * from './effects/Autofocus';
|
|
2
5
|
export * from './effects/Bloom';
|
|
3
6
|
export * from './effects/BrightnessContrast';
|
|
@@ -5,7 +8,7 @@ export * from './effects/ChromaticAberration';
|
|
|
5
8
|
export * from './effects/ColorAverage';
|
|
6
9
|
export * from './effects/ColorDepth';
|
|
7
10
|
export * from './effects/Depth';
|
|
8
|
-
export
|
|
11
|
+
export * from './effects/DepthOfField';
|
|
9
12
|
export * from './effects/DotScreen';
|
|
10
13
|
export * from './effects/Glitch';
|
|
11
14
|
export * from './effects/GodRays';
|
|
@@ -18,7 +21,6 @@ export * from './effects/ScanlineEffect';
|
|
|
18
21
|
export * from './effects/SelectiveBloom';
|
|
19
22
|
export * from './effects/Sepia';
|
|
20
23
|
export * from './effects/SSAO';
|
|
21
|
-
export * from './effects/N8AO';
|
|
22
24
|
export * from './effects/SMAA';
|
|
23
25
|
export * from './effects/Texture';
|
|
24
26
|
export * from './effects/ToneMapping';
|
|
@@ -27,7 +29,6 @@ export * from './effects/ShockWave';
|
|
|
27
29
|
export * from './effects/LUT';
|
|
28
30
|
export * from './effects/TiltShift';
|
|
29
31
|
export * from './effects/TiltShift2';
|
|
32
|
+
export * from './effects/ASCII';
|
|
30
33
|
export * from './effects/SSR';
|
|
31
|
-
export * from './
|
|
32
|
-
export * from './EffectComposer';
|
|
33
|
-
export * from './util';
|
|
34
|
+
export * from './effects/N8AO';
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,42 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import React, { createContext, useState, useMemo, useRef, useContext, useEffect, forwardRef, useLayoutEffect, useImperativeHandle, useCallback } from 'react';
|
|
2
3
|
import * as THREE from 'three';
|
|
3
|
-
import { HalfFloatType, Vector3, TextureLoader, sRGBEncoding, RepeatWrapping, Uniform } from 'three';
|
|
4
|
-
import
|
|
5
|
-
import { useThree, useFrame, useInstanceHandle, createPortal, extend, useLoader } from '@react-three/fiber';
|
|
4
|
+
import { HalfFloatType, Vector3, TextureLoader, sRGBEncoding, RepeatWrapping, Uniform, Texture as Texture$1, Color, CanvasTexture, NearestFilter } from 'three';
|
|
5
|
+
import { useThree, useFrame, useInstanceHandle, extend, createPortal, useLoader, applyProps } from '@react-three/fiber';
|
|
6
6
|
import { EffectComposer as EffectComposer$1, RenderPass, NormalPass, DepthDownsamplingPass, Effect, EffectPass, Pass, DepthOfFieldEffect, MaskFunction, DepthPickingPass, CopyPass, BlendFunction, BloomEffect, BrightnessContrastEffect, ChromaticAberrationEffect, ColorAverageEffect, ColorDepthEffect, DepthEffect, DotScreenEffect, GlitchEffect, GlitchMode, GodRaysEffect, GridEffect, HueSaturationEffect, NoiseEffect, OutlineEffect, PixelationEffect, ScanlineEffect, SelectiveBloomEffect, SepiaEffect, SSAOEffect, SMAAEffect, TextureEffect, ToneMappingEffect, VignetteEffect, ShockWaveEffect, LUT3DEffect, TiltShiftEffect as TiltShiftEffect$1, EffectAttribute } from 'postprocessing';
|
|
7
|
-
import { easing } from 'maath';
|
|
8
7
|
import { isWebGL2Available } from 'three-stdlib';
|
|
9
|
-
import {
|
|
8
|
+
import { easing } from 'maath';
|
|
10
9
|
import { SSREffect } from 'screen-space-reflections';
|
|
10
|
+
import { N8AOPostPass } from 'n8ao';
|
|
11
|
+
|
|
12
|
+
const selectionContext = createContext(null);
|
|
13
|
+
function Selection({ children, enabled = true }) {
|
|
14
|
+
const [selected, select] = useState([]);
|
|
15
|
+
const value = useMemo(() => ({ selected, select, enabled }), [selected, select, enabled]);
|
|
16
|
+
return jsx(selectionContext.Provider, { value: value, children: children });
|
|
17
|
+
}
|
|
18
|
+
function Select({ enabled = false, children, ...props }) {
|
|
19
|
+
const group = useRef(null);
|
|
20
|
+
const api = useContext(selectionContext);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (api && enabled) {
|
|
23
|
+
let changed = false;
|
|
24
|
+
const current = [];
|
|
25
|
+
group.current.traverse((o) => {
|
|
26
|
+
o.type === 'Mesh' && current.push(o);
|
|
27
|
+
if (api.selected.indexOf(o) === -1)
|
|
28
|
+
changed = true;
|
|
29
|
+
});
|
|
30
|
+
if (changed) {
|
|
31
|
+
api.select((state) => [...state, ...current]);
|
|
32
|
+
return () => {
|
|
33
|
+
api.select((state) => state.filter((selected) => !current.includes(selected)));
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}, [enabled, children, api]);
|
|
38
|
+
return (jsx("group", { ref: group, ...props, children: children }));
|
|
39
|
+
}
|
|
11
40
|
|
|
12
41
|
const EffectComposerContext = createContext(null);
|
|
13
42
|
const EffectComposer = React.memo(forwardRef(({ children, camera: _camera, scene: _scene, resolutionScale, enabled = true, renderPriority = 1, autoClear = true, depthBuffer, disableNormalPass, stencilBuffer, multisampling = 8, frameBufferType = HalfFloatType, }, ref) => {
|
|
@@ -100,6 +129,35 @@ const EffectComposer = React.memo(forwardRef(({ children, camera: _camera, scene
|
|
|
100
129
|
return (jsx(EffectComposerContext.Provider, { value: state, children: jsx("group", { ref: group, children: children }) }));
|
|
101
130
|
}));
|
|
102
131
|
|
|
132
|
+
const resolveRef = (ref) => typeof ref === 'object' && ref != null && 'current' in ref ? ref.current : ref;
|
|
133
|
+
let i = 0;
|
|
134
|
+
const components = new WeakMap();
|
|
135
|
+
const wrapEffect = (effect, defaults) =>
|
|
136
|
+
/* @__PURE__ */ React.forwardRef(function Effect({ blendFunction = defaults === null || defaults === void 0 ? void 0 : defaults.blendFunction, opacity = defaults === null || defaults === void 0 ? void 0 : defaults.opacity, ...props }, ref) {
|
|
137
|
+
let Component = components.get(effect);
|
|
138
|
+
if (!Component) {
|
|
139
|
+
const key = `@react-three/postprocessing/${effect.name}-${i++}`;
|
|
140
|
+
extend({ [key]: effect });
|
|
141
|
+
components.set(effect, (Component = key));
|
|
142
|
+
}
|
|
143
|
+
const camera = useThree((state) => state.camera);
|
|
144
|
+
const args = React.useMemo(() => { var _a, _b; return [...((_a = defaults === null || defaults === void 0 ? void 0 : defaults.args) !== null && _a !== void 0 ? _a : []), ...((_b = props.args) !== null && _b !== void 0 ? _b : [{ ...defaults, ...props }])]; },
|
|
145
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
146
|
+
[JSON.stringify(props)]);
|
|
147
|
+
return (jsx(Component, { camera: camera, "blendMode-blendFunction": blendFunction, "blendMode-opacity-value": opacity, ...props, ref: ref, args: args }));
|
|
148
|
+
});
|
|
149
|
+
const useVector2 = (props, key) => {
|
|
150
|
+
const value = props[key];
|
|
151
|
+
return React.useMemo(() => {
|
|
152
|
+
if (typeof value === 'number')
|
|
153
|
+
return new THREE.Vector2(value, value);
|
|
154
|
+
else if (value)
|
|
155
|
+
return new THREE.Vector2(...value);
|
|
156
|
+
else
|
|
157
|
+
return new THREE.Vector2();
|
|
158
|
+
}, [value]);
|
|
159
|
+
};
|
|
160
|
+
|
|
103
161
|
const DepthOfField = forwardRef(function DepthOfField({ target, depthTexture, ...props }, ref) {
|
|
104
162
|
const invalidate = useThree((state) => state.invalidate);
|
|
105
163
|
const { camera } = useContext(EffectComposerContext);
|
|
@@ -204,35 +262,6 @@ const Autofocus = forwardRef(({ target = undefined, mouse: followMouse = false,
|
|
|
204
262
|
: null, jsx(DepthOfField, { ref: dofRef, ...props, target: hitpoint })] }));
|
|
205
263
|
});
|
|
206
264
|
|
|
207
|
-
const resolveRef = (ref) => typeof ref === 'object' && ref != null && 'current' in ref ? ref.current : ref;
|
|
208
|
-
let i = 0;
|
|
209
|
-
const components = new WeakMap();
|
|
210
|
-
const wrapEffect = (effect, defaults) =>
|
|
211
|
-
/* @__PURE__ */ React.forwardRef(function Effect({ blendFunction = defaults === null || defaults === void 0 ? void 0 : defaults.blendFunction, opacity = defaults === null || defaults === void 0 ? void 0 : defaults.opacity, ...props }, ref) {
|
|
212
|
-
let Component = components.get(effect);
|
|
213
|
-
if (!Component) {
|
|
214
|
-
const key = `@react-three/postprocessing/${effect.name}-${i++}`;
|
|
215
|
-
extend({ [key]: effect });
|
|
216
|
-
components.set(effect, (Component = key));
|
|
217
|
-
}
|
|
218
|
-
const camera = useThree((state) => state.camera);
|
|
219
|
-
const args = React.useMemo(() => { var _a, _b; return [...((_a = defaults === null || defaults === void 0 ? void 0 : defaults.args) !== null && _a !== void 0 ? _a : []), ...((_b = props.args) !== null && _b !== void 0 ? _b : [{ ...defaults, ...props }])]; },
|
|
220
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
221
|
-
[JSON.stringify(props)]);
|
|
222
|
-
return (jsx(Component, { camera: camera, "blendMode-blendFunction": blendFunction, "blendMode-opacity-value": opacity, ...props, ref: ref, args: args }));
|
|
223
|
-
});
|
|
224
|
-
const useVector2 = (props, key) => {
|
|
225
|
-
const value = props[key];
|
|
226
|
-
return React.useMemo(() => {
|
|
227
|
-
if (typeof value === 'number')
|
|
228
|
-
return new THREE.Vector2(value, value);
|
|
229
|
-
else if (value)
|
|
230
|
-
return new THREE.Vector2(...value);
|
|
231
|
-
else
|
|
232
|
-
return new THREE.Vector2();
|
|
233
|
-
}, [value]);
|
|
234
|
-
};
|
|
235
|
-
|
|
236
265
|
const Bloom = wrapEffect(BloomEffect, {
|
|
237
266
|
blendFunction: BlendFunction.ADD,
|
|
238
267
|
});
|
|
@@ -293,35 +322,6 @@ const HueSaturation = wrapEffect(HueSaturationEffect);
|
|
|
293
322
|
|
|
294
323
|
const Noise = wrapEffect(NoiseEffect, { blendFunction: BlendFunction.COLOR_DODGE });
|
|
295
324
|
|
|
296
|
-
const selectionContext = createContext(null);
|
|
297
|
-
function Selection({ children, enabled = true }) {
|
|
298
|
-
const [selected, select] = useState([]);
|
|
299
|
-
const value = useMemo(() => ({ selected, select, enabled }), [selected, select, enabled]);
|
|
300
|
-
return jsx(selectionContext.Provider, { value: value, children: children });
|
|
301
|
-
}
|
|
302
|
-
function Select({ enabled = false, children, ...props }) {
|
|
303
|
-
const group = useRef(null);
|
|
304
|
-
const api = useContext(selectionContext);
|
|
305
|
-
useEffect(() => {
|
|
306
|
-
if (api && enabled) {
|
|
307
|
-
let changed = false;
|
|
308
|
-
const current = [];
|
|
309
|
-
group.current.traverse((o) => {
|
|
310
|
-
o.type === 'Mesh' && current.push(o);
|
|
311
|
-
if (api.selected.indexOf(o) === -1)
|
|
312
|
-
changed = true;
|
|
313
|
-
});
|
|
314
|
-
if (changed) {
|
|
315
|
-
api.select((state) => [...state, ...current]);
|
|
316
|
-
return () => {
|
|
317
|
-
api.select((state) => state.filter((selected) => !current.includes(selected)));
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}, [enabled, children, api]);
|
|
322
|
-
return (jsx("group", { ref: group, ...props, children: children }));
|
|
323
|
-
}
|
|
324
|
-
|
|
325
325
|
const Outline = forwardRef(function Outline({ selection = [], selectionLayer = 10, blendFunction, patternTexture, edgeStrength, pulseSpeed, visibleEdgeColor, hiddenEdgeColor, width, height, kernelSize, blur, xRay, ...props }, forwardRef) {
|
|
326
326
|
const invalidate = useThree((state) => state.invalidate);
|
|
327
327
|
const { scene, camera } = useContext(EffectComposerContext);
|
|
@@ -489,26 +489,6 @@ const SSAO = forwardRef(function SSAO(props, ref) {
|
|
|
489
489
|
return jsx("primitive", { ref: ref, object: effect, dispose: null });
|
|
490
490
|
});
|
|
491
491
|
|
|
492
|
-
const N8AO = forwardRef(({ quality, aoRadius = 5, aoSamples = 16, denoiseSamples = 4, denoiseRadius = 12, distanceFalloff = 1, intensity = 1, }, ref) => {
|
|
493
|
-
const { camera, scene } = useThree();
|
|
494
|
-
const effect = useMemo(() => new N8AOPostPass(scene, camera), []);
|
|
495
|
-
useLayoutEffect(() => {
|
|
496
|
-
Object.assign(effect.configuration, {
|
|
497
|
-
aoRadius,
|
|
498
|
-
distanceFalloff,
|
|
499
|
-
intensity,
|
|
500
|
-
aoSamples,
|
|
501
|
-
denoiseSamples,
|
|
502
|
-
denoiseRadius,
|
|
503
|
-
});
|
|
504
|
-
}, [aoRadius, distanceFalloff, intensity, aoSamples, denoiseSamples, denoiseRadius]);
|
|
505
|
-
useLayoutEffect(() => {
|
|
506
|
-
if (quality)
|
|
507
|
-
effect.setQualityMode(quality.charAt(0).toUpperCase() + quality.slice(1));
|
|
508
|
-
}, [quality]);
|
|
509
|
-
return jsx("primitive", { ref: ref, object: effect });
|
|
510
|
-
});
|
|
511
|
-
|
|
512
492
|
const SMAA = wrapEffect(SMAAEffect);
|
|
513
493
|
|
|
514
494
|
const Texture = forwardRef(function Texture({ textureSrc, texture, ...props }, ref) {
|
|
@@ -625,6 +605,93 @@ class TiltShiftEffect extends Effect {
|
|
|
625
605
|
}
|
|
626
606
|
const TiltShift2 = wrapEffect(TiltShiftEffect, { blendFunction: BlendFunction.NORMAL });
|
|
627
607
|
|
|
608
|
+
const fragment = `
|
|
609
|
+
uniform sampler2D uCharacters;
|
|
610
|
+
uniform float uCharactersCount;
|
|
611
|
+
uniform float uCellSize;
|
|
612
|
+
uniform bool uInvert;
|
|
613
|
+
uniform vec3 uColor;
|
|
614
|
+
|
|
615
|
+
const vec2 SIZE = vec2(16.);
|
|
616
|
+
|
|
617
|
+
vec3 greyscale(vec3 color, float strength) {
|
|
618
|
+
float g = dot(color, vec3(0.299, 0.587, 0.114));
|
|
619
|
+
return mix(color, vec3(g), strength);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
vec3 greyscale(vec3 color) {
|
|
623
|
+
return greyscale(color, 1.0);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
|
|
627
|
+
vec2 cell = resolution / uCellSize;
|
|
628
|
+
vec2 grid = 1.0 / cell;
|
|
629
|
+
vec2 pixelizedUV = grid * (0.5 + floor(uv / grid));
|
|
630
|
+
vec4 pixelized = texture2D(inputBuffer, pixelizedUV);
|
|
631
|
+
float greyscaled = greyscale(pixelized.rgb).r;
|
|
632
|
+
|
|
633
|
+
if (uInvert) {
|
|
634
|
+
greyscaled = 1.0 - greyscaled;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
float characterIndex = floor((uCharactersCount - 1.0) * greyscaled);
|
|
638
|
+
vec2 characterPosition = vec2(mod(characterIndex, SIZE.x), floor(characterIndex / SIZE.y));
|
|
639
|
+
vec2 offset = vec2(characterPosition.x, -characterPosition.y) / SIZE;
|
|
640
|
+
vec2 charUV = mod(uv * (cell / SIZE), 1.0 / SIZE) - vec2(0., 1.0 / SIZE) + offset;
|
|
641
|
+
vec4 asciiCharacter = texture2D(uCharacters, charUV);
|
|
642
|
+
|
|
643
|
+
asciiCharacter.rgb = uColor * asciiCharacter.r;
|
|
644
|
+
asciiCharacter.a = pixelized.a;
|
|
645
|
+
outputColor = asciiCharacter;
|
|
646
|
+
}
|
|
647
|
+
`;
|
|
648
|
+
class ASCIIEffect extends Effect {
|
|
649
|
+
constructor({ characters = ` .:,'-^=*+?!|0#X%WM@`, fontSize = 54, cellSize = 16, color = '#ffffff', invert = false, } = {}) {
|
|
650
|
+
const uniforms = new Map([
|
|
651
|
+
['uCharacters', new Uniform(new Texture$1())],
|
|
652
|
+
['uCellSize', new Uniform(cellSize)],
|
|
653
|
+
['uCharactersCount', new Uniform(characters.length)],
|
|
654
|
+
['uColor', new Uniform(new Color(color))],
|
|
655
|
+
['uInvert', new Uniform(invert)],
|
|
656
|
+
]);
|
|
657
|
+
super('ASCIIEffect', fragment, { uniforms });
|
|
658
|
+
const charactersTextureUniform = this.uniforms.get('uCharacters');
|
|
659
|
+
if (charactersTextureUniform) {
|
|
660
|
+
charactersTextureUniform.value = this.createCharactersTexture(characters, fontSize);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
/** Draws the characters on a Canvas and returns a texture */
|
|
664
|
+
createCharactersTexture(characters, fontSize) {
|
|
665
|
+
const canvas = document.createElement('canvas');
|
|
666
|
+
const SIZE = 1024;
|
|
667
|
+
const MAX_PER_ROW = 16;
|
|
668
|
+
const CELL = SIZE / MAX_PER_ROW;
|
|
669
|
+
canvas.width = canvas.height = SIZE;
|
|
670
|
+
const texture = new CanvasTexture(canvas, undefined, RepeatWrapping, RepeatWrapping, NearestFilter, NearestFilter);
|
|
671
|
+
const context = canvas.getContext('2d');
|
|
672
|
+
if (!context) {
|
|
673
|
+
throw new Error('Context not available');
|
|
674
|
+
}
|
|
675
|
+
context.clearRect(0, 0, SIZE, SIZE);
|
|
676
|
+
context.font = `${fontSize}px arial`;
|
|
677
|
+
context.textAlign = 'center';
|
|
678
|
+
context.textBaseline = 'middle';
|
|
679
|
+
context.fillStyle = '#fff';
|
|
680
|
+
for (let i = 0; i < characters.length; i++) {
|
|
681
|
+
const char = characters[i];
|
|
682
|
+
const x = i % MAX_PER_ROW;
|
|
683
|
+
const y = Math.floor(i / MAX_PER_ROW);
|
|
684
|
+
context.fillText(char, x * CELL + CELL / 2, y * CELL + CELL / 2);
|
|
685
|
+
}
|
|
686
|
+
texture.needsUpdate = true;
|
|
687
|
+
return texture;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
const ASCII = forwardRef(({ characters = ` .:,'-^=*+?!|0#X%WM@`, fontSize = 54, cellSize = 16, color = '#ffffff', invert = false }, fref) => {
|
|
691
|
+
const effect = useMemo(() => new ASCIIEffect({ characters, fontSize, cellSize, color, invert }), [characters, fontSize, cellSize, color, invert]);
|
|
692
|
+
return jsx("primitive", { ref: fref, object: effect });
|
|
693
|
+
});
|
|
694
|
+
|
|
628
695
|
const SSR = forwardRef(function SSR({ ENABLE_BLUR = true, USE_MRT = true, ...props }, ref) {
|
|
629
696
|
const { invalidate } = useThree();
|
|
630
697
|
const { scene, camera } = useContext(EffectComposerContext);
|
|
@@ -646,4 +713,26 @@ const SSR = forwardRef(function SSR({ ENABLE_BLUR = true, USE_MRT = true, ...pro
|
|
|
646
713
|
return jsx("primitive", { ref: ref, object: effect, ...props });
|
|
647
714
|
});
|
|
648
715
|
|
|
649
|
-
|
|
716
|
+
const N8AO = forwardRef(({ screenSpaceRadius, quality, aoRadius = 5, aoSamples = 16, denoiseSamples = 4, denoiseRadius = 12, distanceFalloff = 1, intensity = 1, color, }, ref) => {
|
|
717
|
+
const { camera, scene } = useThree();
|
|
718
|
+
const effect = useMemo(() => new N8AOPostPass(scene, camera), []);
|
|
719
|
+
useLayoutEffect(() => {
|
|
720
|
+
applyProps(effect.configuration, {
|
|
721
|
+
color,
|
|
722
|
+
aoRadius,
|
|
723
|
+
distanceFalloff,
|
|
724
|
+
intensity,
|
|
725
|
+
aoSamples,
|
|
726
|
+
denoiseSamples,
|
|
727
|
+
denoiseRadius,
|
|
728
|
+
screenSpaceRadius,
|
|
729
|
+
});
|
|
730
|
+
}, [screenSpaceRadius, color, aoRadius, distanceFalloff, intensity, aoSamples, denoiseSamples, denoiseRadius]);
|
|
731
|
+
useLayoutEffect(() => {
|
|
732
|
+
if (quality)
|
|
733
|
+
effect.setQualityMode(quality.charAt(0).toUpperCase() + quality.slice(1));
|
|
734
|
+
}, [quality]);
|
|
735
|
+
return jsx("primitive", { ref: ref, object: effect });
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
export { ASCII, Autofocus, Bloom, BrightnessContrast, ChromaticAberration, ColorAverage, ColorDepth, Depth, DepthOfField, DotScreen, EffectComposer, EffectComposerContext, Glitch, GodRays, Grid, HueSaturation, LUT, N8AO, Noise, Outline, Pixelation, SMAA, SSAO, SSR, Scanline, Select, Selection, SelectiveBloom, Sepia, ShockWave, Texture, TiltShift, TiltShift2, TiltShiftEffect, ToneMapping, Vignette, resolveRef, selectionContext, useVector2, wrapEffect };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-three/postprocessing",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.1",
|
|
4
4
|
"description": "postprocessing wrapper for React and @react-three/fiber",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"postprocessing",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"maath": "^0.5.3",
|
|
51
|
-
"n8ao": "^1.
|
|
52
|
-
"postprocessing": "^6.
|
|
51
|
+
"n8ao": "^1.4.0",
|
|
52
|
+
"postprocessing": "^6.31.0",
|
|
53
53
|
"screen-space-reflections": "2.5.0",
|
|
54
54
|
"three-stdlib": "^2.21.10"
|
|
55
55
|
},
|