dissolveit
Version:
A customizable dissolve effect component for React Three Fiber applications
87 lines (82 loc) • 2.51 kB
JavaScript
import { jsx as t } from "react/jsx-runtime";
import { useFrame as S } from "@react-three/fiber";
import { easing as m } from "maath";
import * as i from "react";
import * as p from "three";
import g from "three-custom-shader-material";
import { patchShaders as w } from "gl-noise";
const C = (
/* glsl */
`
varying vec2 vUv;
varying vec3 vPosition; // Use world position instead of UV
void main() {
vUv = uv;
vPosition = position;
}
`
), _ = w(
/* glsl */
`
varying vec2 vUv;
varying vec3 vPosition;
uniform float uThickness;
uniform vec3 uColor;
uniform float uProgress;
void main() {
gln_tFBMOpts opts = gln_tFBMOpts(1.0, 0.3, 2.0, 5.0, 1.0, 5, false, false);
// Using world position for better dissolve effect
float noise = gln_sfbm(vPosition, opts);
noise = gln_normalize(noise);
float progress = uProgress;
// The dissolve effect logic: alpha decreases as progress goes from 0 to 1
float alpha = step(1.0 - progress, noise);
float border = step((1.0 - progress) - uThickness, noise) - alpha;
csm_DiffuseColor.a = alpha + border;
csm_DiffuseColor.rgb = mix(csm_DiffuseColor.rgb, uColor, border);
}
`
), D = ({
geometry: l,
baseMaterial: d = new p.MeshStandardMaterial({ color: "#808080" }),
fadeIn: h,
fadeOut: n,
color: s,
thickness: o = 0.1,
intensity: a = 50,
duration: u = 1.2,
onFadeOut: f,
children: P
}) => {
const r = i.useRef(null), e = i.useRef({
uThickness: { value: o },
uColor: { value: new p.Color(s).multiplyScalar(a) },
uProgress: { value: 0 }
});
i.useEffect(() => {
e.current.uThickness.value = o, e.current.uColor.value.set(s).multiplyScalar(a);
}, [o, s, a]), S((b, v) => {
h ? m.damp(e.current.uProgress, "value", 1, u, v) : n && m.damp(e.current.uProgress, "value", 0, u, v), (e.current.uProgress.value === 0 && r.current || e.current.uProgress.value > 0 && r.current) && (r.current.castShadow = !1, r.current.receiveShadow = !1), n && e.current.uProgress.value < 0.1 && f && f();
});
const c = {
baseMaterial: d,
vertexShader: C,
fragmentShader: _,
uniforms: e.current,
toneMapped: !1,
transparent: !0
};
return l ? /* @__PURE__ */ t(
"mesh",
{
ref: r,
geometry: l,
castShadow: !1,
receiveShadow: !1,
children: /* @__PURE__ */ t(g, { ...c })
}
) : /* @__PURE__ */ t(g, { ...c, children: P });
};
export {
D as DissolveEffect
};