1
1
import { DepthOfFieldEffect , MaskFunction } from 'postprocessing'
2
- import { Ref , forwardRef , useMemo , useLayoutEffect , useContext } from 'react'
3
- import { ReactThreeFiber , useThree } from '@react-three/fiber'
2
+ import { Ref , forwardRef , useMemo , useEffect , useContext } from 'react'
3
+ import { ReactThreeFiber } from '@react-three/fiber'
4
4
import { type DepthPackingStrategies , type Texture , Vector3 } from 'three'
5
5
import { EffectComposerContext } from '../EffectComposer'
6
6
@@ -9,34 +9,81 @@ type DOFProps = ConstructorParameters<typeof DepthOfFieldEffect>[1] &
9
9
target : ReactThreeFiber . Vector3
10
10
depthTexture : {
11
11
texture : Texture
12
+ // TODO: narrow to DepthPackingStrategies
12
13
packing : number
13
14
}
15
+ // TODO: not used
14
16
blur : number
15
17
} >
16
18
17
19
export const DepthOfField = forwardRef ( function DepthOfField (
18
- { target, depthTexture, ...props } : DOFProps ,
20
+ {
21
+ blendFunction,
22
+ worldFocusDistance,
23
+ worldFocusRange,
24
+ focusDistance,
25
+ focusRange,
26
+ focalLength,
27
+ bokehScale,
28
+ resolutionScale,
29
+ resolutionX,
30
+ resolutionY,
31
+ width,
32
+ height,
33
+ target,
34
+ depthTexture,
35
+ ...props
36
+ } : DOFProps ,
19
37
ref : Ref < DepthOfFieldEffect >
20
38
) {
21
- const invalidate = useThree ( ( state ) => state . invalidate )
22
39
const { camera } = useContext ( EffectComposerContext )
40
+ const autoFocus = target != null
23
41
const effect = useMemo ( ( ) => {
24
- const effect = new DepthOfFieldEffect ( camera , props )
42
+ const effect = new DepthOfFieldEffect ( camera , {
43
+ blendFunction,
44
+ worldFocusDistance,
45
+ worldFocusRange,
46
+ focusDistance,
47
+ focusRange,
48
+ focalLength,
49
+ bokehScale,
50
+ resolutionScale,
51
+ resolutionX,
52
+ resolutionY,
53
+ width,
54
+ height,
55
+ } )
56
+ // Creating a target enables autofocus, R3F will set via props
57
+ if ( autoFocus ) effect . target = new Vector3 ( )
58
+ // Depth texture for depth picking with optional packing strategy
59
+ if ( depthTexture ) effect . setDepthTexture ( depthTexture . texture , depthTexture . packing as DepthPackingStrategies )
25
60
// Temporary fix that restores DOF 6.21.3 behavior, everything since then lets shapes leak through the blur
26
61
const maskMaterial = ( effect as any ) . maskPass . getFullscreenMaterial ( )
27
62
maskMaterial . maskFunction = MaskFunction . MULTIPLY_RGB_SET_ALPHA
28
63
return effect
29
- } , [ camera , props ] )
30
- useLayoutEffect ( ( ) => {
31
- if ( target && typeof target !== 'number' ) {
32
- const vec : Vector3 =
33
- target instanceof Vector3
34
- ? new Vector3 ( ) . set ( target . x , target . y , target . z )
35
- : new Vector3 ( ) . set ( target [ 0 ] , target [ 1 ] , target [ 2 ] )
36
- effect . target = vec
64
+ } , [
65
+ camera ,
66
+ blendFunction ,
67
+ worldFocusDistance ,
68
+ worldFocusRange ,
69
+ focusDistance ,
70
+ focusRange ,
71
+ focalLength ,
72
+ bokehScale ,
73
+ resolutionScale ,
74
+ resolutionX ,
75
+ resolutionY ,
76
+ width ,
77
+ height ,
78
+ autoFocus ,
79
+ depthTexture ,
80
+ ] )
81
+
82
+ useEffect ( ( ) => {
83
+ return ( ) => {
84
+ effect . dispose ( )
37
85
}
38
- if ( depthTexture ) effect . setDepthTexture ( depthTexture . texture , depthTexture . packing as DepthPackingStrategies )
39
- invalidate ( )
40
- } , [ target , depthTexture , effect ] )
41
- return < primitive ref = { ref } object = { effect } dispose = { null } />
86
+ } , [ effect ] )
87
+
88
+ return < primitive { ...props } ref = { ref } object = { effect } target = { target } />
42
89
} )
0 commit comments