11import { 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'
44import { type DepthPackingStrategies , type Texture , Vector3 } from 'three'
55import { EffectComposerContext } from '../EffectComposer'
66
@@ -9,34 +9,81 @@ type DOFProps = ConstructorParameters<typeof DepthOfFieldEffect>[1] &
99 target : ReactThreeFiber . Vector3
1010 depthTexture : {
1111 texture : Texture
12+ // TODO: narrow to DepthPackingStrategies
1213 packing : number
1314 }
15+ // TODO: not used
1416 blur : number
1517 } >
1618
1719export 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 ,
1937 ref : Ref < DepthOfFieldEffect >
2038) {
21- const invalidate = useThree ( ( state ) => state . invalidate )
2239 const { camera } = useContext ( EffectComposerContext )
40+ const autoFocus = target != null
2341 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 )
2560 // Temporary fix that restores DOF 6.21.3 behavior, everything since then lets shapes leak through the blur
2661 const maskMaterial = ( effect as any ) . maskPass . getFullscreenMaterial ( )
2762 maskMaterial . maskFunction = MaskFunction . MULTIPLY_RGB_SET_ALPHA
2863 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 ( )
3785 }
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 } />
4289} )
0 commit comments