@react-three/postprocessing 3.0.3 → 3.0.5
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/LICENSE +21 -21
- package/README.md +81 -81
- package/dist/EffectComposer.d.ts +28 -0
- package/dist/Selection.d.ts +17 -0
- package/dist/effects/ASCII.d.ts +19 -0
- package/dist/effects/Autofocus.d.ts +23 -0
- package/dist/effects/Bloom.d.ts +2 -0
- package/dist/effects/BrightnessContrast.d.ts +2 -0
- package/dist/effects/ChromaticAberration.d.ts +8 -0
- package/dist/effects/ColorAverage.d.ts +7 -0
- package/dist/effects/ColorDepth.d.ts +2 -0
- package/dist/effects/Depth.d.ts +2 -0
- package/dist/effects/DepthOfField.d.ts +14 -0
- package/dist/effects/DotScreen.d.ts +2 -0
- package/dist/effects/FXAA.d.ts +2 -0
- package/dist/effects/Glitch.d.ts +13 -0
- package/dist/effects/GodRays.d.ts +9 -0
- package/dist/effects/Grid.d.ts +11 -0
- package/dist/effects/HueSaturation.d.ts +2 -0
- package/dist/effects/LUT.d.ts +10 -0
- package/dist/effects/LensFlare.d.ts +54 -0
- package/dist/effects/N8AO.d.ts +19 -0
- package/dist/effects/Noise.d.ts +2 -0
- package/dist/effects/Outline.d.ts +11 -0
- package/dist/effects/Pixelation.d.ts +7 -0
- package/dist/effects/Ramp.d.ts +74 -0
- package/dist/effects/SMAA.d.ts +2 -0
- package/dist/effects/SSAO.d.ts +7 -0
- package/dist/effects/ScanlineEffect.d.ts +2 -0
- package/dist/effects/SelectiveBloom.d.ts +15 -0
- package/dist/effects/Sepia.d.ts +2 -0
- package/dist/effects/ShockWave.d.ts +2 -0
- package/dist/effects/Texture.d.ts +10 -0
- package/dist/effects/TiltShift.d.ts +2 -0
- package/dist/effects/TiltShift2.d.ts +18 -0
- package/dist/effects/ToneMapping.d.ts +4 -0
- package/dist/effects/Vignette.d.ts +2 -0
- package/dist/effects/Water.d.ts +8 -0
- package/dist/index.d.ts +38 -1
- package/dist/index.js +855 -551
- package/dist/index.js.map +1 -1
- package/dist/tests/test-utils.d.ts +12 -0
- package/dist/util.d.ts +25 -0
- package/dist/wrapEffect.d.ts +12 -0
- package/package.json +73 -66
- package/src/EffectComposer.tsx +278 -200
- package/src/Selection.tsx +86 -46
- package/src/effects/ASCII.tsx +136 -135
- package/src/effects/Autofocus.tsx +175 -153
- package/src/effects/Bloom.tsx +6 -6
- package/src/effects/BrightnessContrast.tsx +4 -4
- package/src/effects/ChromaticAberration.tsx +30 -5
- package/src/effects/ColorAverage.tsx +17 -15
- package/src/effects/ColorDepth.tsx +4 -4
- package/src/effects/Depth.tsx +4 -4
- package/src/effects/DepthOfField.tsx +87 -89
- package/src/effects/DotScreen.tsx +4 -4
- package/src/effects/FXAA.tsx +4 -4
- package/src/effects/Glitch.tsx +37 -40
- package/src/effects/GodRays.tsx +20 -16
- package/src/effects/Grid.tsx +28 -21
- package/src/effects/HueSaturation.tsx +4 -4
- package/src/effects/LUT.tsx +27 -26
- package/src/effects/LensFlare.tsx +611 -611
- package/src/effects/N8AO.tsx +81 -81
- package/src/effects/Noise.tsx +4 -4
- package/src/effects/Outline.tsx +85 -117
- package/src/effects/Pixelation.tsx +17 -15
- package/src/effects/Ramp.tsx +150 -150
- package/src/effects/SMAA.tsx +4 -4
- package/src/effects/SSAO.tsx +44 -41
- package/src/effects/ScanlineEffect.tsx +7 -7
- package/src/effects/SelectiveBloom.tsx +116 -126
- package/src/effects/Sepia.tsx +4 -4
- package/src/effects/ShockWave.tsx +4 -4
- package/src/effects/Texture.tsx +27 -23
- package/src/effects/TiltShift.tsx +4 -4
- package/src/effects/TiltShift2.tsx +90 -90
- package/src/effects/ToneMapping.tsx +6 -6
- package/src/effects/Vignette.tsx +4 -4
- package/src/effects/Water.tsx +35 -35
- package/src/index.ts +41 -40
- package/src/tests/ChromaticAberration.test.tsx +31 -0
- package/src/tests/EffectComposer.test.tsx +911 -0
- package/src/tests/Outline.test.tsx +89 -0
- package/src/tests/Selection.test.tsx +324 -0
- package/src/tests/SelectiveBloom.test.tsx +118 -0
- package/src/tests/effects.smoke.test.tsx +234 -0
- package/src/tests/test-utils.tsx +96 -0
- package/src/tests/wrapEffect.test.tsx +209 -0
- package/src/util.tsx +96 -55
- package/src/wrapEffect.tsx +122 -0
- package/src/EffectComposer.test.tsx +0 -126
package/src/effects/ASCII.tsx
CHANGED
|
@@ -1,135 +1,136 @@
|
|
|
1
|
-
// From: https://github.com/emilwidlund/ASCII
|
|
2
|
-
// https://twitter.com/emilwidlund/status/1652386482420609024
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
uniform
|
|
11
|
-
uniform float
|
|
12
|
-
uniform
|
|
13
|
-
uniform
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
vec2
|
|
29
|
-
vec2
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
vec2
|
|
40
|
-
vec2
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
asciiCharacter.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
['
|
|
71
|
-
['
|
|
72
|
-
['
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
context.
|
|
102
|
-
context.
|
|
103
|
-
context.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
1
|
+
// From: https://github.com/emilwidlund/ASCII
|
|
2
|
+
// https://twitter.com/emilwidlund/status/1652386482420609024
|
|
3
|
+
|
|
4
|
+
import { Effect } from 'postprocessing'
|
|
5
|
+
import { Ref, useMemo } from 'react'
|
|
6
|
+
import { CanvasTexture, Color, NearestFilter, RepeatWrapping, Texture, Uniform } from 'three'
|
|
7
|
+
import { useDispose } from '../util'
|
|
8
|
+
|
|
9
|
+
const fragment = /* glsl */ `
|
|
10
|
+
uniform sampler2D uCharacters;
|
|
11
|
+
uniform float uCharactersCount;
|
|
12
|
+
uniform float uCellSize;
|
|
13
|
+
uniform bool uInvert;
|
|
14
|
+
uniform vec3 uColor;
|
|
15
|
+
|
|
16
|
+
const vec2 SIZE = vec2(16.);
|
|
17
|
+
|
|
18
|
+
vec3 greyscale(vec3 color, float strength) {
|
|
19
|
+
float g = dot(color, vec3(0.299, 0.587, 0.114));
|
|
20
|
+
return mix(color, vec3(g), strength);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
vec3 greyscale(vec3 color) {
|
|
24
|
+
return greyscale(color, 1.0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
|
|
28
|
+
vec2 cell = resolution / uCellSize;
|
|
29
|
+
vec2 grid = 1.0 / cell;
|
|
30
|
+
vec2 pixelizedUV = grid * (0.5 + floor(uv / grid));
|
|
31
|
+
vec4 pixelized = texture2D(inputBuffer, pixelizedUV);
|
|
32
|
+
float greyscaled = greyscale(pixelized.rgb).r;
|
|
33
|
+
|
|
34
|
+
if (uInvert) {
|
|
35
|
+
greyscaled = 1.0 - greyscaled;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
float characterIndex = floor((uCharactersCount - 1.0) * greyscaled);
|
|
39
|
+
vec2 characterPosition = vec2(mod(characterIndex, SIZE.x), floor(characterIndex / SIZE.y));
|
|
40
|
+
vec2 offset = vec2(characterPosition.x, -characterPosition.y) / SIZE;
|
|
41
|
+
vec2 charUV = mod(uv * (cell / SIZE), 1.0 / SIZE) - vec2(0., 1.0 / SIZE) + offset;
|
|
42
|
+
vec4 asciiCharacter = texture2D(uCharacters, charUV);
|
|
43
|
+
|
|
44
|
+
asciiCharacter.rgb = uColor * asciiCharacter.r;
|
|
45
|
+
asciiCharacter.a = pixelized.a;
|
|
46
|
+
outputColor = asciiCharacter;
|
|
47
|
+
}
|
|
48
|
+
`
|
|
49
|
+
|
|
50
|
+
interface IASCIIEffectProps {
|
|
51
|
+
font?: string
|
|
52
|
+
characters?: string
|
|
53
|
+
fontSize?: number
|
|
54
|
+
cellSize?: number
|
|
55
|
+
color?: string
|
|
56
|
+
invert?: boolean
|
|
57
|
+
ref?: Ref<ASCIIEffect>
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
class ASCIIEffect extends Effect {
|
|
61
|
+
constructor({
|
|
62
|
+
font = 'arial',
|
|
63
|
+
characters = ` .:,'-^=*+?!|0#X%WM@`,
|
|
64
|
+
fontSize = 54,
|
|
65
|
+
cellSize = 16,
|
|
66
|
+
color = '#ffffff',
|
|
67
|
+
invert = false,
|
|
68
|
+
}: Omit<IASCIIEffectProps, 'ref'> = {}) {
|
|
69
|
+
const uniforms = new Map<string, Uniform>([
|
|
70
|
+
['uCharacters', new Uniform(new Texture())],
|
|
71
|
+
['uCellSize', new Uniform(cellSize)],
|
|
72
|
+
['uCharactersCount', new Uniform(characters.length)],
|
|
73
|
+
['uColor', new Uniform(new Color(color))],
|
|
74
|
+
['uInvert', new Uniform(invert)],
|
|
75
|
+
])
|
|
76
|
+
|
|
77
|
+
super('ASCIIEffect', fragment, { uniforms })
|
|
78
|
+
|
|
79
|
+
const charactersTextureUniform = this.uniforms.get('uCharacters')
|
|
80
|
+
|
|
81
|
+
if (charactersTextureUniform) {
|
|
82
|
+
charactersTextureUniform.value = this.createCharactersTexture(characters, font, fontSize)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Draws the characters on a Canvas and returns a texture */
|
|
87
|
+
public createCharactersTexture(characters: string, font: string, fontSize: number): Texture {
|
|
88
|
+
const canvas = document.createElement('canvas')
|
|
89
|
+
const SIZE = 1024
|
|
90
|
+
const MAX_PER_ROW = 16
|
|
91
|
+
const CELL = SIZE / MAX_PER_ROW
|
|
92
|
+
|
|
93
|
+
canvas.width = canvas.height = SIZE
|
|
94
|
+
const texture = new CanvasTexture(canvas, undefined, RepeatWrapping, RepeatWrapping, NearestFilter, NearestFilter)
|
|
95
|
+
const context = canvas.getContext('2d')
|
|
96
|
+
|
|
97
|
+
if (!context) {
|
|
98
|
+
throw new Error('Context not available')
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
context.clearRect(0, 0, SIZE, SIZE)
|
|
102
|
+
context.font = `${fontSize}px ${font}`
|
|
103
|
+
context.textAlign = 'center'
|
|
104
|
+
context.textBaseline = 'middle'
|
|
105
|
+
context.fillStyle = '#fff'
|
|
106
|
+
|
|
107
|
+
for (let i = 0; i < characters.length; i++) {
|
|
108
|
+
const char = characters[i]
|
|
109
|
+
const x = i % MAX_PER_ROW
|
|
110
|
+
const y = Math.floor(i / MAX_PER_ROW)
|
|
111
|
+
context.fillText(char, x * CELL + CELL / 2, y * CELL + CELL / 2)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
texture.needsUpdate = true
|
|
115
|
+
return texture
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function ASCII({
|
|
120
|
+
font = 'arial',
|
|
121
|
+
characters = ` .:,'-^=*+?!|0#X%WM@`,
|
|
122
|
+
fontSize = 54,
|
|
123
|
+
cellSize = 16,
|
|
124
|
+
color = '#ffffff',
|
|
125
|
+
invert = false,
|
|
126
|
+
ref,
|
|
127
|
+
}: IASCIIEffectProps) {
|
|
128
|
+
const effect = useMemo(
|
|
129
|
+
() => new ASCIIEffect({ characters, font, fontSize, cellSize, color, invert }),
|
|
130
|
+
[characters, fontSize, cellSize, color, invert, font]
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
useDispose(effect)
|
|
134
|
+
|
|
135
|
+
return <primitive ref={ref} object={effect} />
|
|
136
|
+
}
|
|
@@ -1,153 +1,175 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
useImperativeHandle,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
import { EffectComposerContext } from '../EffectComposer'
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
1
|
+
import { createPortal, useFrame, useThree, type Vector3 as R3FVector3 } from '@react-three/fiber'
|
|
2
|
+
import { easing } from 'maath'
|
|
3
|
+
import { CopyPass, DepthOfFieldEffect, DepthPickingPass } from 'postprocessing'
|
|
4
|
+
import {
|
|
5
|
+
Ref,
|
|
6
|
+
useCallback,
|
|
7
|
+
useContext,
|
|
8
|
+
useEffect,
|
|
9
|
+
useImperativeHandle,
|
|
10
|
+
useMemo,
|
|
11
|
+
useRef,
|
|
12
|
+
useState,
|
|
13
|
+
type ComponentProps,
|
|
14
|
+
type RefObject,
|
|
15
|
+
} from 'react'
|
|
16
|
+
import { Mesh, Vector3 } from 'three'
|
|
17
|
+
|
|
18
|
+
import { EffectComposerContext } from '../EffectComposer'
|
|
19
|
+
import { DepthOfField } from './DepthOfField'
|
|
20
|
+
|
|
21
|
+
// EffectComposerImpl.dispose() disposes every pass it currently holds —
|
|
22
|
+
// including these two, since they're added via composer.addPass below.
|
|
23
|
+
// When Autofocus unmounts alongside its ancestor EffectComposer (e.g. a
|
|
24
|
+
// full tree unmount), both the composer's own teardown AND this
|
|
25
|
+
// component's cleanup effect would dispose the same instances. Wrapping
|
|
26
|
+
// dispose here makes it safe no matter which caller gets there first.
|
|
27
|
+
function makeDisposeIdempotent<T extends { dispose: () => void }>(instance: T): T {
|
|
28
|
+
let disposed = false
|
|
29
|
+
const dispose = instance.dispose.bind(instance)
|
|
30
|
+
instance.dispose = () => {
|
|
31
|
+
if (disposed) return
|
|
32
|
+
disposed = true
|
|
33
|
+
dispose()
|
|
34
|
+
}
|
|
35
|
+
return instance
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type AutofocusProps = ComponentProps<typeof DepthOfField> & {
|
|
39
|
+
target?: R3FVector3
|
|
40
|
+
/** should the target follow the pointer */
|
|
41
|
+
mouse?: boolean
|
|
42
|
+
/** size of the debug green point */
|
|
43
|
+
debug?: number
|
|
44
|
+
/** manual update */
|
|
45
|
+
manual?: boolean
|
|
46
|
+
/** approximate time to reach the target */
|
|
47
|
+
smoothTime?: number
|
|
48
|
+
ref?: Ref<AutofocusApi>
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type AutofocusApi = {
|
|
52
|
+
dofRef: RefObject<DepthOfFieldEffect | null>
|
|
53
|
+
hitpoint: Vector3
|
|
54
|
+
update: (delta: number, updateTarget: boolean) => void
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function Autofocus({
|
|
58
|
+
target = undefined,
|
|
59
|
+
mouse: followMouse = false,
|
|
60
|
+
debug = undefined,
|
|
61
|
+
manual = false,
|
|
62
|
+
smoothTime = 0.25,
|
|
63
|
+
ref,
|
|
64
|
+
...props
|
|
65
|
+
}: AutofocusProps) {
|
|
66
|
+
const dofRef = useRef<DepthOfFieldEffect>(null)
|
|
67
|
+
const hitpointRef = useRef<Mesh>(null)
|
|
68
|
+
const targetRef = useRef<Mesh>(null)
|
|
69
|
+
|
|
70
|
+
const scene = useThree(({ scene }) => scene)
|
|
71
|
+
const pointer = useThree(({ pointer }) => pointer)
|
|
72
|
+
const { composer, camera } = useContext(EffectComposerContext)
|
|
73
|
+
|
|
74
|
+
// see: https://codesandbox.io/s/depthpickingpass-x130hg
|
|
75
|
+
const [depthPickingPass] = useState(() => makeDisposeIdempotent(new DepthPickingPass()))
|
|
76
|
+
const [copyPass] = useState(() => makeDisposeIdempotent(new CopyPass()))
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
composer.addPass(depthPickingPass)
|
|
79
|
+
composer.addPass(copyPass)
|
|
80
|
+
return () => {
|
|
81
|
+
composer.removePass(depthPickingPass)
|
|
82
|
+
composer.removePass(copyPass)
|
|
83
|
+
}
|
|
84
|
+
}, [composer, depthPickingPass, copyPass])
|
|
85
|
+
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
return () => {
|
|
88
|
+
depthPickingPass.dispose()
|
|
89
|
+
copyPass.dispose()
|
|
90
|
+
}
|
|
91
|
+
}, [depthPickingPass, copyPass])
|
|
92
|
+
|
|
93
|
+
const [hitpoint] = useState(() => new Vector3(0, 0, 0))
|
|
94
|
+
|
|
95
|
+
const [ndc] = useState(() => new Vector3(0, 0, 0))
|
|
96
|
+
const getHit = useCallback(
|
|
97
|
+
async (x: number, y: number) => {
|
|
98
|
+
ndc.x = x
|
|
99
|
+
ndc.y = y
|
|
100
|
+
ndc.z = await depthPickingPass.readDepth(ndc)
|
|
101
|
+
ndc.z = ndc.z * 2.0 - 1.0
|
|
102
|
+
const hit = 1 - ndc.z > 0.0000001 // it is missed if ndc.z is close to 1
|
|
103
|
+
return hit ? ndc.unproject(camera) : false
|
|
104
|
+
},
|
|
105
|
+
[ndc, depthPickingPass, camera]
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
const update = useCallback(
|
|
109
|
+
async (delta: number, updateTarget = true) => {
|
|
110
|
+
// Update hitpoint
|
|
111
|
+
if (target) {
|
|
112
|
+
hitpoint.set(...(target as unknown as [number, number, number]))
|
|
113
|
+
} else {
|
|
114
|
+
const { x, y } = followMouse ? pointer : { x: 0, y: 0 }
|
|
115
|
+
const hit = await getHit(x, y)
|
|
116
|
+
if (hit) hitpoint.copy(hit)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Update target
|
|
120
|
+
if (updateTarget && dofRef.current?.target) {
|
|
121
|
+
if (smoothTime > 0 && delta > 0) {
|
|
122
|
+
easing.damp3(dofRef.current.target, hitpoint, smoothTime, delta)
|
|
123
|
+
} else {
|
|
124
|
+
dofRef.current.target.copy(hitpoint)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
[target, hitpoint, followMouse, getHit, smoothTime, pointer]
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
useFrame(async (_, delta) => {
|
|
132
|
+
if (!manual) {
|
|
133
|
+
update(delta)
|
|
134
|
+
}
|
|
135
|
+
if (hitpointRef.current) {
|
|
136
|
+
hitpointRef.current.position.copy(hitpoint)
|
|
137
|
+
}
|
|
138
|
+
if (targetRef.current && dofRef.current?.target) {
|
|
139
|
+
targetRef.current.position.copy(dofRef.current.target)
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
// Ref API
|
|
144
|
+
const api = useMemo<AutofocusApi>(
|
|
145
|
+
() => ({
|
|
146
|
+
dofRef,
|
|
147
|
+
hitpoint,
|
|
148
|
+
update,
|
|
149
|
+
}),
|
|
150
|
+
[hitpoint, update]
|
|
151
|
+
)
|
|
152
|
+
useImperativeHandle(ref, () => api, [api])
|
|
153
|
+
|
|
154
|
+
return (
|
|
155
|
+
<>
|
|
156
|
+
{debug
|
|
157
|
+
? createPortal(
|
|
158
|
+
<>
|
|
159
|
+
<mesh ref={hitpointRef}>
|
|
160
|
+
<sphereGeometry args={[debug, 16, 16]} />
|
|
161
|
+
<meshBasicMaterial color="#00ff00" opacity={1} transparent depthWrite={false} />
|
|
162
|
+
</mesh>
|
|
163
|
+
<mesh ref={targetRef}>
|
|
164
|
+
<sphereGeometry args={[debug / 2, 16, 16]} />
|
|
165
|
+
<meshBasicMaterial color="#00ff00" opacity={0.5} transparent depthWrite={false} />
|
|
166
|
+
</mesh>
|
|
167
|
+
</>,
|
|
168
|
+
scene
|
|
169
|
+
)
|
|
170
|
+
: null}
|
|
171
|
+
|
|
172
|
+
<DepthOfField ref={dofRef} {...props} target={hitpoint} />
|
|
173
|
+
</>
|
|
174
|
+
)
|
|
175
|
+
}
|
package/src/effects/Bloom.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { wrapEffect } from '../
|
|
3
|
-
|
|
4
|
-
export const Bloom = /* @__PURE__ */ wrapEffect(BloomEffect, {
|
|
5
|
-
blendFunction: BlendFunction.ADD,
|
|
6
|
-
})
|
|
1
|
+
import { BlendFunction, BloomEffect } from 'postprocessing'
|
|
2
|
+
import { wrapEffect } from '../wrapEffect'
|
|
3
|
+
|
|
4
|
+
export const Bloom = /* @__PURE__ */ wrapEffect(BloomEffect, {
|
|
5
|
+
blendFunction: BlendFunction.ADD,
|
|
6
|
+
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BrightnessContrastEffect } from 'postprocessing'
|
|
2
|
-
import { wrapEffect } from '../
|
|
3
|
-
|
|
4
|
-
export const BrightnessContrast = /* @__PURE__ */ wrapEffect(BrightnessContrastEffect)
|
|
1
|
+
import { BrightnessContrastEffect } from 'postprocessing'
|
|
2
|
+
import { wrapEffect } from '../wrapEffect'
|
|
3
|
+
|
|
4
|
+
export const BrightnessContrast = /* @__PURE__ */ wrapEffect(BrightnessContrastEffect)
|