e.boundingSphereRadius)return;let o=this[e.type];o&&o.call(this,e,t,i,a,e)}_intersectBox(e,t,i,a,r){return this._intersectConvex(e.convexPolyhedronRepresentation,t,i,a,r)}_intersectPlane(e,t,i,a,r){let s=this.from,o=this.to,c=this.direction,l=new y(0,0,1);t.vmult(l,l);let u=new y;s.vsub(i,u);let f=u.dot(l);o.vsub(i,u);let h=u.dot(l);if(f*h>0||s.distanceTo(o)=0&&g<=1&&(s.lerp(o,g,m),m.vsub(i,v),v.normalize(),this.reportIntersection(v,m,r,a,-1)),this.result.shouldStop)return;x>=0&&x<=1&&(s.lerp(o,x,m),m.vsub(i,v),v.normalize(),this.reportIntersection(v,m,r,a,-1))}}_intersectConvex(e,t,i,a,r,s){let o=E7,c=Ga,l=s&&s.faceList||null,u=e.faces,f=e.vertices,h=e.faceNormals,m=this.direction,v=this.from,g=this.to,x=v.distanceTo(g),p=l?l.length:u.length,d=this.result;for(let w=0;!d.shouldStop&&wx||this.reportIntersection(o,D2,r,a,b)}}}}_intersectTrimesh(e,t,i,a,r,s){let o=L7,c=R7,l=F7,u=Ga,f=D7,h=T7,m=H7,v=N7,g=V7,x=e.indices;e.vertices;let p=this.from,d=this.to,w=this.direction;l.position.copy(i),l.quaternion.copy(t),R1.vectorToLocalFrame(i,t,w,f),R1.pointToLocalFrame(i,t,p,h),R1.pointToLocalFrame(i,t,d,m),m.x*=e.scale.x,m.y*=e.scale.y,m.z*=e.scale.z,h.x*=e.scale.x,h.y*=e.scale.y,h.z*=e.scale.z,m.vsub(h,f),f.normalize();let b=h.distanceSquared(m);e.tree.rayQuery(this,l,c);for(let z=0,L=c.length;!this.result.shouldStop&&z!==L;z++){let H=c[z];e.getNormal(H,o),e.getVertex(x[H*3],K2),K2.vsub(h,u);let E=f.dot(o),I=o.dot(u)/E;if(I<0)continue;f.scale(I,D2),D2.vadd(h,D2),e.getVertex(x[H*3+1],ge),e.getVertex(x[H*3+2],xe);let B=D2.distanceSquared(h);!(e2.pointInTriangle(D2,ge,K2,xe)||e2.pointInTriangle(D2,K2,ge,xe))||B>b||(R1.vectorToWorldFrame(t,o,g),R1.pointToWorldFrame(i,t,D2,v),this.reportIntersection(g,v,r,a,H))}c.length=0}reportIntersection(e,t,i,a,r){let s=this.from,o=this.to,c=s.distanceTo(t),l=this.result;if(!(this.skipBackfaces&&e.dot(this.direction)>0))switch(l.hitFaceIndex=typeof r!="undefined"?r:-1,this.mode){case e2.ALL:this.hasHit=!0,l.set(s,o,e,t,i,a,c),l.hasHit=!0,this.callback(l);break;case e2.CLOSEST:(c=0&&(f=r*l-s*o)>=0&&u+fH.maxForce&&(m=H.maxForce-x),w[L]+=m,v+=m>0?m:-m,H.addToWlambda(m)}if(v*ve;)t.pop();for(;t.length=0&&u.restitution>=0&&(o.restitution=l.restitution*u.restitution),o.si=r||i,o.sj=s||a,o}createFrictionEquationsFromContact(e,t){let i=e.bi,a=e.bj,r=e.si,s=e.sj,o=this.world,c=this.currentContactMaterial,l=c.friction,u=r.material||i.material,f=s.material||a.material;if(u&&f&&u.friction>=0&&f.friction>=0&&(l=u.friction*f.friction),l>0){let h=l*o.gravity.length(),m=i.invMass+a.invMass;m>0&&(m=1/m);let v=this.frictionEquationPool,g=v.length?v.pop():new J0(i,a,h*m),x=v.length?v.pop():new J0(i,a,h*m);return g.bi=x.bi=i,g.bj=x.bj=a,g.minForce=x.minForce=-h*m,g.maxForce=x.maxForce=h*m,g.ri.copy(e.ri),g.rj.copy(e.rj),x.ri.copy(e.ri),x.rj.copy(e.rj),e.ni.tangents(g.t,x.t),g.setSpookParams(c.frictionEquationStiffness,c.frictionEquationRelaxation,o.dt),x.setSpookParams(c.frictionEquationStiffness,c.frictionEquationRelaxation,o.dt),g.enabled=x.enabled=e.enabled,t.push(g,x),!0}return!1}createFrictionFromAverage(e){let t=this.result[this.result.length-1];if(!this.createFrictionEquationsFromContact(t,this.frictionResult)||e===1)return;let i=this.frictionResult[this.frictionResult.length-2],a=this.frictionResult[this.frictionResult.length-1];zt.setZero(),Gt.setZero(),qt.setZero();let r=t.bi;t.bj;for(let o=0;o!==e;o++)t=this.result[this.result.length-1-o],t.bi!==r?(zt.vadd(t.ni,zt),Gt.vadd(t.ri,Gt),qt.vadd(t.rj,qt)):(zt.vsub(t.ni,zt),Gt.vadd(t.rj,Gt),qt.vadd(t.ri,qt));let s=1/e;Gt.scale(s,i.ri),qt.scale(s,i.rj),a.ri.copy(i.ri),a.rj.copy(i.rj),zt.normalize(),zt.tangents(i.t,a.t)}getContacts(e,t,i,a,r,s,o){this.contactPointPool=r,this.frictionEquationPool=o,this.result=a,this.frictionResult=s;let c=el,l=tl,u=J7,f=Q7;for(let h=0,m=e.length;h!==m;h++){let v=e[h],g=t[h],x=null;v.material&&g.material&&(x=i.getContactMaterial(v.material,g.material)||null);let p=v.type&a1.KINEMATIC&&g.type&a1.STATIC||v.type&a1.STATIC&&g.type&a1.KINEMATIC||v.type&a1.KINEMATIC&&g.type&a1.KINEMATIC;for(let d=0;dw.boundingSphereRadius+z.boundingSphereRadius)continue;let L=null;w.material&&z.material&&(L=i.getContactMaterial(w.material,z.material)||null),this.currentContactMaterial=L||x||i.defaultContactMaterial;let H=w.type|z.type,E=this[H];if(E){let I=!1;w.type0){let j=wl,Z=Sl;j.copy(m[(D+1)%3]),Z.copy(m[(D+2)%3]);let e1=j.length(),r1=Z.length();j.normalize(),Z.normalize();let P=z6.dot(j),b1=z6.dot(Z);if(P-e1&&b1-r1){let h1=Math.abs(G-Y-v);if((H===null||h1e.boundingSphereRadius+t.boundingSphereRadius)&&e.findSeparatingAxis(t,i,r,a,s,v,h,m)){let g=[],x=Xl;e.clipAgainstHull(i,r,t,a,s,v,-100,100,g);let p=0;for(let d=0;d!==g.length;d++){if(f)return!0;let w=this.createContactEquation(o,c,e,t,l,u),b=w.ri,z=w.rj;v.negate(w.ni),g[d].normal.negate(x),x.scale(g[d].depth,x),g[d].point.vadd(x,b),z.copy(g[d].point),b.vsub(i,b),z.vsub(a,z),b.vadd(i,b),b.vsub(o.position,b),z.vadd(a,z),z.vsub(c.position,z),this.result.push(w),p++,this.enableFrictionReduction||this.createFrictionEquationsFromContact(w,this.frictionResult)}this.enableFrictionReduction&&p&&this.createFrictionFromAverage(p)}}sphereConvex(e,t,i,a,r,s,o,c,l,u,f){let h=this.v3pool;i.vsub(a,Hl);let m=t.faceNormals,v=t.faces,g=t.vertices,x=e.radius,p=!1;for(let d=0;d!==g.length;d++){let w=g[d],b=Fl;s.vmult(w,b),a.vadd(b,b);let z=Rl;if(b.vsub(i,z),z.lengthSquared()0){let T=[];for(let A=0,V=z.length;A!==V;A++){let N=h.get();s.vmult(g[z[A]],N),a.vadd(N,N),T.push(N)}if(zl(T,L,i)){if(f)return!0;p=!0;let A=this.createContactEquation(o,c,e,t,l,u);L.scale(-x,A.ri),L.negate(A.ni);let V=h.get();L.scale(-B,V);let N=h.get();L.scale(-x,N),i.vsub(a,A.rj),A.rj.vadd(N,A.rj),A.rj.vadd(V,A.rj),A.rj.vadd(a,A.rj),A.rj.vsub(c.position,A.rj),A.ri.vadd(i,A.ri),A.ri.vsub(o.position,A.ri),h.release(V),h.release(N),this.result.push(A),this.createFrictionEquationsFromContact(A,this.frictionResult);for(let D=0,R=T.length;D!==R;D++)h.release(T[D]);return}else for(let A=0;A!==z.length;A++){let V=h.get(),N=h.get();s.vmult(g[z[(A+1)%z.length]],V),s.vmult(g[z[(A+2)%z.length]],N),a.vadd(V,V),a.vadd(N,N);let D=Vl;N.vsub(V,D);let R=Nl;D.unit(R);let O=h.get(),Y=h.get();i.vsub(V,Y);let G=Y.dot(R);R.scale(G,O),O.vadd(V,O);let j=h.get();if(O.vsub(i,j),G>0&&G*Gh.length||w>h[0].length)return;p<0&&(p=0),d<0&&(d=0),w<0&&(w=0),b<0&&(b=0),p>=h.length&&(p=h.length-1),d>=h.length&&(d=h.length-1),b>=h[0].length&&(b=h[0].length-1),w>=h[0].length&&(w=h[0].length-1);let z=[];t.getRectMinMax(p,w,d,b,z);let L=z[0],H=z[1];if(x.z-m>H||x.z+m2)return}}boxHeightfield(e,t,i,a,r,s,o,c,l,u,f){return e.convexPolyhedronRepresentation.material=e.material,e.convexPolyhedronRepresentation.collisionResponse=e.collisionResponse,this.convexHeightfield(e.convexPolyhedronRepresentation,t,i,a,r,s,o,c,e,t,f)}convexHeightfield(e,t,i,a,r,s,o,c,l,u,f){let h=t.data,m=t.elementSize,v=e.boundingSphereRadius,g=i9,x=a9,p=t9;R1.pointToLocalFrame(a,s,i,p);let d=Math.floor((p.x-v)/m)-1,w=Math.ceil((p.x+v)/m)+1,b=Math.floor((p.y-v)/m)-1,z=Math.ceil((p.y+v)/m)+1;if(w<0||z<0||d>h.length||b>h[0].length)return;d<0&&(d=0),w<0&&(w=0),b<0&&(b=0),z<0&&(z=0),d>=h.length&&(d=h.length-1),w>=h.length&&(w=h.length-1),z>=h[0].length&&(z=h[0].length-1),b>=h[0].length&&(b=h[0].length-1);let L=[];t.getRectMinMax(d,b,w,z,L);let H=L[0],E=L[1];if(!(p.z-v>E||p.z+v0&&N<0&&(x.vsub(h,p),g.copy(v),g.normalize(),D=p.dot(g),g.scale(D,p),p.vadd(h,p),p.distanceTo(x)0&&i===!0||u<=0&&i===!1){i===null&&(i=u>0);continue}else return!1}return!0}var z6=new y,Al=new y,wl=new y,Sl=new y,_l=[new y,new y,new y,new y,new y,new y],El=new y,Ll=new y,Dl=new y,Tl=new y,Hl=new y,Vl=new y,Nl=new y,Rl=new y,Fl=new y,Bl=new y,Pl=new y,Il=new y,kl=new y,Ul=new y,Ol=new y,Gl=new y,ql=new y,Wl=new y,jl=new y,Xl=new y,Zl=new y,Yl=new y,$l=new y,Kl=new y,Sr=new G1,Jl=new y,Ql=new y,_r=new y,e9=new y,t9=new y,i9=new y,a9=[0],r9=new y,n9=new y,Q0=class{constructor(){this.current=void 0,this.previous=void 0,this.current=[],this.previous=[]}getKey(e,t){if(ta[r];)r++;if(i!==a[r]){for(let s=a.length-1;s>=r;s--)a[s+1]=a[s];a[r]=i}}tick(){let e=this.current;this.current=this.previous,this.previous=e,this.current.length=0}getDiff(e,t){let i=this.current,a=this.previous,r=i.length,s=a.length,o=0;for(let c=0;ca[o];)o++;l=u===a[o],l||Er(e,u)}o=0;for(let c=0;ci[o];)o++;l=i[o]===u,l||Er(t,u)}}};function Er(n,e){n.push((e&4294901760)>>16,e&65535)}var Lr=class{constructor(){this.data={keys:[]}}get(e,t){if(e>t){let i=t;t=e,e=i}return this.data[e+"-"+t]}set(e,t,i){if(e>t){let r=t;t=e,e=r}let a=e+"-"+t;this.get(e,t)||this.data.keys.push(a),this.data[a]=i}reset(){let e=this.data,t=e.keys;for(;t.length>0;){let i=t.pop();delete e[i]}}},e3=class extends O0{constructor(e={}){super();this.dt=void 0,this.allowSleep=void 0,this.contacts=void 0,this.frictionEquations=void 0,this.quatNormalizeSkip=void 0,this.quatNormalizeFast=void 0,this.time=void 0,this.stepnumber=void 0,this.default_dt=void 0,this.nextId=void 0,this.gravity=void 0,this.broadphase=void 0,this.bodies=void 0,this.hasActiveBodies=void 0,this.solver=void 0,this.constraints=void 0,this.narrowphase=void 0,this.collisionMatrix=void 0,this.collisionMatrixPrevious=void 0,this.bodyOverlapKeeper=void 0,this.shapeOverlapKeeper=void 0,this.materials=void 0,this.contactmaterials=void 0,this.contactMaterialTable=void 0,this.defaultMaterial=void 0,this.defaultContactMaterial=void 0,this.doProfiling=void 0,this.profile=void 0,this.accumulator=void 0,this.subsystems=void 0,this.addBodyEvent=void 0,this.removeBodyEvent=void 0,this.idToBodyMap=void 0,this.dt=-1,this.allowSleep=!!e.allowSleep,this.contacts=[],this.frictionEquations=[],this.quatNormalizeSkip=e.quatNormalizeSkip!==void 0?e.quatNormalizeSkip:0,this.quatNormalizeFast=e.quatNormalizeFast!==void 0?e.quatNormalizeFast:!1,this.time=0,this.stepnumber=0,this.default_dt=1/60,this.nextId=0,this.gravity=new y,e.gravity&&this.gravity.copy(e.gravity),this.broadphase=e.broadphase!==void 0?e.broadphase:new v6,this.bodies=[],this.hasActiveBodies=!1,this.solver=e.solver!==void 0?e.solver:new $a,this.constraints=[],this.narrowphase=new Ar(this),this.collisionMatrix=new U0,this.collisionMatrixPrevious=new U0,this.bodyOverlapKeeper=new Q0,this.shapeOverlapKeeper=new Q0,this.materials=[],this.contactmaterials=[],this.contactMaterialTable=new Lr,this.defaultMaterial=new Ve("default"),this.defaultContactMaterial=new He(this.defaultMaterial,this.defaultMaterial,{friction:.3,restitution:0}),this.doProfiling=!1,this.profile={solve:0,makeContactConstraints:0,broadphase:0,integrate:0,narrowphase:0},this.accumulator=0,this.subsystems=[],this.addBodyEvent={type:"addBody",body:null},this.removeBodyEvent={type:"removeBody",body:null},this.idToBodyMap={},this.broadphase.setWorld(this)}getContactMaterial(e,t){return this.contactMaterialTable.get(e.id,t.id)}numObjects(){return this.bodies.length}collisionMatrixTick(){let e=this.collisionMatrixPrevious;this.collisionMatrixPrevious=this.collisionMatrix,this.collisionMatrix=e,this.collisionMatrix.reset(),this.bodyOverlapKeeper.tick(),this.shapeOverlapKeeper.tick()}addConstraint(e){this.constraints.push(e)}removeConstraint(e){let t=this.constraints.indexOf(e);t!==-1&&this.constraints.splice(t,1)}rayTest(e,t,i){i instanceof g6?this.raycastClosest(e,t,{skipBackfaces:!0},i):this.raycastAll(e,t,{skipBackfaces:!0},i)}raycastAll(e,t,i={},a){return i.mode=e2.ALL,i.from=e,i.to=t,i.callback=a,t3.intersectWorld(this,i)}raycastAny(e,t,i={},a){return i.mode=e2.ANY,i.from=e,i.to=t,i.result=a,t3.intersectWorld(this,i)}raycastClosest(e,t,i={},a){return i.mode=e2.CLOSEST,i.from=e,i.to=t,i.result=a,t3.intersectWorld(this,i)}addBody(e){this.bodies.includes(e)||(e.index=this.bodies.length,this.bodies.push(e),e.world=this,e.initPosition.copy(e.position),e.initVelocity.copy(e.velocity),e.timeLastSleepy=this.time,e instanceof a1&&(e.initAngularVelocity.copy(e.angularVelocity),e.initQuaternion.copy(e.quaternion)),this.collisionMatrix.setNumObjects(this.bodies.length),this.addBodyEvent.body=e,this.idToBodyMap[e.id]=e,this.dispatchEvent(this.addBodyEvent))}removeBody(e){e.world=null;let t=this.bodies.length-1,i=this.bodies,a=i.indexOf(e);if(a!==-1){i.splice(a,1);for(let r=0;r!==i.length;r++)i[r].index=r;this.collisionMatrix.setNumObjects(t),this.removeBodyEvent.body=e,delete this.idToBodyMap[e.id],this.dispatchEvent(this.removeBodyEvent)}}getBodyById(e){return this.idToBodyMap[e]}getShapeById(e){let t=this.bodies;for(let i=0;i=e&&re*1e3)););this.accumulator=this.accumulator%e;let s=this.accumulator/e;for(let o=0;o!==this.bodies.length;o++){let c=this.bodies[o];c.previousPosition.lerp(c.position,s,c.interpolatedPosition),c.previousQuaternion.slerp(c.quaternion,s,c.interpolatedQuaternion),c.previousQuaternion.normalize()}this.time+=t}}internalStep(e){this.dt=e;let t=this.contacts,i=u9,a=h9,r=this.numObjects(),s=this.bodies,o=this.solver,c=this.gravity,l=this.doProfiling,u=this.profile,f=a1.DYNAMIC,h=-1/0,m=this.constraints,v=l9;c.length();let g=c.x,x=c.y,p=c.z,d=0;for(l&&(h=o2.now()),d=0;d!==r;d++){let A=s[d];if(A.type===f){let V=A.force,N=A.mass;V.x+=N*g,V.y+=N*x,V.z+=N*p}}for(let A=0,V=this.subsystems.length;A!==V;A++)this.subsystems[A].update();l&&(h=o2.now()),i.length=0,a.length=0,this.broadphase.collisionPairs(this,i,a),l&&(u.broadphase=o2.now()-h);let w=m.length;for(d=0;d!==w;d++){let A=m[d];if(!A.collideConnected)for(let V=i.length-1;V>=0;V-=1)(A.bodyA===i[V]&&A.bodyB===a[V]||A.bodyB===i[V]&&A.bodyA===a[V])&&(i.splice(V,1),a.splice(V,1))}this.collisionMatrixTick(),l&&(h=o2.now());let b=c9,z=t.length;for(d=0;d!==z;d++)b.push(t[d]);t.length=0;let L=this.frictionEquations.length;for(d=0;d!==L;d++)v.push(this.frictionEquations[d]);for(this.frictionEquations.length=0,this.narrowphase.getContacts(i,a,this,t,b,this.frictionEquations,v),l&&(u.narrowphase=o2.now()-h),l&&(h=o2.now()),d=0;d=0&&D.material.friction>=0&&N.material.friction*D.material.friction,N.material.restitution>=0&&D.material.restitution>=0&&(V.restitution=N.material.restitution*D.material.restitution)),o.addEquation(V),N.allowSleep&&N.type===a1.DYNAMIC&&N.sleepState===a1.SLEEPING&&D.sleepState===a1.AWAKE&&D.type!==a1.STATIC){let G=D.velocity.lengthSquared()+D.angularVelocity.lengthSquared(),j=D.sleepSpeedLimit**2;G>=j*2&&(N.wakeUpAfterNarrowphase=!0)}if(D.allowSleep&&D.type===a1.DYNAMIC&&D.sleepState===a1.SLEEPING&&N.sleepState===a1.AWAKE&&N.type!==a1.STATIC){let G=N.velocity.lengthSquared()+N.angularVelocity.lengthSquared(),j=N.sleepSpeedLimit**2;G>=j*2&&(D.wakeUpAfterNarrowphase=!0)}this.collisionMatrix.set(N,D,!0),this.collisionMatrixPrevious.get(N,D)||(_4.body=D,_4.contact=V,N.dispatchEvent(_4),_4.body=N,D.dispatchEvent(_4)),this.bodyOverlapKeeper.set(N.id,D.id),this.shapeOverlapKeeper.set(R.id,O.id)}for(this.emitContactEvents(),l&&(u.makeContactConstraints=o2.now()-h,h=o2.now()),d=0;d!==r;d++){let A=s[d];A.wakeUpAfterNarrowphase&&(A.wakeUp(),A.wakeUpAfterNarrowphase=!1)}for(w=m.length,d=0;d!==w;d++){let A=m[d];A.update();for(let V=0,N=A.equations.length;V!==N;V++){let D=A.equations[V];o.addEquation(D)}}o.solve(e,this),l&&(u.solve=o2.now()-h),o.removeAllEquations();let E=Math.pow;for(d=0;d!==r;d++){let A=s[d];if(A.type&f){let V=E(1-A.linearDamping,e),N=A.velocity;N.scale(V,N);let D=A.angularVelocity;if(D){let R=E(1-A.angularDamping,e);D.scale(R,D)}}}for(this.dispatchEvent(o9),d=0;d!==r;d++){let A=s[d];A.preStep&&A.preStep.call(A)}l&&(h=o2.now());let B=this.stepnumber%(this.quatNormalizeSkip+1)==0,M=this.quatNormalizeFast;for(d=0;d!==r;d++)s[d].integrate(e,B,M);for(this.clearForces(),this.broadphase.dirty=!0,l&&(u.integrate=o2.now()-h),this.stepnumber+=1,this.dispatchEvent(s9),d=0;d!==r;d++){let A=s[d],V=A.postStep;V&&V.call(A)}let T=!0;if(this.allowSleep)for(T=!1,d=0;d!==r;d++){let A=s[d];A.sleepTick(this.time),A.sleepState!==a1.SLEEPING&&(T=!0)}this.hasActiveBodies=T}emitContactEvents(){let e=this.hasAnyEventListener("beginContact"),t=this.hasAnyEventListener("endContact");if((e||t)&&this.bodyOverlapKeeper.getDiff(Re,Fe),e){for(let r=0,s=Re.length;rDate.now()-n}var s9={type:"postStep"},o9={type:"preStep"},_4={type:a1.COLLIDE_EVENT_NAME,body:null,contact:null},c9=[],l9=[],u9=[],h9=[],Re=[],Fe=[],E4={type:"beginContact",bodyA:null,bodyB:null},L4={type:"endContact",bodyA:null,bodyB:null},Be={type:"beginShapeContact",bodyA:null,bodyB:null,shapeA:null,shapeB:null},Pe={type:"endShapeContact",bodyA:null,bodyB:null,shapeA:null,shapeB:null};var W1=class{constructor(e=0,t=0,i=0,a=1){this.x=e,this.y=t,this.z=i,this.w=a}get width(){return this.z}set width(e){this.z=e}get height(){return this.w}set height(e){this.w=e}set(e,t,i,a){return this.x=e,this.y=t,this.z=i,this.w=a,this}setScalar(e){return this.x=e,this.y=e,this.z=e,this.w=e,this}setX(e){return this.x=e,this}setY(e){return this.y=e,this}setZ(e){return this.z=e,this}setW(e){return this.w=e,this}setComponent(e,t){switch(e){case 0:this.x=t;break;case 1:this.y=t;break;case 2:this.z=t;break;case 3:this.w=t;break;default:throw new Error("index is out of range: "+e)}return this}getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw new Error("index is out of range: "+e)}}clone(){return new this.constructor(this.x,this.y,this.z,this.w)}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this.w=e.w!==void 0?e.w:1,this}add(e,t){return t!==void 0?(console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(e,t)):(this.x+=e.x,this.y+=e.y,this.z+=e.z,this.w+=e.w,this)}addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this.w+=e,this}addVectors(e,t){return this.x=e.x+t.x,this.y=e.y+t.y,this.z=e.z+t.z,this.w=e.w+t.w,this}addScaledVector(e,t){return this.x+=e.x*t,this.y+=e.y*t,this.z+=e.z*t,this.w+=e.w*t,this}sub(e,t){return t!==void 0?(console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(e,t)):(this.x-=e.x,this.y-=e.y,this.z-=e.z,this.w-=e.w,this)}subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this.w-=e,this}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this.z=e.z-t.z,this.w=e.w-t.w,this}multiply(e){return this.x*=e.x,this.y*=e.y,this.z*=e.z,this.w*=e.w,this}multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this.w*=e,this}applyMatrix4(e){let t=this.x,i=this.y,a=this.z,r=this.w,s=e.elements;return this.x=s[0]*t+s[4]*i+s[8]*a+s[12]*r,this.y=s[1]*t+s[5]*i+s[9]*a+s[13]*r,this.z=s[2]*t+s[6]*i+s[10]*a+s[14]*r,this.w=s[3]*t+s[7]*i+s[11]*a+s[15]*r,this}divideScalar(e){return this.multiplyScalar(1/e)}setAxisAngleFromQuaternion(e){this.w=2*Math.acos(e.w);let t=Math.sqrt(1-e.w*e.w);return t<1e-4?(this.x=1,this.y=0,this.z=0):(this.x=e.x/t,this.y=e.y/t,this.z=e.z/t),this}setAxisAngleFromRotationMatrix(e){let t,i,a,r,s=.01,o=.1,c=e.elements,l=c[0],u=c[4],f=c[8],h=c[1],m=c[5],v=c[9],g=c[2],x=c[6],p=c[10];if(Math.abs(u-h)b&&w>z?wz?b>8&255]+f2[n>>16&255]+f2[n>>24&255]+"-"+f2[e&255]+f2[e>>8&255]+"-"+f2[e>>16&15|64]+f2[e>>24&255]+"-"+f2[t&63|128]+f2[t>>8&255]+"-"+f2[t>>16&255]+f2[t>>24&255]+f2[i&255]+f2[i>>8&255]+f2[i>>16&255]+f2[i>>24&255]).toUpperCase()}function T2(n,e,t){return Math.max(e,Math.min(t,n))}function Dr(n,e){return(n%e+e)%e}function w6(n,e,t){return(1-t)*n+t*e}function i3(n){return(n&n-1)==0&&n!==0}function Tr(n){return Math.pow(2,Math.floor(Math.log(n)/Math.LN2))}var be=class{constructor(e=0,t=0,i=0,a=1){this._x=e,this._y=t,this._z=i,this._w=a}static slerp(e,t,i,a){return console.warn("THREE.Quaternion: Static .slerp() has been deprecated. Use qm.slerpQuaternions( qa, qb, t ) instead."),i.slerpQuaternions(e,t,a)}static slerpFlat(e,t,i,a,r,s,o){let c=i[a+0],l=i[a+1],u=i[a+2],f=i[a+3],h=r[s+0],m=r[s+1],v=r[s+2],g=r[s+3];if(o===0){e[t+0]=c,e[t+1]=l,e[t+2]=u,e[t+3]=f;return}if(o===1){e[t+0]=h,e[t+1]=m,e[t+2]=v,e[t+3]=g;return}if(f!==g||c!==h||l!==m||u!==v){let x=1-o,p=c*h+l*m+u*v+f*g,d=p>=0?1:-1,w=1-p*p;if(w>Number.EPSILON){let z=Math.sqrt(w),L=Math.atan2(z,p*d);x=Math.sin(x*L)/z,o=Math.sin(o*L)/z}let b=o*d;if(c=c*x+h*b,l=l*x+m*b,u=u*x+v*b,f=f*x+g*b,x===1-o){let z=1/Math.sqrt(c*c+l*l+u*u+f*f);c*=z,l*=z,u*=z,f*=z}}e[t]=c,e[t+1]=l,e[t+2]=u,e[t+3]=f}static multiplyQuaternionsFlat(e,t,i,a,r,s){let o=i[a],c=i[a+1],l=i[a+2],u=i[a+3],f=r[s],h=r[s+1],m=r[s+2],v=r[s+3];return e[t]=o*v+u*f+c*m-l*h,e[t+1]=c*v+u*h+l*f-o*m,e[t+2]=l*v+u*m+o*h-c*f,e[t+3]=u*v-o*f-c*h-l*m,e}get x(){return this._x}set x(e){this._x=e,this._onChangeCallback()}get y(){return this._y}set y(e){this._y=e,this._onChangeCallback()}get z(){return this._z}set z(e){this._z=e,this._onChangeCallback()}get w(){return this._w}set w(e){this._w=e,this._onChangeCallback()}set(e,t,i,a){return this._x=e,this._y=t,this._z=i,this._w=a,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._w)}copy(e){return this._x=e.x,this._y=e.y,this._z=e.z,this._w=e.w,this._onChangeCallback(),this}setFromEuler(e,t){if(!(e&&e.isEuler))throw new Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");let i=e._x,a=e._y,r=e._z,s=e._order,o=Math.cos,c=Math.sin,l=o(i/2),u=o(a/2),f=o(r/2),h=c(i/2),m=c(a/2),v=c(r/2);switch(s){case"XYZ":this._x=h*u*f+l*m*v,this._y=l*m*f-h*u*v,this._z=l*u*v+h*m*f,this._w=l*u*f-h*m*v;break;case"YXZ":this._x=h*u*f+l*m*v,this._y=l*m*f-h*u*v,this._z=l*u*v-h*m*f,this._w=l*u*f+h*m*v;break;case"ZXY":this._x=h*u*f-l*m*v,this._y=l*m*f+h*u*v,this._z=l*u*v+h*m*f,this._w=l*u*f-h*m*v;break;case"ZYX":this._x=h*u*f-l*m*v,this._y=l*m*f+h*u*v,this._z=l*u*v-h*m*f,this._w=l*u*f+h*m*v;break;case"YZX":this._x=h*u*f+l*m*v,this._y=l*m*f+h*u*v,this._z=l*u*v-h*m*f,this._w=l*u*f-h*m*v;break;case"XZY":this._x=h*u*f-l*m*v,this._y=l*m*f-h*u*v,this._z=l*u*v+h*m*f,this._w=l*u*f+h*m*v;break;default:console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: "+s)}return t!==!1&&this._onChangeCallback(),this}setFromAxisAngle(e,t){let i=t/2,a=Math.sin(i);return this._x=e.x*a,this._y=e.y*a,this._z=e.z*a,this._w=Math.cos(i),this._onChangeCallback(),this}setFromRotationMatrix(e){let t=e.elements,i=t[0],a=t[4],r=t[8],s=t[1],o=t[5],c=t[9],l=t[2],u=t[6],f=t[10],h=i+o+f;if(h>0){let m=.5/Math.sqrt(h+1);this._w=.25/m,this._x=(u-c)*m,this._y=(r-l)*m,this._z=(s-a)*m}else if(i>o&&i>f){let m=2*Math.sqrt(1+i-o-f);this._w=(u-c)/m,this._x=.25*m,this._y=(a+s)/m,this._z=(r+l)/m}else if(o>f){let m=2*Math.sqrt(1+o-i-f);this._w=(r-l)/m,this._x=(a+s)/m,this._y=.25*m,this._z=(c+u)/m}else{let m=2*Math.sqrt(1+f-i-o);this._w=(s-a)/m,this._x=(r+l)/m,this._y=(c+u)/m,this._z=.25*m}return this._onChangeCallback(),this}setFromUnitVectors(e,t){let i=e.dot(t)+1;return iMath.abs(e.z)?(this._x=-e.y,this._y=e.x,this._z=0,this._w=i):(this._x=0,this._y=-e.z,this._z=e.y,this._w=i)):(this._x=e.y*t.z-e.z*t.y,this._y=e.z*t.x-e.x*t.z,this._z=e.x*t.y-e.y*t.x,this._w=i),this.normalize()}angleTo(e){return 2*Math.acos(Math.abs(T2(this.dot(e),-1,1)))}rotateTowards(e,t){let i=this.angleTo(e);if(i===0)return this;let a=Math.min(1,t/i);return this.slerp(e,a),this}identity(){return this.set(0,0,0,1)}invert(){return this.conjugate()}conjugate(){return this._x*=-1,this._y*=-1,this._z*=-1,this._onChangeCallback(),this}dot(e){return this._x*e._x+this._y*e._y+this._z*e._z+this._w*e._w}lengthSq(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w}length(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)}normalize(){let e=this.length();return e===0?(this._x=0,this._y=0,this._z=0,this._w=1):(e=1/e,this._x=this._x*e,this._y=this._y*e,this._z=this._z*e,this._w=this._w*e),this._onChangeCallback(),this}multiply(e,t){return t!==void 0?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(e,t)):this.multiplyQuaternions(this,e)}premultiply(e){return this.multiplyQuaternions(e,this)}multiplyQuaternions(e,t){let i=e._x,a=e._y,r=e._z,s=e._w,o=t._x,c=t._y,l=t._z,u=t._w;return this._x=i*u+s*o+a*l-r*c,this._y=a*u+s*c+r*o-i*l,this._z=r*u+s*l+i*c-a*o,this._w=s*u-i*o-a*c-r*l,this._onChangeCallback(),this}slerp(e,t){if(t===0)return this;if(t===1)return this.copy(e);let i=this._x,a=this._y,r=this._z,s=this._w,o=s*e._w+i*e._x+a*e._y+r*e._z;if(o<0?(this._w=-e._w,this._x=-e._x,this._y=-e._y,this._z=-e._z,o=-o):this.copy(e),o>=1)return this._w=s,this._x=i,this._y=a,this._z=r,this;let c=1-o*o;if(c<=Number.EPSILON){let m=1-t;return this._w=m*s+t*this._w,this._x=m*i+t*this._x,this._y=m*a+t*this._y,this._z=m*r+t*this._z,this.normalize(),this._onChangeCallback(),this}let l=Math.sqrt(c),u=Math.atan2(l,o),f=Math.sin((1-t)*u)/l,h=Math.sin(t*u)/l;return this._w=s*f+this._w*h,this._x=i*f+this._x*h,this._y=a*f+this._y*h,this._z=r*f+this._z*h,this._onChangeCallback(),this}slerpQuaternions(e,t,i){return this.copy(e).slerp(t,i)}random(){let e=Math.random(),t=Math.sqrt(1-e),i=Math.sqrt(e),a=2*Math.PI*Math.random(),r=2*Math.PI*Math.random();return this.set(t*Math.cos(a),i*Math.sin(r),i*Math.cos(r),t*Math.sin(a))}equals(e){return e._x===this._x&&e._y===this._y&&e._z===this._z&&e._w===this._w}fromArray(e,t=0){return this._x=e[t],this._y=e[t+1],this._z=e[t+2],this._w=e[t+3],this._onChangeCallback(),this}toArray(e=[],t=0){return e[t]=this._x,e[t+1]=this._y,e[t+2]=this._z,e[t+3]=this._w,e}fromBufferAttribute(e,t){return this._x=e.getX(t),this._y=e.getY(t),this._z=e.getZ(t),this._w=e.getW(t),this}_onChange(e){return this._onChangeCallback=e,this}_onChangeCallback(){}};be.prototype.isQuaternion=!0;var U=class{constructor(e=0,t=0,i=0){this.x=e,this.y=t,this.z=i}set(e,t,i){return i===void 0&&(i=this.z),this.x=e,this.y=t,this.z=i,this}setScalar(e){return this.x=e,this.y=e,this.z=e,this}setX(e){return this.x=e,this}setY(e){return this.y=e,this}setZ(e){return this.z=e,this}setComponent(e,t){switch(e){case 0:this.x=t;break;case 1:this.y=t;break;case 2:this.z=t;break;default:throw new Error("index is out of range: "+e)}return this}getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw new Error("index is out of range: "+e)}}clone(){return new this.constructor(this.x,this.y,this.z)}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this}add(e,t){return t!==void 0?(console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(e,t)):(this.x+=e.x,this.y+=e.y,this.z+=e.z,this)}addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this}addVectors(e,t){return this.x=e.x+t.x,this.y=e.y+t.y,this.z=e.z+t.z,this}addScaledVector(e,t){return this.x+=e.x*t,this.y+=e.y*t,this.z+=e.z*t,this}sub(e,t){return t!==void 0?(console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(e,t)):(this.x-=e.x,this.y-=e.y,this.z-=e.z,this)}subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this.z=e.z-t.z,this}multiply(e,t){return t!==void 0?(console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(e,t)):(this.x*=e.x,this.y*=e.y,this.z*=e.z,this)}multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this}multiplyVectors(e,t){return this.x=e.x*t.x,this.y=e.y*t.y,this.z=e.z*t.z,this}applyEuler(e){return e&&e.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order."),this.applyQuaternion(Hr.setFromEuler(e))}applyAxisAngle(e,t){return this.applyQuaternion(Hr.setFromAxisAngle(e,t))}applyMatrix3(e){let t=this.x,i=this.y,a=this.z,r=e.elements;return this.x=r[0]*t+r[3]*i+r[6]*a,this.y=r[1]*t+r[4]*i+r[7]*a,this.z=r[2]*t+r[5]*i+r[8]*a,this}applyNormalMatrix(e){return this.applyMatrix3(e).normalize()}applyMatrix4(e){let t=this.x,i=this.y,a=this.z,r=e.elements,s=1/(r[3]*t+r[7]*i+r[11]*a+r[15]);return this.x=(r[0]*t+r[4]*i+r[8]*a+r[12])*s,this.y=(r[1]*t+r[5]*i+r[9]*a+r[13])*s,this.z=(r[2]*t+r[6]*i+r[10]*a+r[14])*s,this}applyQuaternion(e){let t=this.x,i=this.y,a=this.z,r=e.x,s=e.y,o=e.z,c=e.w,l=c*t+s*a-o*i,u=c*i+o*t-r*a,f=c*a+r*i-s*t,h=-r*t-s*i-o*a;return this.x=l*c+h*-r+u*-o-f*-s,this.y=u*c+h*-s+f*-r-l*-o,this.z=f*c+h*-o+l*-s-u*-r,this}project(e){return this.applyMatrix4(e.matrixWorldInverse).applyMatrix4(e.projectionMatrix)}unproject(e){return this.applyMatrix4(e.projectionMatrixInverse).applyMatrix4(e.matrixWorld)}transformDirection(e){let t=this.x,i=this.y,a=this.z,r=e.elements;return this.x=r[0]*t+r[4]*i+r[8]*a,this.y=r[1]*t+r[5]*i+r[9]*a,this.z=r[2]*t+r[6]*i+r[10]*a,this.normalize()}divide(e){return this.x/=e.x,this.y/=e.y,this.z/=e.z,this}divideScalar(e){return this.multiplyScalar(1/e)}min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),this.z=Math.min(this.z,e.z),this}max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),this.z=Math.max(this.z,e.z),this}clamp(e,t){return this.x=Math.max(e.x,Math.min(t.x,this.x)),this.y=Math.max(e.y,Math.min(t.y,this.y)),this.z=Math.max(e.z,Math.min(t.z,this.z)),this}clampScalar(e,t){return this.x=Math.max(e,Math.min(t,this.x)),this.y=Math.max(e,Math.min(t,this.y)),this.z=Math.max(e,Math.min(t,this.z)),this}clampLength(e,t){let i=this.length();return this.divideScalar(i||1).multiplyScalar(Math.max(e,Math.min(t,i)))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this}roundToZero(){return this.x=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this.z=this.z<0?Math.ceil(this.z):Math.floor(this.z),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)}normalize(){return this.divideScalar(this.length()||1)}setLength(e){return this.normalize().multiplyScalar(e)}lerp(e,t){return this.x+=(e.x-this.x)*t,this.y+=(e.y-this.y)*t,this.z+=(e.z-this.z)*t,this}lerpVectors(e,t,i){return this.x=e.x+(t.x-e.x)*i,this.y=e.y+(t.y-e.y)*i,this.z=e.z+(t.z-e.z)*i,this}cross(e,t){return t!==void 0?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(e,t)):this.crossVectors(this,e)}crossVectors(e,t){let i=e.x,a=e.y,r=e.z,s=t.x,o=t.y,c=t.z;return this.x=a*c-r*o,this.y=r*s-i*c,this.z=i*o-a*s,this}projectOnVector(e){let t=e.lengthSq();if(t===0)return this.set(0,0,0);let i=e.dot(this)/t;return this.copy(e).multiplyScalar(i)}projectOnPlane(e){return a3.copy(this).projectOnVector(e),this.sub(a3)}reflect(e){return this.sub(a3.copy(e).multiplyScalar(2*this.dot(e)))}angleTo(e){let t=Math.sqrt(this.lengthSq()*e.lengthSq());if(t===0)return Math.PI/2;let i=this.dot(e)/t;return Math.acos(T2(i,-1,1))}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){let t=this.x-e.x,i=this.y-e.y,a=this.z-e.z;return t*t+i*i+a*a}manhattanDistanceTo(e){return Math.abs(this.x-e.x)+Math.abs(this.y-e.y)+Math.abs(this.z-e.z)}setFromSpherical(e){return this.setFromSphericalCoords(e.radius,e.phi,e.theta)}setFromSphericalCoords(e,t,i){let a=Math.sin(t)*e;return this.x=a*Math.sin(i),this.y=Math.cos(t)*e,this.z=a*Math.cos(i),this}setFromCylindrical(e){return this.setFromCylindricalCoords(e.radius,e.theta,e.y)}setFromCylindricalCoords(e,t,i){return this.x=e*Math.sin(t),this.y=i,this.z=e*Math.cos(t),this}setFromMatrixPosition(e){let t=e.elements;return this.x=t[12],this.y=t[13],this.z=t[14],this}setFromMatrixScale(e){let t=this.setFromMatrixColumn(e,0).length(),i=this.setFromMatrixColumn(e,1).length(),a=this.setFromMatrixColumn(e,2).length();return this.x=t,this.y=i,this.z=a,this}setFromMatrixColumn(e,t){return this.fromArray(e.elements,t*4)}setFromMatrix3Column(e,t){return this.fromArray(e.elements,t*3)}equals(e){return e.x===this.x&&e.y===this.y&&e.z===this.z}fromArray(e,t=0){return this.x=e[t],this.y=e[t+1],this.z=e[t+2],this}toArray(e=[],t=0){return e[t]=this.x,e[t+1]=this.y,e[t+2]=this.z,e}fromBufferAttribute(e,t,i){return i!==void 0&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute()."),this.x=e.getX(t),this.y=e.getY(t),this.z=e.getZ(t),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this}randomDirection(){let e=(Math.random()-.5)*2,t=Math.random()*Math.PI*2,i=Math.sqrt(1-e**2);return this.x=i*Math.cos(t),this.y=i*Math.sin(t),this.z=e,this}*[Symbol.iterator](){yield this.x,yield this.y,yield this.z}};U.prototype.isVector3=!0;var a3=new U,Hr=new be;var A1=class{constructor(e=0,t=0){this.x=e,this.y=t}get width(){return this.x}set width(e){this.x=e}get height(){return this.y}set height(e){this.y=e}set(e,t){return this.x=e,this.y=t,this}setScalar(e){return this.x=e,this.y=e,this}setX(e){return this.x=e,this}setY(e){return this.y=e,this}setComponent(e,t){switch(e){case 0:this.x=t;break;case 1:this.y=t;break;default:throw new Error("index is out of range: "+e)}return this}getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;default:throw new Error("index is out of range: "+e)}}clone(){return new this.constructor(this.x,this.y)}copy(e){return this.x=e.x,this.y=e.y,this}add(e,t){return t!==void 0?(console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(e,t)):(this.x+=e.x,this.y+=e.y,this)}addScalar(e){return this.x+=e,this.y+=e,this}addVectors(e,t){return this.x=e.x+t.x,this.y=e.y+t.y,this}addScaledVector(e,t){return this.x+=e.x*t,this.y+=e.y*t,this}sub(e,t){return t!==void 0?(console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(e,t)):(this.x-=e.x,this.y-=e.y,this)}subScalar(e){return this.x-=e,this.y-=e,this}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this}multiply(e){return this.x*=e.x,this.y*=e.y,this}multiplyScalar(e){return this.x*=e,this.y*=e,this}divide(e){return this.x/=e.x,this.y/=e.y,this}divideScalar(e){return this.multiplyScalar(1/e)}applyMatrix3(e){let t=this.x,i=this.y,a=e.elements;return this.x=a[0]*t+a[3]*i+a[6],this.y=a[1]*t+a[4]*i+a[7],this}min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),this}max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),this}clamp(e,t){return this.x=Math.max(e.x,Math.min(t.x,this.x)),this.y=Math.max(e.y,Math.min(t.y,this.y)),this}clampScalar(e,t){return this.x=Math.max(e,Math.min(t,this.x)),this.y=Math.max(e,Math.min(t,this.y)),this}clampLength(e,t){let i=this.length();return this.divideScalar(i||1).multiplyScalar(Math.max(e,Math.min(t,i)))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}roundToZero(){return this.x=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this}negate(){return this.x=-this.x,this.y=-this.y,this}dot(e){return this.x*e.x+this.y*e.y}cross(e){return this.x*e.y-this.y*e.x}lengthSq(){return this.x*this.x+this.y*this.y}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)}normalize(){return this.divideScalar(this.length()||1)}angle(){return Math.atan2(-this.y,-this.x)+Math.PI}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){let t=this.x-e.x,i=this.y-e.y;return t*t+i*i}manhattanDistanceTo(e){return Math.abs(this.x-e.x)+Math.abs(this.y-e.y)}setLength(e){return this.normalize().multiplyScalar(e)}lerp(e,t){return this.x+=(e.x-this.x)*t,this.y+=(e.y-this.y)*t,this}lerpVectors(e,t,i){return this.x=e.x+(t.x-e.x)*i,this.y=e.y+(t.y-e.y)*i,this}equals(e){return e.x===this.x&&e.y===this.y}fromArray(e,t=0){return this.x=e[t],this.y=e[t+1],this}toArray(e=[],t=0){return e[t]=this.x,e[t+1]=this.y,e}fromBufferAttribute(e,t,i){return i!==void 0&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute()."),this.x=e.getX(t),this.y=e.getY(t),this}rotateAround(e,t){let i=Math.cos(t),a=Math.sin(t),r=this.x-e.x,s=this.y-e.y;return this.x=r*i-s*a+e.x,this.y=r*a+s*i+e.y,this}random(){return this.x=Math.random(),this.y=Math.random(),this}*[Symbol.iterator](){yield this.x,yield this.y}};A1.prototype.isVector2=!0;var Vr={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},J2={h:0,s:0,l:0},S6={h:0,s:0,l:0};function r3(n,e,t){return t<0&&(t+=1),t>1&&(t-=1),t<1/6?n+(e-n)*6*t:t<1/2?e:t<2/3?n+(e-n)*6*(2/3-t):n}function At(n){return n<.04045?n*.0773993808:Math.pow(n*.9478672986+.0521327014,2.4)}function n3(n){return n<.0031308?n*12.92:1.055*Math.pow(n,.41666)-.055}var M1=class{constructor(e,t,i){return t===void 0&&i===void 0?this.set(e):this.setRGB(e,t,i)}set(e){return e&&e.isColor?this.copy(e):typeof e=="number"?this.setHex(e):typeof e=="string"&&this.setStyle(e),this}setScalar(e){return this.r=e,this.g=e,this.b=e,this}setHex(e){return e=Math.floor(e),this.r=(e>>16&255)/255,this.g=(e>>8&255)/255,this.b=(e&255)/255,this}setRGB(e,t,i){return this.r=e,this.g=t,this.b=i,this}setHSL(e,t,i){if(e=Dr(e,1),t=T2(t,0,1),i=T2(i,0,1),t===0)this.r=this.g=this.b=i;else{let a=i<=.5?i*(1+t):i+t-i*t,r=2*i-a;this.r=r3(r,a,e+1/3),this.g=r3(r,a,e),this.b=r3(r,a,e-1/3)}return this}setStyle(e){function t(a){a!==void 0&&parseFloat(a)<1&&console.warn("THREE.Color: Alpha component of "+e+" will be ignored.")}let i;if(i=/^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec(e)){let a,r=i[1],s=i[2];switch(r){case"rgb":case"rgba":if(a=/^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s))return this.r=Math.min(255,parseInt(a[1],10))/255,this.g=Math.min(255,parseInt(a[2],10))/255,this.b=Math.min(255,parseInt(a[3],10))/255,t(a[4]),this;if(a=/^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s))return this.r=Math.min(100,parseInt(a[1],10))/100,this.g=Math.min(100,parseInt(a[2],10))/100,this.b=Math.min(100,parseInt(a[3],10))/100,t(a[4]),this;break;case"hsl":case"hsla":if(a=/^\s*(\d*\.?\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s)){let o=parseFloat(a[1])/360,c=parseInt(a[2],10)/100,l=parseInt(a[3],10)/100;return t(a[4]),this.setHSL(o,c,l)}break}}else if(i=/^\#([A-Fa-f\d]+)$/.exec(e)){let a=i[1],r=a.length;if(r===3)return this.r=parseInt(a.charAt(0)+a.charAt(0),16)/255,this.g=parseInt(a.charAt(1)+a.charAt(1),16)/255,this.b=parseInt(a.charAt(2)+a.charAt(2),16)/255,this;if(r===6)return this.r=parseInt(a.charAt(0)+a.charAt(1),16)/255,this.g=parseInt(a.charAt(2)+a.charAt(3),16)/255,this.b=parseInt(a.charAt(4)+a.charAt(5),16)/255,this}return e&&e.length>0?this.setColorName(e):this}setColorName(e){let t=Vr[e.toLowerCase()];return t!==void 0?this.setHex(t):console.warn("THREE.Color: Unknown color "+e),this}clone(){return new this.constructor(this.r,this.g,this.b)}copy(e){return this.r=e.r,this.g=e.g,this.b=e.b,this}copySRGBToLinear(e){return this.r=At(e.r),this.g=At(e.g),this.b=At(e.b),this}copyLinearToSRGB(e){return this.r=n3(e.r),this.g=n3(e.g),this.b=n3(e.b),this}convertSRGBToLinear(){return this.copySRGBToLinear(this),this}convertLinearToSRGB(){return this.copyLinearToSRGB(this),this}getHex(){return this.r*255<<16^this.g*255<<8^this.b*255<<0}getHexString(){return("000000"+this.getHex().toString(16)).slice(-6)}getHSL(e){let t=this.r,i=this.g,a=this.b,r=Math.max(t,i,a),s=Math.min(t,i,a),o,c,l=(s+r)/2;if(s===r)o=0,c=0;else{let u=r-s;switch(c=l<=.5?u/(r+s):u/(2-r-s),r){case t:o=(i-a)/u+(ir&&(r=u),f>s&&(s=f),h>o&&(o=h)}return this.min.set(t,i,a),this.max.set(r,s,o),this}setFromBufferAttribute(e){let t=1/0,i=1/0,a=1/0,r=-1/0,s=-1/0,o=-1/0;for(let c=0,l=e.count;cr&&(r=u),f>s&&(s=f),h>o&&(o=h)}return this.min.set(t,i,a),this.max.set(r,s,o),this}setFromPoints(e){this.makeEmpty();for(let t=0,i=e.length;tthis.max.x||e.ythis.max.y||e.zthis.max.z)}containsBox(e){return this.min.x<=e.min.x&&e.max.x<=this.max.x&&this.min.y<=e.min.y&&e.max.y<=this.max.y&&this.min.z<=e.min.z&&e.max.z<=this.max.z}getParameter(e,t){return t.set((e.x-this.min.x)/(this.max.x-this.min.x),(e.y-this.min.y)/(this.max.y-this.min.y),(e.z-this.min.z)/(this.max.z-this.min.z))}intersectsBox(e){return!(e.max.xthis.max.x||e.max.ythis.max.y||e.max.zthis.max.z)}intersectsSphere(e){return this.clampPoint(e.center,_t),_t.distanceToSquared(e.center)<=e.radius*e.radius}intersectsPlane(e){let t,i;return e.normal.x>0?(t=e.normal.x*this.min.x,i=e.normal.x*this.max.x):(t=e.normal.x*this.max.x,i=e.normal.x*this.min.x),e.normal.y>0?(t+=e.normal.y*this.min.y,i+=e.normal.y*this.max.y):(t+=e.normal.y*this.max.y,i+=e.normal.y*this.min.y),e.normal.z>0?(t+=e.normal.z*this.min.z,i+=e.normal.z*this.max.z):(t+=e.normal.z*this.max.z,i+=e.normal.z*this.min.z),t<=-e.constant&&i>=-e.constant}intersectsTriangle(e){if(this.isEmpty())return!1;this.getCenter(k4),P6.subVectors(this.max,k4),Xt.subVectors(e.a,k4),Zt.subVectors(e.b,k4),Yt.subVectors(e.c,k4),ot.subVectors(Zt,Xt),ct.subVectors(Yt,Zt),Et.subVectors(Xt,Yt);let t=[0,-ot.z,ot.y,0,-ct.z,ct.y,0,-Et.z,Et.y,ot.z,0,-ot.x,ct.z,0,-ct.x,Et.z,0,-Et.x,-ot.y,ot.x,0,-ct.y,ct.x,0,-Et.y,Et.x,0];return!I3(t,Xt,Zt,Yt,P6)||(t=[1,0,0,0,1,0,0,0,1],!I3(t,Xt,Zt,Yt,P6))?!1:(I6.crossVectors(ot,ct),t=[I6.x,I6.y,I6.z],I3(t,Xt,Zt,Yt,P6))}clampPoint(e,t){return t.copy(e).clamp(this.min,this.max)}distanceToPoint(e){return _t.copy(e).clamp(this.min,this.max).sub(e).length()}getBoundingSphere(e){return this.getCenter(e.center),e.radius=this.getSize(_t).length()*.5,e}intersect(e){return this.min.max(e.min),this.max.min(e.max),this.isEmpty()&&this.makeEmpty(),this}union(e){return this.min.min(e.min),this.max.max(e.max),this}applyMatrix4(e){return this.isEmpty()?this:(qe[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(e),qe[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(e),qe[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(e),qe[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(e),qe[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(e),qe[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(e),qe[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(e),qe[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(e),this.setFromPoints(qe),this)}translate(e){return this.min.add(e),this.max.add(e),this}equals(e){return e.min.equals(this.min)&&e.max.equals(this.max)}};Ge.prototype.isBox3=!0;var qe=[new U,new U,new U,new U,new U,new U,new U,new U],_t=new U,P3=new Ge,Xt=new U,Zt=new U,Yt=new U,ot=new U,ct=new U,Et=new U,k4=new U,P6=new U,I6=new U,Lt=new U;function I3(n,e,t,i,a){for(let r=0,s=n.length-3;r<=s;r+=3){Lt.fromArray(n,r);let o=a.x*Math.abs(Lt.x)+a.y*Math.abs(Lt.y)+a.z*Math.abs(Lt.z),c=e.dot(Lt),l=t.dot(Lt),u=i.dot(Lt);if(Math.max(-Math.max(c,l,u),Math.min(c,l,u))>o)return!1}return!0}var B2=class{addEventListener(e,t){this._listeners===void 0&&(this._listeners={});let i=this._listeners;i[e]===void 0&&(i[e]=[]),i[e].indexOf(t)===-1&&i[e].push(t)}hasEventListener(e,t){if(this._listeners===void 0)return!1;let i=this._listeners;return i[e]!==void 0&&i[e].indexOf(t)!==-1}removeEventListener(e,t){if(this._listeners===void 0)return;let a=this._listeners[e];if(a!==void 0){let r=a.indexOf(t);r!==-1&&a.splice(r,1)}}dispatchEvent(e){if(this._listeners===void 0)return;let i=this._listeners[e.type];if(i!==void 0){e.target=this;let a=i.slice(0);for(let r=0,s=a.length;rthis.radius*this.radius&&(t.sub(this.center).normalize(),t.multiplyScalar(this.radius).add(this.center)),t}getBoundingBox(e){return this.isEmpty()?(e.makeEmpty(),e):(e.set(this.center,this.center),e.expandByScalar(this.radius),e)}applyMatrix4(e){return this.center.applyMatrix4(e),this.radius=this.radius*e.getMaxScaleOnAxis(),this}translate(e){return this.center.add(e),this}expandByPoint(e){k3.subVectors(e,this.center);let t=k3.lengthSq();if(t>this.radius*this.radius){let i=Math.sqrt(t),a=(i-this.radius)*.5;this.center.add(k3.multiplyScalar(a/i)),this.radius+=a}return this}union(e){return this.center.equals(e.center)===!0?k6.set(0,0,1).multiplyScalar(e.radius):k6.subVectors(e.center,this.center).normalize().multiplyScalar(e.radius),this.expandByPoint(D8.copy(e.center).add(k6)),this.expandByPoint(D8.copy(e.center).sub(k6)),this}equals(e){return e.center.equals(this.center)&&e.radius===this.radius}clone(){return new this.constructor().copy(this)}};var U1=class{constructor(){this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],arguments.length>0&&console.error("THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.")}set(e,t,i,a,r,s,o,c,l,u,f,h,m,v,g,x){let p=this.elements;return p[0]=e,p[4]=t,p[8]=i,p[12]=a,p[1]=r,p[5]=s,p[9]=o,p[13]=c,p[2]=l,p[6]=u,p[10]=f,p[14]=h,p[3]=m,p[7]=v,p[11]=g,p[15]=x,this}identity(){return this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),this}clone(){return new U1().fromArray(this.elements)}copy(e){let t=this.elements,i=e.elements;return t[0]=i[0],t[1]=i[1],t[2]=i[2],t[3]=i[3],t[4]=i[4],t[5]=i[5],t[6]=i[6],t[7]=i[7],t[8]=i[8],t[9]=i[9],t[10]=i[10],t[11]=i[11],t[12]=i[12],t[13]=i[13],t[14]=i[14],t[15]=i[15],this}copyPosition(e){let t=this.elements,i=e.elements;return t[12]=i[12],t[13]=i[13],t[14]=i[14],this}setFromMatrix3(e){let t=e.elements;return this.set(t[0],t[3],t[6],0,t[1],t[4],t[7],0,t[2],t[5],t[8],0,0,0,0,1),this}extractBasis(e,t,i){return e.setFromMatrixColumn(this,0),t.setFromMatrixColumn(this,1),i.setFromMatrixColumn(this,2),this}makeBasis(e,t,i){return this.set(e.x,t.x,i.x,0,e.y,t.y,i.y,0,e.z,t.z,i.z,0,0,0,0,1),this}extractRotation(e){let t=this.elements,i=e.elements,a=1/$t.setFromMatrixColumn(e,0).length(),r=1/$t.setFromMatrixColumn(e,1).length(),s=1/$t.setFromMatrixColumn(e,2).length();return t[0]=i[0]*a,t[1]=i[1]*a,t[2]=i[2]*a,t[3]=0,t[4]=i[4]*r,t[5]=i[5]*r,t[6]=i[6]*r,t[7]=0,t[8]=i[8]*s,t[9]=i[9]*s,t[10]=i[10]*s,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,this}makeRotationFromEuler(e){e&&e.isEuler||console.error("THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");let t=this.elements,i=e.x,a=e.y,r=e.z,s=Math.cos(i),o=Math.sin(i),c=Math.cos(a),l=Math.sin(a),u=Math.cos(r),f=Math.sin(r);if(e.order==="XYZ"){let h=s*u,m=s*f,v=o*u,g=o*f;t[0]=c*u,t[4]=-c*f,t[8]=l,t[1]=m+v*l,t[5]=h-g*l,t[9]=-o*c,t[2]=g-h*l,t[6]=v+m*l,t[10]=s*c}else if(e.order==="YXZ"){let h=c*u,m=c*f,v=l*u,g=l*f;t[0]=h+g*o,t[4]=v*o-m,t[8]=s*l,t[1]=s*f,t[5]=s*u,t[9]=-o,t[2]=m*o-v,t[6]=g+h*o,t[10]=s*c}else if(e.order==="ZXY"){let h=c*u,m=c*f,v=l*u,g=l*f;t[0]=h-g*o,t[4]=-s*f,t[8]=v+m*o,t[1]=m+v*o,t[5]=s*u,t[9]=g-h*o,t[2]=-s*l,t[6]=o,t[10]=s*c}else if(e.order==="ZYX"){let h=s*u,m=s*f,v=o*u,g=o*f;t[0]=c*u,t[4]=v*l-m,t[8]=h*l+g,t[1]=c*f,t[5]=g*l+h,t[9]=m*l-v,t[2]=-l,t[6]=o*c,t[10]=s*c}else if(e.order==="YZX"){let h=s*c,m=s*l,v=o*c,g=o*l;t[0]=c*u,t[4]=g-h*f,t[8]=v*f+m,t[1]=f,t[5]=s*u,t[9]=-o*u,t[2]=-l*u,t[6]=m*f+v,t[10]=h-g*f}else if(e.order==="XZY"){let h=s*c,m=s*l,v=o*c,g=o*l;t[0]=c*u,t[4]=-f,t[8]=l*u,t[1]=h*f+g,t[5]=s*u,t[9]=m*f-v,t[2]=v*f-m,t[6]=o*u,t[10]=g*f+h}return t[3]=0,t[7]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,this}makeRotationFromQuaternion(e){return this.compose(d9,e,p9)}lookAt(e,t,i){let a=this.elements;return P2.subVectors(e,t),P2.lengthSq()===0&&(P2.z=1),P2.normalize(),lt.crossVectors(i,P2),lt.lengthSq()===0&&(Math.abs(i.z)===1?P2.x+=1e-4:P2.z+=1e-4,P2.normalize(),lt.crossVectors(i,P2)),lt.normalize(),U6.crossVectors(P2,lt),a[0]=lt.x,a[4]=U6.x,a[8]=P2.x,a[1]=lt.y,a[5]=U6.y,a[9]=P2.y,a[2]=lt.z,a[6]=U6.z,a[10]=P2.z,this}multiply(e,t){return t!==void 0?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."),this.multiplyMatrices(e,t)):this.multiplyMatrices(this,e)}premultiply(e){return this.multiplyMatrices(e,this)}multiplyMatrices(e,t){let i=e.elements,a=t.elements,r=this.elements,s=i[0],o=i[4],c=i[8],l=i[12],u=i[1],f=i[5],h=i[9],m=i[13],v=i[2],g=i[6],x=i[10],p=i[14],d=i[3],w=i[7],b=i[11],z=i[15],L=a[0],H=a[4],E=a[8],I=a[12],B=a[1],M=a[5],T=a[9],A=a[13],V=a[2],N=a[6],D=a[10],R=a[14],O=a[3],Y=a[7],G=a[11],j=a[15];return r[0]=s*L+o*B+c*V+l*O,r[4]=s*H+o*M+c*N+l*Y,r[8]=s*E+o*T+c*D+l*G,r[12]=s*I+o*A+c*R+l*j,r[1]=u*L+f*B+h*V+m*O,r[5]=u*H+f*M+h*N+m*Y,r[9]=u*E+f*T+h*D+m*G,r[13]=u*I+f*A+h*R+m*j,r[2]=v*L+g*B+x*V+p*O,r[6]=v*H+g*M+x*N+p*Y,r[10]=v*E+g*T+x*D+p*G,r[14]=v*I+g*A+x*R+p*j,r[3]=d*L+w*B+b*V+z*O,r[7]=d*H+w*M+b*N+z*Y,r[11]=d*E+w*T+b*D+z*G,r[15]=d*I+w*A+b*R+z*j,this}multiplyScalar(e){let t=this.elements;return t[0]*=e,t[4]*=e,t[8]*=e,t[12]*=e,t[1]*=e,t[5]*=e,t[9]*=e,t[13]*=e,t[2]*=e,t[6]*=e,t[10]*=e,t[14]*=e,t[3]*=e,t[7]*=e,t[11]*=e,t[15]*=e,this}determinant(){let e=this.elements,t=e[0],i=e[4],a=e[8],r=e[12],s=e[1],o=e[5],c=e[9],l=e[13],u=e[2],f=e[6],h=e[10],m=e[14],v=e[3],g=e[7],x=e[11],p=e[15];return v*(+r*c*f-a*l*f-r*o*h+i*l*h+a*o*m-i*c*m)+g*(+t*c*m-t*l*h+r*s*h-a*s*m+a*l*u-r*c*u)+x*(+t*l*f-t*o*m-r*s*f+i*s*m+r*o*u-i*l*u)+p*(-a*o*u-t*c*f+t*o*h+a*s*f-i*s*h+i*c*u)}transpose(){let e=this.elements,t;return t=e[1],e[1]=e[4],e[4]=t,t=e[2],e[2]=e[8],e[8]=t,t=e[6],e[6]=e[9],e[9]=t,t=e[3],e[3]=e[12],e[12]=t,t=e[7],e[7]=e[13],e[13]=t,t=e[11],e[11]=e[14],e[14]=t,this}setPosition(e,t,i){let a=this.elements;return e.isVector3?(a[12]=e.x,a[13]=e.y,a[14]=e.z):(a[12]=e,a[13]=t,a[14]=i),this}invert(){let e=this.elements,t=e[0],i=e[1],a=e[2],r=e[3],s=e[4],o=e[5],c=e[6],l=e[7],u=e[8],f=e[9],h=e[10],m=e[11],v=e[12],g=e[13],x=e[14],p=e[15],d=f*x*l-g*h*l+g*c*m-o*x*m-f*c*p+o*h*p,w=v*h*l-u*x*l-v*c*m+s*x*m+u*c*p-s*h*p,b=u*g*l-v*f*l+v*o*m-s*g*m-u*o*p+s*f*p,z=v*f*c-u*g*c-v*o*h+s*g*h+u*o*x-s*f*x,L=t*d+i*w+a*b+r*z;if(L===0)return this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);let H=1/L;return e[0]=d*H,e[1]=(g*h*r-f*x*r-g*a*m+i*x*m+f*a*p-i*h*p)*H,e[2]=(o*x*r-g*c*r+g*a*l-i*x*l-o*a*p+i*c*p)*H,e[3]=(f*c*r-o*h*r-f*a*l+i*h*l+o*a*m-i*c*m)*H,e[4]=w*H,e[5]=(u*x*r-v*h*r+v*a*m-t*x*m-u*a*p+t*h*p)*H,e[6]=(v*c*r-s*x*r-v*a*l+t*x*l+s*a*p-t*c*p)*H,e[7]=(s*h*r-u*c*r+u*a*l-t*h*l-s*a*m+t*c*m)*H,e[8]=b*H,e[9]=(v*f*r-u*g*r-v*i*m+t*g*m+u*i*p-t*f*p)*H,e[10]=(s*g*r-v*o*r+v*i*l-t*g*l-s*i*p+t*o*p)*H,e[11]=(u*o*r-s*f*r-u*i*l+t*f*l+s*i*m-t*o*m)*H,e[12]=z*H,e[13]=(u*g*a-v*f*a+v*i*h-t*g*h-u*i*x+t*f*x)*H,e[14]=(v*o*a-s*g*a-v*i*c+t*g*c+s*i*x-t*o*x)*H,e[15]=(s*f*a-u*o*a+u*i*c-t*f*c-s*i*h+t*o*h)*H,this}scale(e){let t=this.elements,i=e.x,a=e.y,r=e.z;return t[0]*=i,t[4]*=a,t[8]*=r,t[1]*=i,t[5]*=a,t[9]*=r,t[2]*=i,t[6]*=a,t[10]*=r,t[3]*=i,t[7]*=a,t[11]*=r,this}getMaxScaleOnAxis(){let e=this.elements,t=e[0]*e[0]+e[1]*e[1]+e[2]*e[2],i=e[4]*e[4]+e[5]*e[5]+e[6]*e[6],a=e[8]*e[8]+e[9]*e[9]+e[10]*e[10];return Math.sqrt(Math.max(t,i,a))}makeTranslation(e,t,i){return this.set(1,0,0,e,0,1,0,t,0,0,1,i,0,0,0,1),this}makeRotationX(e){let t=Math.cos(e),i=Math.sin(e);return this.set(1,0,0,0,0,t,-i,0,0,i,t,0,0,0,0,1),this}makeRotationY(e){let t=Math.cos(e),i=Math.sin(e);return this.set(t,0,i,0,0,1,0,0,-i,0,t,0,0,0,0,1),this}makeRotationZ(e){let t=Math.cos(e),i=Math.sin(e);return this.set(t,-i,0,0,i,t,0,0,0,0,1,0,0,0,0,1),this}makeRotationAxis(e,t){let i=Math.cos(t),a=Math.sin(t),r=1-i,s=e.x,o=e.y,c=e.z,l=r*s,u=r*o;return this.set(l*s+i,l*o-a*c,l*c+a*o,0,l*o+a*c,u*o+i,u*c-a*s,0,l*c-a*o,u*c+a*s,r*c*c+i,0,0,0,0,1),this}makeScale(e,t,i){return this.set(e,0,0,0,0,t,0,0,0,0,i,0,0,0,0,1),this}makeShear(e,t,i,a,r,s){return this.set(1,i,r,0,e,1,s,0,t,a,1,0,0,0,0,1),this}compose(e,t,i){let a=this.elements,r=t._x,s=t._y,o=t._z,c=t._w,l=r+r,u=s+s,f=o+o,h=r*l,m=r*u,v=r*f,g=s*u,x=s*f,p=o*f,d=c*l,w=c*u,b=c*f,z=i.x,L=i.y,H=i.z;return a[0]=(1-(g+p))*z,a[1]=(m+b)*z,a[2]=(v-w)*z,a[3]=0,a[4]=(m-b)*L,a[5]=(1-(h+p))*L,a[6]=(x+d)*L,a[7]=0,a[8]=(v+w)*H,a[9]=(x-d)*H,a[10]=(1-(h+g))*H,a[11]=0,a[12]=e.x,a[13]=e.y,a[14]=e.z,a[15]=1,this}decompose(e,t,i){let a=this.elements,r=$t.set(a[0],a[1],a[2]).length(),s=$t.set(a[4],a[5],a[6]).length(),o=$t.set(a[8],a[9],a[10]).length();this.determinant()<0&&(r=-r),e.x=a[12],e.y=a[13],e.z=a[14],ie.copy(this);let l=1/r,u=1/s,f=1/o;return ie.elements[0]*=l,ie.elements[1]*=l,ie.elements[2]*=l,ie.elements[4]*=u,ie.elements[5]*=u,ie.elements[6]*=u,ie.elements[8]*=f,ie.elements[9]*=f,ie.elements[10]*=f,t.setFromRotationMatrix(ie),i.x=r,i.y=s,i.z=o,this}makePerspective(e,t,i,a,r,s){s===void 0&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.");let o=this.elements,c=2*r/(t-e),l=2*r/(i-a),u=(t+e)/(t-e),f=(i+a)/(i-a),h=-(s+r)/(s-r),m=-2*s*r/(s-r);return o[0]=c,o[4]=0,o[8]=u,o[12]=0,o[1]=0,o[5]=l,o[9]=f,o[13]=0,o[2]=0,o[6]=0,o[10]=h,o[14]=m,o[3]=0,o[7]=0,o[11]=-1,o[15]=0,this}makeOrthographic(e,t,i,a,r,s){let o=this.elements,c=1/(t-e),l=1/(i-a),u=1/(s-r),f=(t+e)*c,h=(i+a)*l,m=(s+r)*u;return o[0]=2*c,o[4]=0,o[8]=0,o[12]=-f,o[1]=0,o[5]=2*l,o[9]=0,o[13]=-h,o[2]=0,o[6]=0,o[10]=-2*u,o[14]=-m,o[3]=0,o[7]=0,o[11]=0,o[15]=1,this}equals(e){let t=this.elements,i=e.elements;for(let a=0;a<16;a++)if(t[a]!==i[a])return!1;return!0}fromArray(e,t=0){for(let i=0;i<16;i++)this.elements[i]=e[i+t];return this}toArray(e=[],t=0){let i=this.elements;return e[t]=i[0],e[t+1]=i[1],e[t+2]=i[2],e[t+3]=i[3],e[t+4]=i[4],e[t+5]=i[5],e[t+6]=i[6],e[t+7]=i[7],e[t+8]=i[8],e[t+9]=i[9],e[t+10]=i[10],e[t+11]=i[11],e[t+12]=i[12],e[t+13]=i[13],e[t+14]=i[14],e[t+15]=i[15],e}};U1.prototype.isMatrix4=!0;var $t=new U,ie=new U1,d9=new U(0,0,0),p9=new U(1,1,1),lt=new U,U6=new U,P2=new U;var T8=new U1,H8=new be,ut=class{constructor(e=0,t=0,i=0,a=ut.DefaultOrder){this._x=e,this._y=t,this._z=i,this._order=a}get x(){return this._x}set x(e){this._x=e,this._onChangeCallback()}get y(){return this._y}set y(e){this._y=e,this._onChangeCallback()}get z(){return this._z}set z(e){this._z=e,this._onChangeCallback()}get order(){return this._order}set order(e){this._order=e,this._onChangeCallback()}set(e,t,i,a=this._order){return this._x=e,this._y=t,this._z=i,this._order=a,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._order)}copy(e){return this._x=e._x,this._y=e._y,this._z=e._z,this._order=e._order,this._onChangeCallback(),this}setFromRotationMatrix(e,t=this._order,i=!0){let a=e.elements,r=a[0],s=a[4],o=a[8],c=a[1],l=a[5],u=a[9],f=a[2],h=a[6],m=a[10];switch(t){case"XYZ":this._y=Math.asin(T2(o,-1,1)),Math.abs(o)<.9999999?(this._x=Math.atan2(-u,m),this._z=Math.atan2(-s,r)):(this._x=Math.atan2(h,l),this._z=0);break;case"YXZ":this._x=Math.asin(-T2(u,-1,1)),Math.abs(u)<.9999999?(this._y=Math.atan2(o,m),this._z=Math.atan2(c,l)):(this._y=Math.atan2(-f,r),this._z=0);break;case"ZXY":this._x=Math.asin(T2(h,-1,1)),Math.abs(h)<.9999999?(this._y=Math.atan2(-f,m),this._z=Math.atan2(-s,l)):(this._y=0,this._z=Math.atan2(c,r));break;case"ZYX":this._y=Math.asin(-T2(f,-1,1)),Math.abs(f)<.9999999?(this._x=Math.atan2(h,m),this._z=Math.atan2(c,r)):(this._x=0,this._z=Math.atan2(-s,l));break;case"YZX":this._z=Math.asin(T2(c,-1,1)),Math.abs(c)<.9999999?(this._x=Math.atan2(-u,l),this._y=Math.atan2(-f,r)):(this._x=0,this._y=Math.atan2(o,m));break;case"XZY":this._z=Math.asin(-T2(s,-1,1)),Math.abs(s)<.9999999?(this._x=Math.atan2(h,l),this._y=Math.atan2(o,r)):(this._x=Math.atan2(-u,m),this._y=0);break;default:console.warn("THREE.Euler: .setFromRotationMatrix() encountered an unknown order: "+t)}return this._order=t,i===!0&&this._onChangeCallback(),this}setFromQuaternion(e,t,i){return T8.makeRotationFromQuaternion(e),this.setFromRotationMatrix(T8,t,i)}setFromVector3(e,t=this._order){return this.set(e.x,e.y,e.z,t)}reorder(e){return H8.setFromEuler(this),this.setFromQuaternion(H8,e)}equals(e){return e._x===this._x&&e._y===this._y&&e._z===this._z&&e._order===this._order}fromArray(e){return this._x=e[0],this._y=e[1],this._z=e[2],e[3]!==void 0&&(this._order=e[3]),this._onChangeCallback(),this}toArray(e=[],t=0){return e[t]=this._x,e[t+1]=this._y,e[t+2]=this._z,e[t+3]=this._order,e}toVector3(e){return e?e.set(this._x,this._y,this._z):new U(this._x,this._y,this._z)}_onChange(e){return this._onChangeCallback=e,this}_onChangeCallback(){}};ut.prototype.isEuler=!0;ut.DefaultOrder="XYZ";ut.RotationOrders=["XYZ","YZX","ZXY","XZY","YXZ","ZYX"];var U4=class{constructor(){this.mask=1|0}set(e){this.mask=(1<>>0}enable(e){this.mask|=1<0&&console.error("THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.")}set(e,t,i,a,r,s,o,c,l){let u=this.elements;return u[0]=e,u[1]=a,u[2]=o,u[3]=t,u[4]=r,u[5]=c,u[6]=i,u[7]=s,u[8]=l,this}identity(){return this.set(1,0,0,0,1,0,0,0,1),this}copy(e){let t=this.elements,i=e.elements;return t[0]=i[0],t[1]=i[1],t[2]=i[2],t[3]=i[3],t[4]=i[4],t[5]=i[5],t[6]=i[6],t[7]=i[7],t[8]=i[8],this}extractBasis(e,t,i){return e.setFromMatrix3Column(this,0),t.setFromMatrix3Column(this,1),i.setFromMatrix3Column(this,2),this}setFromMatrix4(e){let t=e.elements;return this.set(t[0],t[4],t[8],t[1],t[5],t[9],t[2],t[6],t[10]),this}multiply(e){return this.multiplyMatrices(this,e)}premultiply(e){return this.multiplyMatrices(e,this)}multiplyMatrices(e,t){let i=e.elements,a=t.elements,r=this.elements,s=i[0],o=i[3],c=i[6],l=i[1],u=i[4],f=i[7],h=i[2],m=i[5],v=i[8],g=a[0],x=a[3],p=a[6],d=a[1],w=a[4],b=a[7],z=a[2],L=a[5],H=a[8];return r[0]=s*g+o*d+c*z,r[3]=s*x+o*w+c*L,r[6]=s*p+o*b+c*H,r[1]=l*g+u*d+f*z,r[4]=l*x+u*w+f*L,r[7]=l*p+u*b+f*H,r[2]=h*g+m*d+v*z,r[5]=h*x+m*w+v*L,r[8]=h*p+m*b+v*H,this}multiplyScalar(e){let t=this.elements;return t[0]*=e,t[3]*=e,t[6]*=e,t[1]*=e,t[4]*=e,t[7]*=e,t[2]*=e,t[5]*=e,t[8]*=e,this}determinant(){let e=this.elements,t=e[0],i=e[1],a=e[2],r=e[3],s=e[4],o=e[5],c=e[6],l=e[7],u=e[8];return t*s*u-t*o*l-i*r*u+i*o*c+a*r*l-a*s*c}invert(){let e=this.elements,t=e[0],i=e[1],a=e[2],r=e[3],s=e[4],o=e[5],c=e[6],l=e[7],u=e[8],f=u*s-o*l,h=o*c-u*r,m=l*r-s*c,v=t*f+i*h+a*m;if(v===0)return this.set(0,0,0,0,0,0,0,0,0);let g=1/v;return e[0]=f*g,e[1]=(a*l-u*i)*g,e[2]=(o*i-a*s)*g,e[3]=h*g,e[4]=(u*t-a*c)*g,e[5]=(a*r-o*t)*g,e[6]=m*g,e[7]=(i*c-l*t)*g,e[8]=(s*t-i*r)*g,this}transpose(){let e,t=this.elements;return e=t[1],t[1]=t[3],t[3]=e,e=t[2],t[2]=t[6],t[6]=e,e=t[5],t[5]=t[7],t[7]=e,this}getNormalMatrix(e){return this.setFromMatrix4(e).invert().transpose()}transposeIntoArray(e){let t=this.elements;return e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],this}setUvTransform(e,t,i,a,r,s,o){let c=Math.cos(r),l=Math.sin(r);return this.set(i*c,i*l,-i*(c*s+l*o)+s+e,-a*l,a*c,-a*(-l*s+c*o)+o+t,0,0,1),this}scale(e,t){let i=this.elements;return i[0]*=e,i[3]*=e,i[6]*=e,i[1]*=t,i[4]*=t,i[7]*=t,this}rotate(e){let t=Math.cos(e),i=Math.sin(e),a=this.elements,r=a[0],s=a[3],o=a[6],c=a[1],l=a[4],u=a[7];return a[0]=t*r+i*c,a[3]=t*s+i*l,a[6]=t*o+i*u,a[1]=-i*r+t*c,a[4]=-i*s+t*l,a[7]=-i*o+t*u,this}translate(e,t){let i=this.elements;return i[0]+=e*i[2],i[3]+=e*i[5],i[6]+=e*i[8],i[1]+=t*i[2],i[4]+=t*i[5],i[7]+=t*i[8],this}equals(e){let t=this.elements,i=e.elements;for(let a=0;a<9;a++)if(t[a]!==i[a])return!1;return!0}fromArray(e,t=0){for(let i=0;i<9;i++)this.elements[i]=e[i+t];return this}toArray(e=[],t=0){let i=this.elements;return e[t]=i[0],e[t+1]=i[1],e[t+2]=i[2],e[t+3]=i[3],e[t+4]=i[4],e[t+5]=i[5],e[t+6]=i[6],e[t+7]=i[7],e[t+8]=i[8],e}clone(){return new this.constructor().fromArray(this.elements)}};s2.prototype.isMatrix3=!0;var m9=0,V8=new U,Kt=new be,je=new U1,O6=new U,O4=new U,v9=new U,g9=new be,N8=new U(1,0,0),R8=new U(0,1,0),F8=new U(0,0,1),x9={type:"added"},B8={type:"removed"},X1=class extends B2{constructor(){super();Object.defineProperty(this,"id",{value:m9++}),this.uuid=Ie(),this.name="",this.type="Object3D",this.parent=null,this.children=[],this.up=X1.DefaultUp.clone();let e=new U,t=new ut,i=new be,a=new U(1,1,1);function r(){i.setFromEuler(t,!1)}function s(){t.setFromQuaternion(i,void 0,!1)}t._onChange(r),i._onChange(s),Object.defineProperties(this,{position:{configurable:!0,enumerable:!0,value:e},rotation:{configurable:!0,enumerable:!0,value:t},quaternion:{configurable:!0,enumerable:!0,value:i},scale:{configurable:!0,enumerable:!0,value:a},modelViewMatrix:{value:new U1},normalMatrix:{value:new s2}}),this.matrix=new U1,this.matrixWorld=new U1,this.matrixAutoUpdate=X1.DefaultMatrixAutoUpdate,this.matrixWorldNeedsUpdate=!1,this.layers=new U4,this.visible=!0,this.castShadow=!1,this.receiveShadow=!1,this.frustumCulled=!0,this.renderOrder=0,this.animations=[],this.userData={}}onBeforeRender(){}onAfterRender(){}applyMatrix4(e){this.matrixAutoUpdate&&this.updateMatrix(),this.matrix.premultiply(e),this.matrix.decompose(this.position,this.quaternion,this.scale)}applyQuaternion(e){return this.quaternion.premultiply(e),this}setRotationFromAxisAngle(e,t){this.quaternion.setFromAxisAngle(e,t)}setRotationFromEuler(e){this.quaternion.setFromEuler(e,!0)}setRotationFromMatrix(e){this.quaternion.setFromRotationMatrix(e)}setRotationFromQuaternion(e){this.quaternion.copy(e)}rotateOnAxis(e,t){return Kt.setFromAxisAngle(e,t),this.quaternion.multiply(Kt),this}rotateOnWorldAxis(e,t){return Kt.setFromAxisAngle(e,t),this.quaternion.premultiply(Kt),this}rotateX(e){return this.rotateOnAxis(N8,e)}rotateY(e){return this.rotateOnAxis(R8,e)}rotateZ(e){return this.rotateOnAxis(F8,e)}translateOnAxis(e,t){return V8.copy(e).applyQuaternion(this.quaternion),this.position.add(V8.multiplyScalar(t)),this}translateX(e){return this.translateOnAxis(N8,e)}translateY(e){return this.translateOnAxis(R8,e)}translateZ(e){return this.translateOnAxis(F8,e)}localToWorld(e){return e.applyMatrix4(this.matrixWorld)}worldToLocal(e){return e.applyMatrix4(je.copy(this.matrixWorld).invert())}lookAt(e,t,i){e.isVector3?O6.copy(e):O6.set(e,t,i);let a=this.parent;this.updateWorldMatrix(!0,!1),O4.setFromMatrixPosition(this.matrixWorld),this.isCamera||this.isLight?je.lookAt(O4,O6,this.up):je.lookAt(O6,O4,this.up),this.quaternion.setFromRotationMatrix(je),a&&(je.extractRotation(a.matrixWorld),Kt.setFromRotationMatrix(je),this.quaternion.premultiply(Kt.invert()))}add(e){if(arguments.length>1){for(let t=0;t1){for(let i=0;i0){a.children=[];for(let o=0;o0){a.animations=[];for(let o=0;o0&&(i.geometries=o),c.length>0&&(i.materials=c),l.length>0&&(i.textures=l),u.length>0&&(i.images=u),f.length>0&&(i.shapes=f),h.length>0&&(i.skeletons=h),m.length>0&&(i.animations=m)}return i.object=a,i;function s(o){let c=[];for(let l in o){let u=o[l];delete u.metadata,c.push(u)}return c}}clone(e){return new this.constructor().copy(this,e)}copy(e,t=!0){if(this.name=e.name,this.up.copy(e.up),this.position.copy(e.position),this.rotation.order=e.rotation.order,this.quaternion.copy(e.quaternion),this.scale.copy(e.scale),this.matrix.copy(e.matrix),this.matrixWorld.copy(e.matrixWorld),this.matrixAutoUpdate=e.matrixAutoUpdate,this.matrixWorldNeedsUpdate=e.matrixWorldNeedsUpdate,this.layers.mask=e.layers.mask,this.visible=e.visible,this.castShadow=e.castShadow,this.receiveShadow=e.receiveShadow,this.frustumCulled=e.frustumCulled,this.renderOrder=e.renderOrder,this.userData=JSON.parse(JSON.stringify(e.userData)),t===!0)for(let i=0;i=0;--e)if(n[e]>65535)return!0;return!1}function Dt(n){return document.createElementNS("http://www.w3.org/1999/xhtml",n)}var M9=0,q2=new U1,U3=new X1,Jt=new U,I2=new Ge,G4=new Ge,l2=new U,y2=class extends B2{constructor(){super();Object.defineProperty(this,"id",{value:M9++}),this.uuid=Ie(),this.name="",this.type="BufferGeometry",this.index=null,this.attributes={},this.morphAttributes={},this.morphTargetsRelative=!1,this.groups=[],this.boundingBox=null,this.boundingSphere=null,this.drawRange={start:0,count:1/0},this.userData={}}getIndex(){return this.index}setIndex(e){return Array.isArray(e)?this.index=new(G6(e)?I4:P4)(e,1):this.index=e,this}getAttribute(e){return this.attributes[e]}setAttribute(e,t){return this.attributes[e]=t,this}deleteAttribute(e){return delete this.attributes[e],this}hasAttribute(e){return this.attributes[e]!==void 0}addGroup(e,t,i=0){this.groups.push({start:e,count:t,materialIndex:i})}clearGroups(){this.groups=[]}setDrawRange(e,t){this.drawRange.start=e,this.drawRange.count=t}applyMatrix4(e){let t=this.attributes.position;t!==void 0&&(t.applyMatrix4(e),t.needsUpdate=!0);let i=this.attributes.normal;if(i!==void 0){let r=new s2().getNormalMatrix(e);i.applyNormalMatrix(r),i.needsUpdate=!0}let a=this.attributes.tangent;return a!==void 0&&(a.transformDirection(e),a.needsUpdate=!0),this.boundingBox!==null&&this.computeBoundingBox(),this.boundingSphere!==null&&this.computeBoundingSphere(),this}applyQuaternion(e){return q2.makeRotationFromQuaternion(e),this.applyMatrix4(q2),this}rotateX(e){return q2.makeRotationX(e),this.applyMatrix4(q2),this}rotateY(e){return q2.makeRotationY(e),this.applyMatrix4(q2),this}rotateZ(e){return q2.makeRotationZ(e),this.applyMatrix4(q2),this}translate(e,t,i){return q2.makeTranslation(e,t,i),this.applyMatrix4(q2),this}scale(e,t,i){return q2.makeScale(e,t,i),this.applyMatrix4(q2),this}lookAt(e){return U3.lookAt(e),U3.updateMatrix(),this.applyMatrix4(U3.matrix),this}center(){return this.computeBoundingBox(),this.boundingBox.getCenter(Jt).negate(),this.translate(Jt.x,Jt.y,Jt.z),this}setFromPoints(e){let t=[];for(let i=0,a=e.length;i0&&(e.userData=this.userData),this.parameters!==void 0){let c=this.parameters;for(let l in c)c[l]!==void 0&&(e[l]=c[l]);return e}e.data={attributes:{}};let t=this.index;t!==null&&(e.data.index={type:t.array.constructor.name,array:Array.prototype.slice.call(t.array)});let i=this.attributes;for(let c in i){let l=i[c];e.data.attributes[c]=l.toJSON(e.data)}let a={},r=!1;for(let c in this.morphAttributes){let l=this.morphAttributes[c],u=[];for(let f=0,h=l.length;f0&&(a[c]=u,r=!0)}r&&(e.data.morphAttributes=a,e.data.morphTargetsRelative=this.morphTargetsRelative);let s=this.groups;s.length>0&&(e.data.groups=JSON.parse(JSON.stringify(s)));let o=this.boundingSphere;return o!==null&&(e.data.boundingSphere={center:o.center.toArray(),radius:o.radius}),e}clone(){return new this.constructor().copy(this)}copy(e){this.index=null,this.attributes={},this.morphAttributes={},this.groups=[],this.boundingBox=null,this.boundingSphere=null;let t={};this.name=e.name;let i=e.index;i!==null&&this.setIndex(i.clone(t));let a=e.attributes;for(let l in a){let u=a[l];this.setAttribute(l,u.clone(t))}let r=e.morphAttributes;for(let l in r){let u=[],f=r[l];for(let h=0,m=f.length;h0!=e>0&&this.version++,this._alphaTest=e}onBuild(){}onBeforeRender(){}onBeforeCompile(){}customProgramCacheKey(){return this.onBeforeCompile.toString()}setValues(e){if(e!==void 0)for(let t in e){let i=e[t];if(i===void 0){console.warn("THREE.Material: '"+t+"' parameter is undefined.");continue}if(t==="shading"){console.warn("THREE."+this.type+": .shading has been removed. Use the boolean .flatShading instead."),this.flatShading=i===Br;continue}let a=this[t];if(a===void 0){console.warn("THREE."+this.type+": '"+t+"' is not a property of this material.");continue}a&&a.isColor?a.set(i):a&&a.isVector3&&i&&i.isVector3?a.copy(i):this[t]=i}}toJSON(e){let t=e===void 0||typeof e=="string";t&&(e={textures:{},images:{}});let i={metadata:{version:4.5,type:"Material",generator:"Material.toJSON"}};i.uuid=this.uuid,i.type=this.type,this.name!==""&&(i.name=this.name),this.color&&this.color.isColor&&(i.color=this.color.getHex()),this.roughness!==void 0&&(i.roughness=this.roughness),this.metalness!==void 0&&(i.metalness=this.metalness),this.sheen!==void 0&&(i.sheen=this.sheen),this.sheenColor&&this.sheenColor.isColor&&(i.sheenColor=this.sheenColor.getHex()),this.sheenRoughness!==void 0&&(i.sheenRoughness=this.sheenRoughness),this.emissive&&this.emissive.isColor&&(i.emissive=this.emissive.getHex()),this.emissiveIntensity&&this.emissiveIntensity!==1&&(i.emissiveIntensity=this.emissiveIntensity),this.specular&&this.specular.isColor&&(i.specular=this.specular.getHex()),this.specularIntensity!==void 0&&(i.specularIntensity=this.specularIntensity),this.specularColor&&this.specularColor.isColor&&(i.specularColor=this.specularColor.getHex()),this.shininess!==void 0&&(i.shininess=this.shininess),this.clearcoat!==void 0&&(i.clearcoat=this.clearcoat),this.clearcoatRoughness!==void 0&&(i.clearcoatRoughness=this.clearcoatRoughness),this.clearcoatMap&&this.clearcoatMap.isTexture&&(i.clearcoatMap=this.clearcoatMap.toJSON(e).uuid),this.clearcoatRoughnessMap&&this.clearcoatRoughnessMap.isTexture&&(i.clearcoatRoughnessMap=this.clearcoatRoughnessMap.toJSON(e).uuid),this.clearcoatNormalMap&&this.clearcoatNormalMap.isTexture&&(i.clearcoatNormalMap=this.clearcoatNormalMap.toJSON(e).uuid,i.clearcoatNormalScale=this.clearcoatNormalScale.toArray()),this.map&&this.map.isTexture&&(i.map=this.map.toJSON(e).uuid),this.matcap&&this.matcap.isTexture&&(i.matcap=this.matcap.toJSON(e).uuid),this.alphaMap&&this.alphaMap.isTexture&&(i.alphaMap=this.alphaMap.toJSON(e).uuid),this.lightMap&&this.lightMap.isTexture&&(i.lightMap=this.lightMap.toJSON(e).uuid,i.lightMapIntensity=this.lightMapIntensity),this.aoMap&&this.aoMap.isTexture&&(i.aoMap=this.aoMap.toJSON(e).uuid,i.aoMapIntensity=this.aoMapIntensity),this.bumpMap&&this.bumpMap.isTexture&&(i.bumpMap=this.bumpMap.toJSON(e).uuid,i.bumpScale=this.bumpScale),this.normalMap&&this.normalMap.isTexture&&(i.normalMap=this.normalMap.toJSON(e).uuid,i.normalMapType=this.normalMapType,i.normalScale=this.normalScale.toArray()),this.displacementMap&&this.displacementMap.isTexture&&(i.displacementMap=this.displacementMap.toJSON(e).uuid,i.displacementScale=this.displacementScale,i.displacementBias=this.displacementBias),this.roughnessMap&&this.roughnessMap.isTexture&&(i.roughnessMap=this.roughnessMap.toJSON(e).uuid),this.metalnessMap&&this.metalnessMap.isTexture&&(i.metalnessMap=this.metalnessMap.toJSON(e).uuid),this.emissiveMap&&this.emissiveMap.isTexture&&(i.emissiveMap=this.emissiveMap.toJSON(e).uuid),this.specularMap&&this.specularMap.isTexture&&(i.specularMap=this.specularMap.toJSON(e).uuid),this.specularIntensityMap&&this.specularIntensityMap.isTexture&&(i.specularIntensityMap=this.specularIntensityMap.toJSON(e).uuid),this.specularColorMap&&this.specularColorMap.isTexture&&(i.specularColorMap=this.specularColorMap.toJSON(e).uuid),this.envMap&&this.envMap.isTexture&&(i.envMap=this.envMap.toJSON(e).uuid,this.combine!==void 0&&(i.combine=this.combine)),this.envMapIntensity!==void 0&&(i.envMapIntensity=this.envMapIntensity),this.reflectivity!==void 0&&(i.reflectivity=this.reflectivity),this.refractionRatio!==void 0&&(i.refractionRatio=this.refractionRatio),this.gradientMap&&this.gradientMap.isTexture&&(i.gradientMap=this.gradientMap.toJSON(e).uuid),this.transmission!==void 0&&(i.transmission=this.transmission),this.transmissionMap&&this.transmissionMap.isTexture&&(i.transmissionMap=this.transmissionMap.toJSON(e).uuid),this.thickness!==void 0&&(i.thickness=this.thickness),this.thicknessMap&&this.thicknessMap.isTexture&&(i.thicknessMap=this.thicknessMap.toJSON(e).uuid),this.attenuationDistance!==void 0&&(i.attenuationDistance=this.attenuationDistance),this.attenuationColor!==void 0&&(i.attenuationColor=this.attenuationColor.getHex()),this.size!==void 0&&(i.size=this.size),this.shadowSide!==null&&(i.shadowSide=this.shadowSide),this.sizeAttenuation!==void 0&&(i.sizeAttenuation=this.sizeAttenuation),this.blending!==St&&(i.blending=this.blending),this.side!==ke&&(i.side=this.side),this.vertexColors&&(i.vertexColors=!0),this.opacity<1&&(i.opacity=this.opacity),this.transparent===!0&&(i.transparent=this.transparent),i.depthFunc=this.depthFunc,i.depthTest=this.depthTest,i.depthWrite=this.depthWrite,i.colorWrite=this.colorWrite,i.alphaWrite=this.alphaWrite,i.stencilWrite=this.stencilWrite,i.stencilWriteMask=this.stencilWriteMask,i.stencilFunc=this.stencilFunc,i.stencilRef=this.stencilRef,i.stencilFuncMask=this.stencilFuncMask,i.stencilFail=this.stencilFail,i.stencilZFail=this.stencilZFail,i.stencilZPass=this.stencilZPass,this.rotation&&this.rotation!==0&&(i.rotation=this.rotation),this.polygonOffset===!0&&(i.polygonOffset=!0),this.polygonOffsetFactor!==0&&(i.polygonOffsetFactor=this.polygonOffsetFactor),this.polygonOffsetUnits!==0&&(i.polygonOffsetUnits=this.polygonOffsetUnits),this.linewidth&&this.linewidth!==1&&(i.linewidth=this.linewidth),this.dashSize!==void 0&&(i.dashSize=this.dashSize),this.gapSize!==void 0&&(i.gapSize=this.gapSize),this.scale!==void 0&&(i.scale=this.scale),this.dithering===!0&&(i.dithering=!0),this.alphaTest>0&&(i.alphaTest=this.alphaTest),this.alphaToCoverage===!0&&(i.alphaToCoverage=this.alphaToCoverage),this.premultipliedAlpha===!0&&(i.premultipliedAlpha=this.premultipliedAlpha),this.wireframe===!0&&(i.wireframe=this.wireframe),this.wireframeLinewidth>1&&(i.wireframeLinewidth=this.wireframeLinewidth),this.wireframeLinecap!=="round"&&(i.wireframeLinecap=this.wireframeLinecap),this.wireframeLinejoin!=="round"&&(i.wireframeLinejoin=this.wireframeLinejoin),this.flatShading===!0&&(i.flatShading=this.flatShading),this.visible===!1&&(i.visible=!1),this.toneMapped===!1&&(i.toneMapped=!1),JSON.stringify(this.userData)!=="{}"&&(i.userData=this.userData);function a(r){let s=[];for(let o in r){let c=r[o];delete c.metadata,s.push(c)}return s}if(t){let r=a(e.textures),s=a(e.images);r.length>0&&(i.textures=r),s.length>0&&(i.images=s)}return i}clone(){return new this.constructor().copy(this)}copy(e){this.name=e.name,this.fog=e.fog,this.blending=e.blending,this.side=e.side,this.vertexColors=e.vertexColors,this.opacity=e.opacity,this.transparent=e.transparent,this.blendSrc=e.blendSrc,this.blendDst=e.blendDst,this.blendEquation=e.blendEquation,this.blendSrcAlpha=e.blendSrcAlpha,this.blendDstAlpha=e.blendDstAlpha,this.blendEquationAlpha=e.blendEquationAlpha,this.depthFunc=e.depthFunc,this.depthTest=e.depthTest,this.depthWrite=e.depthWrite,this.stencilWriteMask=e.stencilWriteMask,this.stencilFunc=e.stencilFunc,this.stencilRef=e.stencilRef,this.stencilFuncMask=e.stencilFuncMask,this.stencilFail=e.stencilFail,this.stencilZFail=e.stencilZFail,this.stencilZPass=e.stencilZPass,this.stencilWrite=e.stencilWrite;let t=e.clippingPlanes,i=null;if(t!==null){let a=t.length;i=new Array(a);for(let r=0;r!==a;++r)i[r]=t[r].clone()}return this.clippingPlanes=i,this.clipIntersection=e.clipIntersection,this.clipShadows=e.clipShadows,this.shadowSide=e.shadowSide,this.colorWrite=e.colorWrite,this.alphaWrite=e.alphaWrite,this.precision=e.precision,this.polygonOffset=e.polygonOffset,this.polygonOffsetFactor=e.polygonOffsetFactor,this.polygonOffsetUnits=e.polygonOffsetUnits,this.dithering=e.dithering,this.alphaTest=e.alphaTest,this.alphaToCoverage=e.alphaToCoverage,this.premultipliedAlpha=e.premultipliedAlpha,this.visible=e.visible,this.toneMapped=e.toneMapped,this.userData=JSON.parse(JSON.stringify(e.userData)),this}dispose(){this.dispatchEvent({type:"dispose"})}set needsUpdate(e){e===!0&&this.version++}};H2.prototype.isMaterial=!0;var q4=class extends H2{constructor(e){super();this.type="MeshPhongMaterial",this.color=new M1(16777215),this.specular=new M1(1118481),this.shininess=30,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new M1(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=R6,this.normalScale=new A1(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.combine=Wt,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.specular.copy(e.specular),this.shininess=e.shininess,this.map=e.map,this.lightMap=e.lightMap,this.lightMapIntensity=e.lightMapIntensity,this.aoMap=e.aoMap,this.aoMapIntensity=e.aoMapIntensity,this.emissive.copy(e.emissive),this.emissiveMap=e.emissiveMap,this.emissiveIntensity=e.emissiveIntensity,this.bumpMap=e.bumpMap,this.bumpScale=e.bumpScale,this.normalMap=e.normalMap,this.normalMapType=e.normalMapType,this.normalScale.copy(e.normalScale),this.displacementMap=e.displacementMap,this.displacementScale=e.displacementScale,this.displacementBias=e.displacementBias,this.specularMap=e.specularMap,this.alphaMap=e.alphaMap,this.envMap=e.envMap,this.combine=e.combine,this.reflectivity=e.reflectivity,this.refractionRatio=e.refractionRatio,this.wireframe=e.wireframe,this.wireframeLinewidth=e.wireframeLinewidth,this.wireframeLinecap=e.wireframeLinecap,this.wireframeLinejoin=e.wireframeLinejoin,this.flatShading=e.flatShading,this}};q4.prototype.isMeshPhongMaterial=!0;var Xe=new U,O3=new U,q6=new U,ht=new U,G3=new U,W6=new U,q3=new U,W3=class{constructor(e=new U,t=new U(0,0,-1)){this.origin=e,this.direction=t}set(e,t){return this.origin.copy(e),this.direction.copy(t),this}copy(e){return this.origin.copy(e.origin),this.direction.copy(e.direction),this}at(e,t){return t.copy(this.direction).multiplyScalar(e).add(this.origin)}lookAt(e){return this.direction.copy(e).sub(this.origin).normalize(),this}recast(e){return this.origin.copy(this.at(e,Xe)),this}closestPointToPoint(e,t){t.subVectors(e,this.origin);let i=t.dot(this.direction);return i<0?t.copy(this.origin):t.copy(this.direction).multiplyScalar(i).add(this.origin)}distanceToPoint(e){return Math.sqrt(this.distanceSqToPoint(e))}distanceSqToPoint(e){let t=Xe.subVectors(e,this.origin).dot(this.direction);return t<0?this.origin.distanceToSquared(e):(Xe.copy(this.direction).multiplyScalar(t).add(this.origin),Xe.distanceToSquared(e))}distanceSqToSegment(e,t,i,a){O3.copy(e).add(t).multiplyScalar(.5),q6.copy(t).sub(e).normalize(),ht.copy(this.origin).sub(O3);let r=e.distanceTo(t)*.5,s=-this.direction.dot(q6),o=ht.dot(this.direction),c=-ht.dot(q6),l=ht.lengthSq(),u=Math.abs(1-s*s),f,h,m,v;if(u>0)if(f=s*c-o,h=s*o-c,v=r*u,f>=0)if(h>=-v)if(h<=v){let g=1/u;f*=g,h*=g,m=f*(f+s*h+2*o)+h*(s*f+h+2*c)+l}else h=r,f=Math.max(0,-(s*h+o)),m=-f*f+h*(h+2*c)+l;else h=-r,f=Math.max(0,-(s*h+o)),m=-f*f+h*(h+2*c)+l;else h<=-v?(f=Math.max(0,-(-s*r+o)),h=f>0?-r:Math.min(Math.max(-r,-c),r),m=-f*f+h*(h+2*c)+l):h<=v?(f=0,h=Math.min(Math.max(-r,-c),r),m=h*(h+2*c)+l):(f=Math.max(0,-(s*r+o)),h=f>0?r:Math.min(Math.max(-r,-c),r),m=-f*f+h*(h+2*c)+l);else h=s>0?-r:r,f=Math.max(0,-(s*h+o)),m=-f*f+h*(h+2*c)+l;return i&&i.copy(this.direction).multiplyScalar(f).add(this.origin),a&&a.copy(q6).multiplyScalar(h).add(O3),m}intersectSphere(e,t){Xe.subVectors(e.center,this.origin);let i=Xe.dot(this.direction),a=Xe.dot(Xe)-i*i,r=e.radius*e.radius;if(a>r)return null;let s=Math.sqrt(r-a),o=i-s,c=i+s;return o<0&&c<0?null:o<0?this.at(c,t):this.at(o,t)}intersectsSphere(e){return this.distanceSqToPoint(e.center)<=e.radius*e.radius}distanceToPlane(e){let t=e.normal.dot(this.direction);if(t===0)return e.distanceToPoint(this.origin)===0?0:null;let i=-(this.origin.dot(e.normal)+e.constant)/t;return i>=0?i:null}intersectPlane(e,t){let i=this.distanceToPlane(e);return i===null?null:this.at(i,t)}intersectsPlane(e){let t=e.distanceToPoint(this.origin);return t===0||e.normal.dot(this.direction)*t<0}intersectBox(e,t){let i,a,r,s,o,c,l=1/this.direction.x,u=1/this.direction.y,f=1/this.direction.z,h=this.origin;return l>=0?(i=(e.min.x-h.x)*l,a=(e.max.x-h.x)*l):(i=(e.max.x-h.x)*l,a=(e.min.x-h.x)*l),u>=0?(r=(e.min.y-h.y)*u,s=(e.max.y-h.y)*u):(r=(e.max.y-h.y)*u,s=(e.min.y-h.y)*u),i>s||r>a||((r>i||i!==i)&&(i=r),(s=0?(o=(e.min.z-h.z)*f,c=(e.max.z-h.z)*f):(o=(e.max.z-h.z)*f,c=(e.min.z-h.z)*f),i>c||o>a)||((o>i||i!==i)&&(i=o),(c=0?i:a,t)}intersectsBox(e){return this.intersectBox(e,Xe)!==null}intersectTriangle(e,t,i,a,r){G3.subVectors(t,e),W6.subVectors(i,e),q3.crossVectors(G3,W6);let s=this.direction.dot(q3),o;if(s>0){if(a)return null;o=1}else if(s<0)o=-1,s=-s;else return null;ht.subVectors(this.origin,e);let c=o*this.direction.dot(W6.crossVectors(ht,W6));if(c<0)return null;let l=o*this.direction.dot(G3.cross(ht));if(l<0||c+l>s)return null;let u=-o*ht.dot(q3);return u<0?null:this.at(u/s,r)}applyMatrix4(e){return this.origin.applyMatrix4(e),this.direction.transformDirection(e),this}equals(e){return e.origin.equals(this.origin)&&e.direction.equals(this.direction)}clone(){return new this.constructor().copy(this)}};var ae=new U,Ze=new U,j3=new U,Ye=new U,Qt=new U,e4=new U,P8=new U,X3=new U,Z3=new U,Y3=new U,re=class{constructor(e=new U,t=new U,i=new U){this.a=e,this.b=t,this.c=i}static getNormal(e,t,i,a){a.subVectors(i,t),ae.subVectors(e,t),a.cross(ae);let r=a.lengthSq();return r>0?a.multiplyScalar(1/Math.sqrt(r)):a.set(0,0,0)}static getBarycoord(e,t,i,a,r){ae.subVectors(a,t),Ze.subVectors(i,t),j3.subVectors(e,t);let s=ae.dot(ae),o=ae.dot(Ze),c=ae.dot(j3),l=Ze.dot(Ze),u=Ze.dot(j3),f=s*l-o*o;if(f===0)return r.set(-2,-1,-1);let h=1/f,m=(l*c-o*u)*h,v=(s*u-o*c)*h;return r.set(1-m-v,v,m)}static containsPoint(e,t,i,a){return this.getBarycoord(e,t,i,a,Ye),Ye.x>=0&&Ye.y>=0&&Ye.x+Ye.y<=1}static getUV(e,t,i,a,r,s,o,c){return this.getBarycoord(e,t,i,a,Ye),c.set(0,0),c.addScaledVector(r,Ye.x),c.addScaledVector(s,Ye.y),c.addScaledVector(o,Ye.z),c}static isFrontFacing(e,t,i,a){return ae.subVectors(i,t),Ze.subVectors(e,t),ae.cross(Ze).dot(a)<0}set(e,t,i){return this.a.copy(e),this.b.copy(t),this.c.copy(i),this}setFromPointsAndIndices(e,t,i,a){return this.a.copy(e[t]),this.b.copy(e[i]),this.c.copy(e[a]),this}setFromAttributeAndIndices(e,t,i,a){return this.a.fromBufferAttribute(e,t),this.b.fromBufferAttribute(e,i),this.c.fromBufferAttribute(e,a),this}clone(){return new this.constructor().copy(this)}copy(e){return this.a.copy(e.a),this.b.copy(e.b),this.c.copy(e.c),this}getArea(){return ae.subVectors(this.c,this.b),Ze.subVectors(this.a,this.b),ae.cross(Ze).length()*.5}getMidpoint(e){return e.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)}getNormal(e){return re.getNormal(this.a,this.b,this.c,e)}getPlane(e){return e.setFromCoplanarPoints(this.a,this.b,this.c)}getBarycoord(e,t){return re.getBarycoord(e,this.a,this.b,this.c,t)}getUV(e,t,i,a,r){return re.getUV(e,this.a,this.b,this.c,t,i,a,r)}containsPoint(e){return re.containsPoint(e,this.a,this.b,this.c)}isFrontFacing(e){return re.isFrontFacing(this.a,this.b,this.c,e)}intersectsBox(e){return e.intersectsTriangle(this)}closestPointToPoint(e,t){let i=this.a,a=this.b,r=this.c,s,o;Qt.subVectors(a,i),e4.subVectors(r,i),X3.subVectors(e,i);let c=Qt.dot(X3),l=e4.dot(X3);if(c<=0&&l<=0)return t.copy(i);Z3.subVectors(e,a);let u=Qt.dot(Z3),f=e4.dot(Z3);if(u>=0&&f<=u)return t.copy(a);let h=c*f-u*l;if(h<=0&&c>=0&&u<=0)return s=c/(c-u),t.copy(i).addScaledVector(Qt,s);Y3.subVectors(e,r);let m=Qt.dot(Y3),v=e4.dot(Y3);if(v>=0&&m<=v)return t.copy(r);let g=m*l-c*v;if(g<=0&&l>=0&&v<=0)return o=l/(l-v),t.copy(i).addScaledVector(e4,o);let x=u*v-m*f;if(x<=0&&f-u>=0&&m-v>=0)return P8.subVectors(r,a),o=(f-u)/(f-u+(m-v)),t.copy(a).addScaledVector(P8,o);let p=1/(x+g+h);return s=g*p,o=h*p,t.copy(i).addScaledVector(Qt,s).addScaledVector(e4,o)}equals(e){return e.a.equals(this.a)&&e.b.equals(this.b)&&e.c.equals(this.c)}};var t4=class extends H2{constructor(e){super();this.type="MeshBasicMaterial",this.color=new M1(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.combine=Wt,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,this.lightMap=e.lightMap,this.lightMapIntensity=e.lightMapIntensity,this.aoMap=e.aoMap,this.aoMapIntensity=e.aoMapIntensity,this.specularMap=e.specularMap,this.alphaMap=e.alphaMap,this.envMap=e.envMap,this.combine=e.combine,this.reflectivity=e.reflectivity,this.refractionRatio=e.refractionRatio,this.wireframe=e.wireframe,this.wireframeLinewidth=e.wireframeLinewidth,this.wireframeLinecap=e.wireframeLinecap,this.wireframeLinejoin=e.wireframeLinejoin,this}};t4.prototype.isMeshBasicMaterial=!0;var I8=new U1,i4=new W3,$3=new We,ft=new U,dt=new U,pt=new U,K3=new U,J3=new U,Q3=new U,j6=new U,X6=new U,Z6=new U,Y6=new A1,$6=new A1,K6=new A1,ei=new U,J6=new U,u2=class extends X1{constructor(e=new y2,t=new t4){super();this.type="Mesh",this.geometry=e,this.material=t,this.updateMorphTargets()}copy(e){return super.copy(e),e.morphTargetInfluences!==void 0&&(this.morphTargetInfluences=e.morphTargetInfluences.slice()),e.morphTargetDictionary!==void 0&&(this.morphTargetDictionary=Object.assign({},e.morphTargetDictionary)),this.material=e.material,this.geometry=e.geometry,this}updateMorphTargets(){let e=this.geometry;if(e.isBufferGeometry){let t=e.morphAttributes,i=Object.keys(t);if(i.length>0){let a=t[i[0]];if(a!==void 0){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let r=0,s=a.length;r0&&console.error("THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.")}}raycast(e,t){let i=this.geometry,a=this.material,r=this.matrixWorld;if(a===void 0||(i.boundingSphere===null&&i.computeBoundingSphere(),$3.copy(i.boundingSphere),$3.applyMatrix4(r),e.ray.intersectsSphere($3)===!1)||(I8.copy(r).invert(),i4.copy(e.ray).applyMatrix4(I8),i.boundingBox!==null&&i4.intersectsBox(i.boundingBox)===!1))return;let s;if(i.isBufferGeometry){let o=i.index,c=i.attributes.position,l=i.morphAttributes.position,u=i.morphTargetsRelative,f=i.attributes.uv,h=i.attributes.uv2,m=i.groups,v=i.drawRange;if(o!==null)if(Array.isArray(a))for(let g=0,x=m.length;gt.far?null:{distance:l,point:J6.clone(),object:n}}function Q6(n,e,t,i,a,r,s,o,c,l,u,f){ft.fromBufferAttribute(a,l),dt.fromBufferAttribute(a,u),pt.fromBufferAttribute(a,f);let h=n.morphTargetInfluences;if(r&&h){j6.set(0,0,0),X6.set(0,0,0),Z6.set(0,0,0);for(let v=0,g=r.length;v2048||t.height>2048?(console.warn("THREE.ImageUtils.getDataURL: Image converted to jpg for performance reasons",e),t.toDataURL("image/jpeg",.6)):t.toDataURL("image/png")}static sRGBToLinear(e){if(typeof HTMLImageElement!="undefined"&&e instanceof HTMLImageElement||typeof HTMLCanvasElement!="undefined"&&e instanceof HTMLCanvasElement||typeof ImageBitmap!="undefined"&&e instanceof ImageBitmap){let t=Dt("canvas");t.width=e.width,t.height=e.height;let i=t.getContext("2d");i.drawImage(e,0,0,e.width,e.height);let a=i.getImageData(0,0,e.width,e.height),r=a.data;for(let s=0;s1)switch(this.wrapS){case R4:e.x=e.x-Math.floor(e.x);break;case c2:e.x=e.x<0?0:1;break;case F4:Math.abs(Math.floor(e.x)%2)===1?e.x=Math.ceil(e.x)-e.x:e.x=e.x-Math.floor(e.x);break}if(e.y<0||e.y>1)switch(this.wrapT){case R4:e.y=e.y-Math.floor(e.y);break;case c2:e.y=e.y<0?0:1;break;case F4:Math.abs(Math.floor(e.y)%2)===1?e.y=Math.ceil(e.y)-e.y:e.y=e.y-Math.floor(e.y);break}return this.flipY&&(e.y=1-e.y),e}set needsUpdate(e){e===!0&&this.version++}};J1.DEFAULT_IMAGE=void 0;J1.DEFAULT_MAPPING=f3;J1.prototype.isTexture=!0;function ti(n){return typeof HTMLImageElement!="undefined"&&n instanceof HTMLImageElement||typeof HTMLCanvasElement!="undefined"&&n instanceof HTMLCanvasElement||typeof ImageBitmap!="undefined"&&n instanceof ImageBitmap?W4.getDataURL(n):n.data?{data:Array.prototype.slice.call(n.data),width:n.width,height:n.height,type:n.data.constructor.name}:(console.warn("THREE.Texture: Unable to serialize Texture."),{})}var k8={specular:1515554,color:15790320,shininess:60,flatShading:!0},W2={diceColor:"#202020",textColor:"#ffffff"},ne=class{constructor(e,t,i={diceColor:"#202020",textColor:"#aaaaaa"}){this.w=e;this.h=t;this.options=i;C(this,"body");C(this,"chamferGeometry");C(this,"geometry");C(this,"scale",50);C(this,"shape");C(this,"labels",[" ","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"]);C(this,"shapeData");C(this,"fontFace","Arial");C(this,"textureSize");this.options={...W2,...i}}setColor({diceColor:e,textColor:t}){e&&(this.options.diceColor=e),t&&(this.options.textColor=t)}get radius(){return this.scale*this.scaleFactor}get diceColor(){return this.options.diceColor}get textColor(){return this.options.textColor}get buffer(){return this.geometry.geometry}create(){this.textureSize=this.calculateTextureSize(this.scale/2+this.scale*this.margin)*2;let e=this.getGeometry(),t=this.getMaterials();return this.geometry=new u2(e,t),this.geometry.receiveShadow=!0,this.geometry.castShadow=!0,this.body.position.set(0+this.radius*2*Math.random(),0+this.radius*2*Math.random(),0+this.radius*4),this.body.velocity.x=500*Math.random()*2-1,this.body.velocity.y=500*Math.random()*2-1,this.body.angularVelocity.x=100*Math.random(),this.body.angularVelocity.y=100*Math.random(),this}getGeometry(){let e=new Array(this.vertices.length);for(let i=0;i=0&&u=0&&l!==c+1?o.unshift([r,l],[s,u]):o.push([r,l],[s,u]),c=l)}o.length===4&&i.push([i[o[0][0]][o[0][1]],i[o[1][0]][o[1][1]],i[o[3][0]][o[3][1]],i[o[2][0]][o[2][1]],-1])}for(let r=0;r=0&&u<4){--u==-1&&(u=3);let f=i[l][u];if(s.indexOf(f)>=0){o.push(f);break}}}--c}o.push(-1),i.push(o)}return{vectors:t,faces:i}}makeGeometry(e,t){let i=new y2;for(let f=0;f1&&(o=o/l.length,s.font=`${o}pt '${this.fontFace}'`,c=s.measureText("M").width*1.2,a-=c*l.length/2);for(let f=0,h=l.length;f0?-1:1)*.9,y:this.h*(r.y>0?-1:1)*.9,z:Math.random()*200+200},o=Math.abs(r.x/r.y);o>1?s.y/=o:s.x*=o;let c=this.makeRandomVector(a),l={x:c.x*i,y:c.y*i,z:-10},u={x:-(Math.random()*r.y*5+this.inertia*r.y),y:Math.random()*r.x*5+this.inertia*r.x,z:0},f={x:Math.random(),y:Math.random(),z:Math.random(),w:Math.random()};return{pos:s,velocity:l,angular:u,axis:f}}makeRandomVector(e){let t=Math.random()*Math.PI/5-Math.PI/5/2,i={x:e.x*Math.cos(t)-e.y*Math.sin(t),y:e.x*Math.sin(t)+e.y*Math.cos(t)};return i.x==0&&(i.x=.01),i.y==0&&(i.y=.01),i}get buffer(){return this.geometry.geometry}get result(){return this.getUpsideValue()}getUpsideValue(){let e=new U(0,0,this.sides==4?-1:1),t,i=Math.PI*2,a=this.buffer.getAttribute("normal").array;for(let s=0,o=this.buffer.groups.length;sthis.sides;)s-=this.sides;for(;s<1;)s+=this.sides;t.groups[a].materialIndex=s+1}}this.updateMaterialsForValue(e-i),this.geometry.geometry=t}resetBody(){this.body.vlambda=new y,this.body.position=new y,this.body.previousPosition=new y,this.body.initPosition=new y,this.body.velocity=new y,this.body.initVelocity=new y,this.body.force=new y,this.body.torque=new y,this.body.quaternion=new G1,this.body.initQuaternion=new G1,this.body.angularVelocity=new y,this.body.initAngularVelocity=new y,this.body.interpolatedPosition=new y,this.body.interpolatedQuaternion=new G1,this.body.inertia=new y,this.body.invInertia=new y,this.body.invInertiaWorld=new E2,this.body.invInertiaSolve=new y,this.body.invInertiaWorldSolve=new E2,this.body.wlambda=new y,this.body.updateMassProperties()}updateMaterialsForValue(e){}set(){this.geometry.position.set(this.body.position.x,this.body.position.y,this.body.position.z),this.geometry.quaternion.set(this.body.quaternion.x,this.body.quaternion.y,this.body.quaternion.z,this.body.quaternion.w)}create(){this.body.position.set(this.vector.pos.x,this.vector.pos.y,this.vector.pos.z),this.body.quaternion.setFromAxisAngle(new y(this.vector.axis.x,this.vector.axis.y,this.vector.axis.z),this.vector.axis.w*Math.PI*2),this.body.angularVelocity.set(this.vector.angular.x,this.vector.angular.y,this.vector.angular.z),this.body.velocity.set(this.vector.velocity.x,this.vector.velocity.y,this.vector.velocity.z),this.body.linearDamping=.1,this.body.angularDamping=.1}},Mi=class extends Tt{constructor(e,t,i,a){super(e,t,i);this.w=e;this.h=t;this.data=i;C(this,"sides",20);C(this,"inertia",6);a&&(this.vector=this.generateVector(a)),this.create()}},bi=class extends Tt{constructor(e,t,i,a){super(e,t,i);this.w=e;this.h=t;this.data=i;C(this,"sides",12);C(this,"inertia",8);a&&(this.vector=this.generateVector(a)),this.create()}},Ht=class extends Tt{constructor(e,t,i,a,r=!1){super(e,t,i);this.w=e;this.h=t;this.data=i;this.isPercentile=r;C(this,"sides",10);C(this,"inertia",9);a&&(this.vector=this.generateVector(a)),this.create()}},yi=class extends Tt{constructor(e,t,i,a){super(e,t,i);this.w=e;this.h=t;this.data=i;C(this,"sides",8);C(this,"inertia",10);a&&(this.vector=this.generateVector(a)),this.create()}},Ci=class extends Tt{constructor(e,t,i,a){super(e,t,i);this.w=e;this.h=t;this.data=i;C(this,"sides",6);C(this,"inertia",13);a&&(this.vector=this.generateVector(a)),this.create()}},zi=class extends Tt{constructor(e,t,i,a){super(e,t,i);this.w=e;this.h=t;this.data=i;C(this,"sides",4);C(this,"inertia",5);a&&(this.vector=this.generateVector(a)),this.create()}};var Ai=new U,A9=new U,w9=new s2,se=class{constructor(e=new U(1,0,0),t=0){this.normal=e,this.constant=t}set(e,t){return this.normal.copy(e),this.constant=t,this}setComponents(e,t,i,a){return this.normal.set(e,t,i),this.constant=a,this}setFromNormalAndCoplanarPoint(e,t){return this.normal.copy(e),this.constant=-t.dot(this.normal),this}setFromCoplanarPoints(e,t,i){let a=Ai.subVectors(i,t).cross(A9.subVectors(e,t)).normalize();return this.setFromNormalAndCoplanarPoint(a,e),this}copy(e){return this.normal.copy(e.normal),this.constant=e.constant,this}normalize(){let e=1/this.normal.length();return this.normal.multiplyScalar(e),this.constant*=e,this}negate(){return this.constant*=-1,this.normal.negate(),this}distanceToPoint(e){return this.normal.dot(e)+this.constant}distanceToSphere(e){return this.distanceToPoint(e.center)-e.radius}projectPoint(e,t){return t.copy(this.normal).multiplyScalar(-this.distanceToPoint(e)).add(e)}intersectLine(e,t){let i=e.delta(Ai),a=this.normal.dot(i);if(a===0)return this.distanceToPoint(e.start)===0?t.copy(e.start):null;let r=-(e.start.dot(this.normal)+this.constant)/a;return r<0||r>1?null:t.copy(i).multiplyScalar(r).add(e.start)}intersectsLine(e){let t=this.distanceToPoint(e.start),i=this.distanceToPoint(e.end);return t<0&&i>0||i<0&&t>0}intersectsBox(e){return e.intersectsPlane(this)}intersectsSphere(e){return e.intersectsPlane(this)}coplanarPoint(e){return e.copy(this.normal).multiplyScalar(-this.constant)}applyMatrix4(e,t){let i=t||w9.getNormalMatrix(e),a=this.coplanarPoint(Ai).applyMatrix4(e),r=this.normal.applyMatrix3(i).normalize();return this.constant=-a.dot(r),this}translate(e){return this.constant-=e.dot(this.normal),this}equals(e){return e.normal.equals(this.normal)&&e.constant===this.constant}clone(){return new this.constructor().copy(this)}};se.prototype.isPlane=!0;var r4=new We,t0=new U,Vt=class{constructor(e=new se,t=new se,i=new se,a=new se,r=new se,s=new se){this.planes=[e,t,i,a,r,s]}set(e,t,i,a,r,s){let o=this.planes;return o[0].copy(e),o[1].copy(t),o[2].copy(i),o[3].copy(a),o[4].copy(r),o[5].copy(s),this}copy(e){let t=this.planes;for(let i=0;i<6;i++)t[i].copy(e.planes[i]);return this}setFromProjectionMatrix(e){let t=this.planes,i=e.elements,a=i[0],r=i[1],s=i[2],o=i[3],c=i[4],l=i[5],u=i[6],f=i[7],h=i[8],m=i[9],v=i[10],g=i[11],x=i[12],p=i[13],d=i[14],w=i[15];return t[0].setComponents(o-a,f-c,g-h,w-x).normalize(),t[1].setComponents(o+a,f+c,g+h,w+x).normalize(),t[2].setComponents(o+r,f+l,g+m,w+p).normalize(),t[3].setComponents(o-r,f-l,g-m,w-p).normalize(),t[4].setComponents(o-s,f-u,g-v,w-d).normalize(),t[5].setComponents(o+s,f+u,g+v,w+d).normalize(),this}intersectsObject(e){let t=e.geometry;return t.boundingSphere===null&&t.computeBoundingSphere(),r4.copy(t.boundingSphere).applyMatrix4(e.matrixWorld),this.intersectsSphere(r4)}intersectsSprite(e){return r4.center.set(0,0,0),r4.radius=.7071067811865476,r4.applyMatrix4(e.matrixWorld),this.intersectsSphere(r4)}intersectsSphere(e){let t=this.planes,i=e.center,a=-e.radius;for(let r=0;r<6;r++)if(t[r].distanceToPoint(i)0?e.max.x:e.min.x,t0.y=a.normal.y>0?e.max.y:e.min.y,t0.z=a.normal.z>0?e.max.z:e.min.z,a.distanceToPoint(t0)<0)return!1}return!0}containsPoint(e){let t=this.planes;for(let i=0;i<6;i++)if(t[i].distanceToPoint(e)<0)return!1;return!0}clone(){return new this.constructor().copy(this)}};function i0(){let n=null,e=!1,t=null,i=null;function a(r,s){t(r,s),i=n.requestAnimationFrame(a)}return{start:function(){e!==!0&&t!==null&&(i=n.requestAnimationFrame(a),e=!0)},stop:function(){n.cancelAnimationFrame(i),e=!1},setAnimationLoop:function(r){t=r},setContext:function(r){n=r}}}function U8(n,e){let t=e.isWebGL2,i=new WeakMap;function a(l,u){let f=l.array,h=l.usage,m=n.createBuffer();n.bindBuffer(u,m),n.bufferData(u,f,h),l.onUploadCallback();let v=n.FLOAT;return f instanceof Float32Array?v=n.FLOAT:f instanceof Float64Array?console.warn("THREE.WebGLAttributes: Unsupported data buffer format: Float64Array."):f instanceof Uint16Array?l.isFloat16BufferAttribute?t?v=n.HALF_FLOAT:console.warn("THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2."):v=n.UNSIGNED_SHORT:f instanceof Int16Array?v=n.SHORT:f instanceof Uint32Array?v=n.UNSIGNED_INT:f instanceof Int32Array?v=n.INT:f instanceof Int8Array?v=n.BYTE:(f instanceof Uint8Array||f instanceof Uint8ClampedArray)&&(v=n.UNSIGNED_BYTE),{buffer:m,type:v,bytesPerElement:f.BYTES_PER_ELEMENT,version:l.version}}function r(l,u,f){let h=u.array,m=u.updateRange;n.bindBuffer(f,l),m.count===-1?n.bufferSubData(f,0,h):(t?n.bufferSubData(f,m.offset*h.BYTES_PER_ELEMENT,h,m.offset,m.count):n.bufferSubData(f,m.offset*h.BYTES_PER_ELEMENT,h.subarray(m.offset,m.offset+m.count)),m.count=-1)}function s(l){return l.isInterleavedBufferAttribute&&(l=l.data),i.get(l)}function o(l){l.isInterleavedBufferAttribute&&(l=l.data);let u=i.get(l);u&&(n.deleteBuffer(u.buffer),i.delete(l))}function c(l,u){if(l.isGLBufferAttribute){let h=i.get(l);(!h||h.version0?1:-1,u.push(Y.x,Y.y,Y.z),f.push(Z/H),f.push(1-G/E),R+=1}}for(let G=0;G0&&(t.defines=this.defines),t.vertexShader=this.vertexShader,t.fragmentShader=this.fragmentShader;let i={};for(let a in this.extensions)this.extensions[a]===!0&&(i[a]=!0);return Object.keys(i).length>0&&(t.extensions=i),t}};oe.prototype.isShaderMaterial=!0;var W8=`
#ifdef USE_ALPHAMAP
diffuseColor.a *= texture2D( alphaMap, vUv ).g;
#endif
`;var j8=`
#ifdef USE_ALPHAMAP
uniform sampler2D alphaMap;
#endif
`;var X8=`
#ifdef USE_ALPHATEST
if ( diffuseColor.a < alphaTest ) discard;
#endif
`;var Z8=`
#ifdef USE_ALPHATEST
uniform float alphaTest;
#endif
`;var Y8=`
#ifdef USE_AOMAP
// reads channel R, compatible with a combined OcclusionRoughnessMetallic (RGB) texture
float ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;
reflectedLight.indirectDiffuse *= ambientOcclusion;
#if defined( USE_ENVMAP ) && defined( STANDARD )
float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );
#endif
#endif
`;var $8=`
#ifdef USE_AOMAP
uniform sampler2D aoMap;
uniform float aoMapIntensity;
#endif
`;var K8=`
vec3 transformed = vec3( position );
`;var J8=`
vec3 objectNormal = vec3( normal );
#ifdef USE_TANGENT
vec3 objectTangent = vec3( tangent.xyz );
#endif
`;var Q8=`
vec3 BRDF_Lambert( const in vec3 diffuseColor ) {
return RECIPROCAL_PI * diffuseColor;
} // validated
vec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {
// Original approximation by Christophe Schlick '94
// float fresnel = pow( 1.0 - dotVH, 5.0 );
// Optimized variant (presented by Epic at SIGGRAPH '13)
// https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
float fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );
return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );
} // validated
// Moving Frostbite to Physically Based Rendering 3.0 - page 12, listing 2
// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
float V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {
float a2 = pow2( alpha );
float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );
float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );
return 0.5 / max( gv + gl, EPSILON );
}
// Microfacet Models for Refraction through Rough Surfaces - equation (33)
// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
// alpha is "roughness squared" in Disney\u2019s reparameterization
float D_GGX( const in float alpha, const in float dotNH ) {
float a2 = pow2( alpha );
float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1
return RECIPROCAL_PI * a2 / pow2( denom );
}
// GGX Distribution, Schlick Fresnel, GGX_SmithCorrelated Visibility
vec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {
float alpha = pow2( roughness ); // UE4's roughness
vec3 halfDir = normalize( lightDir + viewDir );
float dotNL = saturate( dot( normal, lightDir ) );
float dotNV = saturate( dot( normal, viewDir ) );
float dotNH = saturate( dot( normal, halfDir ) );
float dotVH = saturate( dot( viewDir, halfDir ) );
vec3 F = F_Schlick( f0, f90, dotVH );
float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );
float D = D_GGX( alpha, dotNH );
return F * ( V * D );
}
// Rect Area Light
// Real-Time Polygonal-Light Shading with Linearly Transformed Cosines
// by Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt
// code: https://github.com/selfshadow/ltc_code/
vec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {
const float LUT_SIZE = 64.0;
const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;
const float LUT_BIAS = 0.5 / LUT_SIZE;
float dotNV = saturate( dot( N, V ) );
// texture parameterized by sqrt( GGX alpha ) and sqrt( 1 - cos( theta ) )
vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );
uv = uv * LUT_SCALE + LUT_BIAS;
return uv;
}
float LTC_ClippedSphereFormFactor( const in vec3 f ) {
// Real-Time Area Lighting: a Journey from Research to Production (p.102)
// An approximation of the form factor of a horizon-clipped rectangle.
float l = length( f );
return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );
}
vec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {
float x = dot( v1, v2 );
float y = abs( x );
// rational polynomial approximation to theta / sin( theta ) / 2PI
float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;
float b = 3.4175940 + ( 4.1616724 + y ) * y;
float v = a / b;
float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;
return cross( v1, v2 ) * theta_sintheta;
}
vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {
// bail if point is on back side of plane of light
// assumes ccw winding order of light vertices
vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];
vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];
vec3 lightNormal = cross( v1, v2 );
if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );
// construct orthonormal basis around N
vec3 T1, T2;
T1 = normalize( V - N * dot( V, N ) );
T2 = - cross( N, T1 ); // negated from paper; possibly due to a different handedness of world coordinate system
// compute transform
mat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );
// transform rect
vec3 coords[ 4 ];
coords[ 0 ] = mat * ( rectCoords[ 0 ] - P );
coords[ 1 ] = mat * ( rectCoords[ 1 ] - P );
coords[ 2 ] = mat * ( rectCoords[ 2 ] - P );
coords[ 3 ] = mat * ( rectCoords[ 3 ] - P );
// project rect onto sphere
coords[ 0 ] = normalize( coords[ 0 ] );
coords[ 1 ] = normalize( coords[ 1 ] );
coords[ 2 ] = normalize( coords[ 2 ] );
coords[ 3 ] = normalize( coords[ 3 ] );
// calculate vector form factor
vec3 vectorFormFactor = vec3( 0.0 );
vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );
vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );
vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );
vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );
// adjust for horizon clipping
float result = LTC_ClippedSphereFormFactor( vectorFormFactor );
/*
// alternate method of adjusting for horizon clipping (see referece)
// refactoring required
float len = length( vectorFormFactor );
float z = vectorFormFactor.z / len;
const float LUT_SIZE = 64.0;
const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;
const float LUT_BIAS = 0.5 / LUT_SIZE;
// tabulated horizon-clipped sphere, apparently...
vec2 uv = vec2( z * 0.5 + 0.5, len );
uv = uv * LUT_SCALE + LUT_BIAS;
float scale = texture2D( ltc_2, uv ).w;
float result = len * scale;
*/
return vec3( result );
}
// End Rect Area Light
float G_BlinnPhong_Implicit( /* const in float dotNL, const in float dotNV */ ) {
// geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v)
return 0.25;
}
float D_BlinnPhong( const in float shininess, const in float dotNH ) {
return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );
}
vec3 BRDF_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {
vec3 halfDir = normalize( lightDir + viewDir );
float dotNH = saturate( dot( normal, halfDir ) );
float dotVH = saturate( dot( viewDir, halfDir ) );
vec3 F = F_Schlick( specularColor, 1.0, dotVH );
float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ );
float D = D_BlinnPhong( shininess, dotNH );
return F * ( G * D );
} // validated
#if defined( USE_SHEEN )
// https://github.com/google/filament/blob/master/shaders/src/brdf.fs
float D_Charlie( float roughness, float dotNH ) {
float alpha = pow2( roughness );
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"
float invAlpha = 1.0 / alpha;
float cos2h = dotNH * dotNH;
float sin2h = max( 1.0 - cos2h, 0.0078125 ); // 2^(-14/2), so sin2h^2 > 0 in fp16
return ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );
}
// https://github.com/google/filament/blob/master/shaders/src/brdf.fs
float V_Neubelt( float dotNV, float dotNL ) {
// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
return saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );
}
vec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {
vec3 halfDir = normalize( lightDir + viewDir );
float dotNL = saturate( dot( normal, lightDir ) );
float dotNV = saturate( dot( normal, viewDir ) );
float dotNH = saturate( dot( normal, halfDir ) );
float D = D_Charlie( sheenRoughness, dotNH );
float V = V_Neubelt( dotNV, dotNL );
return sheenColor * ( D * V );
}
#endif
`;var en=`
#ifdef USE_BUMPMAP
uniform sampler2D bumpMap;
uniform float bumpScale;
// Bump Mapping Unparametrized Surfaces on the GPU by Morten S. Mikkelsen
// https://mmikk.github.io/papers3d/mm_sfgrad_bump.pdf
// Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)
vec2 dHdxy_fwd() {
vec2 dSTdx = dFdx( vUv );
vec2 dSTdy = dFdy( vUv );
float Hll = bumpScale * texture2D( bumpMap, vUv ).x;
float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;
float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;
return vec2( dBx, dBy );
}
vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {
// Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988
vec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );
vec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );
vec3 vN = surf_norm; // normalized
vec3 R1 = cross( vSigmaY, vN );
vec3 R2 = cross( vN, vSigmaX );
float fDet = dot( vSigmaX, R1 ) * faceDirection;
vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );
return normalize( abs( fDet ) * surf_norm - vGrad );
}
#endif
`;var tn=`
#if NUM_CLIPPING_PLANES > 0
vec4 plane;
#pragma unroll_loop_start
for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {
plane = clippingPlanes[ i ];
if ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;
}
#pragma unroll_loop_end
#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES
bool clipped = true;
#pragma unroll_loop_start
for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {
plane = clippingPlanes[ i ];
clipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;
}
#pragma unroll_loop_end
if ( clipped ) discard;
#endif
#endif
`;var an=`
#if NUM_CLIPPING_PLANES > 0
varying vec3 vClipPosition;
uniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];
#endif
`;var rn=`
#if NUM_CLIPPING_PLANES > 0
varying vec3 vClipPosition;
#endif
`;var nn=`
#if NUM_CLIPPING_PLANES > 0
vClipPosition = - mvPosition.xyz;
#endif
`;var sn=`
#if defined( USE_COLOR_ALPHA )
diffuseColor *= vColor;
#elif defined( USE_COLOR )
diffuseColor.rgb *= vColor;
#endif
`;var on=`
#if defined( USE_COLOR_ALPHA )
varying vec4 vColor;
#elif defined( USE_COLOR )
varying vec3 vColor;
#endif
`;var cn=`
#if defined( USE_COLOR_ALPHA )
varying vec4 vColor;
#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )
varying vec3 vColor;
#endif
`;var ln=`
#if defined( USE_COLOR_ALPHA )
vColor = vec4( 1.0 );
#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )
vColor = vec3( 1.0 );
#endif
#ifdef USE_COLOR
vColor *= color;
#endif
#ifdef USE_INSTANCING_COLOR
vColor.xyz *= instanceColor.xyz;
#endif
`;var un=`
#define PI 3.141592653589793
#define PI2 6.283185307179586
#define PI_HALF 1.5707963267948966
#define RECIPROCAL_PI 0.3183098861837907
#define RECIPROCAL_PI2 0.15915494309189535
#define EPSILON 1e-6
#ifndef saturate
// may have defined saturate() already
#define saturate( a ) clamp( a, 0.0, 1.0 )
#endif
#define whiteComplement( a ) ( 1.0 - saturate( a ) )
float pow2( const in float x ) { return x*x; }
float pow3( const in float x ) { return x*x*x; }
float pow4( const in float x ) { float x2 = x*x; return x2*x2; }
float max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }
float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }
// expects values in the range of [0,1]x[0,1], returns values in the [0,1] range.
// do not collapse into a single function per: http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
highp float rand( const in vec2 uv ) {
const highp float a = 12.9898, b = 78.233, c = 43758.5453;
highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );
return fract( sin( sn ) * c );
}
#ifdef HIGH_PRECISION
float precisionSafeLength( vec3 v ) { return length( v ); }
#else
float precisionSafeLength( vec3 v ) {
float maxComponent = max3( abs( v ) );
return length( v / maxComponent ) * maxComponent;
}
#endif
struct IncidentLight {
vec3 color;
vec3 direction;
bool visible;
};
struct ReflectedLight {
vec3 directDiffuse;
vec3 directSpecular;
vec3 indirectDiffuse;
vec3 indirectSpecular;
};
struct GeometricContext {
vec3 position;
vec3 normal;
vec3 viewDir;
#ifdef USE_CLEARCOAT
vec3 clearcoatNormal;
#endif
};
vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
}
vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {
// dir can be either a direction vector or a normal vector
// upper-left 3x3 of matrix is assumed to be orthogonal
return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );
}
mat3 transposeMat3( const in mat3 m ) {
mat3 tmp;
tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );
tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );
tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );
return tmp;
}
// https://en.wikipedia.org/wiki/Relative_luminance
float linearToRelativeLuminance( const in vec3 color ) {
vec3 weights = vec3( 0.2126, 0.7152, 0.0722 );
return dot( weights, color.rgb );
}
bool isPerspectiveMatrix( mat4 m ) {
return m[ 2 ][ 3 ] == - 1.0;
}
vec2 equirectUv( in vec3 dir ) {
// dir is assumed to be unit length
float u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;
float v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
return vec2( u, v );
}
`;var hn=`
#ifdef ENVMAP_TYPE_CUBE_UV
#define cubeUV_maxMipLevel 8.0
#define cubeUV_minMipLevel 4.0
#define cubeUV_maxTileSize 256.0
#define cubeUV_minTileSize 16.0
// These shader functions convert between the UV coordinates of a single face of
// a cubemap, the 0-5 integer index of a cube face, and the direction vector for
// sampling a textureCube (not generally normalized ).
float getFace( vec3 direction ) {
vec3 absDirection = abs( direction );
float face = - 1.0;
if ( absDirection.x > absDirection.z ) {
if ( absDirection.x > absDirection.y )
face = direction.x > 0.0 ? 0.0 : 3.0;
else
face = direction.y > 0.0 ? 1.0 : 4.0;
} else {
if ( absDirection.z > absDirection.y )
face = direction.z > 0.0 ? 2.0 : 5.0;
else
face = direction.y > 0.0 ? 1.0 : 4.0;
}
return face;
}
// RH coordinate system; PMREM face-indexing convention
vec2 getUV( vec3 direction, float face ) {
vec2 uv;
if ( face == 0.0 ) {
uv = vec2( direction.z, direction.y ) / abs( direction.x ); // pos x
} else if ( face == 1.0 ) {
uv = vec2( - direction.x, - direction.z ) / abs( direction.y ); // pos y
} else if ( face == 2.0 ) {
uv = vec2( - direction.x, direction.y ) / abs( direction.z ); // pos z
} else if ( face == 3.0 ) {
uv = vec2( - direction.z, direction.y ) / abs( direction.x ); // neg x
} else if ( face == 4.0 ) {
uv = vec2( - direction.x, direction.z ) / abs( direction.y ); // neg y
} else {
uv = vec2( direction.x, direction.y ) / abs( direction.z ); // neg z
}
return 0.5 * ( uv + 1.0 );
}
vec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {
float face = getFace( direction );
float filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );
mipInt = max( mipInt, cubeUV_minMipLevel );
float faceSize = exp2( mipInt );
float texelSize = 1.0 / ( 3.0 * cubeUV_maxTileSize );
vec2 uv = getUV( direction, face ) * ( faceSize - 1.0 ) + 0.5;
if ( face > 2.0 ) {
uv.y += faceSize;
face -= 3.0;
}
uv.x += face * faceSize;
if ( mipInt < cubeUV_maxMipLevel ) {
uv.y += 2.0 * cubeUV_maxTileSize;
}
uv.y += filterInt * 2.0 * cubeUV_minTileSize;
uv.x += 3.0 * max( 0.0, cubeUV_maxTileSize - 2.0 * faceSize );
uv *= texelSize;
return texture2D( envMap, uv ).rgb;
}
// These defines must match with PMREMGenerator
#define r0 1.0
#define v0 0.339
#define m0 - 2.0
#define r1 0.8
#define v1 0.276
#define m1 - 1.0
#define r4 0.4
#define v4 0.046
#define m4 2.0
#define r5 0.305
#define v5 0.016
#define m5 3.0
#define r6 0.21
#define v6 0.0038
#define m6 4.0
float roughnessToMip( float roughness ) {
float mip = 0.0;
if ( roughness >= r1 ) {
mip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0;
} else if ( roughness >= r4 ) {
mip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1;
} else if ( roughness >= r5 ) {
mip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4;
} else if ( roughness >= r6 ) {
mip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5;
} else {
mip = - 2.0 * log2( 1.16 * roughness ); // 1.16 = 1.79^0.25
}
return mip;
}
vec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {
float mip = clamp( roughnessToMip( roughness ), m0, cubeUV_maxMipLevel );
float mipF = fract( mip );
float mipInt = floor( mip );
vec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );
if ( mipF == 0.0 ) {
return vec4( color0, 1.0 );
} else {
vec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );
return vec4( mix( color0, color1, mipF ), 1.0 );
}
}
#endif
`;var fn=`
vec3 transformedNormal = objectNormal;
#ifdef USE_INSTANCING
// this is in lieu of a per-instance normal-matrix
// shear transforms in the instance matrix are not supported
mat3 m = mat3( instanceMatrix );
transformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );
transformedNormal = m * transformedNormal;
#endif
transformedNormal = normalMatrix * transformedNormal;
#ifdef FLIP_SIDED
transformedNormal = - transformedNormal;
#endif
#ifdef USE_TANGENT
vec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;
#ifdef FLIP_SIDED
transformedTangent = - transformedTangent;
#endif
#endif
`;var dn=`
#ifdef USE_DISPLACEMENTMAP
uniform sampler2D displacementMap;
uniform float displacementScale;
uniform float displacementBias;
#endif
`;var pn=`
#ifdef USE_DISPLACEMENTMAP
transformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );
#endif
`;var mn=`
#ifdef USE_EMISSIVEMAP
vec4 emissiveColor = texture2D( emissiveMap, vUv );
totalEmissiveRadiance *= emissiveColor.rgb;
#endif
`;var vn=`
#ifdef USE_EMISSIVEMAP
uniform sampler2D emissiveMap;
#endif
`;var gn=`
gl_FragColor = linearToOutputTexel( gl_FragColor );
`;var xn=`
vec4 LinearToLinear( in vec4 value ) {
return value;
}
vec4 LinearTosRGB( in vec4 value ) {
return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );
}
`;var Mn=`
#ifdef USE_ENVMAP
#ifdef ENV_WORLDPOS
vec3 cameraToFrag;
if ( isOrthographic ) {
cameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );
} else {
cameraToFrag = normalize( vWorldPosition - cameraPosition );
}
// Transforming Normal Vectors with the Inverse Transformation
vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
#ifdef ENVMAP_MODE_REFLECTION
vec3 reflectVec = reflect( cameraToFrag, worldNormal );
#else
vec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );
#endif
#else
vec3 reflectVec = vReflect;
#endif
#ifdef ENVMAP_TYPE_CUBE
vec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
#elif defined( ENVMAP_TYPE_CUBE_UV )
vec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );
#else
vec4 envColor = vec4( 0.0 );
#endif
#ifdef ENVMAP_BLENDING_MULTIPLY
outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );
#elif defined( ENVMAP_BLENDING_MIX )
outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );
#elif defined( ENVMAP_BLENDING_ADD )
outgoingLight += envColor.xyz * specularStrength * reflectivity;
#endif
#endif
`;var bn=`
#ifdef USE_ENVMAP
uniform float envMapIntensity;
uniform float flipEnvMap;
#ifdef ENVMAP_TYPE_CUBE
uniform samplerCube envMap;
#else
uniform sampler2D envMap;
#endif
#endif
`;var yn=`
#ifdef USE_ENVMAP
uniform float reflectivity;
#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )
#define ENV_WORLDPOS
#endif
#ifdef ENV_WORLDPOS
varying vec3 vWorldPosition;
uniform float refractionRatio;
#else
varying vec3 vReflect;
#endif
#endif
`;var Cn=`
#ifdef USE_ENVMAP
#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )
#define ENV_WORLDPOS
#endif
#ifdef ENV_WORLDPOS
varying vec3 vWorldPosition;
#else
varying vec3 vReflect;
uniform float refractionRatio;
#endif
#endif
`;var zn=`
#ifdef USE_ENVMAP
#ifdef ENV_WORLDPOS
vWorldPosition = worldPosition.xyz;
#else
vec3 cameraToVertex;
if ( isOrthographic ) {
cameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );
} else {
cameraToVertex = normalize( worldPosition.xyz - cameraPosition );
}
vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );
#ifdef ENVMAP_MODE_REFLECTION
vReflect = reflect( cameraToVertex, worldNormal );
#else
vReflect = refract( cameraToVertex, worldNormal, refractionRatio );
#endif
#endif
#endif
`;var An=`
#ifdef USE_FOG
vFogDepth = - mvPosition.z;
#endif
`;var wn=`
#ifdef USE_FOG
varying float vFogDepth;
#endif
`;var Sn=`
#ifdef USE_FOG
#ifdef FOG_EXP2
float fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );
#else
float fogFactor = smoothstep( fogNear, fogFar, vFogDepth );
#endif
gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );
#endif
`;var _n=`
#ifdef USE_FOG
uniform vec3 fogColor;
varying float vFogDepth;
#ifdef FOG_EXP2
uniform float fogDensity;
#else
uniform float fogNear;
uniform float fogFar;
#endif
#endif
`;var En=`
#ifdef USE_GRADIENTMAP
uniform sampler2D gradientMap;
#endif
vec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {
// dotNL will be from -1.0 to 1.0
float dotNL = dot( normal, lightDirection );
vec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );
#ifdef USE_GRADIENTMAP
return vec3( texture2D( gradientMap, coord ).r );
#else
return ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );
#endif
}
`;var Ln=`
#ifdef USE_LIGHTMAP
vec4 lightMapTexel = texture2D( lightMap, vUv2 );
vec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;
#ifndef PHYSICALLY_CORRECT_LIGHTS
lightMapIrradiance *= PI;
#endif
reflectedLight.indirectDiffuse += lightMapIrradiance;
#endif
`;var Dn=`
#ifdef USE_LIGHTMAP
uniform sampler2D lightMap;
uniform float lightMapIntensity;
#endif
`;var Tn=`
vec3 diffuse = vec3( 1.0 );
GeometricContext geometry;
geometry.position = mvPosition.xyz;
geometry.normal = normalize( transformedNormal );
geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );
GeometricContext backGeometry;
backGeometry.position = geometry.position;
backGeometry.normal = -geometry.normal;
backGeometry.viewDir = geometry.viewDir;
vLightFront = vec3( 0.0 );
vIndirectFront = vec3( 0.0 );
#ifdef DOUBLE_SIDED
vLightBack = vec3( 0.0 );
vIndirectBack = vec3( 0.0 );
#endif
IncidentLight directLight;
float dotNL;
vec3 directLightColor_Diffuse;
vIndirectFront += getAmbientLightIrradiance( ambientLightColor );
vIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal );
#ifdef DOUBLE_SIDED
vIndirectBack += getAmbientLightIrradiance( ambientLightColor );
vIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );
#endif
#if NUM_POINT_LIGHTS > 0
#pragma unroll_loop_start
for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {
getPointLightInfo( pointLights[ i ], geometry, directLight );
dotNL = dot( geometry.normal, directLight.direction );
directLightColor_Diffuse = directLight.color;
vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
#ifdef DOUBLE_SIDED
vLightBack += saturate( - dotNL ) * directLightColor_Diffuse;
#endif
}
#pragma unroll_loop_end
#endif
#if NUM_SPOT_LIGHTS > 0
#pragma unroll_loop_start
for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {
getSpotLightInfo( spotLights[ i ], geometry, directLight );
dotNL = dot( geometry.normal, directLight.direction );
directLightColor_Diffuse = directLight.color;
vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
#ifdef DOUBLE_SIDED
vLightBack += saturate( - dotNL ) * directLightColor_Diffuse;
#endif
}
#pragma unroll_loop_end
#endif
#if NUM_DIR_LIGHTS > 0
#pragma unroll_loop_start
for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
getDirectionalLightInfo( directionalLights[ i ], geometry, directLight );
dotNL = dot( geometry.normal, directLight.direction );
directLightColor_Diffuse = directLight.color;
vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
#ifdef DOUBLE_SIDED
vLightBack += saturate( - dotNL ) * directLightColor_Diffuse;
#endif
}
#pragma unroll_loop_end
#endif
#if NUM_HEMI_LIGHTS > 0
#pragma unroll_loop_start
for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {
vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );
#ifdef DOUBLE_SIDED
vIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );
#endif
}
#pragma unroll_loop_end
#endif
`;var Hn=`
uniform bool receiveShadow;
uniform vec3 ambientLightColor;
uniform vec3 lightProbe[ 9 ];
// get the irradiance (radiance convolved with cosine lobe) at the point 'normal' on the unit sphere
// source: https://graphics.stanford.edu/papers/envmap/envmap.pdf
vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {
// normal is assumed to have unit length
float x = normal.x, y = normal.y, z = normal.z;
// band 0
vec3 result = shCoefficients[ 0 ] * 0.886227;
// band 1
result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;
result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;
result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;
// band 2
result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;
result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;
result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );
result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;
result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );
return result;
}
vec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {
vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
vec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );
return irradiance;
}
vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
vec3 irradiance = ambientLightColor;
return irradiance;
}
float getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {
#if defined ( PHYSICALLY_CORRECT_LIGHTS )
// based upon Frostbite 3 Moving to Physically-based Rendering
// page 32, equation 26: E[window1]
// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );
if ( cutoffDistance > 0.0 ) {
distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );
}
return distanceFalloff;
#else
if ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {
return pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );
}
return 1.0;
#endif
}
float getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {
return smoothstep( coneCosine, penumbraCosine, angleCosine );
}
#if NUM_DIR_LIGHTS > 0
struct DirectionalLight {
vec3 direction;
vec3 color;
};
uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];
void getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {
light.color = directionalLight.color;
light.direction = directionalLight.direction;
light.visible = true;
}
#endif
#if NUM_POINT_LIGHTS > 0
struct PointLight {
vec3 position;
vec3 color;
float distance;
float decay;
};
uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
// light is an out parameter as having it as a return value caused compiler errors on some devices
void getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {
vec3 lVector = pointLight.position - geometry.position;
light.direction = normalize( lVector );
float lightDistance = length( lVector );
light.color = pointLight.color;
light.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );
light.visible = ( light.color != vec3( 0.0 ) );
}
#endif
#if NUM_SPOT_LIGHTS > 0
struct SpotLight {
vec3 position;
vec3 direction;
vec3 color;
float distance;
float decay;
float coneCos;
float penumbraCos;
};
uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];
// light is an out parameter as having it as a return value caused compiler errors on some devices
void getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {
vec3 lVector = spotLight.position - geometry.position;
light.direction = normalize( lVector );
float angleCos = dot( light.direction, spotLight.direction );
float spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );
if ( spotAttenuation > 0.0 ) {
float lightDistance = length( lVector );
light.color = spotLight.color * spotAttenuation;
light.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );
light.visible = ( light.color != vec3( 0.0 ) );
} else {
light.color = vec3( 0.0 );
light.visible = false;
}
}
#endif
#if NUM_RECT_AREA_LIGHTS > 0
struct RectAreaLight {
vec3 color;
vec3 position;
vec3 halfWidth;
vec3 halfHeight;
};
// Pre-computed values of LinearTransformedCosine approximation of BRDF
// BRDF approximation Texture is 64x64
uniform sampler2D ltc_1; // RGBA Float
uniform sampler2D ltc_2; // RGBA Float
uniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];
#endif
#if NUM_HEMI_LIGHTS > 0
struct HemisphereLight {
vec3 direction;
vec3 skyColor;
vec3 groundColor;
};
uniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];
vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {
float dotNL = dot( normal, hemiLight.direction );
float hemiDiffuseWeight = 0.5 * dotNL + 0.5;
vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );
return irradiance;
}
#endif
`;var Vn=`
#if defined( USE_ENVMAP )
#ifdef ENVMAP_MODE_REFRACTION
uniform float refractionRatio;
#endif
vec3 getIBLIrradiance( const in vec3 normal ) {
#if defined( ENVMAP_TYPE_CUBE_UV )
vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
vec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );
return PI * envMapColor.rgb * envMapIntensity;
#else
return vec3( 0.0 );
#endif
}
vec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {
#if defined( ENVMAP_TYPE_CUBE_UV )
vec3 reflectVec;
#ifdef ENVMAP_MODE_REFLECTION
reflectVec = reflect( - viewDir, normal );
// Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane.
reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );
#else
reflectVec = refract( - viewDir, normal, refractionRatio );
#endif
reflectVec = inverseTransformDirection( reflectVec, viewMatrix );
vec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );
return envMapColor.rgb * envMapIntensity;
#else
return vec3( 0.0 );
#endif
}
#endif
`;var Nn=`
ToonMaterial material;
material.diffuseColor = diffuseColor.rgb;
`;var Rn=`
varying vec3 vViewPosition;
struct ToonMaterial {
vec3 diffuseColor;
};
void RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {
vec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;
reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
}
void RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {
reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
}
#define RE_Direct RE_Direct_Toon
#define RE_IndirectDiffuse RE_IndirectDiffuse_Toon
#define Material_LightProbeLOD( material ) (0)
`;var Fn=`
BlinnPhongMaterial material;
material.diffuseColor = diffuseColor.rgb;
material.specularColor = specular;
material.specularShininess = shininess;
material.specularStrength = specularStrength;
`;var Bn=`
varying vec3 vViewPosition;
struct BlinnPhongMaterial {
vec3 diffuseColor;
vec3 specularColor;
float specularShininess;
float specularStrength;
};
void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
vec3 irradiance = dotNL * directLight.color;
reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularShininess ) * material.specularStrength;
}
void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
}
#define RE_Direct RE_Direct_BlinnPhong
#define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong
#define Material_LightProbeLOD( material ) (0)
`;var Pn=`
PhysicalMaterial material;
material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );
vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );
float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );
material.roughness = max( roughnessFactor, 0.0525 );// 0.0525 corresponds to the base mip of a 256 cubemap.
material.roughness += geometryRoughness;
material.roughness = min( material.roughness, 1.0 );
#ifdef IOR
#ifdef SPECULAR
float specularIntensityFactor = specularIntensity;
vec3 specularColorFactor = specularColor;
#ifdef USE_SPECULARINTENSITYMAP
specularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;
#endif
#ifdef USE_SPECULARCOLORMAP
specularColorFactor *= texture2D( specularColorMap, vUv ).rgb;
#endif
material.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );
#else
float specularIntensityFactor = 1.0;
vec3 specularColorFactor = vec3( 1.0 );
material.specularF90 = 1.0;
#endif
material.specularColor = mix( min( pow2( ( ior - 1.0 ) / ( ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );
#else
material.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );
material.specularF90 = 1.0;
#endif
#ifdef USE_CLEARCOAT
material.clearcoat = clearcoat;
material.clearcoatRoughness = clearcoatRoughness;
material.clearcoatF0 = vec3( 0.04 );
material.clearcoatF90 = 1.0;
#ifdef USE_CLEARCOATMAP
material.clearcoat *= texture2D( clearcoatMap, vUv ).x;
#endif
#ifdef USE_CLEARCOAT_ROUGHNESSMAP
material.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;
#endif
material.clearcoat = saturate( material.clearcoat ); // Burley clearcoat model
material.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );
material.clearcoatRoughness += geometryRoughness;
material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );
#endif
#ifdef USE_SHEEN
material.sheenColor = sheenColor;
#ifdef USE_SHEENCOLORMAP
material.sheenColor *= texture2D( sheenColorMap, vUv ).rgb;
#endif
material.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );
#ifdef USE_SHEENROUGHNESSMAP
material.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;
#endif
#endif
`;var In=`
struct PhysicalMaterial {
vec3 diffuseColor;
float roughness;
vec3 specularColor;
float specularF90;
#ifdef USE_CLEARCOAT
float clearcoat;
float clearcoatRoughness;
vec3 clearcoatF0;
float clearcoatF90;
#endif
#ifdef USE_SHEEN
vec3 sheenColor;
float sheenRoughness;
#endif
};
// temporary
vec3 clearcoatSpecular = vec3( 0.0 );
vec3 sheenSpecular = vec3( 0.0 );
// This is a curve-fit approxmation to the "Charlie sheen" BRDF integrated over the hemisphere from
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF". The analysis can be found
// in the Sheen section of https://drive.google.com/file/d/1T0D1VSyR4AllqIJTQAraEIzjlb5h4FKH/view?usp=sharing
float IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness) {
float dotNV = saturate( dot( normal, viewDir ) );
float r2 = roughness * roughness;
float a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;
float b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;
float DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );
return saturate( DG * RECIPROCAL_PI );
}
// Analytical approximation of the DFG LUT, one half of the
// split-sum approximation used in indirect specular lighting.
// via 'environmentBRDF' from "Physically Based Shading on Mobile"
// https://www.unrealengine.com/blog/physically-based-shading-on-mobile
vec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {
float dotNV = saturate( dot( normal, viewDir ) );
const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );
const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );
vec4 r = roughness * c0 + c1;
float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;
vec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;
return fab;
}
vec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {
vec2 fab = DFGApprox( normal, viewDir, roughness );
return specularColor * fab.x + specularF90 * fab.y;
}
// Fdez-Ag\xFCera's "Multiple-Scattering Microfacet Model for Real-Time Image Based Lighting"
// Approximates multiscattering in order to preserve energy.
// http://www.jcgt.org/published/0008/01/03/
void computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {
vec2 fab = DFGApprox( normal, viewDir, roughness );
vec3 FssEss = specularColor * fab.x + specularF90 * fab.y;
float Ess = fab.x + fab.y;
float Ems = 1.0 - Ess;
vec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619; // 1/21
vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );
singleScatter += FssEss;
multiScatter += Fms * Ems;
}
#if NUM_RECT_AREA_LIGHTS > 0
void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
vec3 normal = geometry.normal;
vec3 viewDir = geometry.viewDir;
vec3 position = geometry.position;
vec3 lightPos = rectAreaLight.position;
vec3 halfWidth = rectAreaLight.halfWidth;
vec3 halfHeight = rectAreaLight.halfHeight;
vec3 lightColor = rectAreaLight.color;
float roughness = material.roughness;
vec3 rectCoords[ 4 ];
rectCoords[ 0 ] = lightPos + halfWidth - halfHeight; // counterclockwise; light shines in local neg z direction
rectCoords[ 1 ] = lightPos - halfWidth - halfHeight;
rectCoords[ 2 ] = lightPos - halfWidth + halfHeight;
rectCoords[ 3 ] = lightPos + halfWidth + halfHeight;
vec2 uv = LTC_Uv( normal, viewDir, roughness );
vec4 t1 = texture2D( ltc_1, uv );
vec4 t2 = texture2D( ltc_2, uv );
mat3 mInv = mat3(
vec3( t1.x, 0, t1.y ),
vec3( 0, 1, 0 ),
vec3( t1.z, 0, t1.w )
);
// LTC Fresnel Approximation by Stephen Hill
// http://blog.selfshadow.com/publications/s2016-advances/s2016_ltc_fresnel.pdf
vec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );
reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );
reflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );
}
#endif
void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
vec3 irradiance = dotNL * directLight.color;
#ifdef USE_CLEARCOAT
float dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );
vec3 ccIrradiance = dotNLcc * directLight.color;
clearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );
#endif
#ifdef USE_SHEEN
sheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );
#endif
reflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );
reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
}
void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
}
void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {
#ifdef USE_CLEARCOAT
clearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );
#endif
#ifdef USE_SHEEN
sheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );
#endif
// Both indirect specular and indirect diffuse light accumulate here
vec3 singleScattering = vec3( 0.0 );
vec3 multiScattering = vec3( 0.0 );
vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;
computeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );
vec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );
reflectedLight.indirectSpecular += radiance * singleScattering;
reflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;
reflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;
}
#define RE_Direct RE_Direct_Physical
#define RE_Direct_RectArea RE_Direct_RectArea_Physical
#define RE_IndirectDiffuse RE_IndirectDiffuse_Physical
#define RE_IndirectSpecular RE_IndirectSpecular_Physical
// ref: https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
float computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {
return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );
}
`;var kn=`
/**
* This is a template that can be used to light a material, it uses pluggable
* RenderEquations (RE)for specific lighting scenarios.
*
* Instructions for use:
* - Ensure that both RE_Direct, RE_IndirectDiffuse and RE_IndirectSpecular are defined
* - If you have defined an RE_IndirectSpecular, you need to also provide a Material_LightProbeLOD. <---- ???
* - Create a material parameter that is to be passed as the third parameter to your lighting functions.
*
* TODO:
* - Add area light support.
* - Add sphere light support.
* - Add diffuse light probe (irradiance cubemap) support.
*/
GeometricContext geometry;
geometry.position = - vViewPosition;
geometry.normal = normal;
geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );
#ifdef USE_CLEARCOAT
geometry.clearcoatNormal = clearcoatNormal;
#endif
IncidentLight directLight;
#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )
PointLight pointLight;
#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0
PointLightShadow pointLightShadow;
#endif
#pragma unroll_loop_start
for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {
pointLight = pointLights[ i ];
getPointLightInfo( pointLight, geometry, directLight );
#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )
pointLightShadow = pointLightShadows[ i ];
directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;
#endif
RE_Direct( directLight, geometry, material, reflectedLight );
}
#pragma unroll_loop_end
#endif
#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )
SpotLight spotLight;
#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0
SpotLightShadow spotLightShadow;
#endif
#pragma unroll_loop_start
for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {
spotLight = spotLights[ i ];
getSpotLightInfo( spotLight, geometry, directLight );
#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )
spotLightShadow = spotLightShadows[ i ];
directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;
#endif
RE_Direct( directLight, geometry, material, reflectedLight );
}
#pragma unroll_loop_end
#endif
#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )
DirectionalLight directionalLight;
#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0
DirectionalLightShadow directionalLightShadow;
#endif
#pragma unroll_loop_start
for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
directionalLight = directionalLights[ i ];
getDirectionalLightInfo( directionalLight, geometry, directLight );
#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )
directionalLightShadow = directionalLightShadows[ i ];
directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
#endif
RE_Direct( directLight, geometry, material, reflectedLight );
}
#pragma unroll_loop_end
#endif
#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )
RectAreaLight rectAreaLight;
#pragma unroll_loop_start
for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {
rectAreaLight = rectAreaLights[ i ];
RE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );
}
#pragma unroll_loop_end
#endif
#if defined( RE_IndirectDiffuse )
vec3 iblIrradiance = vec3( 0.0 );
vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );
irradiance += getLightProbeIrradiance( lightProbe, geometry.normal );
#if ( NUM_HEMI_LIGHTS > 0 )
#pragma unroll_loop_start
for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {
irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );
}
#pragma unroll_loop_end
#endif
#endif
#if defined( RE_IndirectSpecular )
vec3 radiance = vec3( 0.0 );
vec3 clearcoatRadiance = vec3( 0.0 );
#endif
`;var Un=`
#if defined( RE_IndirectDiffuse )
#ifdef USE_LIGHTMAP
vec4 lightMapTexel = texture2D( lightMap, vUv2 );
vec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;
#ifndef PHYSICALLY_CORRECT_LIGHTS
lightMapIrradiance *= PI;
#endif
irradiance += lightMapIrradiance;
#endif
#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )
iblIrradiance += getIBLIrradiance( geometry.normal );
#endif
#endif
#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )
radiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );
#ifdef USE_CLEARCOAT
clearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );
#endif
#endif
`;var On=`
#if defined( RE_IndirectDiffuse )
RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );
#endif
#if defined( RE_IndirectSpecular )
RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );
#endif
`;var Gn=`
#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )
// Doing a strict comparison with == 1.0 can cause noise artifacts
// on some platforms. See issue #17623.
gl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;
#endif
`;var qn=`
#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )
uniform float logDepthBufFC;
varying float vFragDepth;
varying float vIsPerspective;
#endif
`;var Wn=`
#ifdef USE_LOGDEPTHBUF
#ifdef USE_LOGDEPTHBUF_EXT
varying float vFragDepth;
varying float vIsPerspective;
#else
uniform float logDepthBufFC;
#endif
#endif
`;var jn=`
#ifdef USE_LOGDEPTHBUF
#ifdef USE_LOGDEPTHBUF_EXT
vFragDepth = 1.0 + gl_Position.w;
vIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );
#else
if ( isPerspectiveMatrix( projectionMatrix ) ) {
gl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;
gl_Position.z *= gl_Position.w;
}
#endif
#endif
`;var Xn=`
#ifdef USE_MAP
vec4 sampledDiffuseColor = texture2D( map, vUv );
#ifdef DECODE_VIDEO_TEXTURE
// inline sRGB decode (TODO: Remove this code when https://crbug.com/1256340 is solved)
sampledDiffuseColor = vec4( mix( pow( sampledDiffuseColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), sampledDiffuseColor.rgb * 0.0773993808, vec3( lessThanEqual( sampledDiffuseColor.rgb, vec3( 0.04045 ) ) ) ), sampledDiffuseColor.w );
#endif
diffuseColor *= sampledDiffuseColor;
#endif
`;var Zn=`
#ifdef USE_MAP
uniform sampler2D map;
#endif
`;var Yn=`
#if defined( USE_MAP ) || defined( USE_ALPHAMAP )
vec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;
#endif
#ifdef USE_MAP
diffuseColor *= texture2D( map, uv );
#endif
#ifdef USE_ALPHAMAP
diffuseColor.a *= texture2D( alphaMap, uv ).g;
#endif
`;var $n=`
#if defined( USE_MAP ) || defined( USE_ALPHAMAP )
uniform mat3 uvTransform;
#endif
#ifdef USE_MAP
uniform sampler2D map;
#endif
#ifdef USE_ALPHAMAP
uniform sampler2D alphaMap;
#endif
`;var Kn=`
float metalnessFactor = metalness;
#ifdef USE_METALNESSMAP
vec4 texelMetalness = texture2D( metalnessMap, vUv );
// reads channel B, compatible with a combined OcclusionRoughnessMetallic (RGB) texture
metalnessFactor *= texelMetalness.b;
#endif
`;var Jn=`
#ifdef USE_METALNESSMAP
uniform sampler2D metalnessMap;
#endif
`;var Qn=`
#ifdef USE_MORPHNORMALS
// morphTargetBaseInfluence is set based on BufferGeometry.morphTargetsRelative value:
// When morphTargetsRelative is false, this is set to 1 - sum(influences); this results in normal = sum((target - base) * influence)
// When morphTargetsRelative is true, this is set to 1; as a result, all morph targets are simply added to the base after weighting
objectNormal *= morphTargetBaseInfluence;
#ifdef MORPHTARGETS_TEXTURE
for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {
if ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1, 2 ) * morphTargetInfluences[ i ];
}
#else
objectNormal += morphNormal0 * morphTargetInfluences[ 0 ];
objectNormal += morphNormal1 * morphTargetInfluences[ 1 ];
objectNormal += morphNormal2 * morphTargetInfluences[ 2 ];
objectNormal += morphNormal3 * morphTargetInfluences[ 3 ];
#endif
#endif
`;var es=`
#ifdef USE_MORPHTARGETS
uniform float morphTargetBaseInfluence;
#ifdef MORPHTARGETS_TEXTURE
uniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];
uniform sampler2DArray morphTargetsTexture;
uniform vec2 morphTargetsTextureSize;
vec3 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset, const in int stride ) {
float texelIndex = float( vertexIndex * stride + offset );
float y = floor( texelIndex / morphTargetsTextureSize.x );
float x = texelIndex - y * morphTargetsTextureSize.x;
vec3 morphUV = vec3( ( x + 0.5 ) / morphTargetsTextureSize.x, y / morphTargetsTextureSize.y, morphTargetIndex );
return texture( morphTargetsTexture, morphUV ).xyz;
}
#else
#ifndef USE_MORPHNORMALS
uniform float morphTargetInfluences[ 8 ];
#else
uniform float morphTargetInfluences[ 4 ];
#endif
#endif
#endif
`;var ts=`
#ifdef USE_MORPHTARGETS
// morphTargetBaseInfluence is set based on BufferGeometry.morphTargetsRelative value:
// When morphTargetsRelative is false, this is set to 1 - sum(influences); this results in position = sum((target - base) * influence)
// When morphTargetsRelative is true, this is set to 1; as a result, all morph targets are simply added to the base after weighting
transformed *= morphTargetBaseInfluence;
#ifdef MORPHTARGETS_TEXTURE
for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {
#ifndef USE_MORPHNORMALS
if ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0, 1 ) * morphTargetInfluences[ i ];
#else
if ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0, 2 ) * morphTargetInfluences[ i ];
#endif
}
#else
transformed += morphTarget0 * morphTargetInfluences[ 0 ];
transformed += morphTarget1 * morphTargetInfluences[ 1 ];
transformed += morphTarget2 * morphTargetInfluences[ 2 ];
transformed += morphTarget3 * morphTargetInfluences[ 3 ];
#ifndef USE_MORPHNORMALS
transformed += morphTarget4 * morphTargetInfluences[ 4 ];
transformed += morphTarget5 * morphTargetInfluences[ 5 ];
transformed += morphTarget6 * morphTargetInfluences[ 6 ];
transformed += morphTarget7 * morphTargetInfluences[ 7 ];
#endif
#endif
#endif
`;var is=`
float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;
#ifdef FLAT_SHADED
// Workaround for Adreno GPUs not able to do dFdx( vViewPosition )
vec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );
vec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );
vec3 normal = normalize( cross( fdx, fdy ) );
#else
vec3 normal = normalize( vNormal );
#ifdef DOUBLE_SIDED
normal = normal * faceDirection;
#endif
#ifdef USE_TANGENT
vec3 tangent = normalize( vTangent );
vec3 bitangent = normalize( vBitangent );
#ifdef DOUBLE_SIDED
tangent = tangent * faceDirection;
bitangent = bitangent * faceDirection;
#endif
#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )
mat3 vTBN = mat3( tangent, bitangent, normal );
#endif
#endif
#endif
// non perturbed normal for clearcoat among others
vec3 geometryNormal = normal;
`;var as=`
#ifdef OBJECTSPACE_NORMALMAP
normal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; // overrides both flatShading and attribute normals
#ifdef FLIP_SIDED
normal = - normal;
#endif
#ifdef DOUBLE_SIDED
normal = normal * faceDirection;
#endif
normal = normalize( normalMatrix * normal );
#elif defined( TANGENTSPACE_NORMALMAP )
vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;
mapN.xy *= normalScale;
#ifdef USE_TANGENT
normal = normalize( vTBN * mapN );
#else
normal = perturbNormal2Arb( - vViewPosition, normal, mapN, faceDirection );
#endif
#elif defined( USE_BUMPMAP )
normal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );
#endif
`;var rs=`
#ifndef FLAT_SHADED
varying vec3 vNormal;
#ifdef USE_TANGENT
varying vec3 vTangent;
varying vec3 vBitangent;
#endif
#endif
`;var ns=`
#ifndef FLAT_SHADED
varying vec3 vNormal;
#ifdef USE_TANGENT
varying vec3 vTangent;
varying vec3 vBitangent;
#endif
#endif
`;var ss=`
#ifndef FLAT_SHADED // normal is computed with derivatives when FLAT_SHADED
vNormal = normalize( transformedNormal );
#ifdef USE_TANGENT
vTangent = normalize( transformedTangent );
vBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );
#endif
#endif
`;var os=`
#ifdef USE_NORMALMAP
uniform sampler2D normalMap;
uniform vec2 normalScale;
#endif
#ifdef OBJECTSPACE_NORMALMAP
uniform mat3 normalMatrix;
#endif
#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )
// Normal Mapping Without Precomputed Tangents
// http://www.thetenthplanet.de/archives/1180
vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN, float faceDirection ) {
// Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988
vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );
vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );
vec2 st0 = dFdx( vUv.st );
vec2 st1 = dFdy( vUv.st );
vec3 N = surf_norm; // normalized
vec3 q1perp = cross( q1, N );
vec3 q0perp = cross( N, q0 );
vec3 T = q1perp * st0.x + q0perp * st1.x;
vec3 B = q1perp * st0.y + q0perp * st1.y;
float det = max( dot( T, T ), dot( B, B ) );
float scale = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det );
return normalize( T * ( mapN.x * scale ) + B * ( mapN.y * scale ) + N * mapN.z );
}
#endif
`;var cs=`
#ifdef USE_CLEARCOAT
vec3 clearcoatNormal = geometryNormal;
#endif
`;var ls=`
#ifdef USE_CLEARCOAT_NORMALMAP
vec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;
clearcoatMapN.xy *= clearcoatNormalScale;
#ifdef USE_TANGENT
clearcoatNormal = normalize( vTBN * clearcoatMapN );
#else
clearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN, faceDirection );
#endif
#endif
`;var us=`
#ifdef USE_CLEARCOATMAP
uniform sampler2D clearcoatMap;
#endif
#ifdef USE_CLEARCOAT_ROUGHNESSMAP
uniform sampler2D clearcoatRoughnessMap;
#endif
#ifdef USE_CLEARCOAT_NORMALMAP
uniform sampler2D clearcoatNormalMap;
uniform vec2 clearcoatNormalScale;
#endif
`;var hs=`
#ifdef OPAQUE
diffuseColor.a = 1.0;
#endif
// https://github.com/mrdoob/three.js/pull/22425
#ifdef USE_TRANSMISSION
diffuseColor.a *= transmissionAlpha + 0.1;
#endif
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
`;var fs=`
vec3 packNormalToRGB( const in vec3 normal ) {
return normalize( normal ) * 0.5 + 0.5;
}
vec3 unpackRGBToNormal( const in vec3 rgb ) {
return 2.0 * rgb.xyz - 1.0;
}
const float PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1)
const float UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1)
const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );
const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );
const float ShiftRight8 = 1. / 256.;
vec4 packDepthToRGBA( const in float v ) {
vec4 r = vec4( fract( v * PackFactors ), v );
r.yzw -= r.xyz * ShiftRight8; // tidy overflow
return r * PackUpscale;
}
float unpackRGBAToDepth( const in vec4 v ) {
return dot( v, UnpackFactors );
}
vec4 pack2HalfToRGBA( vec2 v ) {
vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );
return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );
}
vec2 unpackRGBATo2Half( vec4 v ) {
return vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );
}
// NOTE: viewZ/eyeZ is < 0 when in front of the camera per OpenGL conventions
float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {
return ( viewZ + near ) / ( near - far );
}
float orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {
return linearClipZ * ( near - far ) - near;
}
// NOTE: https://twitter.com/gonnavis/status/1377183786949959682
float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {
return ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );
}
float perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {
return ( near * far ) / ( ( far - near ) * invClipZ - far );
}
`;var ds=`
#ifdef PREMULTIPLIED_ALPHA
// Get get normal blending with premultipled, use with CustomBlending, OneFactor, OneMinusSrcAlphaFactor, AddEquation.
gl_FragColor.rgb *= gl_FragColor.a;
#endif
`;var ps=`
vec4 mvPosition = vec4( transformed, 1.0 );
#ifdef USE_INSTANCING
mvPosition = instanceMatrix * mvPosition;
#endif
mvPosition = modelViewMatrix * mvPosition;
gl_Position = projectionMatrix * mvPosition;
`;var ms=`
#ifdef DITHERING
gl_FragColor.rgb = dithering( gl_FragColor.rgb );
#endif
`;var vs=`
#ifdef DITHERING
// based on https://www.shadertoy.com/view/MslGR8
vec3 dithering( vec3 color ) {
//Calculate grid position
float grid_position = rand( gl_FragCoord.xy );
//Shift the individual colors differently, thus making it even harder to see the dithering pattern
vec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );
//modify shift acording to grid position.
dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );
//shift the color by dither_shift
return color + dither_shift_RGB;
}
#endif
`;var gs=`
float roughnessFactor = roughness;
#ifdef USE_ROUGHNESSMAP
vec4 texelRoughness = texture2D( roughnessMap, vUv );
// reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture
roughnessFactor *= texelRoughness.g;
#endif
`;var xs=`
#ifdef USE_ROUGHNESSMAP
uniform sampler2D roughnessMap;
#endif
`;var Ms=`
#ifdef USE_SHADOWMAP
#if NUM_DIR_LIGHT_SHADOWS > 0
uniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];
varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];
struct DirectionalLightShadow {
float shadowBias;
float shadowNormalBias;
float shadowRadius;
vec2 shadowMapSize;
};
uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];
#endif
#if NUM_SPOT_LIGHT_SHADOWS > 0
uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];
varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];
struct SpotLightShadow {
float shadowBias;
float shadowNormalBias;
float shadowRadius;
vec2 shadowMapSize;
};
uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];
#endif
#if NUM_POINT_LIGHT_SHADOWS > 0
uniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];
varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];
struct PointLightShadow {
float shadowBias;
float shadowNormalBias;
float shadowRadius;
vec2 shadowMapSize;
float shadowCameraNear;
float shadowCameraFar;
};
uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];
#endif
/*
#if NUM_RECT_AREA_LIGHTS > 0
// TODO (abelnation): create uniforms for area light shadows
#endif
*/
float texture2DCompare( sampler2D depths, vec2 uv, float compare ) {
return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );
}
vec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {
return unpackRGBATo2Half( texture2D( shadow, uv ) );
}
float VSMShadow (sampler2D shadow, vec2 uv, float compare ){
float occlusion = 1.0;
vec2 distribution = texture2DDistribution( shadow, uv );
float hard_shadow = step( compare , distribution.x ); // Hard Shadow
if (hard_shadow != 1.0 ) {
float distance = compare - distribution.x ;
float variance = max( 0.00000, distribution.y * distribution.y );
float softness_probability = variance / (variance + distance * distance ); // Chebeyshevs inequality
softness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 ); // 0.3 reduces light bleed
occlusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );
}
return occlusion;
}
float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {
float shadow = 1.0;
shadowCoord.xyz /= shadowCoord.w;
shadowCoord.z += shadowBias;
// if ( something && something ) breaks ATI OpenGL shader compiler
// if ( all( something, something ) ) using this instead
bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );
bool inFrustum = all( inFrustumVec );
bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );
bool frustumTest = all( frustumTestVec );
if ( frustumTest ) {
#if defined( SHADOWMAP_TYPE_PCF )
vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
float dx0 = - texelSize.x * shadowRadius;
float dy0 = - texelSize.y * shadowRadius;
float dx1 = + texelSize.x * shadowRadius;
float dy1 = + texelSize.y * shadowRadius;
float dx2 = dx0 / 2.0;
float dy2 = dy0 / 2.0;
float dx3 = dx1 / 2.0;
float dy3 = dy1 / 2.0;
shadow = (
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )
) * ( 1.0 / 17.0 );
#elif defined( SHADOWMAP_TYPE_PCF_SOFT )
vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
float dx = texelSize.x;
float dy = texelSize.y;
vec2 uv = shadowCoord.xy;
vec2 f = fract( uv * shadowMapSize + 0.5 );
uv -= f * texelSize;
shadow = (
texture2DCompare( shadowMap, uv, shadowCoord.z ) +
texture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +
texture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +
mix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ),
texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),
f.x ) +
mix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ),
texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),
f.x ) +
mix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ),
texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),
f.y ) +
mix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ),
texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),
f.y ) +
mix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ),
texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),
f.x ),
mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ),
texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),
f.x ),
f.y )
) * ( 1.0 / 9.0 );
#elif defined( SHADOWMAP_TYPE_VSM )
shadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );
#else // no percentage-closer filtering:
shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );
#endif
}
return shadow;
}
// cubeToUV() maps a 3D direction vector suitable for cube texture mapping to a 2D
// vector suitable for 2D texture mapping. This code uses the following layout for the
// 2D texture:
//
// xzXZ
// y Y
//
// Y - Positive y direction
// y - Negative y direction
// X - Positive x direction
// x - Negative x direction
// Z - Positive z direction
// z - Negative z direction
//
// Source and test bed:
// https://gist.github.com/tschw/da10c43c467ce8afd0c4
vec2 cubeToUV( vec3 v, float texelSizeY ) {
// Number of texels to avoid at the edge of each square
vec3 absV = abs( v );
// Intersect unit cube
float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );
absV *= scaleToCube;
// Apply scale to avoid seams
// two texels less per square (one texel will do for NEAREST)
v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );
// Unwrap
// space: -1 ... 1 range for each square
//
// #X## dim := ( 4 , 2 )
// # # center := ( 1 , 1 )
vec2 planar = v.xy;
float almostATexel = 1.5 * texelSizeY;
float almostOne = 1.0 - almostATexel;
if ( absV.z >= almostOne ) {
if ( v.z > 0.0 )
planar.x = 4.0 - v.x;
} else if ( absV.x >= almostOne ) {
float signX = sign( v.x );
planar.x = v.z * signX + 2.0 * signX;
} else if ( absV.y >= almostOne ) {
float signY = sign( v.y );
planar.x = v.x + 2.0 * signY + 2.0;
planar.y = v.z * signY - 2.0;
}
// Transform to UV space
// scale := 0.5 / dim
// translate := ( center + 0.5 ) / dim
return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );
}
float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {
vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );
// for point lights, the uniform @vShadowCoord is re-purposed to hold
// the vector from the light to the world-space position of the fragment.
vec3 lightToPosition = shadowCoord.xyz;
// dp = normalized distance from light to fragment position
float dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); // need to clamp?
dp += shadowBias;
// bd3D = base direction 3D
vec3 bd3D = normalize( lightToPosition );
#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )
vec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;
return (
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )
) * ( 1.0 / 9.0 );
#else // no percentage-closer filtering
return texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );
#endif
}
#endif
`;var bs=`
#ifdef USE_SHADOWMAP
#if NUM_DIR_LIGHT_SHADOWS > 0
uniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];
varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];
struct DirectionalLightShadow {
float shadowBias;
float shadowNormalBias;
float shadowRadius;
vec2 shadowMapSize;
};
uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];
#endif
#if NUM_SPOT_LIGHT_SHADOWS > 0
uniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];
varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];
struct SpotLightShadow {
float shadowBias;
float shadowNormalBias;
float shadowRadius;
vec2 shadowMapSize;
};
uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];
#endif
#if NUM_POINT_LIGHT_SHADOWS > 0
uniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];
varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];
struct PointLightShadow {
float shadowBias;
float shadowNormalBias;
float shadowRadius;
vec2 shadowMapSize;
float shadowCameraNear;
float shadowCameraFar;
};
uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];
#endif
/*
#if NUM_RECT_AREA_LIGHTS > 0
// TODO (abelnation): uniforms for area light shadows
#endif
*/
#endif
`;var ys=`
#ifdef USE_SHADOWMAP
#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0
// Offsetting the position used for querying occlusion along the world normal can be used to reduce shadow acne.
vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );
vec4 shadowWorldPosition;
#endif
#if NUM_DIR_LIGHT_SHADOWS > 0
#pragma unroll_loop_start
for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {
shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );
vDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;
}
#pragma unroll_loop_end
#endif
#if NUM_SPOT_LIGHT_SHADOWS > 0
#pragma unroll_loop_start
for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {
shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias, 0 );
vSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * shadowWorldPosition;
}
#pragma unroll_loop_end
#endif
#if NUM_POINT_LIGHT_SHADOWS > 0
#pragma unroll_loop_start
for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {
shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );
vPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;
}
#pragma unroll_loop_end
#endif
/*
#if NUM_RECT_AREA_LIGHTS > 0
// TODO (abelnation): update vAreaShadowCoord with area light info
#endif
*/
#endif
`;var Cs=`
float getShadowMask() {
float shadow = 1.0;
#ifdef USE_SHADOWMAP
#if NUM_DIR_LIGHT_SHADOWS > 0
DirectionalLightShadow directionalLight;
#pragma unroll_loop_start
for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {
directionalLight = directionalLightShadows[ i ];
shadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
}
#pragma unroll_loop_end
#endif
#if NUM_SPOT_LIGHT_SHADOWS > 0
SpotLightShadow spotLight;
#pragma unroll_loop_start
for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {
spotLight = spotLightShadows[ i ];
shadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;
}
#pragma unroll_loop_end
#endif
#if NUM_POINT_LIGHT_SHADOWS > 0
PointLightShadow pointLight;
#pragma unroll_loop_start
for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {
pointLight = pointLightShadows[ i ];
shadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;
}
#pragma unroll_loop_end
#endif
/*
#if NUM_RECT_AREA_LIGHTS > 0
// TODO (abelnation): update shadow for Area light
#endif
*/
#endif
return shadow;
}
`;var zs=`
#ifdef USE_SKINNING
mat4 boneMatX = getBoneMatrix( skinIndex.x );
mat4 boneMatY = getBoneMatrix( skinIndex.y );
mat4 boneMatZ = getBoneMatrix( skinIndex.z );
mat4 boneMatW = getBoneMatrix( skinIndex.w );
#endif
`;var As=`
#ifdef USE_SKINNING
uniform mat4 bindMatrix;
uniform mat4 bindMatrixInverse;
#ifdef BONE_TEXTURE
uniform highp sampler2D boneTexture;
uniform int boneTextureSize;
mat4 getBoneMatrix( const in float i ) {
float j = i * 4.0;
float x = mod( j, float( boneTextureSize ) );
float y = floor( j / float( boneTextureSize ) );
float dx = 1.0 / float( boneTextureSize );
float dy = 1.0 / float( boneTextureSize );
y = dy * ( y + 0.5 );
vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );
vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );
vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );
vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );
mat4 bone = mat4( v1, v2, v3, v4 );
return bone;
}
#else
uniform mat4 boneMatrices[ MAX_BONES ];
mat4 getBoneMatrix( const in float i ) {
mat4 bone = boneMatrices[ int(i) ];
return bone;
}
#endif
#endif
`;var ws=`
#ifdef USE_SKINNING
vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
vec4 skinned = vec4( 0.0 );
skinned += boneMatX * skinVertex * skinWeight.x;
skinned += boneMatY * skinVertex * skinWeight.y;
skinned += boneMatZ * skinVertex * skinWeight.z;
skinned += boneMatW * skinVertex * skinWeight.w;
transformed = ( bindMatrixInverse * skinned ).xyz;
#endif
`;var Ss=`
#ifdef USE_SKINNING
mat4 skinMatrix = mat4( 0.0 );
skinMatrix += skinWeight.x * boneMatX;
skinMatrix += skinWeight.y * boneMatY;
skinMatrix += skinWeight.z * boneMatZ;
skinMatrix += skinWeight.w * boneMatW;
skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;
objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;
#ifdef USE_TANGENT
objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;
#endif
#endif
`;var _s=`
float specularStrength;
#ifdef USE_SPECULARMAP
vec4 texelSpecular = texture2D( specularMap, vUv );
specularStrength = texelSpecular.r;
#else
specularStrength = 1.0;
#endif
`;var Es=`
#ifdef USE_SPECULARMAP
uniform sampler2D specularMap;
#endif
`;var Ls=`
#if defined( TONE_MAPPING )
gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );
#endif
`;var Ds=`
#ifndef saturate
// may have defined saturate() already
#define saturate( a ) clamp( a, 0.0, 1.0 )
#endif
uniform float toneMappingExposure;
// exposure only
vec3 LinearToneMapping( vec3 color ) {
return toneMappingExposure * color;
}
// source: https://www.cs.utah.edu/docs/techreports/2002/pdf/UUCS-02-001.pdf
vec3 ReinhardToneMapping( vec3 color ) {
color *= toneMappingExposure;
return saturate( color / ( vec3( 1.0 ) + color ) );
}
// source: http://filmicworlds.com/blog/filmic-tonemapping-operators/
vec3 OptimizedCineonToneMapping( vec3 color ) {
// optimized filmic operator by Jim Hejl and Richard Burgess-Dawson
color *= toneMappingExposure;
color = max( vec3( 0.0 ), color - 0.004 );
return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );
}
// source: https://github.com/selfshadow/ltc_code/blob/master/webgl/shaders/ltc/ltc_blit.fs
vec3 RRTAndODTFit( vec3 v ) {
vec3 a = v * ( v + 0.0245786 ) - 0.000090537;
vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;
return a / b;
}
// this implementation of ACES is modified to accommodate a brighter viewing environment.
// the scale factor of 1/0.6 is subjective. see discussion in #19621.
vec3 ACESFilmicToneMapping( vec3 color ) {
// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
const mat3 ACESInputMat = mat3(
vec3( 0.59719, 0.07600, 0.02840 ), // transposed from source
vec3( 0.35458, 0.90834, 0.13383 ),
vec3( 0.04823, 0.01566, 0.83777 )
);
// ODT_SAT => XYZ => D60_2_D65 => sRGB
const mat3 ACESOutputMat = mat3(
vec3( 1.60475, -0.10208, -0.00327 ), // transposed from source
vec3( -0.53108, 1.10813, -0.07276 ),
vec3( -0.07367, -0.00605, 1.07602 )
);
color *= toneMappingExposure / 0.6;
color = ACESInputMat * color;
// Apply RRT and ODT
color = RRTAndODTFit( color );
color = ACESOutputMat * color;
// Clamp to [0, 1]
return saturate( color );
}
vec3 CustomToneMapping( vec3 color ) { return color; }
`;var Ts=`
#ifdef USE_TRANSMISSION
float transmissionAlpha = 1.0;
float transmissionFactor = transmission;
float thicknessFactor = thickness;
#ifdef USE_TRANSMISSIONMAP
transmissionFactor *= texture2D( transmissionMap, vUv ).r;
#endif
#ifdef USE_THICKNESSMAP
thicknessFactor *= texture2D( thicknessMap, vUv ).g;
#endif
vec3 pos = vWorldPosition;
vec3 v = normalize( cameraPosition - pos );
vec3 n = inverseTransformDirection( normal, viewMatrix );
vec4 transmission = getIBLVolumeRefraction(
n, v, roughnessFactor, material.diffuseColor, material.specularColor, material.specularF90,
pos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,
attenuationColor, attenuationDistance );
totalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor );
transmissionAlpha = mix( transmissionAlpha, transmission.a, transmissionFactor );
#endif
`;var Hs=`
#ifdef USE_TRANSMISSION
// Transmission code is based on glTF-Sampler-Viewer
// https://github.com/KhronosGroup/glTF-Sample-Viewer
uniform float transmission;
uniform float thickness;
uniform float attenuationDistance;
uniform vec3 attenuationColor;
#ifdef USE_TRANSMISSIONMAP
uniform sampler2D transmissionMap;
#endif
#ifdef USE_THICKNESSMAP
uniform sampler2D thicknessMap;
#endif
uniform vec2 transmissionSamplerSize;
uniform sampler2D transmissionSamplerMap;
uniform mat4 modelMatrix;
uniform mat4 projectionMatrix;
varying vec3 vWorldPosition;
vec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {
// Direction of refracted light.
vec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );
// Compute rotation-independant scaling of the model matrix.
vec3 modelScale;
modelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );
modelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );
modelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );
// The thickness is specified in local space.
return normalize( refractionVector ) * thickness * modelScale;
}
float applyIorToRoughness( const in float roughness, const in float ior ) {
// Scale roughness with IOR so that an IOR of 1.0 results in no microfacet refraction and
// an IOR of 1.5 results in the default amount of microfacet refraction.
return roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );
}
vec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {
float framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );
#ifdef TEXTURE_LOD_EXT
return texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );
#else
return texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );
#endif
}
vec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {
if ( attenuationDistance == 0.0 ) {
// Attenuation distance is +\u221E (which we indicate by zero), i.e. the transmitted color is not attenuated at all.
return radiance;
} else {
// Compute light attenuation using Beer's law.
vec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;
vec3 transmittance = exp( - attenuationCoefficient * transmissionDistance ); // Beer's law
return transmittance * radiance;
}
}
vec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,
const in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,
const in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,
const in vec3 attenuationColor, const in float attenuationDistance ) {
vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );
vec3 refractedRayExit = position + transmissionRay;
// Project refracted vector on the framebuffer, while mapping to normalized device coordinates.
vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );
vec2 refractionCoords = ndcPos.xy / ndcPos.w;
refractionCoords += 1.0;
refractionCoords /= 2.0;
// Sample framebuffer to get pixel the refracted ray hits.
vec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );
vec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );
// Get the specular component.
vec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );
return vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );
}
#endif
`;var Vs=`
#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )
varying vec2 vUv;
#endif
`;var Ns=`
#ifdef USE_UV
#ifdef UVS_VERTEX_ONLY
vec2 vUv;
#else
varying vec2 vUv;
#endif
uniform mat3 uvTransform;
#endif
`;var Rs=`
#ifdef USE_UV
vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
#endif
`;var Fs=`
#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )
varying vec2 vUv2;
#endif
`;var Bs=`
#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )
attribute vec2 uv2;
varying vec2 vUv2;
uniform mat3 uv2Transform;
#endif
`;var Ps=`
#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )
vUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;
#endif
`;var Is=`
#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )
vec4 worldPosition = vec4( transformed, 1.0 );
#ifdef USE_INSTANCING
worldPosition = instanceMatrix * worldPosition;
#endif
worldPosition = modelMatrix * worldPosition;
#endif
`;var ks=`
varying vec2 vUv;
uniform mat3 uvTransform;
void main() {
vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
gl_Position = vec4( position.xy, 1.0, 1.0 );
}
`,Us=`
uniform sampler2D t2D;
varying vec2 vUv;
void main() {
gl_FragColor = texture2D( t2D, vUv );
#include
#include
}
`;var Os=`
varying vec3 vWorldDirection;
#include
void main() {
vWorldDirection = transformDirection( position, modelMatrix );
#include
#include
gl_Position.z = gl_Position.w; // set z to camera.far
}
`,Gs=`
#include
uniform float opacity;
varying vec3 vWorldDirection;
#include
void main() {
vec3 vReflect = vWorldDirection;
#include
gl_FragColor = envColor;
gl_FragColor.a *= opacity;
#include
#include
}
`;var qs=`
#include
#include
#include
#include
#include
#include
#include
// This is used for computing an equivalent of gl_FragCoord.z that is as high precision as possible.
// Some platforms compute gl_FragCoord at a lower precision which makes the manually computed value better for
// depth-based postprocessing effects. Reproduced on iPad with A10 processor / iPadOS 13.3.1.
varying vec2 vHighPrecisionZW;
void main() {
#include
#include
#ifdef USE_DISPLACEMENTMAP
#include
#include
#include
#endif
#include
#include
#include
#include
#include
#include
#include
vHighPrecisionZW = gl_Position.zw;
}
`,Ws=`
#if DEPTH_PACKING == 3200
uniform float opacity;
#endif
#include
#include
#include
#include
#include
#include
#include
#include
varying vec2 vHighPrecisionZW;
void main() {
#include
vec4 diffuseColor = vec4( 1.0 );
#if DEPTH_PACKING == 3200
diffuseColor.a = opacity;
#endif
#include
#include
#include
#include
// Higher precision equivalent of gl_FragCoord.z. This assumes depthRange has been left to its default values.
float fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;
#if DEPTH_PACKING == 3200
gl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );
#elif DEPTH_PACKING == 3201
gl_FragColor = packDepthToRGBA( fragCoordZ );
#endif
}
`;var js=`
#define DISTANCE
varying vec3 vWorldPosition;
#include
#include
#include
#include
#include
#include
void main() {
#include
#include
#ifdef USE_DISPLACEMENTMAP
#include
#include
#include
#endif
#include
#include
#include
#include
#include
#include
#include
vWorldPosition = worldPosition.xyz;
}
`,Xs=`
#define DISTANCE
uniform vec3 referencePosition;
uniform float nearDistance;
uniform float farDistance;
varying vec3 vWorldPosition;
#include
#include
#include
#include
#include
#include
#include
void main () {
#include
vec4 diffuseColor = vec4( 1.0 );
#include
#include
#include
float dist = length( vWorldPosition - referencePosition );
dist = ( dist - nearDistance ) / ( farDistance - nearDistance );
dist = saturate( dist ); // clamp to [ 0, 1 ]
gl_FragColor = packDepthToRGBA( dist );
}
`;var Zs=`
varying vec3 vWorldDirection;
#include
void main() {
vWorldDirection = transformDirection( position, modelMatrix );
#include
#include
}
`,Ys=`
uniform sampler2D tEquirect;
varying vec3 vWorldDirection;
#include
void main() {
vec3 direction = normalize( vWorldDirection );
vec2 sampleUV = equirectUv( direction );
gl_FragColor = texture2D( tEquirect, sampleUV );
#include
#include
}
`;var $s=`
uniform float scale;
attribute float lineDistance;
varying float vLineDistance;
#include
#include
#include
#include
#include
#include
void main() {
vLineDistance = scale * lineDistance;
#include
#include
#include
#include
#include
#include
#include
}
`,Ks=`
uniform vec3 diffuse;
uniform float opacity;
uniform float dashSize;
uniform float totalSize;
varying float vLineDistance;
#include
#include
#include
#include
#include
void main() {
#include
if ( mod( vLineDistance, totalSize ) > dashSize ) {
discard;
}
vec3 outgoingLight = vec3( 0.0 );
vec4 diffuseColor = vec4( diffuse, opacity );
#include
#include
outgoingLight = diffuseColor.rgb; // simple shader
#include
#include
#include
#include
#include
}
`;var Js=`
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void main() {
#include
#include
#include
#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )
#include
#include
#include
#include
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
}
`,Qs=`
uniform vec3 diffuse;
uniform float opacity;
#ifndef FLAT_SHADED
varying vec3 vNormal;
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void main() {
#include
vec4 diffuseColor = vec4( diffuse, opacity );
#include
#include
#include
#include
#include
#include
ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
// accumulation (baked indirect lighting only)
#ifdef USE_LIGHTMAP
vec4 lightMapTexel= texture2D( lightMap, vUv2 );
reflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity;
#else
reflectedLight.indirectDiffuse += vec3( 1.0 );
#endif
// modulation
#include
reflectedLight.indirectDiffuse *= diffuseColor.rgb;
vec3 outgoingLight = reflectedLight.indirectDiffuse;
#include
#include
#include
#include