UNPKG

dissolveit

Version:

A customizable dissolve effect component for React Three Fiber applications

87 lines (82 loc) 2.51 kB
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 };