dissolveit
Version:
A customizable dissolve effect component for React Three Fiber applications
31 lines (26 loc) • 2.44 kB
JavaScript
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),P=require("@react-three/fiber"),m=require("maath"),_=require("react"),w=require("three"),d=require("three-custom-shader-material"),j=require("gl-noise");function S(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const o in e)if(o!=="default"){const a=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,a.get?a:{enumerable:!0,get:()=>e[o]})}}return t.default=e,Object.freeze(t)}const c=S(_),h=S(w),C=`
varying vec2 vUv;
varying vec3 vPosition; // Use world position instead of UV
void main() {
vUv = uv;
vPosition = position;
}
`,T=j.patchShaders(`
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);
}
`),y=({geometry:e,baseMaterial:t=new h.MeshStandardMaterial({color:"#808080"}),fadeIn:o,fadeOut:a,color:n,thickness:i=.1,intensity:u=50,duration:f=1.2,onFadeOut:v,children:b})=>{const s=c.useRef(null),r=c.useRef({uThickness:{value:i},uColor:{value:new h.Color(n).multiplyScalar(u)},uProgress:{value:0}});c.useEffect(()=>{r.current.uThickness.value=i,r.current.uColor.value.set(n).multiplyScalar(u)},[i,n,u]),P.useFrame((M,p)=>{o?m.easing.damp(r.current.uProgress,"value",1,f,p):a&&m.easing.damp(r.current.uProgress,"value",0,f,p),(r.current.uProgress.value===0&&s.current||r.current.uProgress.value>0&&s.current)&&(s.current.castShadow=!1,s.current.receiveShadow=!1),a&&r.current.uProgress.value<.1&&v&&v()});const g={baseMaterial:t,vertexShader:C,fragmentShader:T,uniforms:r.current,toneMapped:!1,transparent:!0};return e?l.jsx("mesh",{ref:s,geometry:e,castShadow:!1,receiveShadow:!1,children:l.jsx(d,{...g})}):l.jsx(d,{...g,children:b})};exports.DissolveEffect=y;