@react-three/postprocessing 3.0.5 → 3.1.0
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/README.md +6 -7
- package/dist/EffectComposer.d.ts +9 -2
- package/dist/EffectGroup.d.ts +9 -0
- package/dist/createEffectComponent.d.ts +30 -0
- package/dist/effects/ASCII.d.ts +28 -7
- package/dist/effects/Autofocus.d.ts +1 -1
- package/dist/effects/Bloom.d.ts +9 -1
- package/dist/effects/BrightnessContrast.d.ts +14 -1
- package/dist/effects/ChromaticAberration.d.ts +26 -3
- package/dist/effects/ColorAverage.d.ts +7 -7
- package/dist/effects/ColorDepth.d.ts +7 -1
- package/dist/effects/Depth.d.ts +12 -1
- package/dist/effects/DotScreen.d.ts +14 -1
- package/dist/effects/FXAA.d.ts +10 -1
- package/dist/effects/Glitch.d.ts +16 -11
- package/dist/effects/GodRays.d.ts +1 -1
- package/dist/effects/Grid.d.ts +7 -6
- package/dist/effects/HueSaturation.d.ts +14 -1
- package/dist/effects/LUT.d.ts +1 -1
- package/dist/effects/LensFlare.d.ts +46 -5
- package/dist/effects/Noise.d.ts +7 -1
- package/dist/effects/Outline.d.ts +6 -3
- package/dist/effects/Pixelation.d.ts +1 -1
- package/dist/effects/Ramp.d.ts +58 -6
- package/dist/effects/SMAA.d.ts +9 -1
- package/dist/effects/SSAO.d.ts +1 -1
- package/dist/effects/ScanlineEffect.d.ts +12 -1
- package/dist/effects/SelectiveBloom.d.ts +1 -1
- package/dist/effects/Sepia.d.ts +12 -1
- package/dist/effects/ShockWave.d.ts +11 -1
- package/dist/effects/Texture.d.ts +4 -4
- package/dist/effects/TiltShift.d.ts +9 -1
- package/dist/effects/TiltShift2.d.ts +44 -4
- package/dist/effects/ToneMapping.d.ts +9 -3
- package/dist/effects/Vignette.d.ts +18 -1
- package/dist/effects/Water.d.ts +17 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +2205 -713
- package/dist/index.js.map +1 -1
- package/dist/passes/DepthPicking.d.ts +11 -0
- package/dist/{effects → passes}/N8AO.d.ts +2 -1
- package/dist/util.d.ts +9 -15
- package/dist/wrapEffect.d.ts +3 -3
- package/package.json +4 -3
- package/src/EffectComposer.tsx +143 -42
- package/src/EffectGroup.tsx +74 -0
- package/src/createEffectComponent.tsx +71 -0
- package/src/effects/ASCII.tsx +75 -28
- package/src/effects/Autofocus.tsx +24 -77
- package/src/effects/Bloom.tsx +32 -4
- package/src/effects/BrightnessContrast.tsx +5 -2
- package/src/effects/ChromaticAberration.tsx +13 -21
- package/src/effects/ColorAverage.tsx +3 -16
- package/src/effects/ColorDepth.tsx +23 -2
- package/src/effects/Depth.tsx +4 -2
- package/src/effects/DepthOfField.tsx +48 -26
- package/src/effects/DotScreen.tsx +5 -2
- package/src/effects/FXAA.tsx +4 -2
- package/src/effects/Glitch.tsx +26 -31
- package/src/effects/GodRays.tsx +90 -6
- package/src/effects/Grid.tsx +17 -18
- package/src/effects/HueSaturation.tsx +5 -2
- package/src/effects/LUT.tsx +9 -11
- package/src/effects/LensFlare.tsx +209 -55
- package/src/effects/Noise.tsx +14 -2
- package/src/effects/Outline.tsx +55 -56
- package/src/effects/Pixelation.tsx +11 -8
- package/src/effects/Ramp.tsx +96 -7
- package/src/effects/SMAA.tsx +18 -2
- package/src/effects/SSAO.tsx +130 -22
- package/src/effects/ScanlineEffect.tsx +6 -6
- package/src/effects/SelectiveBloom.tsx +26 -44
- package/src/effects/Sepia.tsx +4 -2
- package/src/effects/ShockWave.tsx +30 -2
- package/src/effects/Texture.tsx +10 -9
- package/src/effects/TiltShift.tsx +30 -2
- package/src/effects/TiltShift2.tsx +72 -6
- package/src/effects/ToneMapping.tsx +16 -3
- package/src/effects/Vignette.tsx +5 -2
- package/src/effects/Water.tsx +21 -6
- package/src/index.ts +4 -2
- package/src/passes/DepthPicking.tsx +63 -0
- package/src/{effects → passes}/N8AO.tsx +28 -4
- package/src/tests/Autofocus.test.tsx +38 -0
- package/src/tests/Bloom.test.tsx +76 -0
- package/src/tests/ChromaticAberration.test.tsx +50 -0
- package/src/tests/ColorDepth.test.tsx +71 -0
- package/src/tests/DepthOfField.test.tsx +130 -0
- package/src/tests/DepthPicking.test.tsx +250 -0
- package/src/tests/EffectComposer.test.tsx +501 -8
- package/src/tests/EffectGroup.test.tsx +337 -0
- package/src/tests/Glitch.test.tsx +56 -0
- package/src/tests/GodRays.test.tsx +101 -0
- package/src/tests/Grid.test.tsx +34 -0
- package/src/tests/LUT.test.tsx +64 -0
- package/src/tests/N8AO.test.tsx +92 -0
- package/src/tests/Outline.test.tsx +122 -0
- package/src/tests/SSAO.test.tsx +140 -0
- package/src/tests/SelectiveBloom.test.tsx +48 -0
- package/src/tests/ShockWave.test.tsx +95 -0
- package/src/tests/TiltShift.test.tsx +76 -0
- package/src/tests/createEffectComponent.test.tsx +286 -0
- package/src/tests/effects.smoke.test.tsx +46 -42
- package/src/util.tsx +148 -23
- package/src/wrapEffect.tsx +3 -2
- package/dist/tests/test-utils.d.ts +0 -12
package/src/effects/Glitch.tsx
CHANGED
|
@@ -1,37 +1,32 @@
|
|
|
1
|
-
import { ReactThreeFiber
|
|
1
|
+
import type { ReactThreeFiber } from '@react-three/fiber'
|
|
2
2
|
import { GlitchEffect, GlitchMode } from 'postprocessing'
|
|
3
|
-
import { Ref
|
|
4
|
-
import {
|
|
3
|
+
import type { Ref } from 'react'
|
|
4
|
+
import { useMemo } from 'react'
|
|
5
|
+
import { createEffectComponent, type EffectOptions } from '../createEffectComponent'
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export function Glitch({ active = true, ref, ...props }: GlitchProps) {
|
|
18
|
-
const invalidate = useThree((state) => state.invalidate)
|
|
19
|
-
const delay = useVector2(props, 'delay')
|
|
20
|
-
const duration = useVector2(props, 'duration')
|
|
21
|
-
const strength = useVector2(props, 'strength')
|
|
22
|
-
const chromaticAberrationOffset = useVector2(props, 'chromaticAberrationOffset')
|
|
23
|
-
|
|
24
|
-
const effect = useMemo(
|
|
25
|
-
() => new GlitchEffect({ ...props, delay, duration, strength, chromaticAberrationOffset }),
|
|
26
|
-
[delay, duration, props, strength, chromaticAberrationOffset]
|
|
27
|
-
)
|
|
7
|
+
type GlitchOptions = Omit<
|
|
8
|
+
EffectOptions<typeof GlitchEffect>,
|
|
9
|
+
'delay' | 'duration' | 'strength' | 'chromaticAberrationOffset'
|
|
10
|
+
> & {
|
|
11
|
+
delay?: ReactThreeFiber.Vector2
|
|
12
|
+
duration?: ReactThreeFiber.Vector2
|
|
13
|
+
strength?: ReactThreeFiber.Vector2
|
|
14
|
+
chromaticAberrationOffset?: ReactThreeFiber.Vector2
|
|
15
|
+
mode?: GlitchMode
|
|
16
|
+
}
|
|
28
17
|
|
|
29
|
-
|
|
30
|
-
effect.mode = active ? props.mode || GlitchMode.SPORADIC : GlitchMode.DISABLED
|
|
31
|
-
invalidate()
|
|
32
|
-
}, [active, effect, invalidate, props.mode])
|
|
18
|
+
const GlitchImpl = /* @__PURE__ */ createEffectComponent<typeof GlitchEffect, GlitchOptions>(GlitchEffect)
|
|
33
19
|
|
|
34
|
-
|
|
20
|
+
export type GlitchProps = GlitchOptions & {
|
|
21
|
+
active?: boolean
|
|
22
|
+
opacity?: number
|
|
23
|
+
ref?: Ref<GlitchEffect>
|
|
24
|
+
}
|
|
35
25
|
|
|
36
|
-
|
|
26
|
+
// dtSize only seeds the auto-generated perturbation map at construction time
|
|
27
|
+
// (skipped entirely once a perturbationMap is provided) - routed through
|
|
28
|
+
// args so it still works as a plain prop.
|
|
29
|
+
export function Glitch({ active = true, mode = GlitchMode.SPORADIC, dtSize, ...props }: GlitchProps) {
|
|
30
|
+
const args = useMemo<[EffectOptions<typeof GlitchEffect>]>(() => [{ dtSize }], [dtSize])
|
|
31
|
+
return <GlitchImpl args={args} mode={active ? mode : GlitchMode.DISABLED} {...props} />
|
|
37
32
|
}
|
package/src/effects/GodRays.tsx
CHANGED
|
@@ -1,18 +1,102 @@
|
|
|
1
|
+
import { useThree } from '@react-three/fiber'
|
|
1
2
|
import { GodRaysEffect } from 'postprocessing'
|
|
2
|
-
import { Ref, RefObject,
|
|
3
|
+
import { Ref, RefObject, use, useEffect, useLayoutEffect, useMemo } from 'react'
|
|
3
4
|
import { Mesh, Points } from 'three'
|
|
4
5
|
import { EffectComposerContext } from '../EffectComposer'
|
|
5
|
-
import { resolveRef, useDispose } from '../util'
|
|
6
|
+
import { applyPierced, readPierced, resolveRef, useDispose, useLiveDefaults } from '../util'
|
|
6
7
|
|
|
7
8
|
type GodRaysProps = ConstructorParameters<typeof GodRaysEffect>[2] & {
|
|
8
9
|
sun: Mesh | Points | RefObject<Mesh | Points>
|
|
9
10
|
ref?: Ref<GodRaysEffect>
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
// GodRaysMaterial (godRaysMaterial) is where density/decay/weight/exposure
|
|
14
|
+
// actually live - clampMax maps to its differently-named maxIntensity.
|
|
15
|
+
// resolutionScale/resolutionX/resolutionY have no setter at all in
|
|
16
|
+
// postprocessing - construction-only. camera+sun being required constructor
|
|
17
|
+
// args also rule out createEffectComponent (needs `new Effect()` to work
|
|
18
|
+
// with zero args).
|
|
19
|
+
const LIVE_KEYS = [
|
|
20
|
+
'blendMode-blendFunction',
|
|
21
|
+
'godRaysMaterial-density',
|
|
22
|
+
'godRaysMaterial-decay',
|
|
23
|
+
'godRaysMaterial-weight',
|
|
24
|
+
'godRaysMaterial-exposure',
|
|
25
|
+
'clampMax',
|
|
26
|
+
'blur',
|
|
27
|
+
'kernelSize',
|
|
28
|
+
'samples',
|
|
29
|
+
'width',
|
|
30
|
+
'height',
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
function get(effect: GodRaysEffect, key: string): unknown {
|
|
34
|
+
return key === 'clampMax' ? effect.godRaysMaterial.maxIntensity : readPierced(effect, key)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function set(effect: GodRaysEffect, key: string, value: unknown): void {
|
|
38
|
+
if (key === 'clampMax') effect.godRaysMaterial.maxIntensity = value as number
|
|
39
|
+
else applyPierced(effect, key, value)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function GodRays({
|
|
43
|
+
sun,
|
|
44
|
+
blendFunction,
|
|
45
|
+
density,
|
|
46
|
+
decay,
|
|
47
|
+
weight,
|
|
48
|
+
exposure,
|
|
49
|
+
clampMax,
|
|
50
|
+
blur,
|
|
51
|
+
kernelSize,
|
|
52
|
+
samples,
|
|
53
|
+
width,
|
|
54
|
+
height,
|
|
55
|
+
resolutionScale,
|
|
56
|
+
resolutionX,
|
|
57
|
+
resolutionY,
|
|
58
|
+
ref,
|
|
59
|
+
}: GodRaysProps) {
|
|
60
|
+
const { camera, autoClear } = use(EffectComposerContext)
|
|
61
|
+
const invalidate = useThree((state) => state.invalidate)
|
|
62
|
+
|
|
63
|
+
const effect = useMemo(
|
|
64
|
+
() => new GodRaysEffect(camera, resolveRef(sun), { resolutionScale, resolutionX, resolutionY }),
|
|
65
|
+
[camera, resolutionScale, resolutionX, resolutionY]
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (autoClear !== false) {
|
|
70
|
+
console.warn(
|
|
71
|
+
'GodRays renders an internal extra pass that needs <EffectComposer autoClear={false}> - without it, occlusion by other objects will look wrong.'
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
}, [autoClear])
|
|
75
|
+
|
|
76
|
+
useLayoutEffect(() => {
|
|
77
|
+
effect.lightSource = resolveRef(sun)
|
|
78
|
+
invalidate()
|
|
79
|
+
}, [effect, sun, invalidate])
|
|
80
|
+
|
|
81
|
+
useLiveDefaults(
|
|
82
|
+
effect,
|
|
83
|
+
{
|
|
84
|
+
'blendMode-blendFunction': blendFunction,
|
|
85
|
+
'godRaysMaterial-density': density,
|
|
86
|
+
'godRaysMaterial-decay': decay,
|
|
87
|
+
'godRaysMaterial-weight': weight,
|
|
88
|
+
'godRaysMaterial-exposure': exposure,
|
|
89
|
+
clampMax,
|
|
90
|
+
blur,
|
|
91
|
+
kernelSize,
|
|
92
|
+
samples,
|
|
93
|
+
width,
|
|
94
|
+
height,
|
|
95
|
+
},
|
|
96
|
+
LIVE_KEYS,
|
|
97
|
+
get,
|
|
98
|
+
set
|
|
99
|
+
)
|
|
16
100
|
|
|
17
101
|
useDispose(effect)
|
|
18
102
|
|
package/src/effects/Grid.tsx
CHANGED
|
@@ -1,28 +1,27 @@
|
|
|
1
1
|
import { useThree } from '@react-three/fiber'
|
|
2
2
|
import { GridEffect } from 'postprocessing'
|
|
3
|
-
import { Ref, useLayoutEffect,
|
|
4
|
-
import {
|
|
3
|
+
import { type Ref, useImperativeHandle, useLayoutEffect, useRef } from 'react'
|
|
4
|
+
import { createEffectComponent, type EffectOptions } from '../createEffectComponent'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}>
|
|
6
|
+
const GridImpl = /* @__PURE__ */ createEffectComponent<typeof GridEffect, EffectOptions<typeof GridEffect>>(GridEffect)
|
|
7
|
+
|
|
8
|
+
export type GridProps = EffectOptions<typeof GridEffect> & {
|
|
9
|
+
size?: { width: number; height: number }
|
|
10
|
+
opacity?: number
|
|
11
|
+
ref?: Ref<GridEffect>
|
|
12
|
+
}
|
|
14
13
|
|
|
15
14
|
export function Grid({ size, ref, ...props }: GridProps) {
|
|
16
15
|
const invalidate = useThree((state) => state.invalidate)
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const localRef = useRef<GridEffect>(null)
|
|
17
|
+
useImperativeHandle(ref, () => localRef.current!, [])
|
|
19
18
|
|
|
20
19
|
useLayoutEffect(() => {
|
|
21
|
-
if (size)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
if (size) {
|
|
21
|
+
localRef.current?.setSize(size.width, size.height)
|
|
22
|
+
invalidate()
|
|
23
|
+
}
|
|
24
|
+
}, [size, invalidate])
|
|
26
25
|
|
|
27
|
-
return <
|
|
26
|
+
return <GridImpl ref={localRef} {...props} />
|
|
28
27
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { HueSaturationEffect } from 'postprocessing'
|
|
2
|
-
import {
|
|
2
|
+
import { createEffectComponent, type EffectOptions } from '../createEffectComponent'
|
|
3
3
|
|
|
4
|
-
export const HueSaturation = /* @__PURE__ */
|
|
4
|
+
export const HueSaturation = /* @__PURE__ */ createEffectComponent<
|
|
5
|
+
typeof HueSaturationEffect,
|
|
6
|
+
EffectOptions<typeof HueSaturationEffect>
|
|
7
|
+
>(HueSaturationEffect)
|
package/src/effects/LUT.tsx
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { useThree } from '@react-three/fiber'
|
|
2
1
|
import { BlendFunction, LUT3DEffect } from 'postprocessing'
|
|
3
|
-
import { Ref,
|
|
2
|
+
import { Ref, useMemo } from 'react'
|
|
4
3
|
import type { Texture } from 'three'
|
|
5
|
-
import { useDispose } from '../util'
|
|
4
|
+
import { useDispose, useLiveDefaults } from '../util'
|
|
6
5
|
|
|
7
6
|
export type LUTProps = {
|
|
8
7
|
lut: Texture
|
|
@@ -11,16 +10,15 @@ export type LUTProps = {
|
|
|
11
10
|
ref?: Ref<LUT3DEffect>
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
const effect = useMemo(() => new LUT3DEffect(lut, props), [lut, props])
|
|
16
|
-
const invalidate = useThree((state) => state.invalidate)
|
|
13
|
+
const LIVE_KEYS = ['blendMode-blendFunction', 'lut', 'tetrahedralInterpolation']
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
// lut is LUT3DEffect's required constructor arg (no default) - only used
|
|
16
|
+
// for the initial instance, later changes go through its own live setter
|
|
17
|
+
// (via useLiveDefaults below) instead of reconstructing.
|
|
18
|
+
export function LUT({ lut, blendFunction, tetrahedralInterpolation, ref }: LUTProps) {
|
|
19
|
+
const effect = useMemo(() => new LUT3DEffect(lut), [])
|
|
23
20
|
|
|
21
|
+
useLiveDefaults(effect, { 'blendMode-blendFunction': blendFunction, lut, tetrahedralInterpolation }, LIVE_KEYS)
|
|
24
22
|
useDispose(effect)
|
|
25
23
|
|
|
26
24
|
return <primitive ref={ref} object={effect} />
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
// Created by Anderson Mancini 2023
|
|
2
2
|
// From https://github.com/ektogamat/R3F-Ultimate-Lens-Flare
|
|
3
3
|
|
|
4
|
-
import { useFrame, useThree } from '@react-three/fiber'
|
|
4
|
+
import { useFrame, useThree, type ReactThreeFiber } from '@react-three/fiber'
|
|
5
5
|
import { easing } from 'maath'
|
|
6
6
|
import { BlendFunction, Effect } from 'postprocessing'
|
|
7
|
-
import { useContext, useEffect, useRef, useState } from 'react'
|
|
7
|
+
import { useContext, useEffect, useRef, useState, type Ref } from 'react'
|
|
8
8
|
import { Color, Mesh, Texture, Uniform, Vector2, Vector3 } from 'three'
|
|
9
9
|
|
|
10
|
+
import { createEffectComponent } from '../createEffectComponent'
|
|
10
11
|
import { EffectComposerContext } from '../EffectComposer'
|
|
11
|
-
import {
|
|
12
|
+
import { useMergeRefs, useVector3 } from '../util'
|
|
12
13
|
|
|
13
14
|
const LensFlareShader = {
|
|
14
15
|
fragmentShader: /* glsl */ `
|
|
@@ -441,26 +442,26 @@ type LensFlareEffectOptions = {
|
|
|
441
442
|
|
|
442
443
|
export class LensFlareEffect extends Effect {
|
|
443
444
|
constructor({
|
|
444
|
-
blendFunction,
|
|
445
|
-
enabled,
|
|
446
|
-
glareSize,
|
|
447
|
-
lensPosition,
|
|
448
|
-
screenRes,
|
|
449
|
-
starPoints,
|
|
450
|
-
flareSize,
|
|
451
|
-
flareSpeed,
|
|
452
|
-
flareShape,
|
|
453
|
-
animated,
|
|
454
|
-
anamorphic,
|
|
455
|
-
colorGain,
|
|
456
|
-
lensDirtTexture,
|
|
457
|
-
haloScale,
|
|
458
|
-
secondaryGhosts,
|
|
459
|
-
aditionalStreaks,
|
|
460
|
-
ghostScale,
|
|
461
|
-
opacity,
|
|
462
|
-
starBurst,
|
|
463
|
-
}: LensFlareEffectOptions) {
|
|
445
|
+
blendFunction = BlendFunction.NORMAL,
|
|
446
|
+
enabled = true,
|
|
447
|
+
glareSize = 0.2,
|
|
448
|
+
lensPosition = new Vector3(-25, 6, -60),
|
|
449
|
+
screenRes = new Vector2(0, 0),
|
|
450
|
+
starPoints = 6,
|
|
451
|
+
flareSize = 0.01,
|
|
452
|
+
flareSpeed = 0.01,
|
|
453
|
+
flareShape = 0.01,
|
|
454
|
+
animated = true,
|
|
455
|
+
anamorphic = false,
|
|
456
|
+
colorGain = new Color(20, 20, 20),
|
|
457
|
+
lensDirtTexture = null,
|
|
458
|
+
haloScale = 0.5,
|
|
459
|
+
secondaryGhosts = true,
|
|
460
|
+
aditionalStreaks = true,
|
|
461
|
+
ghostScale = 0.0,
|
|
462
|
+
opacity = 1.0,
|
|
463
|
+
starBurst = false,
|
|
464
|
+
}: Partial<LensFlareEffectOptions> = {}) {
|
|
464
465
|
super('LensFlareEffect', LensFlareShader.fragmentShader, {
|
|
465
466
|
blendFunction,
|
|
466
467
|
uniforms: new Map<string, Uniform>([
|
|
@@ -493,40 +494,191 @@ export class LensFlareEffect extends Effect {
|
|
|
493
494
|
time.value += deltaTime
|
|
494
495
|
}
|
|
495
496
|
}
|
|
497
|
+
|
|
498
|
+
private u<T>(name: string): T {
|
|
499
|
+
return this.uniforms.get(name)!.value
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
private setU(name: string, value: unknown): void {
|
|
503
|
+
this.uniforms.get(name)!.value = value
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
get enabled(): boolean {
|
|
507
|
+
return this.u('enabled')
|
|
508
|
+
}
|
|
509
|
+
set enabled(value: boolean) {
|
|
510
|
+
this.setU('enabled', value)
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
get glareSize(): number {
|
|
514
|
+
return this.u('glareSize')
|
|
515
|
+
}
|
|
516
|
+
set glareSize(value: number) {
|
|
517
|
+
this.setU('glareSize', value)
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
get lensPosition(): Vector3 {
|
|
521
|
+
return this.u('lensPosition')
|
|
522
|
+
}
|
|
523
|
+
set lensPosition(value: Vector3) {
|
|
524
|
+
this.setU('lensPosition', value)
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
get screenRes(): Vector2 {
|
|
528
|
+
return this.u('screenRes')
|
|
529
|
+
}
|
|
530
|
+
set screenRes(value: Vector2) {
|
|
531
|
+
this.setU('screenRes', value)
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
get starPoints(): number {
|
|
535
|
+
return this.u('starPoints')
|
|
536
|
+
}
|
|
537
|
+
set starPoints(value: number) {
|
|
538
|
+
this.setU('starPoints', value)
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
get flareSize(): number {
|
|
542
|
+
return this.u('flareSize')
|
|
543
|
+
}
|
|
544
|
+
set flareSize(value: number) {
|
|
545
|
+
this.setU('flareSize', value)
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
get flareSpeed(): number {
|
|
549
|
+
return this.u('flareSpeed')
|
|
550
|
+
}
|
|
551
|
+
set flareSpeed(value: number) {
|
|
552
|
+
this.setU('flareSpeed', value)
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
get flareShape(): number {
|
|
556
|
+
return this.u('flareShape')
|
|
557
|
+
}
|
|
558
|
+
set flareShape(value: number) {
|
|
559
|
+
this.setU('flareShape', value)
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
get animated(): boolean {
|
|
563
|
+
return this.u('animated')
|
|
564
|
+
}
|
|
565
|
+
set animated(value: boolean) {
|
|
566
|
+
this.setU('animated', value)
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
get anamorphic(): boolean {
|
|
570
|
+
return this.u('anamorphic')
|
|
571
|
+
}
|
|
572
|
+
set anamorphic(value: boolean) {
|
|
573
|
+
this.setU('anamorphic', value)
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
get colorGain(): Color {
|
|
577
|
+
return this.u('colorGain')
|
|
578
|
+
}
|
|
579
|
+
set colorGain(value: Color) {
|
|
580
|
+
this.setU('colorGain', value)
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
get lensDirtTexture(): Texture | null {
|
|
584
|
+
return this.u('lensDirtTexture')
|
|
585
|
+
}
|
|
586
|
+
set lensDirtTexture(value: Texture | null) {
|
|
587
|
+
this.setU('lensDirtTexture', value)
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
get haloScale(): number {
|
|
591
|
+
return this.u('haloScale')
|
|
592
|
+
}
|
|
593
|
+
set haloScale(value: number) {
|
|
594
|
+
this.setU('haloScale', value)
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
get secondaryGhosts(): boolean {
|
|
598
|
+
return this.u('secondaryGhosts')
|
|
599
|
+
}
|
|
600
|
+
set secondaryGhosts(value: boolean) {
|
|
601
|
+
this.setU('secondaryGhosts', value)
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
get aditionalStreaks(): boolean {
|
|
605
|
+
return this.u('aditionalStreaks')
|
|
606
|
+
}
|
|
607
|
+
set aditionalStreaks(value: boolean) {
|
|
608
|
+
this.setU('aditionalStreaks', value)
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
get ghostScale(): number {
|
|
612
|
+
return this.u('ghostScale')
|
|
613
|
+
}
|
|
614
|
+
set ghostScale(value: number) {
|
|
615
|
+
this.setU('ghostScale', value)
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
get starBurst(): boolean {
|
|
619
|
+
return this.u('starBurst')
|
|
620
|
+
}
|
|
621
|
+
set starBurst(value: boolean) {
|
|
622
|
+
this.setU('starBurst', value)
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
get opacity(): number {
|
|
626
|
+
return this.u('opacity')
|
|
627
|
+
}
|
|
628
|
+
set opacity(value: number) {
|
|
629
|
+
this.setU('opacity', value)
|
|
630
|
+
}
|
|
496
631
|
}
|
|
497
632
|
|
|
498
|
-
type LensFlareProps = {
|
|
633
|
+
type LensFlareProps = Omit<Partial<LensFlareEffectOptions>, 'lensPosition'> & {
|
|
499
634
|
/** Position of the effect */
|
|
500
|
-
lensPosition?: Vector3
|
|
635
|
+
lensPosition?: ReactThreeFiber.Vector3
|
|
501
636
|
/** The time that it takes to fade the occlusion */
|
|
502
637
|
smoothTime?: number
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
638
|
+
ref?: Ref<LensFlareEffect>
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
const LensFlareWrapped = /* @__PURE__ */ createEffectComponent<
|
|
642
|
+
typeof LensFlareEffect,
|
|
643
|
+
Partial<LensFlareEffectOptions> & { ref?: Ref<LensFlareEffect> }
|
|
644
|
+
>(LensFlareEffect)
|
|
645
|
+
|
|
646
|
+
// Stable identity so a parent re-render (e.g. a Leva control) doesn't hand
|
|
647
|
+
// r3f a brand-new Vector2 every time - r3f would then `.copy()` it onto the
|
|
648
|
+
// uniform in place, stomping the viewport-driven value the effect below
|
|
649
|
+
// maintains and leaving screenRes at (0, 0) until the next resize. Never
|
|
650
|
+
// mutated (only ever copied *from*), so it's safe to share across instances.
|
|
651
|
+
const DEFAULT_SCREEN_RES = /* @__PURE__ */ new Vector2(0, 0)
|
|
652
|
+
|
|
653
|
+
// Same reasoning as DEFAULT_SCREEN_RES above - shared, read-only default.
|
|
654
|
+
const DEFAULT_LENS_POSITION = /* @__PURE__ */ new Vector3(-25, 6, -60)
|
|
655
|
+
|
|
656
|
+
export const LensFlare = (props: LensFlareProps) => {
|
|
657
|
+
const {
|
|
658
|
+
ref: forwardedRef,
|
|
659
|
+
smoothTime = 0.07,
|
|
660
|
+
blendFunction = BlendFunction.NORMAL,
|
|
661
|
+
enabled = true,
|
|
662
|
+
glareSize = 0.2,
|
|
663
|
+
screenRes,
|
|
664
|
+
starPoints = 6,
|
|
665
|
+
flareSize = 0.01,
|
|
666
|
+
flareSpeed = 0.01,
|
|
667
|
+
flareShape = 0.01,
|
|
668
|
+
animated = true,
|
|
669
|
+
anamorphic = false,
|
|
670
|
+
colorGain = new Color(20, 20, 20),
|
|
671
|
+
lensDirtTexture = null,
|
|
672
|
+
haloScale = 0.5,
|
|
673
|
+
secondaryGhosts = true,
|
|
674
|
+
aditionalStreaks = true,
|
|
675
|
+
ghostScale = 0.0,
|
|
676
|
+
opacity = 1.0,
|
|
677
|
+
starBurst = false,
|
|
678
|
+
} = props
|
|
679
|
+
|
|
680
|
+
const lensPosition = useVector3({ lensPosition: props.lensPosition ?? DEFAULT_LENS_POSITION }, 'lensPosition')
|
|
681
|
+
|
|
530
682
|
const viewport = useThree(({ viewport }) => viewport)
|
|
531
683
|
const raycaster = useThree(({ raycaster }) => raycaster)
|
|
532
684
|
const { scene, camera } = useContext(EffectComposerContext)
|
|
@@ -534,6 +686,7 @@ export const LensFlare = ({
|
|
|
534
686
|
const [projectedPosition] = useState(() => new Vector3())
|
|
535
687
|
|
|
536
688
|
const ref = useRef<LensFlareEffect>(null)
|
|
689
|
+
const setRef = useMergeRefs(ref, forwardedRef)
|
|
537
690
|
|
|
538
691
|
useFrame((_, delta) => {
|
|
539
692
|
if (!ref?.current) return
|
|
@@ -541,7 +694,7 @@ export const LensFlare = ({
|
|
|
541
694
|
const uOpacity = ref.current.uniforms.get('opacity')
|
|
542
695
|
if (!uLensPosition || !uOpacity) return
|
|
543
696
|
|
|
544
|
-
let target =
|
|
697
|
+
let target = 0
|
|
545
698
|
|
|
546
699
|
projectedPosition.copy(lensPosition).project(camera)
|
|
547
700
|
if (projectedPosition.z > 1) return
|
|
@@ -555,6 +708,7 @@ export const LensFlare = ({
|
|
|
555
708
|
const intersects = raycaster.intersectObjects(scene.children, true)
|
|
556
709
|
const { object } = intersects[0] || {}
|
|
557
710
|
if (object) {
|
|
711
|
+
target = 1
|
|
558
712
|
if (object.userData?.lensflare === 'no-occlusion') {
|
|
559
713
|
target = 0
|
|
560
714
|
} else if (object instanceof Mesh) {
|
|
@@ -586,12 +740,12 @@ export const LensFlare = ({
|
|
|
586
740
|
|
|
587
741
|
return (
|
|
588
742
|
<LensFlareWrapped
|
|
589
|
-
ref={
|
|
743
|
+
ref={setRef}
|
|
590
744
|
blendFunction={blendFunction}
|
|
591
745
|
enabled={enabled}
|
|
592
746
|
glareSize={glareSize}
|
|
593
747
|
lensPosition={lensPosition}
|
|
594
|
-
screenRes={screenRes}
|
|
748
|
+
screenRes={screenRes ?? DEFAULT_SCREEN_RES}
|
|
595
749
|
starPoints={starPoints}
|
|
596
750
|
flareSize={flareSize}
|
|
597
751
|
flareSpeed={flareSpeed}
|
package/src/effects/Noise.tsx
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { BlendFunction, NoiseEffect } from 'postprocessing'
|
|
2
|
-
import {
|
|
2
|
+
import type { Ref } from 'react'
|
|
3
|
+
import { createEffectComponent, type EffectOptions } from '../createEffectComponent'
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
const NoiseImpl = /* @__PURE__ */ createEffectComponent<typeof NoiseEffect, EffectOptions<typeof NoiseEffect>>(
|
|
6
|
+
NoiseEffect
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
export type NoiseProps = EffectOptions<typeof NoiseEffect> & {
|
|
10
|
+
opacity?: number
|
|
11
|
+
ref?: Ref<NoiseEffect>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function Noise({ blendFunction = BlendFunction.COLOR_DODGE, ...props }: NoiseProps) {
|
|
15
|
+
return <NoiseImpl blendFunction={blendFunction} {...props} />
|
|
16
|
+
}
|