Skip to content

Commit 1cb5ea7

Browse files
committed
chore: using wrapEffect
1 parent b8489a3 commit 1cb5ea7

File tree

1 file changed

+109
-111
lines changed

1 file changed

+109
-111
lines changed

src/effects/LensFlare.tsx

Lines changed: 109 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
// From https://github.com/ektogamat/R3F-Ultimate-Lens-Flare
33

44
import * as THREE from 'three'
5-
import { useMemo, useEffect, forwardRef, useState, useContext } from 'react'
5+
import { useEffect, useState, useContext, useRef } from 'react'
66
import { useFrame, useThree } from '@react-three/fiber'
77
import { BlendFunction, Effect } from 'postprocessing'
88
import { easing } from 'maath'
99

1010
import { EffectComposerContext } from '../EffectComposer'
11+
import { wrapEffect } from '../util'
1112

1213
const LensFlareShader = {
1314
fragmentShader: `
@@ -495,8 +496,6 @@ export class LensFlareEffect extends Effect {
495496
}
496497
}
497498

498-
type LensFlareApi = LensFlareEffect
499-
500499
type LensFlareProps = {
501500
/** Position of the effect */
502501
position?: THREE.Vector3
@@ -506,118 +505,117 @@ type LensFlareProps = {
506505
smoothTime?: number
507506
} & Partial<LensFlareEffectOptions>
508507

509-
export const LensFlare = forwardRef<LensFlareApi, LensFlareProps>(
510-
(
511-
{
512-
position = new THREE.Vector3(-25, 6, -60),
513-
followMouse = false,
514-
smoothTime = 0.07,
515-
//
516-
blendFunction = BlendFunction.NORMAL,
517-
enabled = true,
518-
glareSize = 0.2,
519-
lensPosition = new THREE.Vector2(0.01, 0.01),
520-
screenRes = new THREE.Vector2(0, 0),
521-
starPoints = 6,
522-
flareSize = 0.01,
523-
flareSpeed = 0.01,
524-
flareShape = 0.01,
525-
animated = true,
526-
anamorphic = false,
527-
colorGain = new THREE.Color(20, 20, 20),
528-
lensDirtTexture = null,
529-
haloScale = 0.5,
530-
secondaryGhosts = true,
531-
aditionalStreaks = true,
532-
ghostScale = 0.0,
533-
opacity = 1.0,
534-
starBurst = false,
535-
},
536-
ref
537-
) => {
538-
const viewport = useThree(({ viewport }) => viewport)
539-
const raycaster = useThree(({ raycaster }) => raycaster)
540-
const pointer = useThree(({ pointer }) => pointer)
541-
const { scene, camera } = useContext(EffectComposerContext)
542-
543-
const [projectedPosition] = useState(() => new THREE.Vector3())
544-
const [mouse2d] = useState(() => new THREE.Vector2())
545-
546-
const opts = {
547-
blendFunction,
548-
enabled,
549-
glareSize,
550-
lensPosition,
551-
screenRes,
552-
starPoints,
553-
flareSize,
554-
flareSpeed,
555-
flareShape,
556-
animated,
557-
anamorphic,
558-
colorGain,
559-
lensDirtTexture,
560-
haloScale,
561-
secondaryGhosts,
562-
aditionalStreaks,
563-
ghostScale,
564-
opacity,
565-
starBurst,
566-
}
567-
// eslint-disable-next-line react-hooks/exhaustive-deps
568-
const effect = useMemo(() => new LensFlareEffect(opts), [JSON.stringify(opts)])
569-
570-
useFrame((_, delta) => {
571-
const uLensPosition = effect.uniforms.get('lensPosition')
572-
const uOpacity = effect.uniforms.get('opacity')
573-
if (!uLensPosition || !uOpacity) return
574-
575-
let target = 1
576-
577-
if (followMouse) {
578-
uLensPosition.value.x = pointer.x
579-
uLensPosition.value.y = pointer.y
580-
target = 0
581-
} else {
582-
projectedPosition.copy(position).project(camera)
583-
if (projectedPosition.z > 1) return
584-
585-
uLensPosition.value.x = projectedPosition.x
586-
uLensPosition.value.y = projectedPosition.y
587-
588-
mouse2d.set(projectedPosition.x, projectedPosition.y)
589-
raycaster.setFromCamera(mouse2d, camera)
590-
const intersects = raycaster.intersectObjects(scene.children, true)
591-
const { object } = intersects[0]
592-
if (object) {
593-
if (object.userData?.lensflare === 'no-occlusion') {
594-
target = 0
595-
} else if (object instanceof THREE.Mesh) {
596-
if (object.material.uniforms?._transmission?.value > 0.2) {
597-
//Check for MeshTransmissionMaterial
598-
target = 0.2
599-
} else if (object.material._transmission && object.material._transmission > 0.2) {
600-
//Check for MeshPhysicalMaterial with transmission setting
601-
target = 0.2
602-
} else if (object.material.transparent) {
603-
// Check for OtherMaterials with transparent parameter
604-
target = object.material.opacity
605-
}
508+
const LensFlareWrapped = wrapEffect(LensFlareEffect)
509+
510+
export const LensFlare = ({
511+
position = new THREE.Vector3(-25, 6, -60),
512+
followMouse = false,
513+
smoothTime = 0.07,
514+
//
515+
blendFunction = BlendFunction.NORMAL,
516+
enabled = true,
517+
glareSize = 0.2,
518+
lensPosition = new THREE.Vector2(0.01, 0.01),
519+
screenRes = new THREE.Vector2(0, 0),
520+
starPoints = 6,
521+
flareSize = 0.01,
522+
flareSpeed = 0.01,
523+
flareShape = 0.01,
524+
animated = true,
525+
anamorphic = false,
526+
colorGain = new THREE.Color(20, 20, 20),
527+
lensDirtTexture = null,
528+
haloScale = 0.5,
529+
secondaryGhosts = true,
530+
aditionalStreaks = true,
531+
ghostScale = 0.0,
532+
opacity = 1.0,
533+
starBurst = false,
534+
}: LensFlareProps) => {
535+
const viewport = useThree(({ viewport }) => viewport)
536+
const raycaster = useThree(({ raycaster }) => raycaster)
537+
const pointer = useThree(({ pointer }) => pointer)
538+
const { scene, camera } = useContext(EffectComposerContext)
539+
540+
const [projectedPosition] = useState(() => new THREE.Vector3())
541+
const [mouse2d] = useState(() => new THREE.Vector2())
542+
543+
const ref = useRef<LensFlareEffect>(null)
544+
545+
useFrame((_, delta) => {
546+
if (!ref?.current) return
547+
const uLensPosition = ref.current.uniforms.get('lensPosition')
548+
const uOpacity = ref.current.uniforms.get('opacity')
549+
if (!uLensPosition || !uOpacity) return
550+
551+
let target = 1
552+
553+
if (followMouse) {
554+
uLensPosition.value.x = pointer.x
555+
uLensPosition.value.y = pointer.y
556+
target = 0
557+
} else {
558+
projectedPosition.copy(position).project(camera)
559+
if (projectedPosition.z > 1) return
560+
561+
uLensPosition.value.x = projectedPosition.x
562+
uLensPosition.value.y = projectedPosition.y
563+
564+
mouse2d.set(projectedPosition.x, projectedPosition.y)
565+
raycaster.setFromCamera(mouse2d, camera)
566+
const intersects = raycaster.intersectObjects(scene.children, true)
567+
const { object } = intersects[0]
568+
if (object) {
569+
if (object.userData?.lensflare === 'no-occlusion') {
570+
target = 0
571+
} else if (object instanceof THREE.Mesh) {
572+
if (object.material.uniforms?._transmission?.value > 0.2) {
573+
//Check for MeshTransmissionMaterial
574+
target = 0.2
575+
} else if (object.material._transmission && object.material._transmission > 0.2) {
576+
//Check for MeshPhysicalMaterial with transmission setting
577+
target = 0.2
578+
} else if (object.material.transparent) {
579+
// Check for OtherMaterials with transparent parameter
580+
target = object.material.opacity
606581
}
607582
}
608583
}
584+
}
609585

610-
easing.damp(uOpacity, 'value', target, smoothTime, delta)
611-
})
586+
easing.damp(uOpacity, 'value', target, smoothTime, delta)
587+
})
612588

613-
useEffect(() => {
614-
const screenRes = effect.uniforms.get('screenRes')
615-
if (screenRes) {
616-
screenRes.value.x = viewport.width
617-
screenRes.value.y = viewport.height
618-
}
619-
}, [effect, viewport])
589+
useEffect(() => {
590+
if (!ref?.current) return
620591

621-
return <primitive ref={ref} object={effect} dispose={null} />
592+
const screenRes = ref.current.uniforms.get('screenRes')
593+
if (screenRes) {
594+
screenRes.value.x = viewport.width
595+
screenRes.value.y = viewport.height
596+
}
597+
}, [viewport])
598+
599+
const opts = {
600+
blendFunction,
601+
enabled,
602+
glareSize,
603+
lensPosition,
604+
screenRes,
605+
starPoints,
606+
flareSize,
607+
flareSpeed,
608+
flareShape,
609+
animated,
610+
anamorphic,
611+
colorGain,
612+
lensDirtTexture,
613+
haloScale,
614+
secondaryGhosts,
615+
aditionalStreaks,
616+
ghostScale,
617+
opacity,
618+
starBurst,
622619
}
623-
)
620+
return <LensFlareWrapped ref={ref} {...opts} />
621+
}

0 commit comments

Comments
 (0)