-
Notifications
You must be signed in to change notification settings - Fork 100
/
DepthOfField.tsx
89 lines (85 loc) 路 2.31 KB
/
DepthOfField.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
import { DepthOfFieldEffect, MaskFunction } from 'postprocessing'
import { Ref, forwardRef, useMemo, useEffect, useContext } from 'react'
import { ReactThreeFiber } from '@react-three/fiber'
import { type DepthPackingStrategies, type Texture, Vector3 } from 'three'
import { EffectComposerContext } from '../EffectComposer'
type DOFProps = ConstructorParameters<typeof DepthOfFieldEffect>[1] &
Partial<{
target: ReactThreeFiber.Vector3
depthTexture: {
texture: Texture
// TODO: narrow to DepthPackingStrategies
packing: number
}
// TODO: not used
blur: number
}>
export const DepthOfField = forwardRef(function DepthOfField(
{
blendFunction,
worldFocusDistance,
worldFocusRange,
focusDistance,
focusRange,
focalLength,
bokehScale,
resolutionScale,
resolutionX,
resolutionY,
width,
height,
target,
depthTexture,
...props
}: DOFProps,
ref: Ref<DepthOfFieldEffect>
) {
const { camera } = useContext(EffectComposerContext)
const autoFocus = target != null
const effect = useMemo(() => {
const effect = new DepthOfFieldEffect(camera, {
blendFunction,
worldFocusDistance,
worldFocusRange,
focusDistance,
focusRange,
focalLength,
bokehScale,
resolutionScale,
resolutionX,
resolutionY,
width,
height,
})
// Creating a target enables autofocus, R3F will set via props
if (autoFocus) effect.target = new Vector3()
// Depth texture for depth picking with optional packing strategy
if (depthTexture) effect.setDepthTexture(depthTexture.texture, depthTexture.packing as DepthPackingStrategies)
// Temporary fix that restores DOF 6.21.3 behavior, everything since then lets shapes leak through the blur
const maskPass = (effect as any).maskPass
maskPass.maskFunction = MaskFunction.MULTIPLY_RGB_SET_ALPHA
return effect
}, [
camera,
blendFunction,
worldFocusDistance,
worldFocusRange,
focusDistance,
focusRange,
focalLength,
bokehScale,
resolutionScale,
resolutionX,
resolutionY,
width,
height,
autoFocus,
depthTexture,
])
useEffect(() => {
return () => {
effect.dispose()
}
}, [effect])
return <primitive {...props} ref={ref} object={effect} target={target} />
})