glodrei
Version:
useful add-ons for react-three-fiber
2 lines (1 loc) • 5.52 kB
JavaScript
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("react"),r=require("three"),n=require("@react-three/fiber"),a=require("./Texture.cjs.js"),o=require("uuid"),u=require("../helpers/deprecated.cjs.js");function c(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function i(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var l=c(e),s=i(t);const d=new r.Matrix4,f=new r.Vector3,m=new r.Quaternion,p=new r.Vector3,g=new r.Quaternion,h=new r.Vector3,y=s.createContext(null),x=s.forwardRef((({children:e,material:t=r.MeshLambertMaterial,texture:o="https://rawcdn.githack.com/pmndrs/drei-assets/9225a9f1fbd449d9411125c2f419b843d0308c9f/cloud.png",range:c,limit:i=200,frustumCulled:x,...v},b)=>{var M,w;const C=s.useMemo((()=>class extends t{constructor(){super();const e=parseInt(r.REVISION.replace(/\D+/g,""))>=154?"opaque_fragment":"output_fragment";this.onBeforeCompile=t=>{t.vertexShader="attribute float cloudOpacity;\n varying float vOpacity;\n "+t.vertexShader.replace("#include <fog_vertex>","#include <fog_vertex>\n vOpacity = cloudOpacity;\n "),t.fragmentShader="varying float vOpacity;\n "+t.fragmentShader.replace(`#include <${e}>`,`#include <${e}>\n gl_FragColor = vec4(outgoingLight, diffuseColor.a * vOpacity);\n `)}}}),[t]);n.extend({CloudMaterial:C});const E=s.useRef(null),O=s.useRef([]),A=s.useMemo((()=>new Float32Array(Array.from({length:i},(()=>1)))),[i]),j=s.useMemo((()=>new Float32Array(Array.from({length:i},(()=>[1,1,1])).flat())),[i]),R=a.useTexture(o);let U,V=0,_=0;const q=new r.Quaternion,F=new r.Vector3(0,0,1),S=new r.Vector3;n.useFrame(((e,t)=>{for(V=e.clock.getElapsedTime(),d.copy(E.current.matrixWorld).invert(),e.camera.matrixWorld.decompose(p,g,h),_=0;_<O.current.length;_++)U=O.current[_],U.ref.current.matrixWorld.decompose(f,m,h),f.add(S.copy(U.position).applyQuaternion(m).multiply(h)),m.copy(g).multiply(q.setFromAxisAngle(F,U.rotation+=t*U.rotationFactor)),h.multiplyScalar(U.volume+(1+Math.sin(V*U.density*U.speed))/2*U.growth),U.matrix.compose(f,m,h).premultiply(d),U.dist=f.distanceTo(p);for(O.current.sort(((e,t)=>t.dist-e.dist)),_=0;_<O.current.length;_++)U=O.current[_],A[_]=U.opacity*(U.dist<U.fade-1?U.dist/U.fade:1),E.current.setMatrixAt(_,U.matrix),E.current.setColorAt(_,U.color);E.current.geometry.attributes.cloudOpacity.needsUpdate=!0,E.current.instanceMatrix.needsUpdate=!0,E.current.instanceColor&&(E.current.instanceColor.needsUpdate=!0)})),s.useLayoutEffect((()=>{const e=Math.min(i,void 0!==c?c:i,O.current.length);E.current.count=e,u.setUpdateRange(E.current.instanceMatrix,{offset:0,count:16*e}),E.current.instanceColor&&u.setUpdateRange(E.current.instanceColor,{offset:0,count:3*e}),u.setUpdateRange(E.current.geometry.attributes.cloudOpacity,{offset:0,count:e})}));let D=[null!==(M=R.image.width)&&void 0!==M?M:1,null!==(w=R.image.height)&&void 0!==w?w:1];const I=Math.max(D[0],D[1]);return D=[D[0]/I,D[1]/I],s.createElement("group",l.default({ref:b},v),s.createElement(y.Provider,{value:O},e,s.createElement("instancedMesh",{matrixAutoUpdate:!1,ref:E,args:[null,null,i],frustumCulled:x},s.createElement("instancedBufferAttribute",{usage:r.DynamicDrawUsage,attach:"instanceColor",args:[j,3]}),s.createElement("planeGeometry",{args:[...D]},s.createElement("instancedBufferAttribute",{usage:r.DynamicDrawUsage,attach:"attributes-cloudOpacity",args:[A,1]})),s.createElement("cloudMaterial",{key:t.name,map:R,transparent:!0,depthWrite:!1}))))})),v=s.forwardRef((({opacity:e=1,speed:t=0,bounds:a=[5,1,1],segments:u=20,color:c="#ffffff",fade:i=10,volume:d=6,smallestVolume:f=.25,distribute:m=null,growth:p=4,concentrate:g="inside",seed:h=Math.random(),...x},v)=>{function b(){const e=1e4*Math.sin(h++);return e-Math.floor(e)}const M=s.useContext(y),w=s.useRef(null),[C]=s.useState((()=>o.v4())),E=s.useMemo((()=>[...new Array(u)].map(((e,t)=>({segments:u,bounds:new r.Vector3(1,1,1),position:new r.Vector3,uuid:C,index:t,ref:w,dist:0,matrix:new r.Matrix4,color:new r.Color,rotation:t*(Math.PI/u)})))),[u,C]);return s.useLayoutEffect((()=>{E.forEach(((r,o)=>{n.applyProps(r,{volume:d,color:c,speed:t,growth:p,opacity:e,fade:i,bounds:a,density:Math.max(.5,b()),rotationFactor:Math.max(.2,.5*b())*t});const l=null==m?void 0:m(r,o);var s;(l||u>1)&&r.position.copy(r.bounds).multiply(null!==(s=null==l?void 0:l.point)&&void 0!==s?s:{x:2*b()-1,y:2*b()-1,z:2*b()-1});const h=Math.abs(r.position.x),y=Math.abs(r.position.y),x=Math.abs(r.position.z),v=Math.max(h,y,x);r.length=1,h===v&&(r.length-=h/r.bounds.x),y===v&&(r.length-=y/r.bounds.y),x===v&&(r.length-=x/r.bounds.z),r.volume=(void 0!==(null==l?void 0:l.volume)?l.volume:Math.max(Math.max(0,f),"random"===g?b():"inside"===g?r.length:1-r.length))*d}))}),[g,a,i,c,e,p,d,h,u,t]),s.useLayoutEffect((()=>{const e=E;return M.current=[...M.current,...e],()=>{M.current=M.current.filter((e=>e.uuid!==C))}}),[E]),s.useImperativeHandle(v,(()=>w.current),[]),s.createElement("group",l.default({ref:w},x))})),b=s.forwardRef(((e,t)=>s.useContext(y)?s.createElement(v,l.default({ref:t},e)):s.createElement(x,null,s.createElement(v,l.default({ref:t},e)))));exports.Cloud=b,exports.CloudInstance=v,exports.Clouds=x;