@hology/webgpu-renderer 0.1.20 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- var e=new WeakMap;function t(t,r,i){const n=e.get(t);n&&(n.loading=r,n.phase=i)}function r(t,r,i){const n=e.get(t);n&&(n.origins.size>=4096&&!n.origins.has(r)&&n.origins.delete(n.origins.keys().next().value),n.origins.set(r,i))}function i(t,r){const i=e.get(t),n=i?.origins.get(r.label??"");n&&i.descriptorOrigins.set(r,n)}function n(e){let t=2166136261;for(let r=0;r<e.length;r++)t=Math.imul(t^e.charCodeAt(r),16777619);return(t>>>0).toString(16)}function a(e,t){if(null==e||"object"!=typeof e)return e;const r=t.objects.get(e);if(null!=r)return r;if(Array.isArray(e))return e.map(e=>a(e,t));const i={};for(const r of Object.keys(e).sort())"label"!==r&&(i[r]=a(e[r],t));return i}function s(e,t,r=""){if(JSON.stringify(e)===JSON.stringify(t))return[];if(e&&t&&"object"==typeof e&&"object"==typeof t){const i=e,n=t;return[...new Set([...Object.keys(i),...Object.keys(n)])].flatMap(e=>s(i[e],n[e],r?r+"."+e:e))}return[{field:r,previous:e,current:t}]}var o=2,l={minScreenSize:2};function c(e,t){e.userData.detailCulling=t}var u=Object.freeze({minScreenSize:2,maxDistance:0,shadowMinScreenSize:2,shadowMaxDistance:0}),d=[];function h(e,t){let r=!!t;for(let t=e;t&&!r;t=t.parent)r=!!t.userData.detailCulling;if(!r)return u;let i=!0,n=o,a=0,s=!0,c=l.minScreenSize,h=0;const p=e=>{e&&(i=e.enabled??i,n=e.minScreenSize??n,a=e.maxDistance??a,s=e.shadow?.enabled??s,c=e.shadow?.minScreenSize??c,h=e.shadow?.maxDistance??h)};p(t),d.length=0;for(let t=e;t;t=t.parent)d.push(t);for(let e=d.length-1;e>=0;e--)p(d[e].userData.detailCulling);const f=e=>Number.isFinite(e)&&e>0?e:0;return{minScreenSize:i?f(n):0,maxDistance:f(a),shadowMinScreenSize:s?f(c):0,shadowMaxDistance:f(h)}}function p(e,t,r,i,n,a,s,o){if(o>0&&e.distanceTo(a)-t>o)return!1;if(s<=0)return!0;const l=r.elements,c=e.x,u=e.y,d=e.z,h=l[3]*c+l[7]*u+l[11]*d+l[15],p=Math.hypot(l[3],l[7],l[11]),f=h-t*p;if(f<=1e-4)return!0;const m=(l[0]*c+l[4]*u+l[8]*d+l[12])/h,g=(l[1]*c+l[5]*u+l[9]*d+l[13])/h;return t*Math.max((Math.hypot(l[0],l[4],l[8])+Math.abs(m)*p)*i,(Math.hypot(l[1],l[5],l[9])+Math.abs(g)*p)*n)/f>=s}import{Matrix4 as f,Sphere as m,Vector3 as g}from"three";var v=64,x=64,w=40,b=12,y=new Float32Array(w),S=new Float32Array([1,1,1,1]),C="rgba16float",P="rgba8unorm",M=(new f).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),B=[new g(0,-1,0),new g(0,-1,0),new g(0,0,1),new g(0,0,-1),new g(0,-1,0),new g(0,-1,0)],D=[new g(1,0,0),new g(-1,0,0),new g(0,1,0),new g(0,-1,0),new g(0,0,1),new g(0,0,-1)],T=4004,I=[{name:"position",shaderLocation:0,format:"float32x3"}],V=[{name:"position",shaderLocation:0,format:"float32x3"},{name:"skinIndex",shaderLocation:1,format:"uint32x4"},{name:"skinWeight",shaderLocation:2,format:"float32x4"}],R=new f,G=new f,z=(new f,new f,new m),L=new g,U=new g,A=new g,F=(new g,new g,new g,new g,new WeakMap);async function k(e,t){const r=F.get(e)??Promise.resolve();let i;const n=new Promise(e=>{i=e});F.set(e,r.catch(()=>{}).then(()=>n)),await r.catch(()=>{});try{return await new Promise(e=>requestAnimationFrame(()=>e())),t()}finally{i()}}function E(e,t){return i(e,t),"function"==typeof e.createRenderPipelineAsync?e.createRenderPipelineAsync(t):k(e,()=>e.createRenderPipeline(t))}function O(e,t){return i(e,t),"function"==typeof e.createComputePipelineAsync?e.createComputePipelineAsync(t):k(e,()=>e.createComputePipeline(t))}var j=class e{layout;pipeline;static async createAsync(t,r){const{pipelineDescriptor:i}=$(t,r),n=await O(t,i);return new e(t,r,n)}constructor(e,t,r){if(r)return this.layout=r.getBindGroupLayout(0),void(this.pipeline=r);const{layout:i,pipelineDescriptor:n}=$(e,t);this.layout=i,this.pipeline=e.createComputePipeline(n)}createBindGroup(e,t,r){return e.createBindGroup({label:r,layout:this.layout,entries:t})}};function $(e,t){const r=e.createBindGroupLayout({label:t.label?`${t.label}-layout`:void 0,entries:t.bindGroupLayoutEntries});return{layout:r,pipelineDescriptor:{label:t.label,layout:e.createPipelineLayout({label:t.label?`${t.label}-pipeline-layout`:void 0,bindGroupLayouts:[r]}),compute:{module:e.createShaderModule({label:t.label?`${t.label}-module`:void 0,code:t.code}),entryPoint:t.entryPoint??"main"}}}}import{Color as W,DirectionalLight as N,Matrix4 as _,Object3D as H,PointLight as q,Scene as K,SpotLight as Z,Vector3 as Y}from"three";var X=class extends H{constructor(e){super(),this.volume=e}volume;isFogVolumeObject=!0},J={low:{froxelPixelSize:16,depthSlices:32,integrationSubsteps:1,shadowFilterTaps:1,temporalJitter:!0,temporal:{historyWeight:.88,depthRejection:.055,neighborhoodClamp:!0},blur:{scale:.25,radius:2,depthSigma:.06,spatialSigma:1.5,depthAwareUpsample:!1}},medium:{froxelPixelSize:12,depthSlices:40,integrationSubsteps:1,shadowFilterTaps:1,temporalJitter:!0,temporal:{historyWeight:.92,depthRejection:.045,neighborhoodClamp:!0},blur:{scale:.375,radius:2,depthSigma:.055,spatialSigma:1.75,depthAwareUpsample:!0}},high:{froxelPixelSize:8,depthSlices:64,integrationSubsteps:1,shadowFilterTaps:1,temporalJitter:!0,temporal:{historyWeight:.94,depthRejection:.04,neighborhoodClamp:!0},blur:{scale:.5,radius:3,depthSigma:.05,spatialSigma:2,depthAwareUpsample:!0}}},Q=20,ee=16,te=(new _).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),re=new Y,ie=new Y,ne=new Y,ae={label:"VolumetricFogFroxelPass"};function se(e,t,r,i,n,a){e[t]=r,e[t+1]=i,e[t+2]=n,e[t+3]=a}var oe=class{constructor(e=new K,t={}){this.scene=e,this.options=le(t),this.integratedVolume=`${this.options.targetPrefix}Integrated`,this.columnDepthBounds=`${this.options.targetPrefix}DepthBounds`,this.scatteringHistoryA=`${this.options.targetPrefix}ScatteringHistoryA`,this.scatteringHistoryB=`${this.options.targetPrefix}ScatteringHistoryB`,this.activeHistoryRead=this.scatteringHistoryB,this.activeHistoryWrite=this.scatteringHistoryA,this.volumeData=new Float32Array(this.options.maxVolumes*Q);const r=this.options.maxDirectionalLights+this.options.maxPointLights+this.options.maxSpotLights;this.lightData=new Float32Array(r*ee),this.selectedPointIndices=new Int32Array(this.options.maxPointLights),this.selectedPointScores=new Float32Array(this.options.maxPointLights),this.selectedSpotIndices=new Int32Array(this.options.maxSpotLights),this.selectedSpotScores=new Float32Array(this.options.maxSpotLights)}scene;integratedVolume;columnDepthBounds;scatteringHistoryA;scatteringHistoryB;options;resources=new WeakMap;uniformStorage=new ArrayBuffer(256);uniforms=new Float32Array(this.uniformStorage);uniformIntegers=new Uint32Array(this.uniformStorage);volumeData;lightData;selectedPointIndices;selectedPointScores;selectedSpotIndices;selectedSpotScores;collectedVolumes=[];collectedDirectionals=[];collectedPoints=[];collectedSpots=[];volumeCount=0;directionalCount=0;pointCount=0;spotCount=0;collectionCamera=null;collectVolumeObject=e=>{const t=e;t.isFogVolumeObject&&t.volume&&!this.collectedVolumes.includes(t.volume)&&this.collectedVolumes.push(t.volume)};collectLightObject=e=>{const t=this.collectionCamera;e instanceof N&&e.layers.test(t.layers)&&!this.collectedDirectionals.includes(e)?this.collectedDirectionals.push(e):e instanceof q&&e.layers.test(t.layers)?this.collectedPoints.push(e):e instanceof Z&&e.layers.test(t.layers)&&this.collectedSpots.push(e)};executeFroxelPass=e=>{this.executeFroxels(e)};projectionInverse=new _;viewProjectionInverse=new _;previousTemporalViewProjection=new _;previousFroxelViewProjection=new _;previousFroxelCameraPosition=new Y;previousFroxelNear=.1;previousFroxelFar=1;previousFroxelWidth=0;previousFroxelHeight=0;froxelHistoryValid=!1;froxelHistoryWriteIndex=0;activeHistoryRead;activeHistoryWrite;explicitVolumes=[];volumeObjects;extractedLights;cascadeDirectionalLights=[];compositePass=null;blurPassCache=new Map;temporalPassCache=new Map;temporalWriteIndex=0;temporalHistoryValid=!1;activeLastFrame=!1;frameIndex=0;setScene(e){this.scene=e}get enabled(){return this.options.enabled}setOptions(e){const t=le({...this.options,...e,ambientColor:e.ambientColor??this.options.ambientColor,blur:void 0===e.blur?this.options.blur:e.blur,temporal:void 0===e.temporal?this.options.temporal:e.temporal,targetPrefix:this.options.targetPrefix,maxVolumes:this.options.maxVolumes,maxDirectionalLights:this.options.maxDirectionalLights,maxPointLights:this.options.maxPointLights,maxSpotLights:this.options.maxSpotLights});Object.assign(this.options,t),this.compositePass=null,this.blurPassCache.clear(),this.temporalPassCache.clear(),this.reset()}applyPreset(e){this.setOptions(J[e])}reset(){this.frameIndex=0,this.temporalWriteIndex=0,this.temporalHistoryValid=!1,this.froxelHistoryValid=!1,this.froxelHistoryWriteIndex=0,this.previousFroxelWidth=0,this.previousFroxelHeight=0,this.activeLastFrame=!1,this.previousTemporalViewProjection.identity()}setCascadedDirectionalLights(e){this.cascadeDirectionalLights=e}addPasses(e,t){if(this.explicitVolumes=t.volumes??[],this.volumeObjects=t.volumeObjects,this.extractedLights=t.lights,!this.options.enabled||0===this.explicitVolumes.length&&0===this.volumeObjects?.length)return this.activeLastFrame&&this.reset(),t.sceneColor;this.activeLastFrame=!0,e.createTextureTarget(this.integratedVolume,{dimension:"3d",depthOrArrayLayers:this.options.depthSlices,scale:1/this.options.froxelPixelSize,format:"rgba16float",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING}),e.createTextureTarget(this.columnDepthBounds,{scale:1/this.options.froxelPixelSize,format:"rg32float",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING});for(const t of[this.scatteringHistoryA,this.scatteringHistoryB])e.createTextureTarget(t,{dimension:"3d",depthOrArrayLayers:this.options.depthSlices,scale:1/this.options.froxelPixelSize,format:"rgba16float",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING});this.activeHistoryRead=0===this.froxelHistoryWriteIndex?this.scatteringHistoryB:this.scatteringHistoryA,this.activeHistoryWrite=0===this.froxelHistoryWriteIndex?this.scatteringHistoryA:this.scatteringHistoryB,e.addPass({name:"VolumetricFogFroxelPass",inputs:{sceneDepth:t.depth,scatteringHistory:this.activeHistoryRead},outputs:[this.integratedVolume,this.columnDepthBounds,this.activeHistoryWrite],execute:this.executeFroxelPass}),this.froxelHistoryWriteIndex=1-this.froxelHistoryWriteIndex;const r=e.createColorTarget(`${this.options.targetPrefix}Composite`,{format:"rgba16float"});return!1!==this.options.blur?this.addBlurredComposite(e,t,r):(this.compositePass&&this.compositePass.matches(t.sceneColor,t.depth,r)||(this.compositePass=new ce(t.sceneColor,t.depth,this.integratedVolume,this.columnDepthBounds,r,this.options.maxDistance,this.options.fogDitherStrength)),this.compositePass.setFrameIndex(this.frameIndex),e.addFullscreenPass(this.compositePass),r)}addBlurredComposite(e,t,r){const i=this.options.blur;if(!1===i)return r;const n=e.createColorTarget(`${this.options.targetPrefix}Resolved`,{format:"rgba16float",scale:i.scale}),a=e.createColorTarget(`${this.options.targetPrefix}BlurTemporary`,{format:"rgba16float",scale:i.scale}),s=e.createColorTarget(`${this.options.targetPrefix}Blurred`,{format:"rgba16float",scale:i.scale}),o=`resolve:${t.depth}:${n}`;let l=this.blurPassCache.get(o);l||(l=new ue(t.depth,this.integratedVolume,this.columnDepthBounds,n,this.options.maxDistance,this.options.fogDitherStrength),this.blurPassCache.set(o,l)),l.setFrameIndex(this.frameIndex),e.addFullscreenPass(l);const c=n;for(const[r,n,o]of[[c,a,[1,0]],[a,s,[0,1]]]){const a=`blur:${r}:${n}:${o[0]}:${i.radius}:${i.depthSigma}:${i.spatialSigma}`;let s=this.blurPassCache.get(a);s||(s=new he(r,t.depth,n,o,i),this.blurPassCache.set(a,s)),e.addFullscreenPass(s)}const u=`blurComposite:${t.sceneColor}:${t.depth}:${s}:${r}:${i.depthAwareUpsample}`;let d=this.blurPassCache.get(u);return d||(d=new pe(t.sceneColor,t.depth,s,this.integratedVolume,this.columnDepthBounds,r,i.depthAwareUpsample),this.blurPassCache.set(u,d)),e.addFullscreenPass(d),r}addTemporalPass(e,t,r,i){const n=this.options.temporal;if(!1===n)return r;const a=e.createColorTarget(`${this.options.targetPrefix}TemporalA`,{format:"rgba16float",scale:i}),s=e.createColorTarget(`${this.options.targetPrefix}TemporalB`,{format:"rgba16float",scale:i}),o=e.createColorTarget(`${this.options.targetPrefix}TemporalDepthA`,{format:"r16float",scale:i}),l=e.createColorTarget(`${this.options.targetPrefix}TemporalDepthB`,{format:"r16float",scale:i}),c=0===this.temporalWriteIndex?s:a,u=0===this.temporalWriteIndex?a:s,d=0===this.temporalWriteIndex?l:o,h=0===this.temporalWriteIndex?o:l,p=[r,t.depth,t.velocity??"camera",c,d,u,h].join(":");let f=this.temporalPassCache.get(p);return f||(f=new de(r,t.depth,t.velocity,c,d,u,h,n,this),this.temporalPassCache.set(p,f)),e.addFullscreenPass(f),this.temporalWriteIndex=1-this.temporalWriteIndex,u}consumeTemporalHistoryValid(){const e=this.temporalHistoryValid;return this.temporalHistoryValid=!0,e}updateTemporalUniforms(e,t,r,i,n){t.copy(te).multiply(n.camera.projectionMatrix).multiply(n.camera.matrixWorldInverse),r.copy(t).invert();const a=this.consumeTemporalHistoryValid();e.set(r.elements,0),e.set((a?this.previousTemporalViewProjection:t).elements,16),se(e,32,i.historyWeight,i.depthRejection,i.neighborhoodClamp?1:0,a?1:0),this.previousTemporalViewProjection.copy(t)}dispose(){this.compositePass=null,this.blurPassCache.clear(),this.temporalPassCache.clear()}executeFroxels(e){const t=this.getResources(e.device);this.collectSceneData(e.camera);const r=Math.max(.01,e.camera.near),i=Math.min(e.camera.far,this.options.maxDistance);e.camera.getWorldPosition(ie);let n=r+.01;for(let e=0;e<this.volumeCount;e++){const t=e*Q,r=this.volumeData[t]-ie.x,i=this.volumeData[t+1]-ie.y,a=this.volumeData[t+2]-ie.z;n=Math.max(n,Math.sqrt(r*r+i*i+a*a)+this.volumeData[t+3])}const a=Math.max(r+.01,Math.min(i,n));let s=a;for(let e=0;e<this.volumeCount;e++)s=Math.min(s,Math.max(this.volumeData[e*Q+10],r));s=Math.min(s,a);const o=Math.max(1,Math.floor(e.width/this.options.froxelPixelSize)),l=Math.max(1,Math.floor(e.height/this.options.froxelPixelSize));o===this.previousFroxelWidth&&l===this.previousFroxelHeight||(this.froxelHistoryValid=!1),this.projectionInverse.copy(te).multiply(e.camera.projectionMatrix).multiply(e.camera.matrixWorldInverse),this.viewProjectionInverse.copy(this.projectionInverse).invert(),this.uniforms.set(this.viewProjectionInverse.elements,0),this.uniforms[16]=e.camera.position.x,this.uniforms[17]=e.camera.position.y,this.uniforms[18]=e.camera.position.z,this.uniforms[19]=r,se(this.uniforms,20,o,l,this.options.depthSlices,a),this.uniformIntegers[24]=this.volumeCount,this.uniformIntegers[25]=this.directionalCount,this.uniformIntegers[26]=this.pointCount,this.uniformIntegers[27]=this.spotCount,se(this.uniforms,28,this.options.ambientColor.r,this.options.ambientColor.g,this.options.ambientColor.b,this.options.temporalJitter?this.frameIndex++%1024+1:0),e.camera.getWorldDirection(ie),se(this.uniforms,32,ie.x,ie.y,ie.z,Math.max(e.camera.far-r,1e-4)),se(this.uniforms,36,this.options.scatteringIntensity,this.options.spatialJitter?1:0,0,0),this.uniforms.set((this.froxelHistoryValid?this.previousFroxelViewProjection:this.projectionInverse).elements,40),se(this.uniforms,56,this.previousFroxelCameraPosition.x,this.previousFroxelCameraPosition.y,this.previousFroxelCameraPosition.z,this.froxelHistoryValid&&!1!==this.options.temporal?1:0),se(this.uniforms,60,this.previousFroxelNear,this.previousFroxelFar,!1===this.options.temporal?0:this.options.temporal.historyWeight,0),e.device.queue.writeBuffer(t.uniformBuffer,0,this.uniforms),this.volumeCount>0&&e.device.queue.writeBuffer(t.volumeBuffer,0,this.volumeData.buffer,this.volumeData.byteOffset,this.volumeCount*Q*4);const c=this.directionalCount+this.pointCount+this.spotCount;c>0&&e.device.queue.writeBuffer(t.lightBuffer,0,this.lightData.buffer,this.lightData.byteOffset,c*ee*4);const u=e.getSceneLightingResources(),d=e.getTextureView(this.integratedVolume),h=e.getTextureView(this.columnDepthBounds),p=e.getTextureView(this.activeHistoryRead),f=e.getTextureView(this.activeHistoryWrite),m=e.depthView,g=t.bindGroupResources;t.bindGroup&&g&&g.integratedVolumeView===d&&g.historyReadView===p&&g.historyWriteView===f&&g.lightBuffer===u.lightBuffer&&g.comparisonSampler===e.comparisonSampler&&g.directionalShadowView===u.directionalShadowView&&g.pointShadowView===u.pointShadowView&&g.spotShadowView===u.spotShadowView&&g.spotLightMapView===u.spotLightMapView&&g.depthView===m&&g.columnDepthBoundsView===h||(t.bindGroup=e.device.createBindGroup({label:"volumetric-fog-bind-group",layout:t.layout,entries:[{binding:0,resource:{buffer:t.uniformBuffer}},{binding:1,resource:{buffer:t.volumeBuffer}},{binding:2,resource:{buffer:t.lightBuffer}},{binding:3,resource:d},{binding:4,resource:{buffer:u.lightBuffer}},{binding:5,resource:e.comparisonSampler},{binding:6,resource:u.directionalShadowView},{binding:7,resource:u.pointShadowView},{binding:8,resource:u.spotShadowView},{binding:9,resource:m},{binding:10,resource:h},{binding:11,resource:e.linearClampSampler},{binding:12,resource:p},{binding:13,resource:f},{binding:14,resource:u.spotLightMapView}]}),t.bindGroupResources={integratedVolumeView:d,historyReadView:p,historyWriteView:f,lightBuffer:u.lightBuffer,comparisonSampler:e.comparisonSampler,directionalShadowView:u.directionalShadowView,pointShadowView:u.pointShadowView,spotShadowView:u.spotShadowView,spotLightMapView:u.spotLightMapView,depthView:m,columnDepthBoundsView:h});const v=e.encoder.beginComputePass(ae);v.setPipeline(t.pipeline),v.setBindGroup(0,t.bindGroup),v.dispatchWorkgroups(Math.ceil(o/8),Math.ceil(l/8)),v.end(),this.previousFroxelViewProjection.copy(this.projectionInverse),this.previousFroxelCameraPosition.set(this.uniforms[16],this.uniforms[17],this.uniforms[18]),this.previousFroxelNear=s,this.previousFroxelFar=a,this.previousFroxelWidth=o,this.previousFroxelHeight=l,this.froxelHistoryValid=!0}collectSceneData(e){const t=this.collectedVolumes,r=this.collectedDirectionals,i=this.collectedPoints,n=this.collectedSpots;t.length=0,r.length=0,i.length=0,n.length=0;for(const e of this.explicitVolumes)t.push(e);for(const t of this.cascadeDirectionalLights)t.visible&&t.layers.test(e.layers)&&!r.includes(t)&&r.push(t);if(void 0===this.volumeObjects)this.scene.traverseVisible(this.collectVolumeObject);else for(const e of this.volumeObjects)this.collectVolumeObject(e);void 0===this.extractedLights&&(this.collectionCamera=e,this.scene.traverseVisible(this.collectLightObject),this.collectionCamera=null);const a=Math.min(t.length,this.options.maxVolumes);this.volumeData.fill(0,0,a*Q);for(let e=0;e<a;e++)this.writeVolume(e,t[e]);const s=Math.min(this.extractedLights?.directionals.length??r.length,this.options.maxDirectionalLights),o=this.extractedLights?.points,l=this.extractedLights?.spots,c=this.selectClosestLights(o??i,e,this.selectedPointIndices,this.selectedPointScores),u=this.selectClosestLights(l??n,e,this.selectedSpotIndices,this.selectedSpotScores);this.lightData.fill(0,0,(s+c+u)*ee);let d=0;for(let e=0;e<s;e++){const t=this.extractedLights?.directionals[e];t?this.writeExtractedDirectional(d++,t):this.writeDirectional(d++,r[e])}for(let e=0;e<c;e++){const t=this.selectedPointIndices[e];o?this.writeExtractedPoint(d++,o[t],t):this.writePoint(d++,i[t])}for(let e=0;e<u;e++){const t=this.selectedSpotIndices[e];l?this.writeExtractedSpot(d++,l[t],t):this.writeSpot(d++,n[t])}this.volumeCount=a,this.directionalCount=s,this.pointCount=c,this.spotCount=u}selectClosestLights(e,t,r,i){const n=r.length;if(0===n)return 0;t.getWorldPosition(ie);let a=0;for(let t=0;t<e.length;t+=1){const s=e[t],o=Number(s instanceof H?s.userData?.volumetricIntensity??0:s.volumetricIntensity);if(!Number.isFinite(o)||o<=0)continue;const l=s instanceof H?s.getWorldPosition(re):s.position,c=ie.distanceToSquared(l);if(a===n&&c>=i[n-1])continue;let u=Math.min(a,n-1);for(;u>0&&c<i[u-1];)u<n&&(i[u]=i[u-1],r[u]=r[u-1]),u-=1;i[u]=c,r[u]=t,a<n&&(a+=1)}return a}writeVolume(e,t){const r=e*Q;t.object.getWorldPosition(re),t.object.getWorldScale(ne),se(this.volumeData,r,re.x,re.y,re.z,5*Math.max(ne.x,ne.y,ne.z)),se(this.volumeData,r+4,t.albedo.r,t.albedo.g,t.albedo.b,Math.max(0,t.baseDensity)),se(this.volumeData,r+8,t.heightFalloff,t.heightOffset,t.startDistance??3,-Math.max(-.99,Math.min(.99,t.scatteringDistribution))),se(this.volumeData,r+12,t.emissive.r,t.emissive.g,t.emissive.b,t.ambientIntensity??1),this.volumeData[r+16]="lightShaft"===t.scatteringMode?1:0}writeDirectional(e,t){const r=e*ee;t.getWorldPosition(re),t.target.getWorldPosition(ie),ie.sub(re).normalize(),se(this.lightData,r,ie.x,ie.y,ie.z,0);const i=t.intensity*(t.userData?.volumetricIntensity??1);se(this.lightData,r+4,t.color.r*i,t.color.g*i,t.color.b*i,0)}writeExtractedDirectional(e,t){const r=e*ee;se(this.lightData,r,t.direction.x,t.direction.y,t.direction.z,0);const i=t.intensity*t.volumetricIntensity;se(this.lightData,r+4,t.color.x*i,t.color.y*i,t.color.z*i,0)}writePoint(e,t,r=e){const i=e*ee;t.getWorldPosition(re),se(this.lightData,i,re.x,re.y,re.z,Math.max(.001,t.distance||this.options.maxDistance));const n=t.intensity*(t.userData?.volumetricIntensity??1);se(this.lightData,i+4,t.color.r*n,t.color.g*n,t.color.b*n,Math.max(0,t.decay)),this.lightData[i+13]=r}writeExtractedPoint(e,t,r){const i=e*ee;se(this.lightData,i,t.position.x,t.position.y,t.position.z,Math.max(.001,t.range||this.options.maxDistance));const n=t.intensity*t.volumetricIntensity;se(this.lightData,i+4,t.color.x*n,t.color.y*n,t.color.z*n,Math.max(0,t.decay)),this.lightData[i+13]=r,this.lightData[i+14]=1}writeSpot(e,t,r=e){const i=e*ee;t.getWorldPosition(re),t.target.getWorldPosition(ie),ie.sub(re).normalize(),se(this.lightData,i,re.x,re.y,re.z,Math.max(.001,t.distance||this.options.maxDistance));const n=t.intensity*(t.userData?.volumetricIntensity??1);se(this.lightData,i+4,t.color.r*n,t.color.g*n,t.color.b*n,Math.max(0,t.decay)),se(this.lightData,i+8,ie.x,ie.y,ie.z,Math.cos(t.angle)),this.lightData[i+12]=Math.cos(t.angle*(1-t.penumbra)),this.lightData[i+13]=r}writeExtractedSpot(e,t,r){const i=e*ee;se(this.lightData,i,t.position.x,t.position.y,t.position.z,Math.max(.001,t.range||this.options.maxDistance));const n=t.intensity*t.volumetricIntensity;se(this.lightData,i+4,t.color.x*n,t.color.y*n,t.color.z*n,Math.max(0,t.decay)),se(this.lightData,i+8,t.direction.x,t.direction.y,t.direction.z,Math.cos(t.angle)),this.lightData[i+12]=Math.cos(t.angle*(1-t.penumbra)),this.lightData[i+13]=r,this.lightData[i+14]=1}getResources(e){let t=this.resources.get(e);t||(t=new Map,this.resources.set(e,t));const r=[this.options.shadowFilterTaps,this.options.integrationSubsteps,this.options.maxVolumes,this.options.maxDirectionalLights,this.options.maxPointLights,this.options.maxSpotLights].join(":"),i=t.get(r);if(i)return i;const n=e.createBuffer({size:256,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),a=e.createBuffer({size:this.volumeData.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),s=e.createBuffer({size:this.lightData.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),o=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"rgba16float",viewDimension:"3d"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:5,visibility:GPUShaderStage.COMPUTE,sampler:{type:"comparison"}},{binding:6,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:7,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"float",viewDimension:"2d-array"}},{binding:8,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:9,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"depth",viewDimension:"2d"}},{binding:10,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"rg32float",viewDimension:"2d"}},{binding:11,visibility:GPUShaderStage.COMPUTE,sampler:{type:"filtering"}},{binding:12,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"float",viewDimension:"3d"}},{binding:13,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"rgba16float",viewDimension:"3d"}},{binding:14,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"float",viewDimension:"2d"}}]}),l=e.createShaderModule({label:"volumetric-fog-compute",code:ge.replace("__SHADOW_TAPS__",String(this.options.shadowFilterTaps)).replace("__INTEGRATION_SUBSTEPS__",String(this.options.integrationSubsteps))}),c={uniformBuffer:n,volumeBuffer:a,lightBuffer:s,layout:o,pipeline:e.createComputePipeline({layout:e.createPipelineLayout({bindGroupLayouts:[o]}),compute:{module:l,entryPoint:"main"}})};return t.set(r,c),c}};function le(e){return{enabled:e.enabled??!0,froxelPixelSize:Math.max(2,Math.floor(e.froxelPixelSize??8)),depthSlices:Math.max(8,Math.floor(e.depthSlices??64)),integrationSubsteps:e.integrationSubsteps??1,maxDistance:Math.max(1,e.maxDistance??256),targetPrefix:e.targetPrefix??"volumetricFog",maxVolumes:Math.max(1,Math.floor(e.maxVolumes??32)),maxDirectionalLights:Math.min(4,Math.max(1,Math.floor(e.maxDirectionalLights??4))),maxPointLights:Math.min(4,Math.max(0,Math.floor(e.maxPointLights??4))),maxSpotLights:Math.min(4,Math.max(0,Math.floor(e.maxSpotLights??4))),ambientColor:e.ambientColor?.clone()??new W(.03,.035,.045),shadowFilterTaps:e.shadowFilterTaps??1,temporalJitter:e.temporalJitter??!0,temporal:!1!==e.temporal&&{historyWeight:Math.min(.98,Math.max(0,e.temporal?.historyWeight??.92)),depthRejection:Math.max(1e-4,e.temporal?.depthRejection??.04),neighborhoodClamp:e.temporal?.neighborhoodClamp??!0},spatialJitter:e.spatialJitter??!0,fogDitherStrength:Math.max(0,e.fogDitherStrength??.75),scatteringIntensity:Math.max(0,e.scatteringIntensity??1),blur:!1!==e.blur&&{scale:Math.max(.125,Math.min(1,e.blur?.scale??.5)),radius:Math.max(1,Math.min(12,Math.floor(e.blur?.radius??3))),depthSigma:Math.max(1e-4,e.blur?.depthSigma??.05),spatialSigma:Math.max(.1,e.blur?.spatialSigma??2),depthAwareUpsample:e.blur?.depthAwareUpsample??!0}}}var ce=class{constructor(e,t,r,i,n,a,s){this.maxDistance=a,this.ditherStrength=s,this.inputs={sceneColor:e,sceneDepth:t,fogVolume:r,fogBounds:i},this.outputs=n}maxDistance;ditherStrength;name="VolumetricFogCompositePass";sampler="linear";uniformBufferSize=80;inputs;inputDimensions={fogVolume:"3d"};outputs;fragmentShader=ve;data=new Float32Array(20);inverseProjection=new _;frameIndex=0;setFrameIndex(e){this.frameIndex=e}matches(e,t,r){return this.inputs.sceneColor===e&&this.inputs.sceneDepth===t&&this.outputs===r}updateUniforms=e=>(this.inverseProjection.copy(te).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),se(this.data,16,Math.max(.01,e.camera.near),Math.min(e.camera.far,this.maxDistance),this.frameIndex>0?this.frameIndex%1024:-1,this.ditherStrength),this.data)},ue=class{constructor(e,t,r,i,n,a){this.maxDistance=n,this.ditherStrength=a,this.inputs={sceneDepth:e,fogVolume:t,fogBounds:r},this.outputs=i}maxDistance;ditherStrength;name="VolumetricFogResolvePass";sampler="linear";uniformBufferSize=80;inputDimensions={fogVolume:"3d"};inputs;outputs;fragmentShader=xe;data=new Float32Array(20);inverseProjection=new _;frameIndex=0;setFrameIndex(e){this.frameIndex=e}updateUniforms=e=>(this.inverseProjection.copy(te).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),se(this.data,16,Math.max(.01,e.camera.near),Math.min(e.camera.far,this.maxDistance),this.frameIndex>0?this.frameIndex%1024:-1,this.ditherStrength),this.data)},de=class{constructor(e,t,r,i,n,a,s,o,l){var c;this.temporal=o,this.state=l,this.inputs=null==r?{currentFog:e,sceneDepth:t,historyFog:i,historyDepth:n}:{currentFog:e,sceneDepth:t,historyFog:i,historyDepth:n,velocity:r},this.outputs=[a,s],this.fragmentShader=`\nstruct FogTemporalOutput{\n @location(0) fog:vec4<f32>,\n @location(1) depth:vec4<f32>,\n};\nfn currentViewProjectionInverse()->mat4x4<f32>{\n return mat4x4<f32>(fullscreenUniforms[0],fullscreenUniforms[1],fullscreenUniforms[2],fullscreenUniforms[3]);\n}\nfn previousViewProjection()->mat4x4<f32>{\n return mat4x4<f32>(fullscreenUniforms[4],fullscreenUniforms[5],fullscreenUniforms[6],fullscreenUniforms[7]);\n}\nfn loadCurrentFog(pixel:vec2<i32>,size:vec2<i32>)->vec4<f32>{\n return textureLoad(currentFogTexture,clamp(pixel,vec2<i32>(0),size-vec2<i32>(1)),0);\n}\nfn loadHistoryFog(pixel:vec2<i32>,size:vec2<i32>)->vec4<f32>{\n return textureLoad(historyFogTexture,clamp(pixel,vec2<i32>(0),size-vec2<i32>(1)),0);\n}\nfn sampleHistoryBilinear(uv:vec2<f32>)->vec4<f32>{\n let size=vec2<i32>(textureDimensions(historyFogTexture));\n let position=uv*vec2<f32>(size)-0.5;\n let base=vec2<i32>(floor(position));\n let f=fract(position);\n let a=mix(loadHistoryFog(base,size),loadHistoryFog(base+vec2<i32>(1,0),size),f.x);\n let b=mix(loadHistoryFog(base+vec2<i32>(0,1),size),loadHistoryFog(base+vec2<i32>(1,1),size),f.x);\n return mix(a,b,f.y);\n}\nfn loadSceneDepth(uv:vec2<f32>)->f32{\n let size=vec2<i32>(textureDimensions(sceneDepthTexture));\n let pixel=clamp(vec2<i32>(uv*vec2<f32>(size)),vec2<i32>(0),size-vec2<i32>(1));\n return textureLoad(sceneDepthTexture,pixel,0);\n}\nfn loadHistoryDepth(uv:vec2<f32>)->f32{\n let size=vec2<i32>(textureDimensions(historyDepthTexture));\n let pixel=clamp(vec2<i32>(uv*vec2<f32>(size)),vec2<i32>(0),size-vec2<i32>(1));\n return textureLoad(historyDepthTexture,pixel,0).r;\n}\n${(c=null!=r)?"\nfn loadVelocity(uv:vec2<f32>)->vec2<f32>{\n let size=vec2<i32>(textureDimensions(velocityTexture));\n let pixel=clamp(vec2<i32>(uv*vec2<f32>(size)),vec2<i32>(0),size-vec2<i32>(1));\n return textureLoad(velocityTexture,pixel,0).xy;\n}\n":""}\n@fragment fn fsMain(input:FullscreenVertexOutput)->FogTemporalOutput{\n let size=vec2<i32>(textureDimensions(currentFogTexture));\n let pixel=clamp(vec2<i32>(input.position.xy),vec2<i32>(0),size-vec2<i32>(1));\n let uv=(vec2<f32>(pixel)+0.5)/vec2<f32>(size);\n let current=textureLoad(currentFogTexture,pixel,0);\n var neighborhoodMin=current;\n var neighborhoodMax=current;\n for(var y=-1;y<=1;y+=1){\n for(var x=-1;x<=1;x+=1){\n let value=loadCurrentFog(pixel+vec2<i32>(x,y),size);\n neighborhoodMin=min(neighborhoodMin,value);\n neighborhoodMax=max(neighborhoodMax,value);\n }\n }\n let rawDepth=loadSceneDepth(uv);\n let clip=vec4<f32>(uv.x*2.0-1.0,1.0-uv.y*2.0,rawDepth,1.0);\n let worldH=currentViewProjectionInverse()*clip;\n let world=worldH/worldH.w;\n let previousClip=previousViewProjection()*world;\n let previousNdc=previousClip.xy/previousClip.w;\n let cameraHistoryUv=vec2<f32>(previousNdc.x*0.5+0.5,0.5-previousNdc.y*0.5);\n${c?"\n let velocity=loadVelocity(uv);\n let finiteVelocity=all(velocity==velocity)&&all(abs(velocity)<vec2<f32>(2.0));\n let hasUsefulVelocity=finiteVelocity&&dot(velocity,velocity)>1e-12;\n let historyUv=select(cameraHistoryUv,uv-velocity,hasUsefulVelocity);\n":"\n let historyUv=cameraHistoryUv;\n"}\n let validUv=all(historyUv>=vec2<f32>(0.0))&&all(historyUv<=vec2<f32>(1.0));\n let historyValid=fullscreenUniforms[8].w>0.5&&validUv;\n let history=sampleHistoryBilinear(clamp(historyUv,vec2<f32>(0.0),vec2<f32>(1.0)));\n let previousDistance=loadHistoryDepth(clamp(historyUv,vec2<f32>(0.0),vec2<f32>(1.0)));\n let currentDistance=length(world.xyz-fullscreenUniforms[9].xyz);\n let relativeDepthDelta=abs(log(max(previousDistance,0.001)/max(currentDistance,0.001)));\n let rejection=max(fullscreenUniforms[8].y,0.0001);\n let depthWeight=exp(-relativeDepthDelta*relativeDepthDelta/(rejection*rejection));\n let clampedHistory=select(history,clamp(history,neighborhoodMin,neighborhoodMax),fullscreenUniforms[8].z>0.5);\n let historyWeight=select(0.0,fullscreenUniforms[8].x*depthWeight,historyValid);\n var output:FogTemporalOutput;\n output.fog=mix(current,clampedHistory,clamp(historyWeight,0.0,0.98));\n output.depth=vec4<f32>(min(currentDistance,65504.0),0.0,0.0,1.0);\n return output;\n}`}temporal;state;name="VolumetricFogTemporalPass";sampler="nearest";uniformBufferSize=160;inputs;outputs;fragmentShader;uniforms=new Float32Array(this.uniformBufferSize/4);currentViewProjection=new _;currentViewProjectionInverse=new _;updateUniforms=e=>(this.state.updateTemporalUniforms(this.uniforms,this.currentViewProjection,this.currentViewProjectionInverse,this.temporal,e),se(this.uniforms,36,e.camera.position.x,e.camera.position.y,e.camera.position.z,e.camera.far),this.uniforms)},he=class{name;sampler="linear";uniformBufferSize=80;inputs;outputs;fragmentShader;data=new Float32Array(20);inverseProjection=new _;constructor(e,t,r,i,n){this.name=i[0]?"VolumetricFogBlurHorizontalPass":"VolumetricFogBlurVerticalPass",this.inputs={fogInput:e,sceneDepth:t},this.outputs=r,this.data.set([i[0],i[1],n.depthSigma,n.spatialSigma],16),this.fragmentShader=`\nconst BLUR_RADIUS:i32=${n.radius};\nfn inverseProjection() -> mat4x4<f32> { return mat4x4<f32>(fullscreenUniforms[0],fullscreenUniforms[1],fullscreenUniforms[2],fullscreenUniforms[3]); }\nfn viewDistance(uv:vec2<f32>)->f32 { let size=vec2<i32>(textureDimensions(sceneDepthTexture));let pixel=clamp(vec2<i32>(uv*vec2<f32>(size)),vec2<i32>(0),size-vec2<i32>(1));let depth=textureLoad(sceneDepthTexture,pixel,0);let clip=vec4<f32>(uv.x*2.0-1.0,1.0-uv.y*2.0,depth,1.0);let view=inverseProjection()*clip;return length(view.xyz/view.w); }\n@fragment fn fsMain(input:FullscreenVertexOutput)->@location(0) vec4<f32>{\n let size=vec2<f32>(textureDimensions(fogInputTexture));let texel=1.0/size;let direction=fullscreenUniforms[4].xy;let depthSigma=fullscreenUniforms[4].z;let spatialSigma=fullscreenUniforms[4].w;\n let centerDepth=viewDistance(input.uv);var sum=vec4<f32>(0.0);var weightSum=0.0;\n for(var i=-BLUR_RADIUS;i<=BLUR_RADIUS;i+=1){let uv=clamp(input.uv+direction*f32(i)*texel,vec2<f32>(0.0),vec2<f32>(1.0));let sampleDepth=viewDistance(uv);let fi=f32(i);let spatial=exp(-0.5*fi*fi/(spatialSigma*spatialSigma));let delta=log(max(sampleDepth,0.0001)/max(centerDepth,0.0001));let depthWeight=exp(-0.5*delta*delta/(depthSigma*depthSigma));let weight=spatial*depthWeight;sum+=textureSampleLevel(fogInputTexture,fullscreenSampler,uv,0.0)*weight;weightSum+=weight;}\n return sum/max(weightSum,0.0001);\n}`}updateUniforms=e=>(this.inverseProjection.copy(te).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),this.data)},pe=class{name="VolumetricFogBlurCompositePass";sampler="linear";uniformBufferSize=64;inputs;inputDimensions={};outputs;fragmentShader;data=new Float32Array(16);inverseProjection=new _;constructor(e,t,r,i,n,a,s){this.inputs=s?{sceneColor:e,sceneDepth:t,fogInput:r}:{sceneColor:e,fogInput:r},this.outputs=a,this.fragmentShader=s?we:be}updateUniforms=e=>(this.inverseProjection.copy(te).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements),this.data)},fe="\nfn rendererSampleIntegratedFogRaw(uv: vec2<f32>, normalizedDepth: f32) -> vec4<f32> {\n let sliceCount = f32(textureDimensions(volumetricFogTexture).z);\n let slicePosition = clamp(normalizedDepth, 0.0, 1.0) * sliceCount;\n let textureZ = clamp((slicePosition - 0.5) / sliceCount, 0.0, 1.0);\n let integrated = textureSampleLevel(volumetricFogTexture, volumetricFogSampler, vec3<f32>(uv, textureZ), 0.0);\n // The volume stores slice endpoints but has no texel for the near-plane\n // identity value. Reconstruct that missing endpoint for the first slice.\n return mix(vec4<f32>(0.0, 0.0, 0.0, 1.0), integrated, min(slicePosition, 1.0));\n}\nfn rendererSampleIntegratedFog(uv: vec2<f32>, normalizedDepth: f32) -> vec4<f32> {\n return rendererSampleIntegratedFogRaw(uv, normalizedDepth);\n}\nfn rendererApplyVolumetricFog(color: vec4<f32>, worldPosition: vec3<f32>) -> vec4<f32> {\n let clip = rendererCamera.viewProj * vec4<f32>(worldPosition, 1.0);\n let uv = clip.xy / clip.w * vec2<f32>(0.5, -0.5) + vec2<f32>(0.5);\n let distance = length(worldPosition - rendererCamera.cameraPosition.xyz);\n let bounds = textureSampleLevel(volumetricFogBoundsTexture, volumetricFogBoundsSampler, uv, 0.0).rg;\n let z = clamp(log(max(distance, bounds.x) / bounds.x) / max(log(bounds.y / bounds.x), 0.0001), 0.0, 1.0);\n let fog = rendererSampleIntegratedFog(uv, z);\n return vec4<f32>(fog.rgb + color.rgb * fog.a, color.a);\n}";function me(e,t="volumetricFogIntegrated",r=(t.endsWith("Integrated")?`${t.slice(0,-10)}DepthBounds`:"volumetricFogDepthBounds")){return e.graphTextures.volumetricFog={resource:t,dimension:"3d",sampleType:"float",sampler:"filtering",requiresLatePass:!0},e.graphTextures.volumetricFogBounds={resource:r,dimension:"2d",sampleType:"float",sampler:"filtering",requiresLatePass:!0},e.needsUpdate=!0,e}var ge="\nstruct FogUniforms { inverseViewProjection: mat4x4<f32>, cameraNear: vec4<f32>, dimensionsFar: vec4<f32>, counts: vec4<u32>, ambient: vec4<f32>, cameraForwardDepthRange: vec4<f32>, scattering: vec4<f32>, previousViewProjection: mat4x4<f32>, historyCameraValid: vec4<f32>, historyNearFarWeight: vec4<f32> };\nstruct FogVolume { centerRadius: vec4<f32>, albedoDensity: vec4<f32>, heightStartPhase: vec4<f32>, emissiveAmbient: vec4<f32>, mode: vec4<f32> };\nstruct FogLight { positionRange: vec4<f32>, colorDecay: vec4<f32>, directionCone: vec4<f32>, penumbra: vec4<f32> };\nstruct RendererLightUniforms {\n ambientColor: vec4<f32>, lightCounts: vec4<f32>,\n directionalDirections: array<vec4<f32>,4>, directionalColorIntensities: array<vec4<f32>,4>,\n directionalShadowParams: array<vec4<f32>,4>, directionalShadowParams2: array<vec4<f32>,4>, directionalShadowMatrices: array<mat4x4<f32>,4>,\n pointPositionRanges: array<vec4<f32>,64>, pointColorIntensities: array<vec4<f32>,64>, pointParams: array<vec4<f32>,64>, pointShadowParams: array<vec4<f32>,64>, pointShadowParams2: array<vec4<f32>,64>,\n spotPositionRanges: array<vec4<f32>,64>, spotDirectionCones: array<vec4<f32>,64>, spotColorIntensities: array<vec4<f32>,64>,\n spotShadowParams: array<vec4<f32>,64>, spotShadowParams2: array<vec4<f32>,64>, spotParams: array<vec4<f32>,64>, spotShadowMatrices: array<mat4x4<f32>,64>,\n csmCascadeRanges: array<vec4<f32>,4>, hemisphereSkyColorIntensity: vec4<f32>, hemisphereGroundColorIntensity: vec4<f32>, hemisphereDirection: vec4<f32>\n};\n@group(0) @binding(0) var<uniform> uniforms: FogUniforms;\n@group(0) @binding(1) var<storage, read> volumes: array<FogVolume>;\n@group(0) @binding(2) var<storage, read> lights: array<FogLight>;\n@group(0) @binding(3) var outputFog: texture_storage_3d<rgba16float, write>;\n@group(0) @binding(4) var<uniform> rendererLights: RendererLightUniforms;\n@group(0) @binding(5) var shadowSampler: sampler_comparison;\n@group(0) @binding(6) var directionalShadows: texture_depth_2d_array;\n@group(0) @binding(7) var pointShadows: texture_2d_array<f32>;\n@group(0) @binding(8) var spotShadows: texture_depth_2d_array;\n@group(0) @binding(9) var sceneDepth: texture_depth_2d;\n@group(0) @binding(10) var outputDepthBounds: texture_storage_2d<rg32float, write>;\n@group(0) @binding(11) var historySampler: sampler;\n@group(0) @binding(12) var scatteringHistory: texture_3d<f32>;\n@group(0) @binding(13) var outputScatteringHistory: texture_storage_3d<rgba16float, write>;\n@group(0) @binding(14) var spotLightMapAtlas: texture_2d<f32>;\nconst PI = 3.14159265359;\nconst SHADOW_TAPS = __SHADOW_TAPS__;\nconst INTEGRATION_SUBSTEPS = __INTEGRATION_SUBSTEPS__;\nfn phaseHG(cosTheta: f32, g: f32) -> f32 { let gg = g*g; return (1.0-gg)/(4.0*PI*pow(max(0.001,1.0+gg-2.0*g*cosTheta),1.5)); }\nfn attenuation(distance: f32, range: f32, decay: f32) -> f32 { let window = max(0.0, 1.0-pow(distance/range,4.0)); return window*window / max(1.0, pow(distance, decay)); }\nfn spotConeAttenuation(angleCos: f32, coneCos: f32, penumbraCos: f32) -> f32 {\n // Three.js spotlights default to a zero-width penumbra. smoothstep() is\n // undefined when both edges are equal, so use a hard cutoff in that case.\n let width = penumbraCos - coneCos;\n if (width <= 0.000001) { return select(0.0, 1.0, angleCos >= coneCos); }\n return smoothstep(coneCos, penumbraCos, angleCos);\n}\nfn hash12(p:vec2<f32>)->f32 { let p3=fract(vec3<f32>(p.xyx)*0.1031); let q=p3+dot(p3,p3.yzx+33.33); return fract((q.x+q.y)*q.z); }\nfn halton(index:u32,base:u32)->f32{var i=index;var fraction=1.0;var result=0.0;loop{if(i==0u){break;}fraction/=f32(base);result+=fraction*f32(i%base);i/=base;}return result;}\nfn rotatedOffset(tap:i32, angle:f32)->vec2<f32> {\n let disk=array<vec2<f32>,4>(vec2<f32>(-0.326,-0.406),vec2<f32>(-0.840,0.074),vec2<f32>(-0.696,0.457),vec2<f32>(0.203,0.621));\n let v=disk[tap]; let c=cos(angle); let s=sin(angle); return vec2<f32>(c*v.x-s*v.y,s*v.x+c*v.y);\n}\nfn projectedShadow(matrix: mat4x4<f32>, p: vec3<f32>, layer: i32, bias: f32, intensity: f32, textureKind: u32) -> f32 {\n let clip=matrix*vec4<f32>(p,1.0); if (clip.w<=0.0) { return 1.0; } let ndc=clip.xyz/clip.w;\n if (ndc.x < -1.0 || ndc.x > 1.0 || ndc.y < -1.0 || ndc.y > 1.0 || ndc.z < 0.0 || ndc.z > 1.0) { return 1.0; }\n let uv=ndc.xy*vec2<f32>(0.5,-0.5)+vec2<f32>(0.5); var visibility=0.0;\n // Avoid a world-space random pattern swimming through the camera-relative grid.\n let angle=select(0.0,hash12(p.xz+vec2<f32>(uniforms.ambient.w, f32(layer)))*6.2831853,uniforms.ambient.w>0.0);\n if (textureKind==0u) {\n let dims=vec2<f32>(textureDimensions(directionalShadows)); let radius=max(rendererLights.directionalShadowParams2[u32(layer)].x,0.0);let offset=radius/dims;let depth=ndc.z+bias;\n // Match the surface-lighting path: a weighted hardware-PCF center and\n // four cardinal taps. The former sparse rotated disk made partially\n // shadowed froxels jump between a few discrete visibility values.\n let center=textureSampleCompareLevel(directionalShadows,shadowSampler,uv,layer,depth);\n if(SHADOW_TAPS==1){\n visibility=center;\n }else{\n let left=textureSampleCompareLevel(directionalShadows,shadowSampler,clamp(uv-vec2<f32>(offset.x,0.0),vec2<f32>(0.0),vec2<f32>(1.0)),layer,depth);\n let right=textureSampleCompareLevel(directionalShadows,shadowSampler,clamp(uv+vec2<f32>(offset.x,0.0),vec2<f32>(0.0),vec2<f32>(1.0)),layer,depth);\n let up=textureSampleCompareLevel(directionalShadows,shadowSampler,clamp(uv-vec2<f32>(0.0,offset.y),vec2<f32>(0.0),vec2<f32>(1.0)),layer,depth);\n let down=textureSampleCompareLevel(directionalShadows,shadowSampler,clamp(uv+vec2<f32>(0.0,offset.y),vec2<f32>(0.0),vec2<f32>(1.0)),layer,depth);\n visibility=(center*4.0+left+right+up+down)*0.5;\n }\n } else {\n let dims=vec2<f32>(textureDimensions(spotShadows)); let radius=max(rendererLights.spotShadowParams2[u32(layer)].x,1.0);\n for(var tap=0;tap<SHADOW_TAPS;tap+=1){let suv=clamp(uv+rotatedOffset(tap,angle)*radius/dims,vec2<f32>(0.0),vec2<f32>(1.0));let pixel=vec2<i32>(clamp(suv*dims,vec2<f32>(0.0),dims-1.0));visibility+=select(0.0,1.0,ndc.z-bias<=textureLoad(spotShadows,pixel,layer,0));}\n }\n visibility/=f32(SHADOW_TAPS);\n return mix(1.0,visibility,intensity);\n}\nfn pointShadowUvLayer(direction: vec3<f32>, index: u32) -> vec3<f32> {\n let a=abs(direction); var face=0u; var uv=vec2<f32>(0.0);\n if (a.x>=a.y && a.x>=a.z) { if(direction.x>=0.0){face=0u;uv=vec2<f32>(-direction.z,-direction.y)/a.x;}else{face=1u;uv=vec2<f32>(direction.z,-direction.y)/a.x;} }\n else if(a.y>=a.x && a.y>=a.z){if(direction.y>=0.0){face=2u;uv=vec2<f32>(direction.x,direction.z)/a.y;}else{face=3u;uv=vec2<f32>(direction.x,-direction.z)/a.y;}}\n else{if(direction.z>=0.0){face=4u;uv=vec2<f32>(direction.x,-direction.y)/a.z;}else{face=5u;uv=vec2<f32>(-direction.x,-direction.y)/a.z;}}\n return vec3<f32>(uv*0.5+0.5,f32(index*6u+face));\n}\nfn directionalVisibility(index:u32,p:vec3<f32>)->f32 { let sp=rendererLights.directionalShadowParams[index]; if(sp.y<0.5){return 1.0;} return projectedShadow(rendererLights.directionalShadowMatrices[index],p,i32(index),sp.x,rendererLights.directionalShadowParams2[index].y,0u); }\nfn pointVisibility(index:u32,p:vec3<f32>)->f32 { let sp=rendererLights.pointShadowParams[index]; if(sp.y<0.5){return 1.0;} let delta=p-rendererLights.pointPositionRanges[index].xyz; let range=rendererLights.pointPositionRanges[index].w; let uv=pointShadowUvLayer(delta,index); let dims=vec2<f32>(textureDimensions(pointShadows)); let angle=select(0.0,hash12(p.xy+vec2<f32>(uniforms.ambient.w,f32(index)))*6.2831853,uniforms.ambient.w>0.0); var visible=0.0; for(var tap=0;tap<SHADOW_TAPS;tap+=1){let suv=clamp(uv.xy+rotatedOffset(tap,angle)/dims,vec2<f32>(0.0),vec2<f32>(1.0));let pixel=vec2<i32>(clamp(suv*dims,vec2<f32>(0.0),dims-1.0));let stored=textureLoad(pointShadows,pixel,i32(round(uv.z)),0).r;visible+=select(0.0,1.0,length(delta)/max(range,0.0001)-sp.x<=stored);} visible/=f32(SHADOW_TAPS); return mix(1.0,visible,rendererLights.pointShadowParams2[index].y); }\nfn spotVisibility(index:u32,p:vec3<f32>)->f32 { let sp=rendererLights.spotShadowParams[index]; if(sp.y<0.5){return 1.0;} return projectedShadow(rendererLights.spotShadowMatrices[index],p,i32(index),sp.x,rendererLights.spotShadowParams2[index].y,1u); }\nfn fogPointVisibility(light:FogLight,p:vec3<f32>)->f32 { if(light.penumbra.z<0.5){return 1.0;} return pointVisibility(u32(round(light.penumbra.y)),p); }\nfn fogSpotVisibility(light:FogLight,p:vec3<f32>)->f32 { if(light.penumbra.z<0.5){return 1.0;} return spotVisibility(u32(round(light.penumbra.y)),p); }\nfn fogSpotMap(light:FogLight,p:vec3<f32>)->vec3<f32> { let index=u32(round(light.penumbra.y)); if(rendererLights.spotParams[index].w<0.5){return vec3<f32>(1.0);} let clip=rendererLights.spotShadowMatrices[index]*vec4<f32>(p,1.0); if(clip.w<=0.0){return vec3<f32>(1.0);} let ndc=clip.xyz/clip.w; if(any(ndc<vec3<f32>(-1.0,-1.0,0.0))||any(ndc>vec3<f32>(1.0))){return vec3<f32>(1.0);} let uv=ndc.xy*vec2<f32>(0.5,-0.5)+vec2<f32>(0.5);let cell=vec2<f32>(f32(index%8u),f32(index/8u));let cellUv=clamp(uv,vec2<f32>(0.0),vec2<f32>(1.0))*(255.0/256.0)+vec2<f32>(0.5/256.0);return textureSampleLevel(spotLightMapAtlas,historySampler,(cell+cellUv)/8.0,0.0).rgb; }\nfn sceneDistanceAt(pixel:vec2<u32>)->f32{\n let size=textureDimensions(sceneDepth);let clamped=min(pixel,size-vec2<u32>(1u));let depth=textureLoad(sceneDepth,vec2<i32>(clamped),0);\n let uv=(vec2<f32>(clamped)+vec2<f32>(0.5))/vec2<f32>(size);let world4=uniforms.inverseViewProjection*vec4<f32>(uv.x*2.0-1.0,1.0-uv.y*2.0,depth,1.0);\n return length(world4.xyz/world4.w-uniforms.cameraNear.xyz);\n}\n@compute @workgroup_size(8,8,1)\nfn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let dims = vec3<u32>(uniforms.dimensionsFar.xyz); if (id.x >= dims.x || id.y >= dims.y) { return; }\n // Keep the froxel lattice fixed. Moving the complete XY grid with a Halton\n // offset makes high-contrast shaft boundaries alternate between adjacent\n // froxels, which reads as the entire shadow edge blinking. We still use a\n // temporal Z offset to integrate within-slice variation over time without\n // moving the grid or the shadow-classification position sideways.\n let frameIndex=u32(max(uniforms.ambient.w,1.0));\n let temporal=vec2<f32>(0.5);\n let rayJitter=select(hash12(vec2<f32>(id.xy)+vec2<f32>(17.17,43.43)),halton(frameIndex,5u),uniforms.ambient.w>0.0);\n let uv = (vec2<f32>(id.xy)+temporal)/vec2<f32>(dims.xy);\n let farPoint4 = uniforms.inverseViewProjection * vec4<f32>(uv.x*2.0-1.0, 1.0-uv.y*2.0, 1.0, 1.0);\n let camera = uniforms.cameraNear.xyz; let ray = normalize(farPoint4.xyz/farPoint4.w-camera);\n let centerUv=(vec2<f32>(id.xy)+vec2<f32>(0.5))/vec2<f32>(dims.xy);\n let centerFarPoint4=uniforms.inverseViewProjection*vec4<f32>(centerUv.x*2.0-1.0,1.0-centerUv.y*2.0,1.0,1.0);\n let centerRay=normalize(centerFarPoint4.xyz/centerFarPoint4.w-camera);\n let nearPlane = uniforms.cameraNear.w; let farPlane = uniforms.dimensionsFar.w;\n var columnNear=farPlane;\n for(var volumeIndex=0u;volumeIndex<uniforms.counts.x;volumeIndex+=1u){columnNear=min(columnNear,max(volumes[volumeIndex].heightStartPhase.z,nearPlane));}\n columnNear=min(columnNear,farPlane);let columnFar=max(farPlane,columnNear+0.001);textureStore(outputDepthBounds,vec2<i32>(id.xy),vec4<f32>(columnNear,columnFar,0.0,0.0));\n let sliceRatio=pow(columnFar/columnNear,1.0/f32(dims.z));\n var transmittance = 1.0; var scattering = vec3<f32>(0.0); var previousDistance = columnNear; var sliceEnd=columnNear;\n for (var z=0u; z<dims.z; z+=1u) {\n // Every column uses the same logarithmic Z coordinate, so XY filtering\n // blends cumulative fog evaluated at the same physical distance.\n sliceEnd*=sliceRatio; let stepSize = sliceEnd-previousDistance;\n var localScattering=vec3<f32>(0.0);var localExtinction=0.0;\n if(stepSize>0.0){\n // Resizing recreates the 3D history. Use a few stratified samples only on\n // that first frame so the raw one-sample slice pattern is never exposed.\n let integrationSubsteps=max(INTEGRATION_SUBSTEPS,select(4u,INTEGRATION_SUBSTEPS,uniforms.historyCameraValid.w>0.5));\n let substepSize=stepSize/f32(integrationSubsteps);\n for(var substep=0u;substep<integrationSubsteps;substep+=1u){\n let sampleOffset=select(0.5,fract(rayJitter+f32(substep)/f32(integrationSubsteps)),uniforms.scattering.y>0.5);\n let sampleDistance=previousDistance+(f32(substep)+sampleOffset)*substepSize;\n let p = camera + ray*sampleDistance; var sigma = 0.0; var source = vec3<f32>(0.0);\n // Follow the temporally stratified Z sample so history integrates shadow\n // transitions within a slice. XY remains fixed, preventing the complete\n // edge from oscillating sideways between neighboring froxels.\n let shadowP=p;\n let csmCount=u32(round(rendererLights.lightCounts.w));let viewDepth=max(dot(shadowP-camera,uniforms.cameraForwardDepthRange.xyz),0.0);let normalizedViewDepth=viewDepth/uniforms.cameraForwardDepthRange.w;\n var filteredDirectionalVisibility=array<f32,4>(1.0,1.0,1.0,1.0);\n for(var d=0u;d<uniforms.counts.y;d+=1u){var cascadeWeight=1.0;if(d<csmCount){let range=rendererLights.csmCascadeRanges[d].xy;let isLast=d+1u==csmCount;cascadeWeight=select(0.0,1.0,normalizedViewDepth>=range.x&&(normalizedViewDepth<range.y||isLast));}filteredDirectionalVisibility[d]=directionalVisibility(d,shadowP)*cascadeWeight;}\n for (var v=0u; v<uniforms.counts.x; v+=1u) { let volume=volumes[v]; let localDistance=distance(p,volume.centerRadius.xyz);\n if (localDistance < volume.centerRadius.w && sampleDistance >= volume.heightStartPhase.z) {\n var density=volume.albedoDensity.w*exp(-volume.heightStartPhase.x*(p.y-volume.heightStartPhase.y)); density*=1.0-smoothstep(volume.centerRadius.w*0.8,volume.centerRadius.w,localDistance);\n let rendererAmbient=rendererLights.ambientColor.rgb*rendererLights.ambientColor.w;\n let hemisphereAmbient=(rendererLights.hemisphereSkyColorIntensity.rgb*rendererLights.hemisphereSkyColorIntensity.w+rendererLights.hemisphereGroundColorIntensity.rgb*rendererLights.hemisphereGroundColorIntensity.w)*0.5;\n let sceneAmbient=rendererAmbient+hemisphereAmbient;\n let ambient=select(uniforms.ambient.rgb,sceneAmbient,dot(sceneAmbient,sceneAmbient)>0.000001);\n var lighting=ambient*volume.emissiveAmbient.w+volume.emissiveAmbient.rgb; var direct=vec3<f32>(0.0); var shaftVisibility=0.0; var li=0u;\n for (var d=0u; d<uniforms.counts.y; d+=1u) {\n let l=lights[li]; li+=1u;\n shaftVisibility=max(shaftVisibility,filteredDirectionalVisibility[d]);\n direct += l.colorDecay.rgb*phaseHG(dot(ray,l.positionRange.xyz),volume.heightStartPhase.w)*filteredDirectionalVisibility[d];\n }\n for (var q=0u; q<uniforms.counts.z; q+=1u) { let l=lights[li]; li+=1u; let delta=l.positionRange.xyz-p; let dist=length(delta); direct += l.colorDecay.rgb*attenuation(dist,l.positionRange.w,l.colorDecay.w)*phaseHG(dot(ray,normalize(delta)),volume.heightStartPhase.w)*fogPointVisibility(l,p); }\n for (var s=0u; s<uniforms.counts.w; s+=1u) { let l=lights[li]; li+=1u; let delta=l.positionRange.xyz-p; let dist=length(delta); let cd=dot(normalize(-delta),l.directionCone.xyz); let cone=spotConeAttenuation(cd,l.directionCone.w,l.penumbra.x); direct += l.colorDecay.rgb*fogSpotMap(l,p)*attenuation(dist,l.positionRange.w,l.colorDecay.w)*cone*phaseHG(dot(ray,normalize(delta)),volume.heightStartPhase.w)*fogSpotVisibility(l,p); }\n direct*=uniforms.scattering.x;\n if (volume.mode.x < 0.5) { lighting += direct; } else { lighting = direct; }\n // Preserve fractional filtered visibility at shaft boundaries. A hard\n // threshold produces a temporally moving saw-tooth edge as jittered\n // froxels alternate between lit and shadowed. Direct lighting already\n // contains this visibility, while extinction must be scaled explicitly.\n if (volume.mode.x < 0.5) {\n sigma += density; source += lighting*volume.albedoDensity.rgb*density;\n } else {\n let visibleDensity=density*clamp(shaftVisibility,0.0,1.0);\n sigma += visibleDensity; source += lighting*volume.albedoDensity.rgb*density;\n }\n }\n }\n localScattering+=source/f32(integrationSubsteps);localExtinction+=sigma/f32(integrationSubsteps);\n }\n let historyPosition=camera+ray*(previousDistance+0.5*stepSize);\n let previousClip=uniforms.previousViewProjection*vec4<f32>(historyPosition,1.0);\n let previousUv=previousClip.xy/previousClip.w*vec2<f32>(0.5,-0.5)+vec2<f32>(0.5);\n let previousDistanceToCamera=length(historyPosition-uniforms.historyCameraValid.xyz);\n let previousNear=uniforms.historyNearFarWeight.x;let previousFar=uniforms.historyNearFarWeight.y;\n let previousZ=log(max(previousDistanceToCamera,previousNear)/previousNear)/max(log(previousFar/previousNear),0.0001);\n let validHistory=uniforms.historyCameraValid.w>0.5&&previousClip.w>0.0&&all(previousUv>=vec2<f32>(0.0))&&all(previousUv<=vec2<f32>(1.0))&&previousZ>=0.0&&previousZ<=1.0;\n if(validHistory){let history=textureSampleLevel(scatteringHistory,historySampler,vec3<f32>(previousUv,previousZ),0.0);let weight=uniforms.historyNearFarWeight.z;localScattering=mix(localScattering,history.rgb,weight);localExtinction=mix(localExtinction,history.a,weight);}\n }\n textureStore(outputScatteringHistory,vec3<i32>(i32(id.x),i32(id.y),i32(z)),vec4<f32>(localScattering,localExtinction));\n if(localExtinction>0.000001){let extinction=exp(-localExtinction*stepSize);scattering+=transmittance*localScattering*((1.0-extinction)/localExtinction);transmittance*=extinction;}\n textureStore(outputFog, vec3<i32>(i32(id.x),i32(id.y),i32(z)), vec4<f32>(scattering,transmittance)); previousDistance=sliceEnd;\n }\n}",ve="\nfn inverseProjection() -> mat4x4<f32> { return mat4x4<f32>(fullscreenUniforms[0],fullscreenUniforms[1],fullscreenUniforms[2],fullscreenUniforms[3]); }\nfn fogDither(pixel:vec2<f32>,frame:f32)->f32 { let p3=fract(vec3<f32>(pixel.xyx+frame*vec3<f32>(0.754877,0.569841,0.438289))*0.1031); let q=p3+dot(p3,p3.yzx+33.33); return fract((q.x+q.y)*q.z)-0.5; }\nfn sampleIntegratedFogRaw(uv:vec2<f32>,normalizedDepth:f32)->vec4<f32>{\n let slices=f32(textureDimensions(fogVolumeTexture).z);let slicePosition=clamp(normalizedDepth,0.0,1.0)*slices;\n let textureZ=clamp((slicePosition-0.5)/slices,0.0,1.0);let integrated=textureSampleLevel(fogVolumeTexture,fullscreenSampler,vec3<f32>(uv,textureZ),0.0);\n return mix(vec4<f32>(0.0,0.0,0.0,1.0),integrated,min(slicePosition,1.0));\n}\nfn sampleIntegratedFog(uv:vec2<f32>,normalizedDepth:f32)->vec4<f32>{return sampleIntegratedFogRaw(uv,normalizedDepth);}\n@fragment fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let pixel=vec2<i32>(input.position.xy); let color=textureLoad(sceneColorTexture,pixel,0); let depth=textureLoad(sceneDepthTexture,pixel,0);\n let clip=vec4<f32>(input.uv.x*2.0-1.0,1.0-input.uv.y*2.0,depth,1.0); let view=inverseProjection()*clip; let distance=length(view.xyz/view.w);\n let bounds=textureSampleLevel(fogBoundsTexture,fullscreenSampler,input.uv,0.0).rg;let z=clamp(log(max(distance,bounds.x)/bounds.x)/max(log(bounds.y/bounds.x),0.0001),0.0,1.0);\n let frame=fullscreenUniforms[4].z; let ditherStrength=fullscreenUniforms[4].w;\n let noise=fogDither(input.position.xy,max(frame,0.0));\n let fog=sampleIntegratedFog(input.uv,z);\n let fogAmount=clamp(1.0-fog.a,0.0,1.0); let dither=vec3<f32>(noise*(ditherStrength/255.0)*fogAmount);\n return vec4<f32>(max(vec3<f32>(0.0),fog.rgb+color.rgb*fog.a+dither),color.a);\n}",xe="\nfn inverseProjection() -> mat4x4<f32> { return mat4x4<f32>(fullscreenUniforms[0],fullscreenUniforms[1],fullscreenUniforms[2],fullscreenUniforms[3]); }\nfn fogDither(pixel:vec2<f32>,frame:f32)->f32 { let p3=fract(vec3<f32>(pixel.xyx+frame*vec3<f32>(0.754877,0.569841,0.438289))*0.1031); let q=p3+dot(p3,p3.yzx+33.33); return fract((q.x+q.y)*q.z)-0.5; }\nfn sampleIntegratedFogRaw(uv:vec2<f32>,normalizedDepth:f32)->vec4<f32>{\n let slices=f32(textureDimensions(fogVolumeTexture).z);let slicePosition=clamp(normalizedDepth,0.0,1.0)*slices;\n let textureZ=clamp((slicePosition-0.5)/slices,0.0,1.0);let integrated=textureSampleLevel(fogVolumeTexture,fullscreenSampler,vec3<f32>(uv,textureZ),0.0);\n return mix(vec4<f32>(0.0,0.0,0.0,1.0),integrated,min(slicePosition,1.0));\n}\nfn sampleIntegratedFog(uv:vec2<f32>,normalizedDepth:f32)->vec4<f32>{return sampleIntegratedFogRaw(uv,normalizedDepth);}\n@fragment fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let depthSize=vec2<i32>(textureDimensions(sceneDepthTexture)); let depthPixel=clamp(vec2<i32>(input.uv*vec2<f32>(depthSize)),vec2<i32>(0),depthSize-vec2<i32>(1));\n let depth=textureLoad(sceneDepthTexture,depthPixel,0); let clip=vec4<f32>(input.uv.x*2.0-1.0,1.0-input.uv.y*2.0,depth,1.0);\n let view=inverseProjection()*clip; let distance=length(view.xyz/view.w); let nearPlane=fullscreenUniforms[4].x; let farPlane=fullscreenUniforms[4].y;\n let bounds=textureSampleLevel(fogBoundsTexture,fullscreenSampler,input.uv,0.0).rg;let z=clamp(log(max(distance,bounds.x)/bounds.x)/max(log(bounds.y/bounds.x),0.0001),0.0,1.0);var fog=sampleIntegratedFog(input.uv,z);let frame=fullscreenUniforms[4].z; let noise=fogDither(input.position.xy,max(frame,0.0));\n fog=vec4<f32>(max(vec3<f32>(0.0),fog.rgb+vec3<f32>(noise*(fullscreenUniforms[4].w/255.0)*clamp(1.0-fog.a,0.0,1.0))),fog.a); return fog;\n}";var we="\nfn loadDepth(uv:vec2<f32>)->f32{let size=vec2<i32>(textureDimensions(sceneDepthTexture));let pixel=clamp(vec2<i32>(uv*vec2<f32>(size)),vec2<i32>(0),size-vec2<i32>(1));return textureLoad(sceneDepthTexture,pixel,0);}\n@fragment fn fsMain(input:FullscreenVertexOutput)->@location(0) vec4<f32>{\n let color=textureLoad(sceneColorTexture,vec2<i32>(input.position.xy),0);let fogSize=vec2<f32>(textureDimensions(fogInputTexture));let texel=1.0/fogSize;let grid=input.uv*fogSize-0.5;let base=(floor(grid)+0.5)*texel;\n let candidates=array<vec2<f32>,4>(base,base+vec2<f32>(texel.x,0.0),base+vec2<f32>(0.0,texel.y),base+texel);let centerDepth=loadDepth(input.uv);var bestUv=clamp(candidates[0],vec2<f32>(0.0),vec2<f32>(1.0));var bestDifference=abs(centerDepth-loadDepth(bestUv));var maxDifference=bestDifference;\n for(var i=1;i<4;i+=1){let uv=clamp(candidates[i],vec2<f32>(0.0),vec2<f32>(1.0));let difference=abs(centerDepth-loadDepth(uv));maxDifference=max(maxDifference,difference);if(difference<bestDifference){bestDifference=difference;bestUv=uv;}}\n let sampleUv=select(input.uv,bestUv,maxDifference>0.001);let fog=textureSampleLevel(fogInputTexture,fullscreenSampler,sampleUv,0.0);return vec4<f32>(fog.rgb+color.rgb*fog.a,color.a);\n}",be="\n@fragment fn fsMain(input:FullscreenVertexOutput)->@location(0) vec4<f32>{\n let color=textureLoad(sceneColorTexture,vec2<i32>(input.position.xy),0);\n let fog=textureSampleLevel(fogInputTexture,fullscreenSampler,input.uv,0.0);\n return vec4<f32>(fog.rgb+color.rgb*fog.a,color.a);\n}";import{ByteType as ye,DepthFormat as Se,DepthStencilFormat as Ce,FloatType as Pe,HalfFloatType as Me,IntType as Be,RED_GREEN_RGTC2_Format as De,RED_RGTC1_Format as Te,RGBA_ASTC_10x10_Format as Ie,RGBA_ASTC_10x5_Format as Ve,RGBA_ASTC_10x6_Format as Re,RGBA_ASTC_10x8_Format as Ge,RGBA_ASTC_12x10_Format as ze,RGBA_ASTC_12x12_Format as Le,RGBA_ASTC_4x4_Format as Ue,RGBA_ASTC_5x4_Format as Ae,RGBA_ASTC_5x5_Format as Fe,RGBA_ASTC_6x5_Format as ke,RGBA_ASTC_6x6_Format as Ee,RGBA_ASTC_8x5_Format as Oe,RGBA_ASTC_8x6_Format as je,RGBA_ASTC_8x8_Format as $e,RGBA_BPTC_Format as We,RGBA_ETC2_EAC_Format as Ne,RGBA_S3TC_DXT1_Format as _e,RGBA_S3TC_DXT3_Format as He,RGBA_S3TC_DXT5_Format as qe,RGBAFormat as Ke,RGBAIntegerFormat as Ze,RGFormat as Ye,RGIntegerFormat as Xe,RGB_ETC1_Format as Je,RGB_ETC2_Format as Qe,RGB_S3TC_DXT1_Format as et,RGBFormat as tt,RedFormat as rt,RedIntegerFormat as it,ShortType as nt,SIGNED_RED_GREEN_RGTC2_Format as at,SIGNED_RED_RGTC1_Format as st,SRGBColorSpace as ot,UnsignedByteType as lt,UnsignedInt248Type as ct,UnsignedInt5999Type as ut,UnsignedIntType as dt,UnsignedShortType as ht}from"three";function pt(e,t){const r=xt(e),i=function(e,t){const r=e.format,i=e.type,n=e.colorSpace===ot;let a=null;if(wt(e))switch(r){case et:case _e:a=n?"bc1-rgba-unorm-srgb":"bc1-rgba-unorm";break;case He:a=n?"bc2-rgba-unorm-srgb":"bc2-rgba-unorm";break;case qe:a=n?"bc3-rgba-unorm-srgb":"bc3-rgba-unorm";break;case Te:a="bc4-r-unorm";break;case st:a="bc4-r-snorm";break;case De:a="bc5-rg-unorm";break;case at:a="bc5-rg-snorm";break;case We:a=n?"bc7-rgba-unorm-srgb":"bc7-rgba-unorm";break;case Qe:case Je:a=n?"etc2-rgb8unorm-srgb":"etc2-rgb8unorm";break;case Ne:a=n?"etc2-rgba8unorm-srgb":"etc2-rgba8unorm";break;case Ue:a=n?"astc-4x4-unorm-srgb":"astc-4x4-unorm";break;case Ae:a=n?"astc-5x4-unorm-srgb":"astc-5x4-unorm";break;case Fe:a=n?"astc-5x5-unorm-srgb":"astc-5x5-unorm";break;case ke:a=n?"astc-6x5-unorm-srgb":"astc-6x5-unorm";break;case Ee:a=n?"astc-6x6-unorm-srgb":"astc-6x6-unorm";break;case Oe:a=n?"astc-8x5-unorm-srgb":"astc-8x5-unorm";break;case je:a=n?"astc-8x6-unorm-srgb":"astc-8x6-unorm";break;case $e:a=n?"astc-8x8-unorm-srgb":"astc-8x8-unorm";break;case Ve:a=n?"astc-10x5-unorm-srgb":"astc-10x5-unorm";break;case Re:a=n?"astc-10x6-unorm-srgb":"astc-10x6-unorm";break;case Ge:a=n?"astc-10x8-unorm-srgb":"astc-10x8-unorm";break;case Ie:a=n?"astc-10x10-unorm-srgb":"astc-10x10-unorm";break;case ze:a=n?"astc-12x10-unorm-srgb":"astc-12x10-unorm";break;case Le:a=n?"astc-12x12-unorm-srgb":"astc-12x12-unorm";break;case Ke:a=n?"rgba8unorm-srgb":"rgba8unorm"}else switch(r){case Ke:switch(i){case ye:a="rgba8snorm";break;case nt:a="rgba16sint";break;case ht:a="rgba16uint";break;case dt:a="rgba32uint";break;case Be:a="rgba32sint";break;case lt:a=n?"rgba8unorm-srgb":"rgba8unorm";break;case Me:a="rgba16float";break;case Pe:a="rgba32float"}break;case tt:switch(i){case ut:a="rgb9e5ufloat";break;case 35899:a="rg11b10ufloat"}break;case rt:switch(i){case ye:a="r8snorm";break;case nt:a="r16sint";break;case ht:a="r16uint";break;case dt:a="r32uint";break;case Be:a="r32sint";break;case lt:a="r8unorm";break;case Me:a="r16float";break;case Pe:a="r32float"}break;case Ye:switch(i){case ye:a="rg8snorm";break;case nt:a="rg16sint";break;case ht:a="rg16uint";break;case dt:a="rg32uint";break;case Be:a="rg32sint";break;case lt:a="rg8unorm";break;case Me:a="rg16float";break;case Pe:a="rg32float"}break;case Se:switch(i){case ht:a="depth16unorm";break;case dt:a="depth24plus";break;case Pe:a="depth32float"}break;case Ce:switch(i){case ct:a="depth24plus-stencil8";break;case Pe:bt("depth32float-stencil8",t,e,"DepthTexture with DepthStencilFormat + FloatType"),a="depth32float-stencil8"}break;case it:switch(i){case Be:a="r32sint";break;case dt:a="r32uint"}break;case Xe:switch(i){case Be:a="rg32sint";break;case dt:a="rg32uint"}break;case Ze:switch(i){case Be:a="rgba32sint";break;case dt:a="rgba32uint"}}if(!a)throw new Error(`Texture format "${r}" with type "${i}" from "${e.constructor.name}" is not supported by this renderer yet.`);const s=function(e){if(e.startsWith("bc"))return"texture-compression-bc";if(e.startsWith("etc2")||e.startsWith("eac"))return"texture-compression-etc2";if(e.startsWith("astc"))return"texture-compression-astc";return null}(a);s&&bt(s,t,e,`Texture format "${a}"`);return a}(e,t),n=function(e){const t=vt(e);if("cube"===t)return"cube";if("2d-array"===t)return"2d-array";if("3d"===t)return"3d";return"2d"}(e),a=function(e){return"3d"===vt(e)?"3d":"2d"}(e),s=function(e,t,r){if(!0===e.isDepthTexture)return"depth";if(t.endsWith("uint"))return"uint";if(t.endsWith("sint"))return"sint";if(!0===e.isDataTexture||!0===e.isDataArrayTexture||!0===e.isData3DTexture){if(e.type===Be)return"sint";if(e.type===dt)return"uint";if(e.type===Pe&&!yt(r,"float32-filterable")&&("r32float"===t||"rg32float"===t||"rgba32float"===t))return"unfilterable-float"}return"float"}(e,i,t),o=function(e,t){const r=e.compareFunction;if("depth"===t&&null!=r)return"comparison";if("float"===t)return"filtering";return"non-filtering"}(e,s),l=function(e){if(!0===e.isCompressedCubeTexture){const t=e.image;return Math.max(1,t?.[0]?.mipmaps?.length??1)}const t=e.mipmaps;return Math.max(1,t?.length??1)}(e);return{format:i,textureDimension:a,viewDimension:n,sampleType:s,samplerBindingType:o,wgslTextureType:gt(n,s),wgslSamplerType:"comparison"===o?"sampler_comparison":"sampler",width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers,mipLevelCount:l,compressed:wt(e)}}function ft(e,t){const r=pt(e,t);return[r.format,r.textureDimension,r.viewDimension,r.sampleType,r.samplerBindingType,r.width,r.height,r.depthOrArrayLayers,r.mipLevelCount].join(":")}function mt(e){const t=xt(e),r=e.compareFunction;return[vt(e),e.format,e.type,e.colorSpace,r??"none",t.depthOrArrayLayers].join(":")}function gt(e,t){if("depth"===t)switch(e){case"2d-array":return"texture_depth_2d_array";case"cube":return"texture_depth_cube";default:return"texture_depth_2d"}const r="uint"===t?"u32":"sint"===t?"i32":"f32";switch(e){case"2d-array":return`texture_2d_array<${r}>`;case"cube":return`texture_cube<${r}>`;case"3d":return`texture_3d<${r}>`;default:return`texture_2d<${r}>`}}function vt(e){return!0===e.isCubeTexture?"cube":!0===e.isArrayTexture||!0===e.isDataArrayTexture||!0===e.isCompressedArrayTexture?"2d-array":!0===e.is3DTexture||!0===e.isData3DTexture?"3d":"2d"}function xt(e){if(!0===e.isCubeTexture){const t=e.image,r=t?.[0],i=r?.image??r;return{width:i?.width??1,height:i?.height??1,depthOrArrayLayers:6}}const t=e.image;return{width:t?.width??1,height:t?.height??1,depthOrArrayLayers:t?.depth??1}}function wt(e){return!0===e.isCompressedTexture||!0===e.isCompressedArrayTexture}function bt(e,t,r,i){if(!yt(t,e))throw new Error(`${i} for "${r.name||r.uuid}" requires the WebGPU feature "${e}", which is not enabled on this device.`)}function yt(e,t){return!!e&&(e instanceof Set?e.has(t):"features"in e?e.features.has(t):e.has(t))}import{Color as St,Matrix3 as Ct,Matrix4 as Pt,Vector2 as Mt,Vector3 as Bt,Vector4 as Dt}from"three";var Tt=new ArrayBuffer(8),It=new Float64Array(Tt),Vt=new Uint32Array(Tt),Rt={f32:{alignment:4,size:4},i32:{alignment:4,size:4},u32:{alignment:4,size:4},"vec2<f32>":{alignment:8,size:8},"vec3<f32>":{alignment:16,size:12},"vec4<f32>":{alignment:16,size:16},"mat3x3<f32>":{alignment:16,size:48},"mat4x4<f32>":{alignment:16,size:64}};function Gt(e,t){return Math.ceil(e/t)*t}function zt(e,t,r,i){const n="boolean"==typeof i?i?1:0:Number(i);"i32"!==r?"u32"!==r?e.setFloat32(t,n,!0):e.setUint32(t,n,!0):e.setInt32(t,n,!0)}function Lt(e,t,r,i){for(let n=0;n<i;n+=1)e[t+n]=Ut(r,n,i)}function Ut(e,t,r){if("number"==typeof e||"boolean"==typeof e)return 0===t?Number(e):0;if(Array.isArray(e))return e[t]??0;if(e instanceof Ct||e instanceof Pt)return e.elements[t]??0;if(e instanceof St)return 0===t?e.r:1===t?e.g:2===t?e.b:3===t&&r>=4?1:0;if(e instanceof Mt||e instanceof Bt||e instanceof Dt){if(0===t)return e.x;if(1===t)return e.y;if(2===t&&(e instanceof Bt||e instanceof Dt))return e.z;if(3===t&&e instanceof Dt)return e.w}return 0}function At(e,t,r){for(let i=0;i<3;i+=1){const n=3*i,a=t+4*i;e[a+0]=Ut(r,n+0,9),e[a+1]=Ut(r,n+1,9),e[a+2]=Ut(r,n+2,9),e[a+3]=0}}function Ft(e){let t=0;const r=[];for(const[i,n]of Object.entries(e)){const e=Rt[n.type];t=Gt(t,e.alignment),r.push({name:i,offset:t,type:n.type}),t+=e.size}return{byteLength:Gt(t,16),entries:r}}function kt(e,t){const r=new ArrayBuffer(t.byteLength);return Ot(e,t,new DataView(r),new Float32Array(r)),r}var Et=class{constructor(e){this.layout=e,this.buffer=new ArrayBuffer(e.byteLength),this.view=new DataView(this.buffer),this.floats=new Float32Array(this.buffer)}layout;buffer;view;floats;update(e){return Ot(e,this.layout,this.view,this.floats),this.buffer}};function Ot(e,t,r,i){i.fill(0);for(const n of t.entries){const t=e[n.name],a=n.offset/4;switch(n.type){case"f32":case"i32":case"u32":zt(r,n.offset,n.type,t.value);break;case"vec2<f32>":Lt(i,a,t.value,2);break;case"vec3<f32>":Lt(i,a,t.value,3);break;case"vec4<f32>":Lt(i,a,t.value,4);break;case"mat3x3<f32>":At(i,a,t.value);break;case"mat4x4<f32>":t.value instanceof Pt?i.set(t.value.elements,a):Lt(i,a,t.value,16)}}}function jt(e,t){let r=Math.imul(e^t,16777619);return r^=r>>>13,r>>>0}function $t(e,t){return It[0]=t,e=jt(e,Vt[0]??0),e=jt(e,Vt[1]??0)}function Wt(e,t,r){const i=function(e,t){return"number"==typeof e||"boolean"==typeof e?[Number(e)]:Array.isArray(e)?Array.from(e.slice(0,t)):e instanceof St?t>=4?[e.r,e.g,e.b,1]:[e.r,e.g,e.b]:e instanceof Mt?[e.x,e.y]:e instanceof Bt?[e.x,e.y,e.z]:e instanceof Dt?[e.x,e.y,e.z,e.w]:e instanceof Ct||e instanceof Pt?Array.from(e.elements):[]}(t,r);e=jt(e,i.length);for(let t=0;t<i.length;t+=1)e=$t(e,i[t]??0);return e}var Nt="\nstruct FullscreenVertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) uv: vec2<f32>,\n};\n\n@vertex\nfn vsMain(@builtin(vertex_index) vertexIndex: u32) -> FullscreenVertexOutput {\n var output: FullscreenVertexOutput;\n let position = array<vec2<f32>, 3>(\n vec2(-1.0, -3.0),\n vec2(-1.0, 1.0),\n vec2(3.0, 1.0),\n );\n let clip = position[vertexIndex];\n output.position = vec4(clip, 0.0, 1.0);\n output.uv = clip * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n return output;\n}\n";function _t(e,t,r,i){let n=e.execution;if(!n){const a=[];for(let e=0;e<t;e++)a.push({binding:e,resource:null});e.uniformBuffer&&a.push({binding:t,resource:{buffer:e.uniformBuffer}});const s=[];for(let e=0;e<r;e++)s.push({view:null,clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"});n={resources:[],entries:a,attachments:s,bindGroupDescriptor:{label:`${i}-bind-group`,layout:e.bindGroupLayout,entries:a},passDescriptor:{label:i,colorAttachments:s}},e.execution=n}return n.passDescriptor.label=i,n}var Ht=new WeakMap;function qt(e){let t=Ht.get(e);return t||(t={outputFormats:[],inputDimensions:[]},Ht.set(e,t)),t}var Kt=new WeakMap;function Zt(e,t,r,i,n){let a=Kt.get(e);a||Kt.set(e,a=new Map);let s=a.get(t);s||(s={module:e.createShaderModule({label:r,code:t}),variants:new Map},a.set(t,s));let o=s.variants.get(i);return o||s.variants.set(i,o=n(s.module)),o}function Yt(){return{children:new WeakMap}}function Xt(e,t,r,i){let n=e;for(const e of t){let t=n.children.get(e);t||(t=Yt(),n.children.set(e,t)),n=t}return n.bindGroup??=r.createBindGroup(i),n.bindGroup}var Jt=new WeakMap,Qt=new WeakMap;function er(e){return e?"string"==typeof e?[e]:Array.from(e):[]}function tr(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}var rr=class{constructor(e){this.context=e}context;sceneColor="sceneColor";mainDepth="mainDepth";postProcessColor="postProcessColor";createColorTarget(e,t={}){return this.context.defineColorTarget(e,t),e}createTextureTarget(e,t={}){return this.context.defineTextureTarget(e,t),e}addStandardScenePasses(e=this.sceneColor){this.context.addDirectionalShadowPass(),this.context.addPointShadowPass(),this.context.addSpotShadowPass(),this.context.addDepthPrepass(),this.context.addHiZPasses(),this.context.addVisibilityPass(),this.context.addOpaquePass(e),this.context.addHiZHistoryPass("OpaquePass"),this.context.addSceneTextureCopyPass(e),this.context.addLatePass(e)}addDirectionalShadowPass(){this.context.addDirectionalShadowPass()}addPointShadowPass(){this.context.addPointShadowPass()}addSpotShadowPass(){this.context.addSpotShadowPass()}addDepthPrepass(){this.context.addDepthPrepass()}addHiZPasses(){this.context.addHiZPasses()}addVisibilityPass(){this.context.addVisibilityPass()}addForwardPass(e=this.sceneColor){this.context.addForwardPass(e)}addOpaquePass(e=this.sceneColor){this.context.addOpaquePass(e)}addSceneTextureCopyPass(e=this.sceneColor,t){this.context.addSceneTextureCopyPass(e,t)}addLatePass(e=this.sceneColor){this.context.addLatePass(e)}addHiZHistoryPass(e="ForwardPass"){this.context.addHiZHistoryPass(e)}addMaterialPass(e={}){const t={name:e.name,outputs:e.outputs??this.sceneColor,drawStage:e.drawStage,loadColor:e.loadColor,clearColor:e.clearColor,loadDepth:e.loadDepth,objectFilter:e.objectFilter,overrideMaterial:e.overrideMaterial};this.context.addMaterialPass(t)}addPass(e){const t=e.inputs?Object.values(e.inputs):void 0,r=er(e.outputs),i={name:e.name,reads:t,writes:r.length>0?r:void 0,dependsOn:e.dependsOn,execute:e.execute};this.context.addCustomPass(i)}addFullscreenPass(e){const t=er(e.outputs),r=Object.entries(e.inputs),i=Object.entries(e.textures??{});for(const[t]of i)if(t in e.inputs)throw new Error(`Fullscreen pass "${e.name}" cannot use "${t}" as both an input and an external texture.`);const n=r.map(([,e])=>e===this.mainDepth?"depth":"color");this.addPass({name:e.name,inputs:e.inputs,outputs:t,execute:a=>{const{outputFormats:s,inputDimensions:o}=qt(e);s.length=t.length;for(let e=0;e<t.length;e++)s[e]=a.getColorFormat(t[e]);const l=i.map(([,e])=>ft(e,a.device)).join("|");o.length=r.length;for(let t=0;t<r.length;t++)o[t]=e.inputDimensions?.[r[t][0]]??"2d";const c=`${s.join("|")}:${n.map((e,t)=>`${e}-${o[t]}`).join("|")}:${l}:${e.uniformBufferSize??0}`,u=c,d=function(e,t){let r=Jt.get(e);r||(r=new WeakMap,Jt.set(e,r));let i=r.get(t);return i||(i=new Map,r.set(t,i)),i}(e,a.device);let h=d.get(u);if(!h){const t=i.map(([,e])=>pt(e,a.device)),l=[Nt,"@group(0) @binding(0) var fullscreenSampler: sampler;",r.map(([e],t)=>`@group(0) @binding(${t+1}) var ${e}Texture: ${"depth"===n[t]?"texture_depth_2d":"3d"===o[t]?"texture_3d<f32>":"texture_2d<f32>"};`).join("\n"),i.map(([e],i)=>{const n=r.length+1+2*i,a=t[i];return`@group(0) @binding(${n}) var ${e}Sampler: ${a.wgslSamplerType};\n@group(0) @binding(${n+1}) var ${e}Texture: ${a.wgslTextureType};`}).join("\n"),e.uniformBufferSize?`@group(0) @binding(${r.length+1+2*i.length}) var<uniform> fullscreenUniforms: array<vec4<f32>, ${Math.max(1,Math.ceil(e.uniformBufferSize/16))}>;`:"",e.fragmentShader].filter(Boolean).join("\n\n"),p=`${c}:sampler=${"nearest"===e.sampler?"non-filtering":"filtering"}`,{bindGroupLayout:f,pipeline:m}=Zt(a.device,l,`${e.name}-shader-module`,p,l=>{const c=a.device.createBindGroupLayout({label:`${e.name}-layout`,entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"nearest"===e.sampler?"non-filtering":"filtering"}},...r.map((e,t)=>({binding:t+1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth"===n[t]?"depth":"float",viewDimension:"3d"===o[t]?"3d":"2d"}})),...t.flatMap((e,t)=>{const i=r.length+1+2*t;return[{binding:i,visibility:GPUShaderStage.FRAGMENT,sampler:{type:e.samplerBindingType}},{binding:i+1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:e.sampleType,viewDimension:e.viewDimension}}]}),...e.uniformBufferSize?[{binding:r.length+1+2*i.length,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]:[]]}),u=a.device.createPipelineLayout({label:`${e.name}-pipeline-layout`,bindGroupLayouts:[c]});return{bindGroupLayout:c,pipeline:a.device.createRenderPipeline({label:`${e.name}-pipeline`,layout:u,vertex:{module:l,entryPoint:"vsMain"},fragment:{module:l,entryPoint:"fsMain",targets:s.map(e=>({format:e}))},primitive:{topology:"triangle-list"}})}});h={bindGroupLayout:f,pipeline:m,uniformBuffer:e.uniformBufferSize?a.device.createBuffer({label:`${e.name}-uniform-buffer`,size:16*Math.ceil(Math.max(16,e.uniformBufferSize)/16),usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}):null,bindGroupCache:Yt()},d.set(u,h)}const{pipeline:p,uniformBuffer:f}=h,m=e.updateUniforms?.(a)??null;f&&m&&a.device.queue.writeBuffer(f,0,m.buffer,m.byteOffset,m.byteLength);const g=_t(h,r.length+1+2*i.length,t.length,e.name),v=g.resources;v[0]="nearest"===e.sampler||"linear"!==e.sampler&&n.includes("depth")?a.nearestClampSampler:a.linearClampSampler;for(let e=0;e<r.length;e++)v[e+1]="depth"===n[e]?a.depthView:a.getColorView(r[e][1]);for(let e=0;e<i.length;e++){const t=a.getExternalTexture(i[e][1]),n=r.length+1+2*e;v[n]=t.sampler,v[n+1]=t.view}const x=r.length+1+2*i.length;for(let e=0;e<x;e++)g.entries[e].resource=v[e];f&&(v[x]=f);const w=Xt(h.bindGroupCache,v,a.device,g.bindGroupDescriptor);for(let e=0;e<t.length;e++)g.attachments[e].view=a.getColorView(t[e]);const b=a.encoder.beginRenderPass(g.passDescriptor);b.setPipeline(p),b.setBindGroup(0,w),b.draw(3),b.end()}})}addNodeFullscreenPass(e){const t=er(e.outputs),i=Object.entries(function(e){const t={};for(const[r,i]of Object.entries(e.sceneTextures??{}))t[r]="sceneDepth"===i?{resource:"mainDepth",dimension:"depth-2d",sampleType:"depth",sampler:"non-filtering"}:{resource:"sceneColor",dimension:"2d",sampleType:"float",sampler:"filtering"};return{...t,...e.graphTextures}}(e.shader)).map(([t,r])=>[t,null!=e.inputOverrides?.[t]?{...r,resource:e.inputOverrides[t]}:r]),n=Object.entries(e.shader.textures??{}),a=Object.fromEntries(i.map(([e,t])=>[e,t.resource])),s=Ft(e.shader.uniforms);this.addPass({name:e.name,inputs:a,outputs:t,execute:a=>{const{outputFormats:o}=qt(e);o.length=t.length;for(let e=0;e<t.length;e++)o[e]=a.getColorFormat(t[e]);const l=i.map(([e,t])=>`${e}:${t.dimension}:${t.sampleType}:${t.sampler??"filtering"}`).join("|"),c=n.map(([,e])=>ft(e,a.device)).join("|"),u=s.entries.map(e=>`${e.name}:${e.type}:${e.offset}`).join("|"),d=`${o.join("|")}:${l}:${c}:${u}`,h=function(e,t){let r=Qt.get(e);r||(r=new WeakMap,Qt.set(e,r));let i=r.get(t);return i||(i=new Map,r.set(t,i)),i}(e.shader,a.device);let p=h.get(d);if(!p){const t=n.map(([,e])=>pt(e,a.device)),l=[];for(const[,e]of i){const t=l.length;l.push({binding:t,visibility:GPUShaderStage.FRAGMENT,sampler:{type:e.sampler??("depth-2d"===e.dimension?"non-filtering":"filtering")}},{binding:t+1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:e.sampleType??("depth-2d"===e.dimension?"depth":"float"),viewDimension:"3d"===e.dimension?"3d":"2d"}})}for(const[e,r]of t.entries()){const e=l.length;l.push({binding:e,visibility:GPUShaderStage.FRAGMENT,sampler:{type:r.samplerBindingType}},{binding:e+1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:r.sampleType,viewDimension:r.viewDimension}})}const c=2*(i.length+n.length);s.byteLength>0&&l.push({binding:c,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}});const u=i.map(([e,t],r)=>{const i=tr(e);return`@group(0) @binding(${2*r}) var ${i}Sampler: ${"comparison"===t.sampler?"sampler_comparison":"sampler"};\n@group(0) @binding(${2*r+1}) var ${i}Texture: ${"depth-2d"===t.dimension?"texture_depth_2d":"3d"===t.dimension?"texture_3d<f32>":"texture_2d<f32>"};`}).join("\n"),f=n.map(([e],r)=>{const n=2*(i.length+r),a=t[r],s=tr(e);return`@group(0) @binding(${n}) var ${s}Sampler: ${a.wgslSamplerType};\n@group(0) @binding(${n+1}) var ${s}Texture: ${a.wgslTextureType};`}).join("\n"),m=s.entries.map(e=>` ${tr(e.name)}: ${e.type},`).join("\n"),g=s.byteLength>0?`struct MaterialUniforms {\n${m}\n};\n@group(0) @binding(${c}) var<uniform> materialUniforms: MaterialUniforms;`:"",v=[Nt,u,f,g,e.shader.fragmentShader].filter(Boolean).join("\n\n"),x=JSON.stringify([o,l]),{bindGroupLayout:w,pipeline:b}=Zt(a.device,v,`${e.name}-node-shader-module`,x,t=>{const i=a.device.createBindGroupLayout({label:`${e.name}-node-layout`,entries:l}),n=a.device.createPipelineLayout({label:`${e.name}-node-pipeline-layout`,bindGroupLayouts:[i]});e.diagnosticOrigin&&r(a.device,`${e.name}-node-pipeline`,e.diagnosticOrigin);return{bindGroupLayout:i,pipeline:a.device.createRenderPipeline({label:`${e.name}-node-pipeline`,layout:n,vertex:{module:t,entryPoint:"vsMain"},fragment:{module:t,entryPoint:"fsMain",targets:o.map(e=>({format:e}))},primitive:{topology:"triangle-list"}})}});p={bindGroupLayout:w,pipeline:b,uniformBuffer:s.byteLength>0?a.device.createBuffer({label:`${e.name}-node-uniforms`,size:s.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}):null,bindGroupCache:Yt()},h.set(d,p)}const{pipeline:f,uniformBuffer:m}=p;e.shader.syncLiveUniforms(e.shader.uniforms),m&&a.device.queue.writeBuffer(m,0,(p.uniformData??=new Et(s)).update(e.shader.uniforms));const g=2*(i.length+n.length),v=_t(p,g,t.length,e.name),x=v.resources;for(let e=0;e<i.length;e++){const t=i[e][1];x[2*e]="comparison"===t.sampler?a.comparisonSampler:"non-filtering"===t.sampler||"depth-2d"===t.dimension?a.nearestClampSampler:a.linearClampSampler,x[2*e+1]=a.getTextureView(t.resource)}for(let e=0;e<n.length;e++){const t=a.getExternalTexture(n[e][1]),r=2*(i.length+e);x[r]=t.sampler,x[r+1]=t.view}for(let e=0;e<g;e++)v.entries[e].resource=x[e];m&&(x[g]=m);const w=Xt(p.bindGroupCache,x,a.device,v.bindGroupDescriptor);for(let e=0;e<t.length;e++)v.attachments[e].view=a.getColorView(t[e]);const b=a.encoder.beginRenderPass(v.passDescriptor);b.setPipeline(f),b.setBindGroup(0,w),b.draw(3),b.end()}})}present(e=this.sceneColor){this.context.addPresentPass(e)}};import{AlwaysCompare as ir,BufferAttribute as nr,EqualCompare as ar,GreaterCompare as sr,GreaterEqualCompare as or,InterleavedBufferAttribute as lr,LessCompare as cr,LessEqualCompare as ur,MirroredRepeatWrapping as dr,NearestFilter as hr,NearestMipmapLinearFilter as pr,NearestMipmapNearestFilter as fr,NeverCompare as mr,NotEqualCompare as gr,Object3D as vr,RepeatWrapping as xr,Vector3 as wr}from"three";import{Material as br}from"three";var yr=[{name:"position",shaderLocation:0,format:"float32x3"},{name:"normal",shaderLocation:1,format:"float32x3",defaultValue:[0,0,1]},{name:"uv",shaderLocation:2,format:"float32x2",defaultValue:[0,0]},{name:"color",shaderLocation:3,format:"float32x4",defaultValue:[1,1,1,1]}],Sr=class e extends br{isWGSLShaderMaterial=!0;vertexShader;fragmentShader;depthVertexShader;depthFragmentShader;pointShadowVertexShader;pointShadowFragmentShader;defines;uniforms;textures;sceneTextures;graphTextures;storageBuffers;vertexAttributes;primitiveTopology;wireframe;uniformLayoutCache=null;programCacheKeyCache=null;textureListCache=null;textureVersionsCache=[];textureVersionHashCache=0;storageBufferBindingListCache=null;storageBufferListCache=null;textureLayoutKeyDeviceCache=null;textureLayoutKeyCache=null;uniformValuesAutoUpdate=!0;uniformValuesAutoVersion=0;set uniformValuesNeedsUpdate(e){e&&this.uniformValuesAutoVersion++}constructor(e){super();const{vertexShader:t,fragmentShader:r,depthVertexShader:i,depthFragmentShader:n,pointShadowVertexShader:a,pointShadowFragmentShader:s,defines:o,uniforms:l,textures:c,sceneTextures:u,graphTextures:d,storageBuffers:h,vertexAttributes:p,primitiveTopology:f,uniformValuesAutoUpdate:m,wireframe:g,...v}=e,x=function(e,t){const r={},i={...t};for(const[t,n]of Object.entries(e)){const e=Br(t,n);"texture"!==e.kind?r[t]=e.uniform:i[t]=e.texture}return{uniforms:r,textures:i}}(l??{},c??{});this.type="WGSLShaderMaterial",this.vertexShader=t,this.fragmentShader=r,this.depthVertexShader=i??null,this.depthFragmentShader=n??null,this.pointShadowVertexShader=a??null,this.pointShadowFragmentShader=s??null,this.defines={...o??{}},this.uniforms=x.uniforms,this.textures=x.textures,this.sceneTextures={...u??{}},this.graphTextures={...d??{}},this.storageBuffers={...h??{}},this.vertexAttributes=Pr(p??yr),this.primitiveTopology=f??"triangle-list",this.uniformValuesAutoUpdate=m??!0,this.wireframe=g??!1,this.transparent=v.transparent??!1,this.depthTest=v.depthTest??!0,this.depthWrite=v.depthWrite??!0,this.setValues(v)}getUniformLayout(){return null===this.uniformLayoutCache&&(this.uniformLayoutCache=Ft(this.uniforms)),this.uniformLayoutCache}setUniform(e,t){const r=Br(e,t);return"texture"===r.kind?(delete this.uniforms[e],this.textures[e]=r.texture,this.uniformLayoutCache=null,this.invalidateBindingCache(),this.invalidateProgramStructureCache(),this.needsUpdate=!0,this):(delete this.textures[e],this.uniforms[e]=r.uniform,this.uniformLayoutCache=null,this.invalidateBindingCache(),this.invalidateProgramStructureCache(),this.needsUpdate=!0,this)}setDefine(e,t=!0){return this.defines[e]=t,this.invalidateProgramStructureCache(),this.needsUpdate=!0,this}deleteDefine(e){return delete this.defines[e],this.invalidateProgramStructureCache(),this.needsUpdate=!0,this}setTexture(e,t){return delete this.uniforms[e],this.textures[e]=t,this.uniformLayoutCache=null,this.invalidateBindingCache(),this.invalidateProgramStructureCache(),this.needsUpdate=!0,this}setStorageBuffer(e,t){return this.storageBuffers[e]=t,this.invalidateBindingCache(),this.invalidateProgramStructureCache(),this.needsUpdate=!0,this}setVertexAttributes(e){return this.vertexAttributes=Pr(e),this.invalidateProgramStructureCache(),this.needsUpdate=!0,this}copy(e){return super.copy(e),this.vertexShader=e.vertexShader,this.fragmentShader=e.fragmentShader,this.depthVertexShader=e.depthVertexShader,this.depthFragmentShader=e.depthFragmentShader,this.pointShadowVertexShader=e.pointShadowVertexShader,this.pointShadowFragmentShader=e.pointShadowFragmentShader,this.defines={...e.defines},this.uniforms=Object.fromEntries(Object.entries(e.uniforms).map(([e,t])=>[e,{type:t.type,value:Mr(t.value)}])),this.textures={...e.textures},this.sceneTextures={...e.sceneTextures},this.graphTextures={...e.graphTextures},this.storageBuffers={...e.storageBuffers},this.vertexAttributes=Pr(e.vertexAttributes),this.primitiveTopology=e.primitiveTopology,this.wireframe=e.wireframe,this.uniformValuesAutoUpdate=e.uniformValuesAutoUpdate,this.uniformValuesAutoVersion=e.uniformValuesAutoVersion,this.uniformLayoutCache=null,this.invalidateBindingCache(),this.invalidateProgramStructureCache(),this}clone(){return new e({vertexShader:this.vertexShader,fragmentShader:this.fragmentShader}).copy(this)}customProgramCacheKey(){if(null!==this.programCacheKeyCache)return this.programCacheKeyCache;const e=Object.keys(this.defines).sort((e,t)=>e.localeCompare(t));let t=`vertex:${this.vertexShader};fragment:${this.fragmentShader};depthVertex:${this.depthVertexShader??""};depthFragment:${this.depthFragmentShader??""};pointShadowVertex:${this.pointShadowVertexShader??""};pointShadowFragment:${this.pointShadowFragmentShader??""};`;for(const r of e)t+=`${r}:${String(this.defines[r])};`;for(const e in this.uniforms)t+=`uniform:${e}:${this.uniforms[e].type};`;for(const[e,r]of Object.entries(this.textures))t+=`texture:${e}:${mt(r)};`;for(const[e,r]of Object.entries(this.sceneTextures))t+=`sceneTexture:${e}:${r};`;for(const[e,r]of Object.entries(this.getGraphTextureInputs()))t+=`graphTexture:${e}:${r.resource}:${r.dimension}:${r.sampleType??"float"}:${r.sampler??"filtering"}:${Number(r.requiresLatePass??!1)};`;for(const[e,r]of Object.entries(this.storageBuffers))t+=`storage:${e}:${r.type}:${r.visibility??"fragment"};`;for(const e of this.vertexAttributes){const r=e.defaultValue?e.defaultValue.join(","):"";t+=`attribute:${e.name}:${e.shaderLocation}:${e.format}:${e.stepMode??"vertex"}:${r};`}return t+=`topology:${this.primitiveTopology};wireframe:${Number(this.wireframe)};transparent:${Number(this.transparent)};blending:${this.blending};premultipliedAlpha:${Number(this.premultipliedAlpha)};blendSrc:${this.blendSrc};blendDst:${this.blendDst};blendEquation:${this.blendEquation};blendSrcAlpha:${this.blendSrcAlpha};blendDstAlpha:${this.blendDstAlpha};blendEquationAlpha:${this.blendEquationAlpha};depthWrite:${Number(this.depthWrite)};depthTest:${Number(this.depthTest)};side:${String(this.side)};shadowSide:${String(this.shadowSide)};`,this.programCacheKeyCache=t,this.programCacheKeyCache}getTexturesList(){return null===this.textureListCache&&(this.textureListCache=Object.values(this.textures)),this.textureListCache}usesSceneTextures(){return this.usesSceneColor()||this.usesSceneDepth()}usesSceneColor(){return Object.values(this.sceneTextures).includes("sceneColor")||Object.values(this.graphTextures).some(e=>"sceneColorSnapshot"===e.resource)}usesSceneDepth(){return Object.values(this.sceneTextures).includes("sceneDepth")||Object.values(this.graphTextures).some(e=>"sceneDepthSnapshot"===e.resource)}getGraphTextureInputs(){const e={...this.graphTextures};for(const[t,r]of Object.entries(this.sceneTextures))e[t]="sceneDepth"===r?{resource:"sceneDepthSnapshot",dimension:"2d",sampleType:"unfilterable-float",sampler:"non-filtering",requiresLatePass:!0}:{resource:"sceneColorSnapshot",dimension:"2d",sampleType:"float",sampler:"filtering",requiresLatePass:!0};return e}requiresLatePass(){return Object.values(this.getGraphTextureInputs()).some(e=>!0===e.requiresLatePass)}getUniformValueHash(){return function(e,t){let r=2166136261;for(let i=0;i<t.entries.length;i+=1){const n=t.entries[i],a=e[n.name];if(a)switch(r=jt(r,n.offset),n.type){case"f32":case"i32":case"u32":r=$t(r,"boolean"==typeof a.value?a.value?1:0:Number(a.value));break;case"vec2<f32>":r=Wt(r,a.value,2);break;case"vec3<f32>":r=Wt(r,a.value,3);break;case"vec4<f32>":r=Wt(r,a.value,4);break;case"mat3x3<f32>":r=Wt(r,a.value,9);break;case"mat4x4<f32>":r=Wt(r,a.value,16);break;default:r=jt(r,i+17)}else r=jt(r,i+1)}return r>>>0}(this.uniforms,this.getUniformLayout())}getTextureVersionsList(){const e=this.getTexturesList(),t=this.textureVersionsCache;t.length=e.length;let r=2166136261;for(let i=0;i<e.length;i+=1){const n=e[i].version;t[i]=n,r=Math.imul((r^n)>>>0,16777619)>>>0}return this.textureVersionHashCache=r,t}getTextureVersionHash(){return this.getTextureVersionsList(),this.textureVersionHashCache}getStorageBufferBindingList(){return null===this.storageBufferBindingListCache&&(this.storageBufferBindingListCache=Object.values(this.storageBuffers)),this.storageBufferBindingListCache}getStorageBufferList(){if(null===this.storageBufferListCache){const e=this.getStorageBufferBindingList();this.storageBufferListCache=e.map(e=>e.buffer)}return this.storageBufferListCache}getTextureLayoutKey(e){return null!==this.textureLayoutKeyCache&&this.textureLayoutKeyDeviceCache===e||(this.textureLayoutKeyDeviceCache=e,this.textureLayoutKeyCache=this.getTexturesList().map(t=>ft(t,e)).join("|")),this.textureLayoutKeyCache}invalidateProgramStructureCache(){this.programCacheKeyCache=null}invalidateBindingCache(){this.textureListCache=null,this.textureVersionsCache.length=0,this.textureVersionHashCache=0,this.storageBufferBindingListCache=null,this.storageBufferListCache=null,this.textureLayoutKeyDeviceCache=null,this.textureLayoutKeyCache=null}};function Cr(e){return!0===e.isWGSLShaderMaterial}function Pr(e){return e.map(e=>({name:e.name,shaderLocation:e.shaderLocation,format:e.format,stepMode:e.stepMode,defaultValue:e.defaultValue?Array.from(e.defaultValue):void 0}))}function Mr(e){return Array.isArray(e)?Array.from(e):"number"==typeof e||"boolean"==typeof e?e:e.clone()}function Br(e,t){const r=Tr(t)?t:null,i=null!==r&&"value"in r?r.value:t;if(function(e){return Dr(e,"isTexture")}(i))return{kind:"texture",texture:i};if(!function(e){return"number"==typeof e||"boolean"==typeof e||Array.isArray(e)||Dr(e,"isColor")||Dr(e,"isVector2")||Dr(e,"isVector3")||Dr(e,"isVector4")||Dr(e,"isMatrix3")||Dr(e,"isMatrix4")}(i))throw new Error(`Unsupported WGSLShaderMaterial uniform "${e}". Use a number, boolean, vector, color, matrix, numeric array, or Texture.`);const n=r?.type,a=function(e){return"f32"===e||"i32"===e||"u32"===e||"vec2<f32>"===e||"vec3<f32>"===e||"vec4<f32>"===e||"mat3x3<f32>"===e||"mat4x4<f32>"===e}(n)?n:function(e,t){if("number"==typeof t)return"f32";if("boolean"==typeof t)return"u32";if(Array.isArray(t)){if(t.length<=1)return"f32";if(2===t.length)return"vec2<f32>";if(3===t.length)return"vec3<f32>";if(4===t.length)return"vec4<f32>";if(9===t.length)return"mat3x3<f32>";if(16===t.length)return"mat4x4<f32>";throw new Error(`Cannot infer WGSL type for uniform "${e}" from an array of length ${t.length}. Provide an explicit type.`)}if(Dr(t,"isColor"))return"vec3<f32>";if(Dr(t,"isVector2"))return"vec2<f32>";if(Dr(t,"isVector3"))return"vec3<f32>";if(Dr(t,"isVector4"))return"vec4<f32>";if(Dr(t,"isMatrix3"))return"mat3x3<f32>";if(Dr(t,"isMatrix4"))return"mat4x4<f32>";throw new Error(`Cannot infer WGSL type for uniform "${e}". Provide an explicit type.`)}(e,i);return{kind:"uniform",uniform:{type:a,value:i}}}function Dr(e,t){return Tr(e)&&!0===e[t]}function Tr(e){return"object"==typeof e&&null!==e}var Ir=new WeakMap,Vr=1;function Rr(e){return e?"version"in e?e.version:e.data.version:0}function Gr(e){const t=Object.keys(e.attributes).sort().map(t=>{const r=e.getAttribute(t);return[t,Rr(r),r?.itemSize??0,r?.count??0].join(":")}).join("|"),r=e.index?.version??0,i=e.groups.map(e=>`${e.start}:${e.count}:${e.materialIndex??0}`).join("|");return[t,r,e.drawRange.start,e.drawRange.count,i].join(";")}function zr(e){switch(e){case"float32":case"uint32":case"sint32":return 1;case"float32x2":case"uint32x2":case"sint32x2":return 2;case"float32x3":case"uint32x3":case"sint32x3":return 3;default:return 4}}function Lr(e){return 4*zr(e)}function Ur(e,t){switch(t){case"uint32":return new Uint32Array(e);case"sint32":return new Int32Array(e);default:return new Float32Array(e)}}function Ar(e,t,r,i){switch(r){case"uint32":e[t]=Math.max(0,Math.round(i));break;case"sint32":e[t]=Math.trunc(i);break;default:e[t]=i}}function Fr(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r+=1)if(e[r]!==t[r])return!1;return!0}function kr(e,t,r,i){const n=Math.max(4,t.byteLength),a=e.createBuffer({label:i,size:4*Math.ceil(n/4),usage:r,mappedAtCreation:!0});return new Uint8Array(a.getMappedRange()).set(new Uint8Array(t.buffer,t.byteOffset,t.byteLength)),a.unmap(),a}function Er(e){switch(e){case"vertex":return GPUShaderStage.VERTEX;case"vertex-fragment":return GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT;default:return GPUShaderStage.FRAGMENT}}function Or(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r+=1)if(e[r]!==t[r])return!1;return!0}function jr(e,t){if(!e)return!1;if(e.length!==t.length)return!1;for(let r=0;r<e.length;r+=1)if(e[r]!==t[r])return!1;return!0}function $r(e,t,r){try{return e.beginComputePass({timestampWrites:{querySet:t,...r}}).end(),!0}catch{return!1}}function Wr(e,t,r,i){if(e instanceof nr&&!e.normalized&&e.itemSize===r&&e.count===t&&e.array instanceof Float32Array)return e.array;const n=new Float32Array(t*r);if(!e){for(let e=0;e<t;e+=1)n.set(i,e*r);return n}for(let a=0;a<t;a+=1){for(let t=0;t<r;t+=1)t<e.itemSize?n[a*r+t]=e.getComponent(a,t):n[a*r+t]=i[t]??0;3===e.itemSize&&4===r&&(n[a*r+3]=i[3]??1)}return n}function Nr(e,t,r,i,n=0){const a=zr(r),s=(o=r).startsWith("uint32")?"uint32":o.startsWith("sint32")?"sint32":"float32";var o;if(!e)return function(e,t,r,i,n,a){const s=Ur(r*i,a);for(let o=0;o<r;o+=1){const r=o*t,l=o*i;for(let o=0;o<i;o+=1)Ar(s,l+o,a,e&&o<t?e[r+o]??n[o]??0:n[o]??0)}return s}(void 0,0,t,a,i,s);if(0===n&&e instanceof nr&&!e.normalized&&e.itemSize===a&&e.count===t){const t=e.array;if("float32"===s&&t instanceof Float32Array||"uint32"===s&&t instanceof Uint32Array||"sint32"===s&&t instanceof Int32Array)return t}const l=Ur(t*a,s);if("float32"===s&&!e.normalized&&(e instanceof nr?e.getComponent===nr.prototype.getComponent:e.getComponent===lr.prototype.getComponent)){const r=e instanceof lr,s=r?e.data.array:e.array,o=r?e.data.stride:e.itemSize,c=r?e.offset:0,u=Math.min(a,e.itemSize);for(let r=0;r<t;r++){const t=r*a,d=r-n,h=d>=0&&d<e.count,p=d*o+c;for(let e=0;e<a;e++)l[t+e]=h&&e<u?s[p+e]:i[e]??0}return l}for(let r=0;r<t;r+=1){const t=r*a,o=r-n,c=o>=0&&o<e.count;for(let r=0;r<a;r+=1){Ar(l,t+r,s,c&&r<e.itemSize?e.getComponent(o,r):i[r]??0)}}return l}function _r(e,t,r,i){return Number.isFinite(i)&&i>0?i:t?Math.max(0,(e.index?.count??0)-r):Math.max(0,e.getAttribute("position").count-r)}function Hr(e,t){return{start:e.drawRange.start,count:_r(e,t,e.drawRange.start,e.drawRange.count)}}function qr(e){return e===xr?"repeat":e===dr?"mirror-repeat":"clamp-to-edge"}function Kr(e){return e===hr||e===fr||e===pr?"nearest":"linear"}function Zr(e){return"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement||"undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement||"undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap||"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas||"undefined"!=typeof HTMLVideoElement&&e instanceof HTMLVideoElement?e:null}function Yr(e){return e}function Xr(e,t,r,i,n,a,s,o,l,c,u){return e.appendMatrixAndColorValues(t,r,i,n,a,s,o,l,c,u)}function Jr(e,t,r,i,n,a,s,o,l,c,u){return e.appendMatrixAndColorValues(t.elements,r,i,n,a,s,o,l,c,u)}function Qr(e,t,r){const i=e.elements;for(let e=0;e<16;e+=1)i[e]=t[r+e]??0;return e}function ei(e){const t=Ir.get(e);if(void 0!==t)return t;const r=Vr+=1;return Ir.set(e,r),r}function ti(e,t,r,i,n,a){return[ei(e),ei(t),r?1:0,i,n,a?ei(a):0].join(":")}function ri(e,t,r,i,n,a){let s=2166136261;return s=si(s,e),s=si(s,t),s=si(s,r?1:0),s=si(s,i),s=si(s,n),s=si(s,a),s}function ii(e,t){return e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:(r=e.sortMaterialId,i=e.sortGeometryId,n=e.indexed,a=e.start,s=e.count,o=e.sortCustomDepthMaterialId,l=t.sortMaterialId,c=t.sortGeometryId,u=t.indexed,d=t.start,h=t.count,p=t.sortCustomDepthMaterialId,r!==l?r-l:i!==c?i-c:n!==u?n?-1:1:a!==d?a-d:s!==h?s-h:o-p);var r,i,n,a,s,o,l,c,u,d,h,p}function ni(e,t){return e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:0!==e.transparentSortGroup&&e.transparentSortGroup===t.transparentSortGroup&&e.transparentSortOrder!==t.transparentSortOrder?e.transparentSortOrder-t.transparentSortOrder:e.sortDepth!==t.sortDepth?t.sortDepth-e.sortDepth:ii(e,t)}function ai(e){for(let t=0;t<e.length;t+=1)if(e[t].hasRenderCallbacks)return!0;return!1}function si(e,t){let r=Math.imul((e^t)>>>0,16777619);return r^=r>>>13,r>>>0}function oi(e,t){return e.cameraDetailRejected===t.cameraDetailRejected&&e.detailCulling?.minScreenSize===t.detailCulling?.minScreenSize&&e.detailCulling?.maxDistance===t.detailCulling?.maxDistance&&e.detailCulling?.shadowMinScreenSize===t.detailCulling?.shadowMinScreenSize&&e.detailCulling?.shadowMaxDistance===t.detailCulling?.shadowMaxDistance&&e.renderOrder===t.renderOrder&&!e.hasRenderCallbacks&&!t.hasRenderCallbacks&&e.castShadow===t.castShadow&&e.receiveShadow===t.receiveShadow&&ci(e)===ci(t)&&e.usesBatching===t.usesBatching&&e.sortMaterialId===t.sortMaterialId&&e.sortGeometryId===t.sortGeometryId&&e.indexed===t.indexed&&e.start===t.start&&e.count===t.count&&e.sortCustomDepthMaterialId===t.sortCustomDepthMaterialId}function li(e,t){return e.cameraDetailRejected===t.cameraDetailRejected&&e.detailCulling?.minScreenSize===t.detailCulling?.minScreenSize&&e.detailCulling?.maxDistance===t.detailCulling?.maxDistance&&e.detailCulling?.shadowMinScreenSize===t.detailCulling?.shadowMinScreenSize&&e.detailCulling?.shadowMaxDistance===t.detailCulling?.shadowMaxDistance&&e.renderOrder===t.renderOrder&&!e.hasRenderCallbacks&&!t.hasRenderCallbacks&&e.castShadow===t.castShadow&&e.receiveShadow===t.receiveShadow&&ci(e)===ci(t)&&e.usesBatching===t.usesBatching&&e.sortMaterialId===t.sortMaterialId&&e.sortGeometryId===t.sortGeometryId&&e.indexed===t.indexed&&e.start===t.start&&e.count===t.count&&e.sortCustomDepthMaterialId===t.sortCustomDepthMaterialId}function ci(e){return e.frontFaceCW}function ui(e,t){for(let r=0;r<16;r+=1)t[r]=e[r]??0}function di(e,t){for(let r=0;r<16;r+=1)if((e[r]??0)!==(t[r]??0))return!1;return!0}function hi(e){return 1===(e[0]??0)&&0===(e[1]??0)&&0===(e[2]??0)&&0===(e[3]??0)&&0===(e[4]??0)&&1===(e[5]??0)&&0===(e[6]??0)&&0===(e[7]??0)&&0===(e[8]??0)&&0===(e[9]??0)&&1===(e[10]??0)&&0===(e[11]??0)&&0===(e[12]??0)&&0===(e[13]??0)&&0===(e[14]??0)&&1===(e[15]??0)}function pi(e,t,r,i){r.x<e.x&&(e.x=r.x),r.y<e.y&&(e.y=r.y),r.z<e.z&&(e.z=r.z),i.x>t.x&&(t.x=i.x),i.y>t.y&&(t.y=i.y),i.z>t.z&&(t.z=i.z)}function fi(e,t){return t.multiplyMatrices(G.multiplyMatrices(M,e.projectionMatrix),e.matrixWorldInverse)}function mi(e,t,r,i,n,a){const s=Math.hypot(r,i,n)||1;e[t+0]=r/s,e[t+1]=i/s,e[t+2]=n/s,e[t+3]=a/s}function gi(e,t,r,i,n){const a=-n;for(let n=0;n<24;n+=4){if(e[n+0]*t+e[n+1]*r+e[n+2]*i+e[n+3]<a)return!1}return!0}function vi(e){return null===e.boundingSphere&&e.computeBoundingSphere(),e.boundingSphere?{center:e.boundingSphere.center.clone(),radius:e.boundingSphere.radius}:{center:new wr,radius:1}}function xi(e){const t=e.elements,r=Math.hypot(t[0],t[1],t[2]),i=Math.hypot(t[4],t[5],t[6]),n=Math.hypot(t[8],t[9],t[10]);return Math.max(r,i,n,1e-5)}function wi(e,t,r,i,n,a,s){const o=r.elements,l=a.elements,c=e.x,u=e.y,d=e.z,h=o[0]*c+o[4]*u+o[8]*d+o[12],p=o[1]*c+o[5]*u+o[9]*d+o[13],f=o[2]*c+o[6]*u+o[10]*d+o[14],m=i[n]*h+i[n+4]*p+i[n+8]*f+i[n+12],g=i[n+1]*h+i[n+5]*p+i[n+9]*f+i[n+13],v=i[n+2]*h+i[n+6]*p+i[n+10]*f+i[n+14];s.set(l[0]*m+l[4]*g+l[8]*v+l[12],l[1]*m+l[5]*g+l[9]*v+l[13],l[2]*m+l[6]*g+l[10]*v+l[14]);const x=i[n],w=i[n+4],b=i[n+8],y=i[n+1],S=i[n+5],C=i[n+9],P=i[n+2],M=i[n+6],B=i[n+10],D=x*o[0]+w*o[1]+b*o[2],T=x*o[4]+w*o[5]+b*o[6],I=x*o[8]+w*o[9]+b*o[10],V=y*o[0]+S*o[1]+C*o[2],R=y*o[4]+S*o[5]+C*o[6],G=y*o[8]+S*o[9]+C*o[10],z=P*o[0]+M*o[1]+B*o[2],L=P*o[4]+M*o[5]+B*o[6],U=P*o[8]+M*o[9]+B*o[10],A=l[0]*D+l[4]*V+l[8]*z,F=l[0]*T+l[4]*R+l[8]*L,k=l[0]*I+l[4]*G+l[8]*U,E=l[1]*D+l[5]*V+l[9]*z,O=l[1]*T+l[5]*R+l[9]*L,j=l[1]*I+l[5]*G+l[9]*U,$=l[2]*D+l[6]*V+l[10]*z,W=l[2]*T+l[6]*R+l[10]*L,N=l[2]*I+l[6]*G+l[10]*U,_=Math.hypot(A,E,$),H=Math.hypot(F,O,W),q=Math.hypot(k,j,N);return t*Math.max(_,H,q,1e-5)}function bi(e,t,r,i){const n=r.x-i,a=r.y-i,s=r.z-i,o=r.x+i,l=r.y+i,c=r.z+i;n<e.x&&(e.x=n),a<e.y&&(e.y=a),s<e.z&&(e.z=s),o>t.x&&(t.x=o),l>t.y&&(t.y=l),c>t.z&&(t.z=c)}function yi(e){return Math.floor(Math.max(0,e.count)/3)*Math.max(0,e.instanceCount)}function Si(e){const t=e??1;if(!Number.isInteger(t)||t<1)throw new Error(`Renderer sampleCount must be a positive integer. Received: ${e}`);return t}function Ci(e){const t=e.customDepthMaterial;return t&&Cr(t)?t:null}var Pi=class{palettes=new WeakMap;dispose(){this.palettes=new WeakMap}update(e){const t=16*e.bones.length;if(e.boneInverses.length!==e.bones.length)throw new Error("Skeleton inverse-bind count does not match bones");let r=this.palettes.get(e);r&&r.values.length===t||(r={values:new Float32Array(t),published:null},this.palettes.set(e,r)),e.boneMatrices.length<t&&(e.boneMatrices=new Float32Array(t)),function(e,t=!0){const r=e.bones,i=e.boneInverses,n=e.boneMatrices;for(let e=0;e<r.length;e+=1){const t=r[e],a=t?.matrixWorld.elements,s=i[e].elements,o=16*e;if(!a){n.set(s,o);continue}const l=a[0],c=a[4],u=a[8],d=a[12],h=a[1],p=a[5],f=a[9],m=a[13],g=a[2],v=a[6],x=a[10],w=a[14],b=a[3],y=a[7],S=a[11],C=a[15],P=s[0],M=s[4],B=s[8],D=s[12],T=s[1],I=s[5],V=s[9],R=s[13],G=s[2],z=s[6],L=s[10],U=s[14],A=s[3],F=s[7],k=s[11],E=s[15];n[o]=l*P+c*T+u*G+d*A,n[o+4]=l*M+c*I+u*z+d*F,n[o+8]=l*B+c*V+u*L+d*k,n[o+12]=l*D+c*R+u*U+d*E,n[o+1]=h*P+p*T+f*G+m*A,n[o+5]=h*M+p*I+f*z+m*F,n[o+9]=h*B+p*V+f*L+m*k,n[o+13]=h*D+p*R+f*U+m*E,n[o+2]=g*P+v*T+x*G+w*A,n[o+6]=g*M+v*I+x*z+w*F,n[o+10]=g*B+v*V+x*L+w*k,n[o+14]=g*D+v*R+x*U+w*E,n[o+3]=b*P+y*T+S*G+C*A,n[o+7]=b*M+y*I+S*z+C*F,n[o+11]=b*B+y*V+S*L+C*k,n[o+15]=b*D+y*R+S*U+C*E}t&&null!==e.boneTexture&&(e.boneTexture.needsUpdate=!0)}(e,!1);let i=!1;for(let n=0;n<t;n++){const t=e.boneMatrices[n];r.values[n]!==t&&(i=!0),r.values[n]=t}return!i&&r.published===e.boneMatrices||null===e.boneTexture||(e.boneTexture.needsUpdate=!0),r.published=e.boneMatrices,i}},Mi=class{data;lengthFloats=0;constructor(e=1024){this.data=new Float32Array(e)}get floatLength(){return this.lengthFloats}get rawData(){return this.data}get byteLength(){return this.lengthFloats*Float32Array.BYTES_PER_ELEMENT}get instanceCount(){return this.lengthFloats/w}reset(){this.lengthFloats=0}appendMatrixAndColor(e,t,r=e,i=2,n=1,a=0){return this.appendMatrixAndColorValues(e,t[0]??1,t[1]??1,t[2]??1,t[3]??1,void 0,r,i,n,a)}appendMatrixAndColorValues(e,t,r,i,n,a=this.instanceCount,s=e,o=2,l=1,c=0){const u=this.instanceCount;this.ensureCapacity(this.lengthFloats+w);const d=this.lengthFloats;for(let t=0;t<16;t+=1)this.data[d+t]=e[t]??0;this.data[d+16]=t,this.data[d+17]=r,this.data[d+18]=i,this.data[d+19]=n,this.data[d+20]=a,this.data[d+21]=o,this.data[d+22]=l,this.data[d+23]=c;for(let t=0;t<16;t+=1)this.data[d+24+t]=s[t]??e[t]??0;return this.lengthFloats+=w,u}appendRange(e,t,r){if(r<=0)return;const i=t*w,n=i+r*w;this.ensureCapacity(this.lengthFloats+(n-i)),this.data.set(e.data.subarray(i,n),this.lengthFloats),this.lengthFloats+=n-i}appendBuilder(e){this.appendRange(e,0,e.instanceCount)}beginWriteInstances(e){const t=e*w;return this.ensureCapacity(t),this.lengthFloats=t,this.data}toFloat32Array(){return this.data.slice(0,this.lengthFloats)}ensureCapacity(e){if(e<=this.data.length)return;let t=this.data.length;for(;t<e;)t*=2;const r=new Float32Array(t);r.set(this.data.subarray(0,this.lengthFloats),0),this.data=r}},Bi=class{disposed=!1;cachedInstanceData=new Mi;residentInstanceBinding={mode:"packed",buffer:null,colorBuffer:null,sceneBindGroup:null,shadowBindGroup:null,shadowBindGroups:new Map,sceneBindGroupVersion:0,shadowBindGroupVersion:0};residentBufferSize=0;residentColorBufferSize=0;residentBufferDirty=!1;residentColorBufferDirty=!1;count=-1;update(e,t,r,i,n,a){const s=this.cachedInstanceData.rawData;let o=e!==this.count||s[21]!==Math.fround(i)||s[22]!==Math.fround(n)||s[23]!==a;for(let e=0;!o&&e<16;e++)o=s[e]!==Math.fround(t[e])||s[24+e]!==Math.fround(r[e]);if(o){this.cachedInstanceData.reset();for(let s=0;s<e;s++)this.cachedInstanceData.appendMatrixAndColorValues(t,1,1,1,1,s,r,i,n,a);this.count=e,this.residentBufferDirty=!0}}dispose(){this.disposed=!0;const e=this.residentInstanceBinding;e.buffer?.destroy(),e.buffer=null,e.sceneBindGroup=null,e.shadowBindGroup=null,e.shadowBindGroups.clear(),this.residentBufferSize=0,this.count=-1}},Di=class{records=new WeakMap;get(e,t,r,i,n,a,s){let o=this.records.get(e);o||(o=[],this.records.set(e,o));let l=o[t];if(!l||l.material!==r||l.customDepthMaterial!==s||l.indexed!==i||l.start!==n||l.count!==a){const c=ei(r),u=ei(e),d=s?ei(s):0;l={material:r,customDepthMaterial:s,indexed:i,start:n,count:a,materialId:c,geometryId:u,depthMaterialId:d,batchKey:ti(r,e,i,n,a,s),batchHash:ri(c,u,i,n,a,d)},o[t]=l}return l}},Ti=class e{constructor(e,t,r,i){this.device=e,this.camera=t,this.lights=r,this.pipeline=i}device;camera;lights;pipeline;texture=null;textureView=null;bindGroup=null;columns=0;rows=0;static async createAsync(t,r,i){const n=await O(t,{label:"tiled-point-lights",layout:"auto",compute:{module:t.createShaderModule({label:"tiled-point-lights",code:"\nstruct Camera {\n viewProj: mat4x4<f32>,\n position: vec4<f32>,\n viewport: vec4<f32>,\n};\n@group(0) @binding(0) var<uniform> camera: Camera;\n@group(0) @binding(1) var<uniform> lights: array<vec4<f32>, 1001>;\n@group(0) @binding(2) var masks: texture_storage_2d<rg32uint, write>;\n\nfn normalizePlane(plane: vec4<f32>) -> vec4<f32> {\n return plane / max(length(plane.xyz), 1e-20);\n}\n\n@compute @workgroup_size(8, 8)\nfn main(@builtin(global_invocation_id) id: vec3<u32>) {\n if (any(id.xy >= textureDimensions(masks))) { return; }\n let lo = vec2<f32>(id.xy * 16u) / camera.viewport.xy;\n let hi = min(vec2<f32>((id.xy + 1u) * 16u), camera.viewport.xy) / camera.viewport.xy;\n let rows = transpose(camera.viewProj);\n let left = normalizePlane(rows[0] - (lo.x * 2.0 - 1.0) * rows[3]);\n let right = normalizePlane((hi.x * 2.0 - 1.0) * rows[3] - rows[0]);\n let top = normalizePlane((1.0 - lo.y * 2.0) * rows[3] - rows[1]);\n let bottom = normalizePlane(rows[1] - (1.0 - hi.y * 2.0) * rows[3]);\n var mask = vec2<u32>(0u);\n let count = min(u32(lights[1].y), 64u);\n for (var i = 0u; i < count; i++) {\n let center = vec4<f32>(lights[34u + i].xyz, 1.0);\n // Use the authored attenuation cutoff, NOT the finite shadow-camera range.\n let radius = lights[162u + i].x;\n let distance = min(min(dot(left, center), dot(right, center)), min(dot(top, center), dot(bottom, center)));\n // A small conservative tolerance avoids precision cracks on tile boundaries.\n if (radius <= 0.0 || distance >= -radius - max(0.001, radius * 1e-5)) {\n mask[i >> 5u] |= 1u << (i & 31u);\n }\n }\n textureStore(masks, vec2<i32>(id.xy), vec4<u32>(mask, 0u, 0u));\n}\n"}),entryPoint:"main"}});return new e(t,r,i,n)}get view(){if(!this.textureView)throw new Error("Tiled lighting has not been sized.");return this.textureView}resize(e,t){const r=Math.max(1,Math.ceil(e/16)),i=Math.max(1,Math.ceil(t/16));return(r!==this.columns||i!==this.rows)&&(this.texture?.destroy(),this.columns=r,this.rows=i,this.texture=this.device.createTexture({label:"tiled-point-light-masks",size:[r,i],format:"rg32uint",usage:GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.TEXTURE_BINDING}),this.textureView=this.texture.createView(),this.bindGroup=this.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:this.camera}},{binding:1,resource:{buffer:this.lights}},{binding:2,resource:this.textureView}]}),!0)}execute(e){const t=e.beginComputePass({label:"TiledPointLightsPass"});t.setPipeline(this.pipeline),t.setBindGroup(0,this.bindGroup),t.dispatchWorkgroups(Math.ceil(this.columns/8),Math.ceil(this.rows/8)),t.end()}destroy(){this.texture?.destroy()}};import{AdditiveBlending as Ii,BackSide as Vi,BufferAttribute as Ri,BufferGeometry as Gi,Color as zi,DoubleSide as Li,FrontSide as Ui,InstancedBufferAttribute as Ai,InstancedBufferGeometry as Fi,InstancedMesh as ki,MultiplyBlending as Ei,Matrix4 as Oi,Mesh as ji,OrthographicCamera as $i,PerspectiveCamera as Wi,SkinnedMesh as Ni,Sphere as _i,SubtractiveBlending as Hi,Vector2 as qi,Vector3 as Ki,Vector4 as Zi,ShaderMaterial as Yi}from"three";var Xi=/^[A-Za-z_][A-Za-z0-9_]*$/;function Ji(e,t={},r={}){const i=function(e){const t=new Map;for(const[r,i]of Object.entries(e))Xi.test(r)&&!1!==i&&null!=i&&t.set(r,{name:r,parameters:null,body:Qi(i)});return t}(t),n=new Map,a=[],s=[],o=e.split(/\r?\n/),l=r.sourceName??"shader";for(let e=0;e<o.length;e+=1){const t=o[e],r=en(t),c=rn(a);if(!r){s.push(c?an(t,i,n):"");continue}const{name:u,rest:d}=r;switch(u){case"define":if(c){const t=tn(d,i,l,e+1),r=i.get(t);null===r.parameters?n.delete(t):n.set(t,r)}s.push("");break;case"undef":c&&(i.delete(d.trim()),n.delete(d.trim())),s.push("");break;case"ifdef":{const e=c,t=e&&i.has(d.trim());a.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),s.push("");break}case"ifndef":{const e=c,t=e&&!i.has(d.trim());a.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),s.push("");break}case"if":{const e=c,t=e&&pn(d,i);a.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),s.push("");break}case"elif":{const t=nn(a,l,e+1,u);if(t.elseSeen)throw new Error(`${l}:${e+1}: #elif after #else`);const r=t.parentActive&&!t.branchTaken&&pn(d,i);t.active=r,t.branchTaken=t.branchTaken||r,s.push("");break}case"else":{const t=nn(a,l,e+1,u);if(t.elseSeen)throw new Error(`${l}:${e+1}: duplicate #else`);t.active=t.parentActive&&!t.branchTaken,t.branchTaken=!0,t.elseSeen=!0,s.push("");break}case"endif":nn(a,l,e+1,u),a.pop(),s.push("");break;case"error":if(c)throw new Error(`${l}:${e+1}: ${d.trim()||"#error"}`);s.push("");break;case"warning":case"line":case"version":case"pragma":s.push("");break;default:if(c)throw new Error(`${l}:${e+1}: unsupported preprocessor directive #${u}`);s.push("")}}if(a.length>0)throw new Error(`${l}: unterminated preprocessor conditional`);return s.join("\n")}function Qi(e){return"boolean"==typeof e?e?"1":"0":String(e)}function en(e){const t=/^\s*#\s*([A-Za-z_][A-Za-z0-9_]*)(.*)$/.exec(e);return t?{name:t[1],rest:t[2]??""}:null}function tn(e,t,r,i){const n=/^\s*([A-Za-z_][A-Za-z0-9_]*)(.*)$/.exec(e);if(!n)throw new Error(`${r}:${i}: invalid #define`);const a=n[1],s=n[2]??"";if(s.startsWith("(")){const e=hn(s,0);if(e<0)throw new Error(`${r}:${i}: invalid function-like #define ${a}`);const n=s.slice(1,e).trim(),o=0===n.length?[]:n.split(",").map(e=>e.trim());for(const e of o)if(!Xi.test(e))throw new Error(`${r}:${i}: invalid macro parameter "${e}"`);return t.set(a,{name:a,parameters:o,body:mn(s.slice(e+1)).trim()||"1"}),a}return t.set(a,{name:a,parameters:null,body:mn(s).trim()||"1"}),a}function rn(e){for(const t of e)if(!t.active)return!1;return!0}function nn(e,t,r,i){const n=e[e.length-1];if(!n)throw new Error(`${t}:${r}: #${i} without matching #if`);return n}function an(e,t,r){let i=e;for(let e=0;e<8;e+=1){const e=i;if(i=on(i,r),i=sn(i,t),i===e)return i}return i}function sn(e,t){let r=null,i=0;for(let n=0;n<e.length;){let a=e.charCodeAt(n);if(a>=65&&a<=90||a>=97&&a<=122||95===a){const s=n++;let o=a>=65&&a<=90;for(;n<e.length;)if(a=e.charCodeAt(n),a>=65&&a<=90)n++;else if(a>=97&&a<=122)o=!1,n++;else{if(!(a>=48&&a<=57||95===a))break;n++}if(!o)continue;const l=e.slice(s,n),c=t.get(l);null===c?.parameters&&(r??=[],r.push(e.slice(i,s),c.body),i=n)}else n++}return null===r?e:(r.push(e.slice(i)),r.join(""))}function on(e,t){if(0===t.size||!e.includes("("))return e;let r=e;for(const e of t.values())null!==e.parameters&&(r=ln(r,e));return r}function ln(e,t){let r="",i=0;for(;i<e.length;){const n=cn(e,t.name,i);if(n<0){r+=e.slice(i);break}let a=n+t.name.length;for(;/\s/.test(e[a]??"");)a+=1;if("("!==e[a]){r+=e.slice(i,n+t.name.length),i=n+t.name.length;continue}const s=hn(e,a);if(s<0){r+=e.slice(i);break}const o=dn(e.slice(a+1,s));r+=e.slice(i,n),r+=un(t,o),i=s+1}return r}function cn(e,t,r){let i=e.indexOf(t,r);for(;i>=0;){const r=i>0?e[i-1]:"",n=e[i+t.length]??"";if(!/[A-Za-z0-9_]/.test(r)&&!/[A-Za-z0-9_]/.test(n))return i;i=e.indexOf(t,i+t.length)}return-1}function un(e,t){let r=e.body;const i=e.parameters??[];for(let e=0;e<i.length;e+=1){const n=i[e],a=t[e]?.trim()??"";r=r.replace(new RegExp(`\\b${gn(n)}\\b`,"g"),a)}return r}function dn(e){const t=[];let r=0,i=0;for(let n=0;n<e.length;n+=1){const a=e[n];"("===a?r+=1:")"===a?r-=1:","===a&&0===r&&(t.push(e.slice(i,n)),i=n+1)}return(e.length>0||i>0)&&t.push(e.slice(i)),t}function hn(e,t){let r=0;for(let i=t;i<e.length;i+=1){const t=e[i];if("("===t)r+=1;else if(")"===t&&(r-=1,0===r))return i}return-1}function pn(e,t){const r=function(e){const t=[];let r=0;for(;r<e.length;){const i=e[r];if(/\s/.test(i)){r+=1;continue}const n=e.slice(r,r+2);if(["&&","||","==","!=","<=",">="].includes(n)){t.push({type:"operator",value:n}),r+=2;continue}if("!<>+-*/%".includes(i)){t.push({type:"operator",value:i}),r+=1;continue}if("("===i||")"===i){t.push({type:"paren",value:i}),r+=1;continue}const a=/^(?:0x[0-9A-Fa-f]+|\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)/.exec(e.slice(r));if(a){t.push({type:"number",value:a[0]}),r+=a[0].length;continue}const s=/^[A-Za-z_][A-Za-z0-9_]*/.exec(e.slice(r));s?(t.push({type:"identifier",value:s[0]}),r+=s[0].length):r+=1}return t}(mn(e));return 0!==new fn(r,t).parseExpression()}var fn=class{constructor(e,t){this.tokens=e,this.macros=t}tokens;macros;cursor=0;parseExpression(){return this.parseLogicalOr()}parseLogicalOr(){let e=this.parseLogicalAnd();for(;this.consumeOperator("||");){const t=this.parseLogicalAnd();e=0!==e||0!==t?1:0}return e}parseLogicalAnd(){let e=this.parseEquality();for(;this.consumeOperator("&&");){const t=this.parseEquality();e=0!==e&&0!==t?1:0}return e}parseEquality(){let e=this.parseComparison();for(;;)if(this.consumeOperator("=="))e=e===this.parseComparison()?1:0;else{if(!this.consumeOperator("!="))return e;e=e!==this.parseComparison()?1:0}}parseComparison(){let e=this.parseAdditive();for(;;)if(this.consumeOperator("<"))e=e<this.parseAdditive()?1:0;else if(this.consumeOperator(">"))e=e>this.parseAdditive()?1:0;else if(this.consumeOperator("<="))e=e<=this.parseAdditive()?1:0;else{if(!this.consumeOperator(">="))return e;e=e>=this.parseAdditive()?1:0}}parseAdditive(){let e=this.parseMultiplicative();for(;;)if(this.consumeOperator("+"))e+=this.parseMultiplicative();else{if(!this.consumeOperator("-"))return e;e-=this.parseMultiplicative()}}parseMultiplicative(){let e=this.parseUnary();for(;;)if(this.consumeOperator("*"))e*=this.parseUnary();else if(this.consumeOperator("/"))e/=this.parseUnary();else{if(!this.consumeOperator("%"))return e;e%=this.parseUnary()}}parseUnary(){return this.consumeOperator("!")?0===this.parseUnary()?1:0:this.consumeOperator("-")?-this.parseUnary():this.consumeOperator("+")?this.parseUnary():this.parsePrimary()}parsePrimary(){const e=this.peek();if(!e)return 0;if("number"===e.type)return this.cursor+=1,e.value.startsWith("0x")?Number.parseInt(e.value,16):Number.parseFloat(e.value);if("identifier"===e.type&&"defined"===e.value){if(this.cursor+=1,this.consumeParen("(")){const e=this.consumeIdentifier();return this.consumeParen(")"),e&&this.macros.has(e)?1:0}const e=this.consumeIdentifier();return e&&this.macros.has(e)?1:0}if("identifier"===e.type)return this.cursor+=1,function(e){if(!e)return 0;const t=e.body.trim();if("true"===t)return 1;if("false"===t)return 0;const r=t.startsWith("0x")?Number.parseInt(t,16):Number.parseFloat(t);return Number.isFinite(r)?r:1}(this.macros.get(e.value));if(this.consumeParen("(")){const e=this.parseExpression();return this.consumeParen(")"),e}return this.cursor+=1,0}consumeIdentifier(){const e=this.peek();return"identifier"!==e?.type?null:(this.cursor+=1,e.value)}consumeOperator(e){const t=this.peek();return"operator"===t?.type&&t.value===e&&(this.cursor+=1,!0)}consumeParen(e){const t=this.peek();return"paren"===t?.type&&t.value===e&&(this.cursor+=1,!0)}peek(){return this.tokens[this.cursor]}};function mn(e){const t=e.indexOf("//");return t>=0?e.slice(0,t):e}function gn(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var vn=/(?!\s*@invariant)\s+(?=(?:[A-Za-z_]\w*\s*:|vec4(?:\s*<\s*f32\s*>|f)\b))/y;function xn(e){return 32===e||9===e||10===e||13===e}var wn=class{passes=[];addPass(e){this.passes.push(e)}async executeAsync(e,t){const r=this.resolveExecutionOrder(),i=performance.now();t?.begin?.(r,e);for(let i=0;i<r.length;i+=1){const n=r[i];t?.beforePass?.(n,i,e);const a=performance.now();await(n.prepare?.(e)),n.execute(e),t?.afterPass?.(n,i,performance.now()-a,e)}t?.end?.(r,performance.now()-i,e)}execute(e,t){const r=this.resolveExecutionOrder(),i=performance.now();t?.begin?.(r,e);for(let i=0;i<r.length;i+=1){const n=r[i];t?.beforePass?.(n,i,e);const a=performance.now();n.execute(e),t?.afterPass?.(n,i,performance.now()-a,e)}t?.end?.(r,performance.now()-i,e)}reset(){this.passes.length=0}resolveExecutionOrder(){const e=new Map,t=new Map,r=new Map,i=new Map;for(const i of this.passes)e.set(i.name,i),t.set(i.name,new Set(i.dependsOn??[])),r.set(i.name,new Set);for(const e of this.passes){const r=t.get(e.name);for(const t of e.reads??[]){const n=i.get(t);n&&n!==e.name&&r.add(n)}for(const t of e.writes??[]){const n=i.get(t);n&&n!==e.name&&r.add(n),i.set(t,e.name)}}for(const[e,i]of t)for(const t of i){const i=r.get(t);if(!i)throw new Error(`RenderGraph dependency "${t}" for pass "${e}" is missing.`);i.add(e)}const n=Array.from(t.entries()).filter(([,e])=>0===e.size).map(([e])=>e),a=[];for(;n.length>0;){const i=n.shift();a.push(e.get(i));for(const e of r.get(i)??[]){const r=t.get(e);r.delete(i),0===r.size&&n.push(e)}}if(a.length!==this.passes.length)throw new Error("RenderGraph contains a dependency cycle.");return a}};import{CubeUVReflectionMapping as bn,HalfFloatType as yn,LinearFilter as Sn,LinearSRGBColorSpace as Cn,RGBAFormat as Pn,Texture as Mn}from"three";var Bn=[.125,.215,.35,.446,.526,.582],Dn=20,Tn=function(){const e=(1+Math.sqrt(5))/2,t=1/e;return[[-e,t,0],[e,t,0],[-t,0,e],[t,0,e],[0,e,-t],[0,e,t],[-1,1,-1],[1,1,-1],[-1,1,1],[1,1,1]]}(),In=class{constructor(e,t=20){this.context=e;const{device:r}=e,i=Math.max(1,Math.min(20,Math.floor(t)));this.maxBlurSamples=i,this.equirectBindGroupLayout=r.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"unfilterable-float",viewDimension:"2d"}}]}),this.blurBindGroupLayout=r.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}}]}),this.equirectPipeline=Vn(r,this.equirectBindGroupLayout,zn,"pmrem-equirectangular"),this.blurPipeline=Vn(r,this.blurBindGroupLayout,Ln.replaceAll("PMREM_MAX_SAMPLES",String(i)),"pmrem-blur")}context;equirectPipeline;blurPipeline;equirectBindGroupLayout;blurBindGroupLayout;maxBlurSamples;fromEquirectangular(e){const t=this.context.getTextureResource(e);if("2d"!==t.viewDimension)throw new Error("WebGpuPMREMGenerator.fromEquirectangular() requires a 2D equirectangular texture.");const r=2**Math.floor(Math.log2(Math.max(16,Math.floor(t.width/4)))),i=Math.floor(Math.log2(r)),n=function(e){const t=[];for(let r=e;r>=4;r-=1){const i=2**r;t.push({mip:r,size:i,sigma:r===e?0:1/i})}for(let e=0;e<Bn.length;e+=1)t.push({mip:4-e-1,size:16,sigma:Bn[e]});return t}(i),a=3*Math.max(r,112),s=4*r,{device:o}=this.context,l=GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,c=o.createTexture({label:"pmrem-cubeuv",size:{width:a,height:s},format:"rgba16float",usage:l}),u=o.createTexture({label:"pmrem-cubeuv-ping",size:{width:a,height:s},format:"rgba16float",usage:l}),d=o.createSampler({magFilter:"linear",minFilter:"linear"}),h=o.createCommandEncoder({label:"pmrem-generation"}),p=[],f=Rn(o,new Float32Array([t.width,t.height,r,0]));p.push(f);const m=o.createBindGroup({layout:this.equirectBindGroupLayout,entries:[{binding:0,resource:{buffer:f}},{binding:1,resource:t.view}]}),g=h.beginRenderPass({colorAttachments:[{view:c.createView(),loadOp:"clear",storeOp:"store",clearValue:[0,0,0,1]}]});g.setViewport(0,0,3*r,2*r,0,1),g.setScissorRect(0,0,3*r,2*r),g.setPipeline(this.equirectPipeline),g.setBindGroup(0,m),g.draw(36),g.end();for(let e=1;e<n.length;e+=1){const t=n[e-1],r=n[e],o=Math.sqrt(r.sigma*r.sigma-t.sigma*t.sigma),l=Tn[(n.length-e-1)%Tn.length];this.encodeBlurPass({encoder:h,source:c,target:u,sampler:d,atlasWidth:a,atlasHeight:s,maxMip:i,inputLevel:t,outputLevel:r,sigma:o,poleAxis:l,latitudinal:!0,clear:!0,transientBuffers:p}),this.encodeBlurPass({encoder:h,source:u,target:c,sampler:d,atlasWidth:a,atlasHeight:s,maxMip:i,inputLevel:r,outputLevel:r,sigma:o,poleAxis:l,latitudinal:!1,clear:!1,transientBuffers:p})}o.queue.submit([h.finish()]),o.queue.onSubmittedWorkDone().then(()=>{for(const e of p)e.destroy();u.destroy()});const v=new Mn;return v.image={width:a,height:s},v.name="PMREM.cubeUv",v.mapping=bn,v.format=Pn,v.type=yn,v.colorSpace=Cn,v.minFilter=Sn,v.magFilter=Sn,v.generateMipmaps=!1,v.needsUpdate=!0,this.context.registerTextureResource(v,{version:v.version,width:a,height:s,depthOrArrayLayers:1,format:"rgba16float",textureDimension:"2d",viewDimension:"2d",sampleType:"float",samplerBindingType:"filtering",mipLevelCount:1,texture:c,view:c.createView(),sampler:d}),{texture:v,dispose:()=>{c.destroy(),v.dispose()}}}encodeBlurPass(e){const{encoder:t,source:r,target:i,sampler:n,atlasWidth:a,atlasHeight:s,maxMip:o,inputLevel:l,outputLevel:c,sigma:u,poleAxis:d,latitudinal:h,clear:p,transientBuffers:f}=e,m=l.size-1,g=Math.PI/(2*m),v=u/g,x=Math.min(this.maxBlurSamples,1+Math.floor(3*v)),w=function(e,t){const r=new Float32Array(Dn);let i=0;for(let n=0;n<Dn;n+=1){const a=n/e,s=Math.exp(-a*a/2);r[n]=s,0===n?i+=s:n<t&&(i+=2*s)}for(let e=0;e<r.length;e+=1)r[e]/=i;return r}(v,x),b=Rn(this.context.device,function(e){const t=new ArrayBuffer(144),r=new DataView(t);return r.setFloat32(0,e.atlasWidth,!0),r.setFloat32(4,e.atlasHeight,!0),r.setFloat32(8,e.outputFaceSize,!0),r.setFloat32(12,e.inputMip,!0),r.setFloat32(16,e.dTheta,!0),r.setUint32(20,e.sampleCount,!0),r.setUint32(24,e.latitudinal?1:0,!0),r.setFloat32(28,e.maxMip,!0),r.setFloat32(32,e.poleAxis[0],!0),r.setFloat32(36,e.poleAxis[1],!0),r.setFloat32(40,e.poleAxis[2],!0),new Float32Array(t,48,Dn).set(e.weights),new Float32Array(t)}({atlasWidth:a,atlasHeight:s,outputFaceSize:c.size,inputMip:l.mip,dTheta:g,sampleCount:x,latitudinal:h,poleAxis:d,weights:w,maxMip:o}));f.push(b);const y=this.context.device.createBindGroup({layout:this.blurBindGroupLayout,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:r.createView()},{binding:2,resource:n}]}),S=3*c.size*Math.max(0,4-c.mip),C=4*(2**o-c.size),P=t.beginRenderPass({colorAttachments:[{view:i.createView(),loadOp:p?"clear":"load",storeOp:"store",clearValue:[0,0,0,1]}]});P.setViewport(S,C,3*c.size,2*c.size,0,1),P.setScissorRect(S,C,3*c.size,2*c.size),P.setPipeline(this.blurPipeline),P.setBindGroup(0,y),P.draw(36),P.end()}};function Vn(e,t,r,i){const n=e.createShaderModule({code:r,label:`${i}-shader`});return"function"==typeof n.getCompilationInfo&&n.getCompilationInfo().then(e=>{const t=e.messages.filter(e=>"error"===e.type);t.length>0&&console.error(`[WebGpuPMREMGenerator] ${i} WGSL compilation failed.`,t)}),e.createRenderPipeline({label:i,layout:e.createPipelineLayout({bindGroupLayouts:[t]}),vertex:{module:n,entryPoint:"vs"},fragment:{module:n,entryPoint:"fs",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list"}})}function Rn(e,t){const r=e.createBuffer({size:t.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});return e.queue.writeBuffer(r,0,t.buffer,t.byteOffset,t.byteLength),r}var Gn="\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n @location(1) @interpolate(flat) face: u32,\n};\n\nconst corners = array<vec2f, 6>(\n vec2f(0, 0), vec2f(1, 0), vec2f(1, 1),\n vec2f(0, 0), vec2f(1, 1), vec2f(0, 1),\n);\n\n@vertex\nfn vs(@builtin(vertex_index) index: u32) -> VertexOutput {\n let face = index / 6u;\n let corner = corners[index % 6u];\n var output: VertexOutput;\n output.position = vec4f(\n (corner.x + f32(face % 3u)) / 3.0 * 2.0 - 1.0,\n 1.0 - (corner.y + f32(face / 3u)),\n 0.0,\n 1.0,\n );\n output.uv = corner;\n output.face = face;\n return output;\n}\n\nfn cubeDirection(inputUv: vec2f, face: u32, faceSize: f32) -> vec3f {\n let gutter = 1.0 / (faceSize - 2.0);\n let uv = (inputUv * (1.0 + 2.0 * gutter) - vec2f(gutter)) * 2.0 - 1.0;\n if (face == 0u) { return normalize(vec3f(1.0, uv.y, uv.x)); }\n if (face == 1u) { return normalize(vec3f(-uv.x, 1.0, -uv.y)); }\n if (face == 2u) { return normalize(vec3f(-uv.x, uv.y, 1.0)); }\n if (face == 3u) { return normalize(vec3f(-1.0, uv.y, -uv.x)); }\n if (face == 4u) { return normalize(vec3f(-uv.x, -1.0, uv.y)); }\n return normalize(vec3f(uv.x, uv.y, -1.0));\n}\n",zn=`${Gn}\nstruct EquirectParams {\n sourceSize: vec2f,\n faceSize: f32,\n _padding: f32,\n};\n\n@group(0) @binding(0) var<uniform> params: EquirectParams;\n@group(0) @binding(1) var environmentMap: texture_2d<f32>;\n\nfn sampleEquirectangular(direction: vec3f) -> vec3f {\n let uv = vec2f(\n atan2(direction.z, direction.x) / (2.0 * 3.141592653589793) + 0.5,\n asin(clamp(direction.y, -1.0, 1.0)) / 3.141592653589793 + 0.5,\n );\n let pixel = uv * params.sourceSize - vec2f(0.5);\n let base = vec2i(floor(pixel));\n let fraction = fract(pixel);\n let width = i32(params.sourceSize.x);\n let height = i32(params.sourceSize.y);\n let x0 = (base.x % width + width) % width;\n let x1 = (x0 + 1) % width;\n let y0 = clamp(base.y, 0, height - 1);\n let y1 = min(y0 + 1, height - 1);\n let top = mix(\n textureLoad(environmentMap, vec2i(x0, y0), 0).rgb,\n textureLoad(environmentMap, vec2i(x1, y0), 0).rgb,\n fraction.x,\n );\n let bottom = mix(\n textureLoad(environmentMap, vec2i(x0, y1), 0).rgb,\n textureLoad(environmentMap, vec2i(x1, y1), 0).rgb,\n fraction.x,\n );\n return mix(top, bottom, fraction.y);\n}\n\n@fragment\nfn fs(input: VertexOutput) -> @location(0) vec4f {\n let direction = cubeDirection(input.uv, input.face, params.faceSize);\n return vec4f(sampleEquirectangular(direction), 1.0);\n}\n`,Ln=`${Gn}\nstruct BlurParams {\n atlasSize: vec2f,\n outputFaceSize: f32,\n inputMip: f32,\n dTheta: f32,\n samples: u32,\n latitudinal: u32,\n maxMip: f32,\n poleAxis: vec3f,\n _padding: f32,\n weights: array<vec4f, 5>,\n};\n\n@group(0) @binding(0) var<uniform> params: BlurParams;\n@group(0) @binding(1) var environmentMap: texture_2d<f32>;\n@group(0) @binding(2) var environmentSampler: sampler;\n\nfn cubeFace(direction: vec3f) -> f32 {\n let absolute = abs(direction);\n if (absolute.x > absolute.z) {\n if (absolute.x > absolute.y) { return select(3.0, 0.0, direction.x > 0.0); }\n return select(4.0, 1.0, direction.y > 0.0);\n }\n if (absolute.z > absolute.y) { return select(5.0, 2.0, direction.z > 0.0); }\n return select(4.0, 1.0, direction.y > 0.0);\n}\n\nfn cubeUv(direction: vec3f, face: f32) -> vec2f {\n if (face == 0.0) { return 0.5 * (vec2f(direction.z, direction.y) / abs(direction.x) + 1.0); }\n if (face == 1.0) { return 0.5 * (vec2f(-direction.x, -direction.z) / abs(direction.y) + 1.0); }\n if (face == 2.0) { return 0.5 * (vec2f(-direction.x, direction.y) / abs(direction.z) + 1.0); }\n if (face == 3.0) { return 0.5 * (vec2f(-direction.z, direction.y) / abs(direction.x) + 1.0); }\n if (face == 4.0) { return 0.5 * (vec2f(-direction.x, direction.z) / abs(direction.y) + 1.0); }\n return 0.5 * (vec2f(direction.x, direction.y) / abs(direction.z) + 1.0);\n}\n\nfn sampleCubeUv(direction: vec3f) -> vec3f {\n var face = cubeFace(direction);\n let filterOffset = max(4.0 - params.inputMip, 0.0);\n let mip = max(params.inputMip, 4.0);\n let faceSize = exp2(mip);\n var uv = cubeUv(direction, face) * (faceSize - 2.0) + 1.0;\n if (face > 2.0) {\n uv.y += faceSize;\n face -= 3.0;\n }\n uv.x += face * faceSize + filterOffset * 3.0 * 16.0;\n uv.y += 4.0 * (exp2(params.maxMip) - faceSize);\n return textureSampleLevel(environmentMap, environmentSampler, uv / params.atlasSize, 0.0).rgb;\n}\n\nfn weight(index: u32) -> f32 {\n return params.weights[index / 4u][index % 4u];\n}\n\nfn rotatedSample(direction: vec3f, theta: f32, axis: vec3f) -> vec3f {\n let cosine = cos(theta);\n let sampleDirection = direction * cosine\n + cross(axis, direction) * sin(theta)\n + axis * dot(axis, direction) * (1.0 - cosine);\n return sampleCubeUv(sampleDirection);\n}\n\n@fragment\nfn fs(input: VertexOutput) -> @location(0) vec4f {\n let direction = cubeDirection(input.uv, input.face, params.outputFaceSize);\n var axis = select(cross(params.poleAxis, direction), params.poleAxis, params.latitudinal != 0u);\n if (dot(axis, axis) < 0.000001) { axis = vec3f(direction.z, 0.0, -direction.x); }\n axis = normalize(axis);\n var color = weight(0u) * rotatedSample(direction, 0.0, axis);\n for (var index = 1u; index < PMREM_MAX_SAMPLES; index += 1u) {\n if (index >= params.samples) { break; }\n let theta = params.dTheta * f32(index);\n color += weight(index) * rotatedSample(direction, -theta, axis);\n color += weight(index) * rotatedSample(direction, theta, axis);\n }\n return vec4f(color, 1.0);\n}\n`;function Un(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}function An(e,t){const r=Object.entries(e.uniforms).map(([e,t])=>` ${Un(e)}: ${t.type},`).join("\n"),i=r?`\nstruct MaterialUniforms {\n${r}\n};\n\n@group(1) @binding(0) var<uniform> materialUniforms: MaterialUniforms;\n`:"",n=Object.entries(e.textures).map(([e,r],i)=>{const n=1+2*i,a=Un(e),s=pt(r,t);return[`@group(1) @binding(${n}) var ${a}Sampler: ${s.wgslSamplerType};`,`@group(1) @binding(${n+1}) var ${a}Texture: ${s.wgslTextureType};`].join("\n")}).join("\n"),a=1+2*Object.keys(e.textures).length;return`${i}\n${n}\n${Object.entries(e.storageBuffers).map(([e,t],r)=>{const i=Un(e);return`@group(1) @binding(${a+r}) var<storage, read> ${i}: ${t.type};`}).join("\n")}`}function Fn(e){return`\nfn rendererModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererInstanceModelMatrix(instanceIndex);\n}\n\nfn rendererNormalMatrix(instanceIndex: u32) -> mat3x3<f32> {\n ${e?"let view = rendererViewMatrix();\n let viewRotation = mat3x3<f32>(view[0].xyz, view[1].xyz, view[2].xyz);\n return viewRotation * rendererInstanceNormalMatrix(instanceIndex);":"return rendererInstanceNormalMatrix(instanceIndex);"}\n}\n\nfn modelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererModelMatrix(instanceIndex);\n}\n\nfn normalMatrix(instanceIndex: u32) -> mat3x3<f32> {\n return rendererNormalMatrix(instanceIndex);\n}\n${e?`\nfn rendererViewMatrix() -> mat4x4<f32> {\n return ${e}.view;\n}\n\nfn rendererProjectionMatrix() -> mat4x4<f32> {\n return ${e}.projection;\n}\n\nfn rendererModelViewMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererViewMatrix() * rendererModelMatrix(instanceIndex);\n}\n\nfn rendererModelViewProjectionMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererProjectionMatrix() * rendererModelViewMatrix(instanceIndex);\n}\n\nfn rendererCameraPosition() -> vec3<f32> {\n return ${e}.cameraPosition.xyz;\n}\n\nfn rendererCameraNear() -> f32 {\n return ${e}.nearFar.x;\n}\n\nfn rendererCameraFar() -> f32 {\n return ${e}.nearFar.y;\n}\n\n${"rendererCamera"===e?`\nfn rendererFogColor() -> vec3<f32> {\n return ${e}.fogColor.rgb;\n}\n\nfn rendererFogNear() -> f32 {\n return ${e}.fogParams.x;\n}\n\nfn rendererFogFar() -> f32 {\n return ${e}.fogParams.y;\n}\n\nfn rendererFogDensity() -> f32 {\n return ${e}.fogParams.z;\n}\n\nfn rendererFogMode() -> f32 {\n return ${e}.fogParams.w;\n}\n`:""}\n\nfn rendererElapsedTime() -> f32 {\n return ${"rendererCamera"===e?"rendererCamera.viewportAndTime.w":"shadowCamera"===e?"shadowCamera.timeAndPadding.x":null};\n}\n\nfn rendererViewportSize() -> vec2<f32> {\n return ${"rendererCamera"===e?"rendererCamera.viewportAndTime.xy":"shadowCamera"===e?"shadowCamera.timeAndPadding.yz":null};\n}\n\nfn viewMatrix() -> mat4x4<f32> {\n return rendererViewMatrix();\n}\n\nfn projectionMatrix() -> mat4x4<f32> {\n return rendererProjectionMatrix();\n}\n\nfn modelViewMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererModelViewMatrix(instanceIndex);\n}\n\nfn modelViewProjectionMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererModelViewProjectionMatrix(instanceIndex);\n}\n\nfn cameraPosition() -> vec3<f32> {\n return rendererCameraPosition();\n}\n`:""}`}function kn(e){return e?"\nstruct RendererSkinningUniforms {\n bindMatrix: mat4x4<f32>,\n bindMatrixInverse: mat4x4<f32>,\n};\n\n@group(2) @binding(0) var<storage, read> rendererBoneMatrixColumns: array<vec4<f32>>;\n@group(2) @binding(1) var<uniform> rendererSkinning: RendererSkinningUniforms;\n@group(2) @binding(2) var<storage, read> rendererPreviousBoneMatrixColumns: array<vec4<f32>>;\n\nfn rendererBoneMatrix(index: u32) -> mat4x4<f32> {\n let base = index * 4u;\n return mat4x4<f32>(\n rendererBoneMatrixColumns[base + 0u],\n rendererBoneMatrixColumns[base + 1u],\n rendererBoneMatrixColumns[base + 2u],\n rendererBoneMatrixColumns[base + 3u],\n );\n}\n\nfn rendererPreviousBoneMatrix(index: u32) -> mat4x4<f32> {\n let base = index * 4u;\n return mat4x4<f32>(\n rendererPreviousBoneMatrixColumns[base + 0u],\n rendererPreviousBoneMatrixColumns[base + 1u],\n rendererPreviousBoneMatrixColumns[base + 2u],\n rendererPreviousBoneMatrixColumns[base + 3u],\n );\n}\n\nfn rendererSkinPosition(position: vec3<f32>, skinIndex: vec4<u32>, skinWeight: vec4<f32>) -> vec3<f32> {\n let boundPosition = rendererSkinning.bindMatrix * vec4(position, 1.0);\n let weightSum = skinWeight.x + skinWeight.y + skinWeight.z + skinWeight.w;\n if (weightSum <= 0.0) {\n return position;\n }\n let skinnedPosition =\n (rendererBoneMatrix(skinIndex.x) * boundPosition) * skinWeight.x +\n (rendererBoneMatrix(skinIndex.y) * boundPosition) * skinWeight.y +\n (rendererBoneMatrix(skinIndex.z) * boundPosition) * skinWeight.z +\n (rendererBoneMatrix(skinIndex.w) * boundPosition) * skinWeight.w;\n let fallbackWeight = max(0.0, 1.0 - weightSum);\n return (rendererSkinning.bindMatrixInverse * (skinnedPosition + boundPosition * fallbackWeight)).xyz;\n}\n\nfn rendererPreviousSkinPosition(position: vec3<f32>, skinIndex: vec4<u32>, skinWeight: vec4<f32>) -> vec3<f32> {\n let boundPosition = rendererSkinning.bindMatrix * vec4(position, 1.0);\n let weightSum = skinWeight.x + skinWeight.y + skinWeight.z + skinWeight.w;\n if (weightSum <= 0.0) {\n return position;\n }\n let skinnedPosition =\n (rendererPreviousBoneMatrix(skinIndex.x) * boundPosition) * skinWeight.x +\n (rendererPreviousBoneMatrix(skinIndex.y) * boundPosition) * skinWeight.y +\n (rendererPreviousBoneMatrix(skinIndex.z) * boundPosition) * skinWeight.z +\n (rendererPreviousBoneMatrix(skinIndex.w) * boundPosition) * skinWeight.w;\n let fallbackWeight = max(0.0, 1.0 - weightSum);\n return (rendererSkinning.bindMatrixInverse * (skinnedPosition + boundPosition * fallbackWeight)).xyz;\n}\n\nfn rendererSkinNormal(normal: vec3<f32>, skinIndex: vec4<u32>, skinWeight: vec4<f32>) -> vec3<f32> {\n let boundNormal = rendererSkinning.bindMatrix * vec4(normal, 0.0);\n let weightSum = skinWeight.x + skinWeight.y + skinWeight.z + skinWeight.w;\n if (weightSum <= 0.0) {\n return normalize(normal);\n }\n let skinnedNormal =\n (rendererBoneMatrix(skinIndex.x) * boundNormal) * skinWeight.x +\n (rendererBoneMatrix(skinIndex.y) * boundNormal) * skinWeight.y +\n (rendererBoneMatrix(skinIndex.z) * boundNormal) * skinWeight.z +\n (rendererBoneMatrix(skinIndex.w) * boundNormal) * skinWeight.w;\n let fallbackWeight = max(0.0, 1.0 - weightSum);\n return normalize((rendererSkinning.bindMatrixInverse * (skinnedNormal + boundNormal * fallbackWeight)).xyz);\n}\n":""}function En(e,t,r="packed",i=!0,n=!1,a){const s="particle"!==r&&!e.transparent&&!e.requiresLatePass(),o=An(e,t),l=function(e){return Object.entries(e.getGraphTextureInputs()).map(([e,t],r)=>{const i=Un(e);return`@group(3) @binding(${2*r}) var ${i}Sampler: ${"comparison"===t.sampler?"sampler_comparison":"sampler"};\n@group(3) @binding(${2*r+1}) var ${i}Texture: ${"depth-2d"===t.dimension?"texture_depth_2d":"3d"===t.dimension?"texture_3d<f32>":"texture_2d<f32>"};`}).join("\n")}(e),c="packed-visible"===r,u=i?"\nfn rendererSampleDirectionalShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n if (lightIndex >= rendererDirectionalLightCount() || !rendererDirectionalShadowEnabledForLight(lightIndex)) {\n return 1.0;\n }\n\n let matrix = rendererDirectionalShadowMatrixForLight(lightIndex);\n let shadowClip = matrix * vec4(worldPosition, 1.0);\n if (shadowClip.w <= 0.0) {\n return 1.0;\n }\n\n let ndc = shadowClip.xyz / shadowClip.w;\n if (ndc.x < -1.0 || ndc.x > 1.0 || ndc.y < -1.0 || ndc.y > 1.0 || ndc.z < 0.0 || ndc.z > 1.0) {\n return 1.0;\n }\n\n let uv = ndc.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n let dims = vec2<f32>(textureDimensions(rendererDirectionalShadowTexture));\n let texel = 1.0 / max(dims, vec2(1.0, 1.0));\n let radius = max(rendererLights.directionalShadowParams2[lightIndex].x, 0.0);\n // Match Three.js/three-shader-graph semantics: negative bias moves the\n // receiver toward the light and therefore reduces self-shadowing.\n let depth = ndc.z + rendererDirectionalShadowBiasForLight(lightIndex);\n let filterOffset = texel * radius;\n\n // Each comparison-level sample is already a hardware-filtered 2x2 PCF\n // lookup. A weighted center plus four cardinal taps gives a compact tent\n // filter (five lookups rather than nine manual depth loads) and is legal in\n // non-uniform control flow because the explicit level computes no derivatives.\n let center = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n uv,\n i32(lightIndex),\n depth\n );\n let left = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n clamp(uv - vec2(filterOffset.x, 0.0), vec2(0.0), vec2(1.0)),\n i32(lightIndex),\n depth\n );\n let right = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n clamp(uv + vec2(filterOffset.x, 0.0), vec2(0.0), vec2(1.0)),\n i32(lightIndex),\n depth\n );\n let up = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n clamp(uv - vec2(0.0, filterOffset.y), vec2(0.0), vec2(1.0)),\n i32(lightIndex),\n depth\n );\n let down = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n clamp(uv + vec2(0.0, filterOffset.y), vec2(0.0), vec2(1.0)),\n i32(lightIndex),\n depth\n );\n let shadow = (center * 4.0 + left + right + up + down) * 0.125;\n return mix(1.0, shadow, rendererDirectionalShadowIntensityForLight(lightIndex));\n}\n\nfn rendererSampleDirectionalShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n let params = rendererLights.directionalShadowParams[lightIndex];\n return rendererSampleDirectionalShadowForLight(lightIndex, worldPosition + normalize(worldNormal) * params.w);\n}\n\nfn rendererPointShadowUvLayer(direction: vec3<f32>, pointIndex: u32) -> vec3<f32> {\n let absDir = abs(direction);\n var face = 0u;\n var uv = vec2<f32>(0.0, 0.0);\n if (absDir.x >= absDir.y && absDir.x >= absDir.z) {\n if (direction.x >= 0.0) {\n face = 0u;\n uv = vec2<f32>(-direction.z, -direction.y) / absDir.x;\n } else {\n face = 1u;\n uv = vec2<f32>(direction.z, -direction.y) / absDir.x;\n }\n } else if (absDir.y >= absDir.x && absDir.y >= absDir.z) {\n if (direction.y >= 0.0) {\n face = 2u;\n uv = vec2<f32>(direction.x, direction.z) / absDir.y;\n } else {\n face = 3u;\n uv = vec2<f32>(direction.x, -direction.z) / absDir.y;\n }\n } else {\n if (direction.z >= 0.0) {\n face = 4u;\n uv = vec2<f32>(direction.x, -direction.y) / absDir.z;\n } else {\n face = 5u;\n uv = vec2<f32>(-direction.x, -direction.y) / absDir.z;\n }\n }\n // WebGPU's framebuffer/texture Y axis points down. The face-local value\n // above is NDC (Y up), so mirror Y just like the projected directional and\n // spot shadow paths do before sampling their render targets.\n let textureUv = uv * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n return vec3<f32>(textureUv, f32(pointIndex * 6u + face));\n}\n\nfn rendererSamplePointShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n if (lightIndex >= rendererPointLightCount() || !rendererPointShadowEnabledForLight(lightIndex)) {\n return 1.0;\n }\n let lightPosition = rendererPointLightPositionForLight(lightIndex);\n let range = rendererPointLightShadowRangeForLight(lightIndex);\n let toFragment = worldPosition - lightPosition;\n let distanceToLight = length(toFragment);\n if (distanceToLight >= range) {\n return 1.0;\n }\n let uvLayer = rendererPointShadowUvLayer(toFragment, lightIndex);\n let dims = vec2<f32>(textureDimensions(rendererPointShadowTexture));\n let sampleUv = clamp(uvLayer.xy, vec2(0.0, 0.0), vec2(1.0, 1.0));\n let pixel = vec2<i32>(clamp(sampleUv * dims, vec2(0.0, 0.0), dims - vec2(1.0, 1.0)));\n let closestDepth = textureLoad(rendererPointShadowTexture, pixel, i32(round(uvLayer.z)), 0).r;\n let currentDepth = clamp(distanceToLight / max(range, 0.0001), 0.0, 1.0) - rendererPointShadowBiasForLight(lightIndex);\n let shadow = select(0.0, 1.0, currentDepth <= closestDepth);\n return mix(1.0, shadow, rendererPointShadowIntensityForLight(lightIndex));\n}\n\nfn rendererSamplePointShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n let params = rendererLights.pointShadowParams[lightIndex];\n let lightDirection = normalize(worldPosition - rendererPointLightPositionForLight(lightIndex));\n return rendererSamplePointShadowForLight(lightIndex, worldPosition + normalize(worldNormal + lightDirection) * params.w);\n}\n\nfn rendererSampleSpotShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n if (lightIndex >= rendererSpotLightCount() || !rendererSpotShadowEnabledForLight(lightIndex)) {\n return 1.0;\n }\n let matrix = rendererSpotShadowMatrixForLight(lightIndex);\n let shadowClip = matrix * vec4(worldPosition, 1.0);\n if (shadowClip.w <= 0.0) {\n return 1.0;\n }\n let ndc = shadowClip.xyz / shadowClip.w;\n if (ndc.x < -1.0 || ndc.x > 1.0 || ndc.y < -1.0 || ndc.y > 1.0 || ndc.z < 0.0 || ndc.z > 1.0) {\n return 1.0;\n }\n let uv = ndc.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n let dims = vec2<f32>(textureDimensions(rendererSpotShadowTexture));\n let texel = 1.0 / max(dims, vec2(1.0, 1.0));\n let radius = max(rendererLights.spotShadowParams2[lightIndex].x, 1.0);\n let depth = ndc.z - rendererSpotShadowBiasForLight(lightIndex);\n var sum = 0.0;\n for (var y: i32 = -1; y <= 1; y = y + 1) {\n for (var x: i32 = -1; x <= 1; x = x + 1) {\n let offset = vec2<f32>(f32(x), f32(y)) * texel * radius;\n let sampleUv = clamp(uv + offset, vec2(0.0, 0.0), vec2(1.0, 1.0));\n let pixel = vec2<i32>(clamp(sampleUv * dims, vec2(0.0, 0.0), dims - vec2(1.0, 1.0)));\n let shadowDepth = textureLoad(rendererSpotShadowTexture, pixel, i32(lightIndex), 0);\n sum += select(0.0, 1.0, depth <= shadowDepth);\n }\n }\n return mix(1.0, sum / 9.0, rendererSpotShadowIntensityForLight(lightIndex));\n}\n\nfn rendererSampleSpotShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n let params = rendererLights.spotShadowParams[lightIndex];\n return rendererSampleSpotShadowForLight(lightIndex, worldPosition + normalize(worldNormal) * params.w);\n}\n\nfn rendererSampleDirectionalShadow(worldPosition: vec3<f32>) -> f32 {\n return rendererSampleDirectionalShadowForLight(0u, worldPosition);\n}\n\nfn rendererSampleDirectionalShadowWithNormal(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n return rendererSampleDirectionalShadowForLightWithNormal(0u, worldPosition, worldNormal);\n}\n\nfn rendererSamplePointShadow(worldPosition: vec3<f32>) -> f32 {\n return rendererSamplePointShadowForLight(0u, worldPosition);\n}\n\nfn rendererSamplePointShadowWithNormal(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n return rendererSamplePointShadowForLightWithNormal(0u, worldPosition, worldNormal);\n}\n\nfn rendererSampleSpotShadow(worldPosition: vec3<f32>) -> f32 {\n return rendererSampleSpotShadowForLight(0u, worldPosition);\n}\n\nfn rendererSampleSpotShadowWithNormal(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n return rendererSampleSpotShadowForLightWithNormal(0u, worldPosition, worldNormal);\n}\n":"\nfn rendererSampleDirectionalShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n _ = lightIndex;\n _ = worldPosition;\n return 1.0;\n}\n\nfn rendererSampleDirectionalShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n _ = worldNormal;\n return rendererSampleDirectionalShadowForLight(lightIndex, worldPosition);\n}\n\nfn rendererSamplePointShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n _ = lightIndex;\n _ = worldPosition;\n return 1.0;\n}\n\nfn rendererSamplePointShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n _ = worldNormal;\n return rendererSamplePointShadowForLight(lightIndex, worldPosition);\n}\n\nfn rendererSampleSpotShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n _ = lightIndex;\n _ = worldPosition;\n return 1.0;\n}\n\nfn rendererSampleSpotShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n _ = worldNormal;\n return rendererSampleSpotShadowForLight(lightIndex, worldPosition);\n}\n\nfn rendererSampleDirectionalShadow(worldPosition: vec3<f32>) -> f32 {\n _ = worldPosition;\n return 1.0;\n}\n\nfn rendererSampleDirectionalShadowWithNormal(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n _ = worldPosition;\n _ = worldNormal;\n return 1.0;\n}\n\nfn rendererSamplePointShadow(worldPosition: vec3<f32>) -> f32 {\n _ = worldPosition;\n return 1.0;\n}\n\nfn rendererSamplePointShadowWithNormal(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n _ = worldPosition;\n _ = worldNormal;\n return 1.0;\n}\n\nfn rendererSampleSpotShadow(worldPosition: vec3<f32>) -> f32 {\n _ = worldPosition;\n return 1.0;\n}\n\nfn rendererSampleSpotShadowWithNormal(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n _ = worldPosition;\n _ = worldNormal;\n return 1.0;\n}\n";return`\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n nearFar: vec4<f32>,\n fogColor: vec4<f32>,\n fogParams: vec4<f32>,\n motionCurrentViewProj: mat4x4<f32>,\n motionPreviousViewProj: mat4x4<f32>,\n motionParams: vec4<f32>,\n};\n\nstruct RendererLightUniforms {\n ambientColor: vec4<f32>,\n lightCounts: vec4<f32>,\n directionalDirections: array<vec4<f32>, 4>,\n directionalColorIntensities: array<vec4<f32>, 4>,\n directionalShadowParams: array<vec4<f32>, 4>,\n directionalShadowParams2: array<vec4<f32>, 4>,\n directionalShadowMatrices: array<mat4x4<f32>, 4>,\n pointPositionRanges: array<vec4<f32>, 64>,\n pointColorIntensities: array<vec4<f32>, 64>,\n pointParams: array<vec4<f32>, 64>,\n pointShadowParams: array<vec4<f32>, 64>,\n pointShadowParams2: array<vec4<f32>, 64>,\n spotPositionRanges: array<vec4<f32>, 64>,\n spotDirectionCones: array<vec4<f32>, 64>,\n spotColorIntensities: array<vec4<f32>, 64>,\n spotShadowParams: array<vec4<f32>, 64>,\n spotShadowParams2: array<vec4<f32>, 64>,\n spotParams: array<vec4<f32>, 64>,\n spotShadowMatrices: array<mat4x4<f32>, 64>,\n csmCascadeRanges: array<vec4<f32>, 4>,\n hemisphereSkyColorIntensity: vec4<f32>,\n hemisphereGroundColorIntensity: vec4<f32>,\n hemisphereDirection: vec4<f32>,\n};\n\n${"particle"===r?`\n@group(1) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(1) @binding(1) var<uniform> rendererLights: RendererLightUniforms;\n@group(1) @binding(2) var rendererShadowSampler: sampler_comparison;\n@group(1) @binding(3) var rendererDirectionalShadowTexture: texture_depth_2d_array;\n@group(1) @binding(4) var rendererLinearClampSampler: sampler;\n@group(1) @binding(5) var rendererPointShadowTexture: texture_2d_array<f32>;\n@group(1) @binding(6) var rendererSpotShadowTexture: texture_depth_2d_array;\n@group(1) @binding(7) var rendererSpotLightMapAtlas: texture_2d<f32>;\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 { return instanceIndex; }\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n ${a??"_ = instanceIndex;\n return mat4x4<f32>(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));"}\n}\nfn rendererPreviousInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> { return rendererInstanceModelMatrix(instanceIndex); }\nfn rendererMotionBlurParams(instanceIndex: u32) -> vec4<f32> { _ = instanceIndex; return vec4<f32>(1.0, 1.0, 0.0, 0.0); }\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> { _ = instanceIndex; return vec4<f32>(1.0); }\n`:"instanced-direct"===r?"\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> rendererLights: RendererLightUniforms;\n@group(0) @binding(2) var<storage, read> rendererInstanceMatrices: array<vec4<f32>>;\n@group(0) @binding(3) var<storage, read> rendererInstanceColors: array<vec4<f32>>;\n@group(0) @binding(4) var rendererShadowSampler: sampler_comparison;\n@group(0) @binding(5) var rendererDirectionalShadowTexture: texture_depth_2d_array;\n@group(0) @binding(6) var rendererLinearClampSampler: sampler;\n@group(0) @binding(7) var rendererPointShadowTexture: texture_2d_array<f32>;\n@group(0) @binding(8) var rendererSpotShadowTexture: texture_depth_2d_array;\n@group(0) @binding(10) var rendererSpotLightMapAtlas: texture_2d<f32>;\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 {\n return instanceIndex;\n}\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let base = instanceIndex * 4u;\n return mat4x4<f32>(\n rendererInstanceMatrices[base + 0u],\n rendererInstanceMatrices[base + 1u],\n rendererInstanceMatrices[base + 2u],\n rendererInstanceMatrices[base + 3u]\n );\n}\n\nfn rendererPreviousInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererInstanceModelMatrix(instanceIndex);\n}\n\nfn rendererMotionBlurParams(instanceIndex: u32) -> vec4<f32> {\n _ = instanceIndex;\n return vec4<f32>(1.0, 1.0, 0.0, 0.0);\n}\n\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> {\n return rendererInstanceColors[instanceIndex];\n}\n":`\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> rendererLights: RendererLightUniforms;\n@group(0) @binding(2) var<storage, read> rendererInstances: array<RendererInstanceData>;\n@group(0) @binding(3) var rendererShadowSampler: sampler_comparison;\n@group(0) @binding(4) var rendererDirectionalShadowTexture: texture_depth_2d_array;\n@group(0) @binding(5) var rendererLinearClampSampler: sampler;\n@group(0) @binding(6) var rendererPointShadowTexture: texture_2d_array<f32>;\n@group(0) @binding(7) var rendererSpotShadowTexture: texture_depth_2d_array;\n@group(0) @binding(9) var rendererSpotLightMapAtlas: texture_2d<f32>;\n${c?"@group(0) @binding(8) var<storage, read> rendererVisibleInstanceIndices: array<u32>;":""}\n\nfn rendererResolveInstanceIndex(instanceIndex: u32) -> u32 {\n ${c?"return rendererVisibleInstanceIndices[instanceIndex];":"return instanceIndex;"}\n}\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[rendererResolveInstanceIndex(instanceIndex)];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\nfn rendererPreviousInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[rendererResolveInstanceIndex(instanceIndex)];\n return mat4x4<f32>(instance.previousModel0, instance.previousModel1, instance.previousModel2, instance.previousModel3);\n}\n\nfn rendererMotionBlurParams(instanceIndex: u32) -> vec4<f32> {\n return vec4<f32>(rendererInstances[rendererResolveInstanceIndex(instanceIndex)].batching.yzw, 0.0);\n}\n\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> {\n return rendererInstances[rendererResolveInstanceIndex(instanceIndex)].color;\n}\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 {\n return u32(round(rendererInstances[rendererResolveInstanceIndex(instanceIndex)].batching.x));\n}\n`}\n\n${s?"@group(0) @binding(11) var rendererPointLightTiles: texture_2d<u32>;":""}\n\nfn rendererFullPointLightMask() -> vec2<u32> {\n let count = min(rendererPointLightCount(), 64u);\n // Shifts by 32 wrap to zero in WGSL; explicitly handle empty words.\n let low = 0xffffffffu >> (32u - min(count, 32u));\n let high = 0xffffffffu >> (32u - min(count - min(count, 32u), 32u));\n return vec2<u32>(select(low, 0u, count == 0u), select(high, 0u, count <= 32u));\n}\n\nfn rendererPointLightMask(pixel: vec2<f32>) -> vec2<u32> {\n ${s?"\n if (rendererCamera.nearFar.w > 0.5 && rendererPointLightCount() > 0u) {\n // Tile boundaries align to derivative quads; clamp edge helpers.\n let tile = min(vec2<u32>(max(pixel, vec2<f32>(0.0))) / 16u, textureDimensions(rendererPointLightTiles) - 1u);\n return textureLoad(rendererPointLightTiles, vec2<i32>(tile), 0).xy;\n }":"_ = pixel;"}\n return rendererFullPointLightMask();\n}\n\nfn rendererInverseMat3(m: mat3x3<f32>) -> mat3x3<f32> {\n let a = m[0];\n let b = m[1];\n let c = m[2];\n let r0 = cross(b, c);\n let r1 = cross(c, a);\n let r2 = cross(a, b);\n let det = dot(r2, c);\n let safeDet = select(det, select(-1e-8, 1e-8, det >= 0.0), abs(det) < 1e-8);\n let invDet = 1.0 / safeDet;\n return transpose(mat3x3<f32>(r0 * invDet, r1 * invDet, r2 * invDet));\n}\n\nfn rendererInstanceNormalMatrix(instanceIndex: u32) -> mat3x3<f32> {\n let model = rendererInstanceModelMatrix(instanceIndex);\n let model3x3 = mat3x3<f32>(model[0].xyz, model[1].xyz, model[2].xyz);\n return transpose(rendererInverseMat3(model3x3));\n}\n\nfn rendererWorldPosition(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n return rendererInstanceModelMatrix(instanceIndex) * vec4(localPosition, 1.0);\n}\n\nfn rendererClipPosition(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n return rendererCamera.viewProj * rendererWorldPosition(localPosition, instanceIndex);\n}\n\nfn rendererMotionCurrentClip(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(localPosition, 1.0);\n return rendererCamera.motionCurrentViewProj * world;\n}\n\nfn rendererMotionPreviousClip(\n currentLocalPosition: vec3<f32>,\n previousLocalPosition: vec3<f32>,\n instanceIndex: u32\n) -> vec4<f32> {\n let params = rendererMotionBlurParams(instanceIndex);\n let useObjectHistory = params.x >= 1.5 && params.z >= 0.5;\n var previousModel = rendererInstanceModelMatrix(instanceIndex);\n var previousLocal = currentLocalPosition;\n if (useObjectHistory) {\n previousModel = rendererPreviousInstanceModelMatrix(instanceIndex);\n previousLocal = previousLocalPosition;\n }\n return rendererCamera.motionPreviousViewProj * previousModel * vec4(previousLocal, 1.0);\n}\n\nfn rendererWorldNormal(localNormal: vec3<f32>, instanceIndex: u32) -> vec3<f32> {\n return normalize(rendererInstanceNormalMatrix(instanceIndex) * localNormal);\n}\n\n${Fn("rendererCamera")}\n\nfn rendererDirectionalLightDirection() -> vec3<f32> {\n return rendererDirectionalLightDirectionForLight(0u);\n}\n\nfn rendererDirectionalLightColor() -> vec3<f32> {\n return rendererDirectionalLightColorForLight(0u);\n}\n\nfn rendererPointLightPosition() -> vec3<f32> {\n return rendererPointLightPositionForLight(0u);\n}\n\nfn rendererPointLightRange() -> f32 {\n return rendererPointLightRangeForLight(0u);\n}\n\nfn rendererPointLightColor() -> vec3<f32> {\n return rendererPointLightColorForLight(0u);\n}\n\nfn rendererAmbientLight() -> vec3<f32> {\n return rendererLights.ambientColor.xyz * rendererLights.ambientColor.w;\n}\n\nfn rendererHemisphereLight(worldNormal: vec3<f32>) -> vec3<f32> {\n let directionLength = length(rendererLights.hemisphereDirection.xyz);\n if (directionLength <= 0.0) {\n return vec3<f32>(0.0);\n }\n let sky = rendererLights.hemisphereSkyColorIntensity;\n let ground = rendererLights.hemisphereGroundColorIntensity;\n let weight = dot(normalize(worldNormal), rendererLights.hemisphereDirection.xyz / directionLength) * 0.5 + 0.5;\n return mix(ground.xyz * ground.w, sky.xyz * sky.w, weight);\n}\n\nfn rendererIndirectDiffuse(worldNormal: vec3<f32>) -> vec3<f32> {\n return rendererAmbientLight() + rendererHemisphereLight(worldNormal);\n}\n\nfn rendererDirectionalLightCount() -> u32 {\n return u32(round(rendererLights.lightCounts.x));\n}\n\nfn rendererPointLightCount() -> u32 {\n return u32(round(rendererLights.lightCounts.y));\n}\n\nfn rendererSpotLightCount() -> u32 {\n return u32(round(rendererLights.lightCounts.z));\n}\n\nfn rendererCsmCascadeCount() -> u32 {\n return u32(round(rendererLights.lightCounts.w));\n}\n\nfn rendererCsmCascadeRangeForLight(lightIndex: u32) -> vec2<f32> {\n return rendererLights.csmCascadeRanges[lightIndex].xy;\n}\n\nfn rendererDirectionalLightDirectionForLight(lightIndex: u32) -> vec3<f32> {\n return normalize(-rendererLights.directionalDirections[lightIndex].xyz);\n}\n\nfn rendererDirectionalLightColorForLight(lightIndex: u32) -> vec3<f32> {\n let value = rendererLights.directionalColorIntensities[lightIndex];\n return value.xyz * value.w;\n}\n\nfn rendererPointLightPositionForLight(lightIndex: u32) -> vec3<f32> {\n return rendererLights.pointPositionRanges[lightIndex].xyz;\n}\n\nfn rendererPointLightRangeForLight(lightIndex: u32) -> f32 {\n return rendererLights.pointParams[lightIndex].x;\n}\n\nfn rendererPointLightShadowRangeForLight(lightIndex: u32) -> f32 {\n return rendererLights.pointPositionRanges[lightIndex].w;\n}\n\nfn rendererPointLightDecayForLight(lightIndex: u32) -> f32 {\n return rendererLights.pointParams[lightIndex].y;\n}\n\nfn rendererPointLightColorForLight(lightIndex: u32) -> vec3<f32> {\n let value = rendererLights.pointColorIntensities[lightIndex];\n return value.xyz * value.w;\n}\n\nfn rendererSpotLightPositionForLight(lightIndex: u32) -> vec3<f32> {\n return rendererLights.spotPositionRanges[lightIndex].xyz;\n}\n\nfn rendererSpotLightRangeForLight(lightIndex: u32) -> f32 {\n return rendererLights.spotPositionRanges[lightIndex].w;\n}\n\nfn rendererSpotLightDirectionForLight(lightIndex: u32) -> vec3<f32> {\n // The packed value points from the light towards its target. Material\n // lighting evaluates the incident direction from the fragment back to the\n // light, matching rendererDirectionalLightDirectionForLight().\n return normalize(-rendererLights.spotDirectionCones[lightIndex].xyz);\n}\n\nfn rendererSpotLightConeCosForLight(lightIndex: u32) -> f32 {\n return rendererLights.spotDirectionCones[lightIndex].w;\n}\n\nfn rendererSpotLightPenumbraCosForLight(lightIndex: u32) -> f32 {\n return rendererLights.spotParams[lightIndex].y;\n}\n\nfn rendererSpotLightDecayForLight(lightIndex: u32) -> f32 {\n return rendererLights.spotParams[lightIndex].z;\n}\n\nfn rendererSpotLightColorForLight(lightIndex: u32) -> vec3<f32> {\n let value = rendererLights.spotColorIntensities[lightIndex];\n return value.xyz * value.w;\n}\n\n// These structs make the renderer's packed light buffer available to generic\n// graph nodes. The graph only depends on the semantic fields; this header can\n// later source them from Forward+ storage buffers without changing materials.\nstruct RendererDirectionalLight {\n direction: vec3<f32>,\n color: vec3<f32>,\n};\n\nfn rendererDirectionalLightForLight(lightIndex: u32) -> RendererDirectionalLight {\n return RendererDirectionalLight(\n rendererDirectionalLightDirectionForLight(lightIndex),\n rendererDirectionalLightColorForLight(lightIndex)\n );\n}\n\n// These records match three-shader-graph's established shadow structs. They\n// intentionally expose metadata only; sampling stays behind the renderer's\n// semantic shadow functions so graph code never depends on the atlas layout.\nstruct RendererDirectionalLightShadow {\n shadowBias: f32,\n shadowNormalBias: f32,\n shadowRadius: f32,\n shadowMapSize: vec2<f32>,\n};\n\nfn rendererDirectionalLightShadowForLight(lightIndex: u32) -> RendererDirectionalLightShadow {\n let params = rendererLights.directionalShadowParams[lightIndex];\n let params2 = rendererLights.directionalShadowParams2[lightIndex];\n return RendererDirectionalLightShadow(\n params.x,\n params.w,\n params2.x,\n vec2<f32>(params.z)\n );\n}\n\nstruct RendererPointLight {\n position: vec3<f32>,\n color: vec3<f32>,\n distance: f32,\n decay: f32,\n};\n\nfn rendererPointLightForLight(lightIndex: u32) -> RendererPointLight {\n return RendererPointLight(\n rendererPointLightPositionForLight(lightIndex),\n rendererPointLightColorForLight(lightIndex),\n rendererPointLightRangeForLight(lightIndex),\n rendererPointLightDecayForLight(lightIndex)\n );\n}\n\nstruct RendererPointLightShadow {\n shadowBias: f32,\n shadowNormalBias: f32,\n shadowRadius: f32,\n shadowMapSize: vec2<f32>,\n shadowCameraNear: f32,\n shadowCameraFar: f32,\n};\n\nfn rendererPointLightShadowForLight(lightIndex: u32) -> RendererPointLightShadow {\n let params = rendererLights.pointShadowParams[lightIndex];\n let params2 = rendererLights.pointShadowParams2[lightIndex];\n return RendererPointLightShadow(\n params.x,\n params.w,\n params2.x,\n vec2<f32>(params.z),\n params2.z,\n params2.w\n );\n}\n\nstruct RendererSpotLight {\n position: vec3<f32>,\n direction: vec3<f32>,\n color: vec3<f32>,\n distance: f32,\n decay: f32,\n coneCos: f32,\n penumbraCos: f32,\n};\n\nfn rendererSpotLightForLight(lightIndex: u32) -> RendererSpotLight {\n return RendererSpotLight(\n rendererSpotLightPositionForLight(lightIndex),\n rendererSpotLightDirectionForLight(lightIndex),\n rendererSpotLightColorForLight(lightIndex),\n rendererSpotLightRangeForLight(lightIndex),\n rendererSpotLightDecayForLight(lightIndex),\n rendererSpotLightConeCosForLight(lightIndex),\n rendererSpotLightPenumbraCosForLight(lightIndex)\n );\n}\n\nstruct RendererSpotLightShadow {\n shadowBias: f32,\n shadowNormalBias: f32,\n shadowRadius: f32,\n shadowMapSize: vec2<f32>,\n};\n\nfn rendererSpotLightShadowForLight(lightIndex: u32) -> RendererSpotLightShadow {\n let params = rendererLights.spotShadowParams[lightIndex];\n let params2 = rendererLights.spotShadowParams2[lightIndex];\n return RendererSpotLightShadow(\n params.x,\n params.w,\n params2.x,\n vec2<f32>(params.z)\n );\n}\n\nfn rendererDirectionalShadowMatrixForLight(lightIndex: u32) -> mat4x4<f32> {\n return rendererLights.directionalShadowMatrices[lightIndex];\n}\n\nfn rendererDirectionalShadowMatrix() -> mat4x4<f32> {\n return rendererDirectionalShadowMatrixForLight(0u);\n}\n\nfn rendererDirectionalShadowBias() -> f32 {\n return rendererDirectionalShadowBiasForLight(0u);\n}\n\nfn rendererDirectionalShadowBiasForLight(lightIndex: u32) -> f32 {\n return rendererLights.directionalShadowParams[lightIndex].x;\n}\n\nfn rendererDirectionalShadowEnabled() -> bool {\n return rendererDirectionalShadowEnabledForLight(0u);\n}\n\nfn rendererDirectionalShadowEnabledForLight(lightIndex: u32) -> bool {\n return rendererLights.directionalShadowParams[lightIndex].y >= 0.5;\n}\n\nfn rendererDirectionalShadowIntensityForLight(lightIndex: u32) -> f32 {\n return rendererLights.directionalShadowParams2[lightIndex].y;\n}\n\nfn rendererDirectionalShadowMapSize() -> f32 {\n return rendererLights.directionalShadowParams[0].z;\n}\n\nfn rendererPointShadowBias() -> f32 {\n return rendererPointShadowBiasForLight(0u);\n}\n\nfn rendererPointShadowBiasForLight(lightIndex: u32) -> f32 {\n return rendererLights.pointShadowParams[lightIndex].x;\n}\n\nfn rendererPointShadowEnabled() -> bool {\n return rendererPointShadowEnabledForLight(0u);\n}\n\nfn rendererPointShadowEnabledForLight(lightIndex: u32) -> bool {\n return rendererLights.pointShadowParams[lightIndex].y >= 0.5;\n}\n\nfn rendererPointShadowIntensityForLight(lightIndex: u32) -> f32 {\n return rendererLights.pointShadowParams2[lightIndex].y;\n}\n\nfn rendererSpotShadowMatrixForLight(lightIndex: u32) -> mat4x4<f32> {\n return rendererLights.spotShadowMatrices[lightIndex];\n}\n\nfn rendererSpotShadowBiasForLight(lightIndex: u32) -> f32 {\n return rendererLights.spotShadowParams[lightIndex].x;\n}\n\nfn rendererSpotShadowEnabledForLight(lightIndex: u32) -> bool {\n return rendererLights.spotShadowParams[lightIndex].y >= 0.5;\n}\n\nfn rendererSpotShadowIntensityForLight(lightIndex: u32) -> f32 {\n return rendererLights.spotShadowParams2[lightIndex].y;\n}\n\nfn rendererSampleSpotLightMapForLight(lightIndex: u32, worldPosition: vec3<f32>) -> vec3<f32> {\n if (lightIndex >= rendererSpotLightCount() || rendererLights.spotParams[lightIndex].w < 0.5) {\n return vec3<f32>(1.0);\n }\n let clip = rendererSpotShadowMatrixForLight(lightIndex) * vec4<f32>(worldPosition, 1.0);\n if (clip.w <= 0.0) { return vec3<f32>(1.0); }\n let ndc = clip.xyz / clip.w;\n if (any(ndc < vec3<f32>(-1.0, -1.0, 0.0)) || any(ndc > vec3<f32>(1.0))) {\n return vec3<f32>(1.0);\n }\n let projectedUv = ndc.xy * vec2<f32>(0.5, -0.5) + vec2<f32>(0.5);\n let cell = vec2<f32>(f32(lightIndex % 8u), f32(lightIndex / 8u));\n let cellUv = clamp(projectedUv, vec2<f32>(0.0), vec2<f32>(1.0)) * (255.0 / 256.0) + vec2<f32>(0.5 / 256.0);\n let atlasUv = (cell + cellUv) / 8.0;\n return textureSampleLevel(rendererSpotLightMapAtlas, rendererLinearClampSampler, atlasUv, 0.0).rgb;\n}\n\n${u}\n${kn(n)}\n${o}\n${l}\n`}function On(e=!0,t){return En({uniforms:{},textures:{},storageBuffers:{},getGraphTextureInputs:()=>({})},void 0,"particle",e,!1,t)}function jn(e,t,r,i="packed",n=!1){const a="camera"===t?`\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n nearFar: vec4<f32>,\n fogColor: vec4<f32>,\n fogParams: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> rendererLights: array<vec4<f32>, 11>;\n${"instanced-direct"===i?"@group(0) @binding(2) var<storage, read> rendererInstanceMatrices: array<vec4<f32>>;\n@group(0) @binding(3) var<storage, read> rendererInstanceColors: array<vec4<f32>>;":"@group(0) @binding(2) var<storage, read> rendererInstances: array<RendererInstanceData>;"}\n\nfn rendererClipPosition(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n return rendererCamera.viewProj * rendererWorldPosition(localPosition, instanceIndex);\n}\n`:`\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n nearFar: vec4<f32>,\n timeAndPadding: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n${"instanced-direct"===i?"@group(0) @binding(1) var<storage, read> rendererInstanceMatrices: array<vec4<f32>>;\n@group(0) @binding(2) var<storage, read> rendererInstanceColors: array<vec4<f32>>;":"@group(0) @binding(1) var<storage, read> rendererInstances: array<RendererInstanceData>;"}\n\nfn rendererClipPosition(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n return shadowCamera.viewProj * rendererWorldPosition(localPosition, instanceIndex);\n}\n`,s=An(e,r);return`\n${a}\n\n${"instanced-direct"===i?"\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let base = instanceIndex * 4u;\n return mat4x4<f32>(\n rendererInstanceMatrices[base + 0u],\n rendererInstanceMatrices[base + 1u],\n rendererInstanceMatrices[base + 2u],\n rendererInstanceMatrices[base + 3u]\n );\n}\n\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> {\n return rendererInstanceColors[instanceIndex];\n}\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 {\n return instanceIndex;\n}\n":"\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> {\n return rendererInstances[instanceIndex].color;\n}\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 {\n return u32(round(rendererInstances[instanceIndex].batching.x));\n}\n"}\n\nfn rendererInverseMat3(m: mat3x3<f32>) -> mat3x3<f32> {\n let a = m[0];\n let b = m[1];\n let c = m[2];\n let r0 = cross(b, c);\n let r1 = cross(c, a);\n let r2 = cross(a, b);\n let det = dot(r2, c);\n let safeDet = select(det, select(-1e-8, 1e-8, det >= 0.0), abs(det) < 1e-8);\n let invDet = 1.0 / safeDet;\n return transpose(mat3x3<f32>(r0 * invDet, r1 * invDet, r2 * invDet));\n}\n\nfn rendererInstanceNormalMatrix(instanceIndex: u32) -> mat3x3<f32> {\n let model = rendererInstanceModelMatrix(instanceIndex);\n let model3x3 = mat3x3<f32>(model[0].xyz, model[1].xyz, model[2].xyz);\n return transpose(rendererInverseMat3(model3x3));\n}\n\nfn rendererWorldPosition(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n return rendererInstanceModelMatrix(instanceIndex) * vec4(localPosition, 1.0);\n}\n\nfn rendererWorldNormal(localNormal: vec3<f32>, instanceIndex: u32) -> vec3<f32> {\n return normalize(rendererInstanceNormalMatrix(instanceIndex) * localNormal);\n}\n\n${Fn("camera"===t?"rendererCamera":"shadowCamera")}\n${kn(n)}\n${s}\n`}var $n=class{constructor(e,t,r={}){this.name=e,this.callback=t,this.reads=r.reads,this.writes=r.writes,this.dependsOn=r.dependsOn}name;callback;reads;writes;dependsOn;execute(e){this.callback(e)}};function Wn(e,t){e.latestFrameProfile=Hn(t.profile),(t.pendingGpuRead||t.pendingVisibilityRead)&&Promise.all([t.pendingGpuRead?Nn(t.profile,t.pendingGpuRead):Promise.resolve(),t.pendingVisibilityRead?_n(t.profile,t.pendingVisibilityRead):Promise.resolve()]).then(()=>{const r=Hn(t.profile);e.latestFrameProfile=r,e.latestCompletedFrameProfile=r})}async function Nn(e,t){try{await t.readBuffer.mapAsync(GPUMapMode.READ);const r=t.readBuffer.getMappedRange(),i=new BigUint64Array(r.slice(0));let n=0;const a=t.profile.passes.map((e,t)=>{const r=Number(i[2*t]??0n),a=Number(i[2*t+1]??0n),s=Math.max(0,a-r)/1e6;return n+=s,{...e,gpuTimeMs:s}});e.gpuTimeMs=n,e.gpuProfilingReason=null,e.passes=a}catch{e.timestampQueryActive=!1,e.gpuTimeMs=null,e.gpuProfilingReason="timestamp readback failed after submission",e.passes=e.passes.map(e=>({...e,gpuTimeMs:null}))}finally{"mapped"===t.readBuffer.mapState&&t.readBuffer.unmap(),t.querySet.destroy(),t.resolveBuffer.destroy(),t.readBuffer.destroy()}}async function _n(e,t){try{await t.readBuffer.mapAsync(GPUMapMode.READ);const r=new Uint32Array(t.readBuffer.getMappedRange());let i=0,n=0,a=0,s=0,o=0;for(const e of t.regions){let t=0;const l=e.byteOffset/Uint32Array.BYTES_PER_ELEMENT;for(let i=0;i<e.drawCount;i+=1)t+=r[l+5*i+1]??0,o+=Math.floor((r[l+5*i]??0)/3)*(r[l+5*i+1]??0);"dynamic"===e.kind?(i+=e.totalInstances,n+=t):(a+=e.totalInstances,s+=t)}const l=i+a,c=n+s;e.visibility={visibleTriangles:o,totalInstances:l,visibleInstances:c,culledInstances:Math.max(0,l-c),dynamicTotalInstances:i,dynamicVisibleInstances:n,staticTotalInstances:a,staticVisibleInstances:s}}catch{e.visibility=null}finally{"mapped"===t.readBuffer.mapState&&t.readBuffer.unmap(),t.readBuffer.destroy()}}function Hn(e){return{...e,cpuPhases:{...e.cpuPhases},passes:e.passes.map(e=>({...e})),visibility:e.visibility?{...e.visibility}:null}}import{Frustum as qn,Matrix4 as Kn,Sphere as Zn}from"three";function Yn(e,t,r,i,n,a,s,o){const l=e[t+3];if(n>0&&!(l*i>=n*(s?.85:1.15)))return!1;const c=e[t],u=e[t+1],d=e[t+2];if(a>0){const e=c-o.x,t=u-o.y,r=d-o.z,i=a+l;if(!(e*e+t*t+r*r<=i*i))return!1}for(let e=0;e<6;e++){const t=r.planes[e],i=t.normal;if(i.x*c+i.y*u+i.z*d+t.constant<-l)return!1}return!0}var Xn=new qn,Jn=new Kn,Qn=new Zn,ea=new WeakMap,ta=[],ra=new WeakMap,ia=L.clone();function na(e,t,r,i){let n=ea.get(e);n||(n=new WeakMap,ea.set(e,n));let a=n.get(t);a||(a=[],n.set(t,a)),ta.length=0,i.getWorldPosition(ia);const s=e.instanceVisibilityResource.metadata,o=Math.max(Math.abs(t.projectionMatrix.elements[0])*r,Math.abs(t.projectionMatrix.elements[5])*r);let l=ra.get(e);l||(l=new WeakMap,ra.set(e,l));let c=l.get(t);c||(c=new Uint8Array(e.instanceCount),l.set(t,c));let u=0;for(const t of e.shadowChunks)if(Qn.center.copy(t.boundsCenter),Qn.radius=t.boundsRadius,Xn.intersectsSphere(Qn))for(const r of t.drawIndices){const t=e.draws[r],i=t.detailCulling;let n=-1;const l=t.instanceStart+t.instanceCount;for(let e=t.instanceStart;e<=l;e++){let r=!1;if(e<l){r=Yn(s,8*e,Xn,o,i.shadowMinScreenSize,i.shadowMaxDistance,0!==c[e],ia),c[e]=r?1:0}if(r&&n<0&&(n=e),!r&&n>=0){let r=a[u];r?r.source!==t&&(Object.assign(r.draw,t),r.source=t):(r={source:t,draw:{...t}},a[u]=r);const i=r.draw;i.instanceStart=n,i.instanceCount=e-n,ta.push(i),u++,n=-1}}}return ta}function aa(e){return e.usesBatching}function sa(e){return!e.wireframe&&e.material.primitiveTopology.startsWith("triangle")}function oa(e,t){return"pointShadow"===t?null!==e.material.pointShadowVertexShader&&null!==e.material.pointShadowFragmentShader:null!==e.material.depthVertexShader}function la(e,t){if(!this.state.visibilityKernel||!this.state.drawMetadataResource||0===this.state.drawMetadataResource.count)return;const r=e.beginComputePass({label:"renderer-visibility-pass"});r.setPipeline(this.state.visibilityKernel.pipeline),r.setBindGroup(0,t),r.dispatchWorkgroups(Math.ceil(this.state.drawMetadataResource.count/64)),r.end()}var ca=new WeakMap;function ua(e,t){if(!(this.state.staticVisibilityClearKernel&&this.state.staticVisibilityCullKernel&&this.state.staticVisibilityIndirectBuildKernel&&this.getHiZOcclusionCullingActive()&&this.state.device))return;let r=ca.get(this);r||(r=[],ca.set(this,r)),r.length=0;for(const e of this.staticDrawSets){if(!e.publicSet.enabled||0===e.drawMetadataResource.count)continue;if("postpass"===t&&e.lastPreVisibilityFrameToken!==this.staticFrameToken)continue;if(!this.state.device)continue;const i="prepass"===t?e.visibilityParamsUpload:e.postVisibilityParamsUpload,n="prepass"===t?e.visibilityParamsBuffer:e.postVisibilityParamsBuffer,a="prepass"===t?this.state.temporalHiZHistoryValid?3:0:5;i[1]===this.state.hizMipCount&&i[3]===a||(i[1]=this.state.hizMipCount,i[3]=a,this.state.device.queue.writeBuffer(n,0,Yr(i),0,4));this.getOrCreateStaticVisibilityBindGroup(e,t)&&("prepass"!==t||e.visibilityClearBindGroup&&e.visibilityIndirectBuildBindGroup&&e.postVisibilityIndirectBuildBindGroup||(e.visibilityClearBindGroup=this.state.staticVisibilityClearKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:e.visibilityParamsBuffer}},{binding:1,resource:{buffer:e.instanceVisibilityResource.visibleCountsBuffer}},{binding:2,resource:{buffer:e.instanceVisibilityResource.postVisibleCountsBuffer}},{binding:3,resource:{buffer:e.instanceVisibilityResource.visibleInstanceMaskBuffer}}],`${e.label}-visibility-clear-bind-group`),e.visibilityIndirectBuildBindGroup=this.state.staticVisibilityIndirectBuildKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:e.visibilityParamsBuffer}},{binding:1,resource:{buffer:e.instanceVisibilityResource.visibleCountsBuffer}},{binding:2,resource:{buffer:e.instanceVisibilityResource.postVisibleCountsBuffer}},{binding:3,resource:{buffer:e.drawMetadataResource.indirectBuffer}},{binding:4,resource:{buffer:e.drawMetadataResource.postIndirectBuffer}}],`${e.label}-visibility-indirect-build-bind-group`),e.postVisibilityIndirectBuildBindGroup=this.state.staticVisibilityIndirectBuildKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:e.postVisibilityParamsBuffer}},{binding:1,resource:{buffer:e.instanceVisibilityResource.visibleCountsBuffer}},{binding:2,resource:{buffer:e.instanceVisibilityResource.postVisibleCountsBuffer}},{binding:3,resource:{buffer:e.drawMetadataResource.indirectBuffer}},{binding:4,resource:{buffer:e.drawMetadataResource.postIndirectBuffer}}],`${e.label}-post-visibility-indirect-build-bind-group`)),r.push(e))}if(0===r.length)return;if("prepass"===t){const t=e.beginComputePass({label:"static-temporal-visibility-clear-pass"});t.setPipeline(this.state.staticVisibilityClearKernel.pipeline);for(const e of r)t.setBindGroup(0,e.visibilityClearBindGroup),t.dispatchWorkgroups(Math.ceil(Math.max(e.drawMetadataResource.count,e.instanceVisibilityResource.instanceCount)/64));t.end()}const i=e.beginComputePass({label:`static-temporal-visibility-${t}-cull-pass`});i.setPipeline(this.state.staticVisibilityCullKernel.pipeline);for(const e of r)i.setBindGroup(0,"prepass"===t?e.visibilityBindGroup:e.postVisibilityBindGroup),i.dispatchWorkgroups(Math.ceil(e.instanceVisibilityResource.instanceCount/64));i.end();const n=e.beginComputePass({label:`static-temporal-visibility-${t}-indirect-build-pass`});n.setPipeline(this.state.staticVisibilityIndirectBuildKernel.pipeline);for(const e of r)n.setBindGroup(0,"prepass"===t?e.visibilityIndirectBuildBindGroup:e.postVisibilityIndirectBuildBindGroup),n.dispatchWorkgroups(Math.ceil(e.drawMetadataResource.count/64)),"prepass"===t?e.lastPreVisibilityFrameToken=this.staticFrameToken:e.lastVisibilityFrameToken=this.staticFrameToken;n.end(),r.length=0}function da(e,t){if(!(this.state.device&&this.state.staticVisibilityCullKernel&&this.state.hizTexture&&this.state.temporalVisibilityBuffer&&this.state.nearestClampSampler))return null;const r="prepass"===t?e.visibilityBindGroup:e.postVisibilityBindGroup;if(r&&e.visibilityBindGroupHizVersion===this.hizResourceVersion)return r;const i=this.state.staticVisibilityCullKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:this.state.temporalVisibilityBuffer}},{binding:1,resource:{buffer:"prepass"===t?e.visibilityParamsBuffer:e.postVisibilityParamsBuffer}},{binding:2,resource:this.state.nearestClampSampler},{binding:3,resource:this.state.hizTexture.createView()},{binding:4,resource:{buffer:e.instanceVisibilityResource.instanceMetadataBuffer}},{binding:5,resource:{buffer:e.drawMetadataResource.metadataBuffer}},{binding:6,resource:{buffer:e.instanceVisibilityResource.visibleCountsBuffer}},{binding:7,resource:{buffer:e.instanceVisibilityResource.visibleInstanceIndicesBuffer}},{binding:8,resource:{buffer:e.instanceVisibilityResource.visibleInstanceMaskBuffer}},{binding:9,resource:{buffer:e.instanceVisibilityResource.postVisibleCountsBuffer}}],`${e.label}-temporal-visibility-${t}-bind-group`);return"prepass"===t?e.visibilityBindGroup=i:e.postVisibilityBindGroup=i,e.visibilityBindGroupHizVersion=this.hizResourceVersion,i}function ha(e,t,r,i){if(!this.state.shadowDepthPipeline||0===this.state.directionalShadowLayerViews.length)return void this.clearDirectionalShadow(e);let n=!1;for(let t=0;t<r.lights.directionals.length;t+=1){const a=r.lights.directionals[t],s=this.state.directionalShadowLayerViews[t];if(!a.castShadow||!s)continue;n=!0;const o=this.directionalShadowCameras[t];if(!(this.directionalShadowScheduler.updateMask&1<<t)){i.directionalShadowReused=(i.directionalShadowReused??0)+1;continue}i.directionalShadowUpdates=(i.directionalShadowUpdates??0)+1,i.directionalShadowUpdateMask=(i.directionalShadowUpdateMask??0)|1<<t,this.directionalShadowScheduler.forcedMask&1<<t&&(i.directionalShadowForced=(i.directionalShadowForced??0)+1),Xn.setFromProjectionMatrix(Jn.multiplyMatrices(o.projectionMatrix,o.matrixWorldInverse));const l=this.getShadowCameraBuffer(t);this.writeShadowCameraBuffer(fi(o,this.shadowViewProjScratch),0,0,0,1,l,o);const c=this.getSharedShadowBindGroupForCameraBuffer(l),u=e.beginRenderPass({label:`renderer-directional-shadow-pass-${t}`,colorAttachments:[],depthStencilAttachment:{view:s,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});u.setPipeline(this.state.shadowDepthPipeline),u.setBindGroup(0,c),r.camera.getWorldPosition(ia),this.drawDepthLike(u,r.shadowDraws??[...r.gpuOpaqueDraws,...r.directOpaqueDraws],i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"});for(const e of this.staticDrawSets)e.publicSet.enabled&&0!==e.draws.length&&"late"!==e.drawStage&&this.drawDepthLike(u,na(e,o,this.state.directionalShadowTextureSize,r.camera),i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"});u.end(),this.directionalShadowScheduler.commit(t)}n||this.clearDirectionalShadow(e)}function pa(e,t,r,i){if(!r.lights.points.some(e=>e.castShadow))return;if(!this.state.pointShadowPipeline||!this.state.pointShadowFaceViews.length||!this.state.pointShadowDepthFaceViews.length)return void this.clearPointShadow(e);let n=!1;for(let t=0;t<r.lights.points.length;t+=1){const a=r.lights.points[t];if(a.castShadow){n=!0;for(let n=0;n<6;n+=1){const s=6*t+n,o=this.pointShadowCameras[t][n];o.near=a.shadowCameraNear,o.far=a.shadowCameraFar,o.position.copy(a.position),L.copy(a.position).add(D[n]),o.up.copy(B[n]),o.lookAt(L),o.updateMatrixWorld(!0),o.updateProjectionMatrix();const l=this.getShadowCameraBuffer(4+s);this.writeShadowCameraBuffer(fi(o,this.shadowViewProjScratch),a.position.x,a.position.y,a.position.z,a.range,l,o);const c=this.getSharedShadowBindGroupForCameraBuffer(l),u=e.beginRenderPass({label:`renderer-point-shadow-pass-${t}-${n}`,colorAttachments:[{view:this.state.pointShadowFaceViews[s],clearValue:{r:1,g:1,b:1,a:1},loadOp:"clear",storeOp:"store"}],depthStencilAttachment:{view:this.state.pointShadowDepthFaceViews[s],depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});u.setPipeline(this.state.pointShadowPipeline),u.setBindGroup(0,c),this.drawDepthLike(u,r.gpuOpaqueDraws,i,{fallbackPipeline:this.state.pointShadowPipeline,fallbackPipelineDirect:this.state.pointShadowPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedPointShadowPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"pointShadow",customDepthMode:"use"}),this.drawDepthLike(u,r.directOpaqueDraws,i,{fallbackPipeline:this.state.pointShadowPipeline,fallbackPipelineDirect:this.state.pointShadowPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedPointShadowPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"pointShadow",customDepthMode:"use"});for(const e of this.staticDrawSets)e.publicSet.enabled&&0!==e.draws.length&&"late"!==e.drawStage&&(this.renderBundleScratch[0]=Sa.call(this,e,c,l,"pointShadow",this.state.pointShadowPipeline,this.state.pointShadowPipelineDirect),u.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(e,i));u.end()}}}n||this.clearPointShadow(e)}function fa(e,t,r,i){if(!r.lights.spots.some(e=>e.castShadow))return;if(!this.state.shadowDepthPipeline||0===this.state.spotShadowLayerViews.length)return void this.clearSpotShadow(e);let n=!1;for(let t=0;t<r.lights.spots.length;t+=1){const a=r.lights.spots[t],s=this.state.spotShadowLayerViews[t];if(!a.castShadow||!s)continue;n=!0;const o=this.spotShadowCameras[t];o.near=a.shadowCameraNear,o.far=a.shadowCameraFar,o.fov=a.shadowCameraFov,o.aspect=1,o.position.copy(a.position),L.copy(a.position).add(a.direction),o.lookAt(L),o.updateMatrixWorld(!0),o.updateProjectionMatrix();const l=this.getShadowCameraBuffer(28+t);this.writeShadowCameraBuffer(fi(o,this.shadowViewProjScratch),0,0,0,1,l,o);const c=this.getSharedShadowBindGroupForCameraBuffer(l),u=e.beginRenderPass({label:`renderer-spot-shadow-pass-${t}`,colorAttachments:[],depthStencilAttachment:{view:s,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});u.setPipeline(this.state.shadowDepthPipeline),u.setBindGroup(0,c),this.drawDepthLike(u,r.gpuOpaqueDraws,i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"}),this.drawDepthLike(u,r.directOpaqueDraws,i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"});for(const e of this.staticDrawSets)e.publicSet.enabled&&0!==e.draws.length&&"late"!==e.drawStage&&(this.renderBundleScratch[0]=Sa.call(this,e,c,l,"directionalShadow",this.state.shadowDepthPipeline,this.state.shadowDepthPipelineDirect),u.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(e,i));u.end()}n||this.clearSpotShadow(e)}function ma(e,t,r,i){if(!this.state.depthPrepassPipeline||!this.state.mainDepthView)return;const n=e.beginRenderPass({label:"renderer-depth-prepass",colorAttachments:[],depthStencilAttachment:{view:this.state.mainDepthView,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});n.setPipeline(this.state.depthPrepassPipeline),n.setBindGroup(0,t),this.executeStaticDepthPrepass(n,t,i),this.drawDepthLike(n,r.gpuOpaqueDraws,i,{fallbackPipeline:this.state.depthPrepassPipeline,fallbackPipelineDirect:this.state.depthPrepassPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedDepthPrepassPipeline,fallbackBindGroup:t,passKind:"prepass",customDepthMode:"skip"}),this.drawDepthLike(n,r.directOpaqueDraws,i,{fallbackPipeline:this.state.depthPrepassPipeline,fallbackPipelineDirect:this.state.depthPrepassPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedDepthPrepassPipeline,fallbackBindGroup:t,passKind:"prepass",customDepthMode:"skip"}),n.end()}function ga(e,t,r){for(const i of this.staticDrawSets){if(!i.publicSet.enabled||0===i.draws.length||"late"===i.drawStage)continue;if(this.getHiZOcclusionCullingActive()&&i.lastPreVisibilityFrameToken===this.staticFrameToken&&wa(i)){const e=this.getOrCreateStaticVisibleDepthSceneBindGroup(i);this.renderBundleScratch[0]=va.call(this,i,e)}else this.renderBundleScratch[0]=this.getOrCreateStaticDepthPrepassBundle(i,t);e.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(i,r)}}function va(e,t,r=e.drawMetadataResource.indirectBuffer,i="prepass"){if(!this.state.device||!this.state.depthPrepassPipelineVisible)throw new Error("Renderer visible depth prepass resources are not initialized.");const n=e.indirectDepthPrepassBundles[i];if(n?.sceneBindGroup===t&&n.indirectBuffer===r)return n.bundle;const a=`${e.label}-static-temporal-depth-${i}-bundle-${e.id}`,s=this.state.device.createRenderBundleEncoder({label:a,colorFormats:[],depthStencilFormat:"depth32float",sampleCount:1});s.setPipeline(this.state.depthPrepassPipelineVisible),s.setBindGroup(0,t);let o=null;for(let t=0;t<e.draws.length;t+=1){const i=e.draws[t];i.customDepthMaterial||oa(i,"prepass")||Fa(i.material)||!sa(i)||(o!==i.geometryKey&&(o=i.geometryKey,this.bindGeometryVertexBuffers(s,i.geometry,i.geometryResource,I,0,1,i.wireframe)),s.drawIndexedIndirect(r,5*t*Uint32Array.BYTES_PER_ELEMENT))}const l=s.finish({label:a});return e.indirectDepthPrepassBundles[i]={sceneBindGroup:t,indirectBuffer:r,bundle:l},l}function xa(e){if(this.sampleCount<=1||!this.state.mainDepthView||!this.getHiZOcclusionCullingActive())return;let t=null;for(const r of this.staticDrawSets){if(!r.publicSet.enabled||0===r.draws.length||"late"===r.drawStage||r.lastVisibilityFrameToken!==this.staticFrameToken||!wa(r))continue;t||(t=e.beginRenderPass({label:"renderer-static-temporal-depth-resolve",colorAttachments:[],depthStencilAttachment:{view:this.state.mainDepthView,depthLoadOp:"load",depthStoreOp:"store"}}));const i=this.getOrCreateStaticVisibleDepthSceneBindGroup(r);this.renderBundleScratch[0]=va.call(this,r,i,r.drawMetadataResource.postIndirectBuffer,"postpass"),t.executeBundles(this.renderBundleScratch)}t?.end()}function wa(e){for(const t of e.draws)if(t.customDepthMaterial||oa(t,"prepass")||Fa(t.material)||!sa(t))return!1;return!0}function ba(e,t){if(!this.state.device||!this.state.depthPrepassPipeline)throw new Error("Renderer is not initialized.");const r=this.resolveSceneBindGroupForDraw(e.draws[0],t);if(e.depthPrepassBundle&&e.depthPrepassBundleSceneBindGroup===r)return e.depthPrepassBundle;const i=ya.call(this,e,"prepass"),n=`${e.label}-static-depth-prepass-bundle-${e.id}`,a=this.state.device.createRenderBundleEncoder({label:n,colorFormats:[],depthStencilFormat:"depth32float",sampleCount:1});a.setBindGroup(0,r);let s=null,o=null,l=null;for(let t=0;t<e.draws.length;t+=1){const r=e.draws[t],n=i[t];if(r.customDepthMaterial||!n&&(Fa(r.material)||!sa(r)))continue;const c=n?.pipeline??this.state.depthPrepassPipeline;s!==c&&(s=c,o=null,l=null,a.setPipeline(c)),n&&o!==n.bindGroup&&(o=n.bindGroup,a.setBindGroup(1,o)),l!==r.geometryKey&&(l=r.geometryKey,this.bindGeometryVertexBuffers(a,r.geometry,r.geometryResource,n?.vertexAttributes??I,r.instanceStart,r.instanceCount,r.wireframe)),a.drawIndexed(r.count,r.instanceCount,r.start,0,r.instanceStart)}const c=a.finish({label:n});return e.depthPrepassBundle=c,e.depthPrepassBundleSceneBindGroup=r,c}function ya(e,t){const r=t,i=e.depthMaterialResources.get(r);if(i)return i;const n=e.draws.map(e=>{const r=oa(e,t);if(e.customDepthMaterial||!r)return null;return this.getDepthPassMaterialResourceForDraw(e.material,t,e)});return e.depthMaterialResources.set(r,n),n}function Sa(e,t,r,i,n,a,s){if(!this.state.device)throw new Error("Renderer is not initialized.");const o=this.resolveShadowBindGroupForDraw(e.draws[0],t,r),l=s?null:e.shadowBundles.get(o),c=s?s.bundles.get(o):l?.[i];if(c)return c;const u=ya.call(this,e,i),d=`${e.label}-static-${i}-bundle-${e.id}`,h=this.state.device.createRenderBundleEncoder({label:d,colorFormats:"pointShadow"===i?["rgba16float"]:[],depthStencilFormat:"depth32float",sampleCount:1});h.setBindGroup(0,o);let p=null,f=null,m=null;const g=s?.drawIndices;for(let t=0;t<(g?.length??e.draws.length);t+=1){const r=g?.[t]??t,i=e.draws[r];if(!i.castShadow)continue;const s=u[r],o=s?.pipeline??("instanced-direct"===this.getDrawInstanceAccessMode(i)&&a?a:n);p!==o&&(p=o,f=null,m=null,h.setPipeline(o)),s&&f!==s.bindGroup&&(f=s.bindGroup,h.setBindGroup(1,f)),m!==i.geometryKey&&(m=i.geometryKey,this.bindGeometryVertexBuffers(h,i.geometry,i.geometryResource,s?.vertexAttributes??I,i.instanceStart,i.instanceCount,i.wireframe)),h.drawIndexed(i.count,i.instanceCount,i.start,0,i.instanceStart)}const v=h.finish({label:d});return s?s.bundles.set(o,v):e.shadowBundles.set(o,{...l,[i]:v}),v}function Ca(e,t=!1,r=!1){if(!(this.state.device&&this.state.hizTexture&&this.state.mainDepthTexture&&this.state.mainDepthView&&this.state.hizCopyKernel&&this.state.hizReduceKernel))return;let i=this.state.hizCopyBindGroup;i||(i=this.state.hizCopyKernel.createBindGroup(this.state.device,[{binding:0,resource:this.state.mainDepthView},{binding:1,resource:this.state.hizMipViews[0]}],"renderer-hiz-copy-bind-group"),this.state.hizCopyBindGroup=i);const n=e.beginComputePass({label:"renderer-hiz-copy-pass"});if(n.setPipeline(this.state.hizCopyKernel.pipeline),n.setBindGroup(0,i),n.dispatchWorkgroups(Math.ceil(this.state.width/8),Math.ceil(this.state.height/8)),n.end(),!r){for(let t=1;t<this.state.hizMipCount;t+=1){const r=Math.max(1,this.state.width>>t),i=Math.max(1,this.state.height>>t);let n=this.state.hizReduceBindGroups[t];n||(n=this.state.hizReduceKernel.createBindGroup(this.state.device,[{binding:0,resource:this.state.hizMipViews[t-1]},{binding:1,resource:this.state.hizMipViews[t]}],`renderer-hiz-reduce-bind-group-${t}`),this.state.hizReduceBindGroups[t]=n);const a=e.beginComputePass({label:`renderer-hiz-reduce-pass-${t}`});a.setPipeline(this.state.hizReduceKernel.pipeline),a.setBindGroup(0,n),a.dispatchWorkgroups(Math.ceil(r/8),Math.ceil(i/8)),a.end()}t&&this.commitTemporalHiZHistory()}}function Pa(e,t,r,i,n,a,s=!1,o="all",l=!1,c=this.sampleCount){if(!this.state.mainDepthView)return;const u=c>1,d=u?this.ensureMsaaColorTarget(t):null,h=u?this.ensureMsaaDepthTarget(d.width,d.height):null,p=e.beginRenderPass({label:"renderer-forward-pass",colorAttachments:[{view:d?.view??r,resolveTarget:d?r:void 0,clearValue:{r:this.clearColor[0],g:this.clearColor[1],b:this.clearColor[2],a:this.clearColor[3]},loadOp:l?"load":"clear",storeOp:d?"discard":"store"}],depthStencilAttachment:{view:h?.view??this.state.mainDepthView,depthClearValue:1,depthLoadOp:h||s?"clear":"load",depthStoreOp:h?"discard":"store"}});let f=null,m=null,g=null,v=null,x=null;const w=e=>{e.sourceObject&&e.hasRenderCallbacks&&e.sourceObject.onBeforeRender(this,n.scene,n.camera,e.geometry,e.material,e.geometryGroup);const t=e.geometryResource,r=this.getMaterialResourceForDraw(e,[C],c),s=this.resolveSceneBindGroupForDraw(e,i);if(f!==r.pipeline&&(f=r.pipeline,g=null,x=null,p.setPipeline(f)),g!==e.geometryKey&&(g=e.geometryKey,this.bindGeometryVertexBuffers(p,e.geometry,t,r.vertexAttributes,e.instanceStart,e.instanceCount,e.wireframe)),v!==s&&(v=s,p.setBindGroup(0,s)),m!==e.material){if(m=e.material,p.setBindGroup(1,r.bindGroup),!r.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");p.setBindGroup(3,this.createGraphTextureBindGroup(e.material,r.graphTextureBindGroupLayout))}r.usesSkinning&&e.skinning&&x!==e.skinning.bindGroup&&(x=e.skinning.bindGroup,p.setBindGroup(2,x)),e.indexed&&(e.wireframe?t.wireframeIndex:t.index)?p.drawIndexed(e.count,e.instanceCount,e.start,0,e.instanceStart):p.draw(e.count,e.instanceCount,e.start,e.instanceStart),this.recordDraw(e,a),e.sourceObject&&e.hasRenderCallbacks&&e.sourceObject.onAfterRender(this,n.scene,n.camera,e.geometry,e.material,e.geometryGroup)};if(this.executeStaticForwardPass(p,i,a,o,c),f=null,m=null,g=null,v=null,x=null,"late"!==o&&this.getHiZOcclusionCullingActive()&&this.state.drawMetadataResource){const e=this.buildIndirectSubmissionStreams(n.gpuOpaqueDraws,i),t=this.renderBundleScratch;t.length=0;for(let r=0;r<e.length;r+=1){const i=e[r];t[0]=this.getOrCreateIndirectForwardBundle(i),p.executeBundles(t),a.drawCallCount+=i.drawCallCount,a.triangleCount+=i.triangleCount}f=null,m=null,g=null,v=null}else if("late"!==o){const e=ai(n.gpuOpaqueDraws)||n.gpuOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(n.gpuOpaqueDraws,i,a);if(e)this.renderBundleScratch[0]=e,p.executeBundles(this.renderBundleScratch);else for(const e of n.gpuOpaqueDraws)w(e)}const b="late"===o||ai(n.directOpaqueDraws)||n.directOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(n.directOpaqueDraws,i,a);if(b)this.renderBundleScratch[0]=b,p.executeBundles(this.renderBundleScratch);else if("late"!==o)for(const e of n.directOpaqueDraws)w(e);if("opaque"!==o)for(const e of n.transparentDraws)w(e);p.end()}function Ma(e,t,r,i="all",n=this.sampleCount){for(const a of this.staticDrawSets)if(a.publicSet.enabled&&0!==a.draws.length&&("all"===i||a.drawStage===i)){if("opaque"===a.drawStage&&this.getHiZOcclusionCullingActive()&&a.lastVisibilityFrameToken===this.staticFrameToken){const t=this.getOrCreateStaticVisibleSceneBindGroup(a),i=this.getOrCreateStaticIndirectSubmissionStreams(a,t);for(const t of i)if(this.getMultiDrawIndirectActive()){if(e.setPipeline(t.materialResource.pipeline),this.bindGeometryVertexBuffers(e,t.geometry,t.geometryResource,t.materialResource.vertexAttributes,0,1,t.material.wireframe),e.setBindGroup(0,t.sceneBindGroup),e.setBindGroup(1,t.materialResource.bindGroup),!t.materialResource.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");e.setBindGroup(3,this.createGraphTextureBindGroup(t.material,t.materialResource.graphTextureBindGroupLayout)),e.multiDrawIndexedIndirect(a.drawMetadataResource.indirectBuffer,5*t.indirectStartIndex*Uint32Array.BYTES_PER_ELEMENT,t.indirectCount),r.drawCallCount+=t.drawCallCount,r.triangleCount+=t.triangleCount}else this.renderBundleScratch[0]=this.getOrCreateIndirectForwardBundle(t,a.drawMetadataResource,a.indirectForwardBundleCache,`${a.label}-static-indirect-forward-bundle`),e.executeBundles(this.renderBundleScratch),r.drawCallCount+=t.drawCallCount,r.triangleCount+=t.triangleCount;continue}this.renderBundleScratch[0]=this.getOrCreateStaticDirectForwardBundle(a,t,n),e.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(a,r)}}function Ba(e,t,r=this.sampleCount){if(!this.state.device||!this.state.format)throw new Error("Renderer is not initialized.");const i=this.resolveSceneBindGroupForDraw(e.draws[0],t);if(e.directForwardBundle&&e.directForwardBundleSceneBindGroup===i&&e.directForwardBundleSampleCount===r)return e.directForwardBundle;null==e.draws[0]?.materialResource&&(this.refreshStaticDrawMaterialResources(e.draws),this.syncStaticVisibleMaterialBindingCaches(e));const n=`${e.label}-static-forward-direct-bundle-${e.id}`,a=this.state.device.createRenderBundleEncoder({label:n,colorFormats:[C],depthStencilFormat:"depth32float",sampleCount:r});let s=null,o=null,l=null;a.setBindGroup(0,i);for(const t of e.draws){const i=("opaque"===e.drawStage?t.materialResource:null)??this.getMaterialResource(t.material,this.getDrawInstanceAccessMode(t),t.receiveShadow,void 0,null!==t.skinning,aa(t),r);if(s!==i.pipeline&&(s=i.pipeline,l=null,a.setPipeline(s)),l!==t.geometryKey&&(l=t.geometryKey,this.bindGeometryVertexBuffers(a,t.geometry,t.geometryResource,i.vertexAttributes,t.instanceStart,t.instanceCount,t.wireframe)),o!==i.bindGroup){if(o=i.bindGroup,a.setBindGroup(1,o),!i.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");a.setBindGroup(3,this.createGraphTextureBindGroup(t.material,i.graphTextureBindGroupLayout))}a.drawIndexed(t.count,t.instanceCount,t.start,0,t.instanceStart)}const c=a.finish({label:n});return e.directForwardBundle=c,e.directForwardBundleSceneBindGroup=i,e.directForwardBundleSampleCount=r,c}function Da(e){for(const t of e.visibleMaterialBindings){const r=t.drawIndices[0];t.resource=e.draws[r]?.materialResource??e.visibleDrawMaterialResources[r]??null}}function Ta(e){for(const t of e)t.materialResource=this.getMaterialResource(t.material,this.getDrawInstanceAccessMode(t),t.receiveShadow,void 0,null!==t.skinning,aa(t))}function Ia(e,t){t.drawCallCount+=e.drawCallCount,t.triangleCount+=e.triangleCount}function Va(){return this.staticDrawSets.some(e=>e.publicSet.enabled&&e.draws.length>0)}function Ra(e,t,r){if(!(this.state.device&&this.state.presentPipeline&&this.state.fullscreenTextureBindGroupLayout&&this.state.linearClampSampler))return;let i=this.state.presentBindGroups.get(t);i||(i=this.state.device.createBindGroup({label:"renderer-present-bind-group",layout:this.state.fullscreenTextureBindGroupLayout,entries:[{binding:0,resource:this.state.linearClampSampler},{binding:1,resource:t}]}),this.state.presentBindGroups.set(t,i));const n=e.beginRenderPass({label:"renderer-present-pass",colorAttachments:[{view:r,clearValue:{r:this.clearColor[0],g:this.clearColor[1],b:this.clearColor[2],a:this.clearColor[3]},loadOp:"clear",storeOp:"store"}]});n.setPipeline(this.state.presentPipeline),n.setBindGroup(0,i),n.draw(3),n.end()}function Ga(e){for(let t=0;t<this.state.directionalShadowLayerViews.length;t+=1){e.beginRenderPass({label:`renderer-clear-directional-shadow-${t}`,colorAttachments:[],depthStencilAttachment:{view:this.state.directionalShadowLayerViews[t],depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}}).end()}}function za(e){for(let t=0;t<this.state.pointShadowFaceViews.length;t+=1){e.beginRenderPass({label:`renderer-clear-point-shadow-${t}`,colorAttachments:[{view:this.state.pointShadowFaceViews[t],clearValue:{r:1,g:1,b:1,a:1},loadOp:"clear",storeOp:"store"}],depthStencilAttachment:{view:this.state.pointShadowDepthFaceViews[t],depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}}).end()}}function La(e){for(let t=0;t<this.state.spotShadowLayerViews.length;t+=1){e.beginRenderPass({label:`renderer-clear-spot-shadow-${t}`,colorAttachments:[],depthStencilAttachment:{view:this.state.spotShadowLayerViews[t],depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}}).end()}}function Ua(e,t,r,i){let n=null,a=null,s=null,o=null,l=null;for(const c of t){if("directionalShadow"===i.passKind){if(Qn.center.copy(c.boundsCenter),Qn.radius=c.boundsRadius,!Xn.intersectsSphere(Qn))continue;const e=c.detailCulling??h(c.sourceObject);if(!c.staticLocalBoundsCenter&&!p(c.boundsCenter,c.boundsRadius,Jn,this.state.directionalShadowTextureSize,this.state.directionalShadowTextureSize,ia,.85*e.shadowMinScreenSize,e.shadowMaxDistance))continue}if("prepass"!==i.passKind&&!c.castShadow)continue;if("prepass"===i.passKind&&null===c.material.depthVertexShader&&Fa(c.material))continue;if("skip"===i.customDepthMode&&c.customDepthMaterial)continue;const t=oa(c,i.passKind),u="use"===i.customDepthMode&&c.customDepthMaterial?c.customDepthMaterial:"ignore"!==i.customDepthMode&&t?c.material:null,d=u?this.getDepthPassMaterialResourceForDraw(u,i.passKind,c):null;if(!d&&!sa(c))continue;const f=null!==c.skinning,m=d?.pipeline??(f&&i.fallbackSkinnedPipeline?i.fallbackSkinnedPipeline:"instanced-direct"===this.getDrawInstanceAccessMode(c)&&i.fallbackPipelineDirect?i.fallbackPipelineDirect:i.fallbackPipeline);a!==m&&(a=m,s=null,o=null,l=null,n=null,e.setPipeline(m));const g="prepass"===i.passKind?this.resolveSceneBindGroupForDraw(c,i.fallbackBindGroup):this.resolveShadowBindGroupForDraw(c,i.fallbackBindGroup,i.shadowCameraBuffer);s!==g&&(s=g,e.setBindGroup(0,g)),d?o!==d.bindGroup&&(o=d.bindGroup,e.setBindGroup(1,d.bindGroup)):o=null,(d?.usesSkinning??f)&&c.skinning&&l!==c.skinning.bindGroup&&(l=c.skinning.bindGroup,e.setBindGroup(2,l));const v=c.geometryResource;n!==c.geometryKey&&(n=c.geometryKey,this.bindGeometryVertexBuffers(e,c.geometry,v,d?.vertexAttributes??(f?V:I),c.instanceStart,c.instanceCount,c.wireframe)),c.indexed&&(c.wireframe?v.wireframeIndex:v.index)?e.drawIndexed(c.count,c.instanceCount,c.start,0,c.instanceStart):e.draw(c.count,c.instanceCount,c.start,c.instanceStart),this.recordDraw(c,r)}}var Aa=new WeakMap;function Fa(e){if(e.transparent)return!0;let t=Aa.get(e);return null==t&&(t=e.transparent||e.alphaTest>0||/\bdiscard\b/.test(e.fragmentShader),Aa.set(e,t)),t}import{Matrix4 as ka,OrthographicCamera as Ea,Vector3 as Oa}from"three";var ja=(e,t)=>void 0!==e&&Number.isFinite(e)&&e>0?e:t,$a=class{constructor(e){this.cameras=e,this.layers=e.map(()=>({valid:!1,source:null,direction:new Oa,rangeX:0,rangeY:0,nextUpdateMs:0,lastUpdateMs:-1/0,candidate:new Ea}))}cameras;layers;updateMask=0;forcedMask=0;settings={enabled:!1,maxUpdateHz:60,cascadeUpdateHz:[60,30,15,7.5],maxUpdatesPerFrame:2,coverageMargin:.05,teleportDistance:10};previousProjection=new ka;previousPosition=new Oa;viewerPosition=new Oa;corner=new Oa;viewerValid=!1;revision=-1;timeMs=0;setOptions(e){this.settings={enabled:e.enabled??!1,maxUpdateHz:ja(e.maxUpdateHz,60),cascadeUpdateHz:(e.cascadeUpdateHz?.length?e.cascadeUpdateHz:[60,30,15,7.5]).map(e=>ja(e,60)),maxUpdatesPerFrame:Math.max(1,Math.floor(ja(e.maxUpdatesPerFrame,2))),coverageMargin:Number.isFinite(e.coverageMargin)?Math.max(0,Math.min(.5,e.coverageMargin)):.05,teleportDistance:ja(e.teleportDistance,10)},this.invalidate()}invalidate(){for(const e of this.layers)e.valid=!1}interval(e){const t=this.settings.cascadeUpdateHz;return 1e3/Math.min(this.settings.maxUpdateHz,t[Math.min(e,t.length-1)])}prepare(e,t,r,i,n,a){this.timeMs=n,this.updateMask=this.forcedMask=0,t.getWorldPosition(this.viewerPosition);let s=this.revision!==a;if(this.viewerValid){s||=this.viewerPosition.distanceToSquared(this.previousPosition)>this.settings.teleportDistance**2;const e=t.projectionMatrix.elements,r=this.previousProjection.elements,i=!0===t.isPerspectiveCamera;for(let t=0;t<16;t++)if((i?8!==t&&9!==t:12!==t&&13!==t)&&Math.abs(e[t]-r[t])>1e-6){s=!0;break}}this.revision=a,this.previousPosition.copy(this.viewerPosition),this.previousProjection.copy(t.projectionMatrix),this.viewerValid=!0,s&&this.invalidate();for(let t=0;t<this.layers.length;t++){const n=this.layers[t],a=e[t];if(!a?.castShadow){n.valid=!1;continue}const s=n.candidate;s.left=a.shadowCameraLeft,s.right=a.shadowCameraRight,s.top=a.shadowCameraTop,s.bottom=a.shadowCameraBottom,s.near=a.shadowCameraNear,s.far=a.shadowCameraFar,s.position.copy(a.position),s.lookAt(a.target),s.updateMatrixWorld(!0),s.updateProjectionMatrix();const o=t<i?r[t].x:0,l=t<i?r[t].y:0,c=!n.valid||n.source!==a.sourceLight||n.direction.distanceToSquared(a.direction)>1e-12||n.rangeX!==o||n.rangeY!==l||!this.containsCandidate(this.cameras[t],s);this.settings.enabled&&!c||(this.updateMask|=1<<t,c&&(this.forcedMask|=1<<t))}let o=this.settings.maxUpdatesPerFrame;for(;this.settings.enabled&&o-- >0;){let t=-1,r=1/0;for(let i=0;i<e.length;i++){if(!e[i].castShadow||this.updateMask&1<<i)continue;const a=this.layers[i].nextUpdateMs;n+1e-6>=a&&a<r&&(r=a,t=i)}if(t<0)break;this.updateMask|=1<<t}for(let t=0;t<e.length;t++){if(!(this.updateMask&1<<t))continue;const n=e[t],a=this.layers[t],s=this.cameras[t];if(s.copy(a.candidate),this.settings.enabled){const e=this.settings.coverageMargin,t=s.right-s.left,r=s.top-s.bottom,i=s.far-s.near;s.left-=t*e,s.right+=t*e,s.bottom-=r*e,s.top+=r*e,s.near-=i*e,s.far+=i*e,s.updateProjectionMatrix()}a.source=n.sourceLight,a.direction.copy(n.direction),a.rangeX=t<i?r[t].x:0,a.rangeY=t<i?r[t].y:0}}commit(e){const t=this.layers[e],r=this.interval(e);!t.valid||this.forcedMask&1<<e||!Number.isFinite(t.nextUpdateMs)?t.nextUpdateMs=this.timeMs+r+e*(1e3/this.settings.maxUpdateHz)/this.layers.length:(t.nextUpdateMs+=Math.max(1,Math.floor((this.timeMs-t.nextUpdateMs)/r)+1)*r,t.nextUpdateMs<=this.timeMs&&(t.nextUpdateMs=this.timeMs+r)),t.lastUpdateMs=this.timeMs,t.valid=!0}containsCandidate(e,t){for(let r=0;r<2;r++)for(let i=0;i<2;i++)for(let n=0;n<2;n++){this.corner.set(r?t.right:t.left,i?t.top:t.bottom,-(n?t.far:t.near)).applyMatrix4(t.matrixWorld).applyMatrix4(e.matrixWorldInverse);const a=1e-5;if(this.corner.x<e.left-a||this.corner.x>e.right+a||this.corner.y<e.bottom-a||this.corner.y>e.top+a||this.corner.z<-e.far-a||this.corner.z>-e.near+a)return!1}return!0}};import{Vector3 as Wa}from"three";function Na(e){return`${Math.floor(e.x/32)}:${Math.floor(e.y/32)}:${Math.floor(e.z/32)}`}function _a(e,t){if(!t)return[e];const r=new Map;for(const t of e){const e=Na(t.boundsCenter);let i=r.get(e);i||(i=[],r.set(e,i)),i.push(t)}return[...r.values()]}var Ha=class{constructor(e,t,r,i,n){this.state=e,this.staticDrawSets=t,this.getGeometryResourceForGeometry=r,this.resolveMaterial=i,this.ensureWireframeIndex=n}state;staticDrawSets;getGeometryResourceForGeometry;resolveMaterial;ensureWireframeIndex;nextStaticDrawSetId=1;activeObject=null;activeDetailDefaults;activeMaterialSnapshots=null;getGeometryResource(e){return this.getGeometryResourceForGeometry(e)}resolveStaticMaterial(e){const t=this.resolveMaterial(e);if(!t||!this.activeMaterialSnapshots)return t;let r=this.activeMaterialSnapshots.get(t);return r||(r=t.clone(),r.name=t.name?`${t.name} (static snapshot)`:"Static draw-set material snapshot",this.activeMaterialSnapshots.set(t,r)),r}createStaticDrawSet(e,t={}){if(!(this.state.initialized&&this.state.device&&this.state.staticVisibilityClearKernel&&this.state.staticVisibilityCullKernel&&this.state.staticVisibilityIndirectBuildKernel))throw new Error("WebGpuRenderer.initialize() must complete before creating a static draw set.");const r=t.label??`static-draw-set-${this.nextStaticDrawSetId}`,i=t.onUnsupported??"throw",n=t.allowUnsortedLateDraws??!1,a=[],s=new Mi(4096),o=(e,t)=>{if("skip"!==i)throw new Error(`StaticDrawSet "${r}" does not support ${e.type||"Object3D"} "${e.name||e.uuid}": ${t}.`)};this.activeDetailDefaults=t.detailCulling,e.updateMatrixWorld(!0);const l=new Map;this.activeMaterialSnapshots=l;try{e.traverseVisible(e=>{this.activeObject=e,e.isSkinnedMesh?o(e,"skinned meshes are dynamic"):e.isBatchedMesh?this.collectStaticBatchedMesh(e,s,a,r,o,n):e.isInstancedMesh?this.collectStaticInstancedMesh(e,s,a,r,o,n):e.isMesh&&this.collectStaticMesh(e,s,a,r,o,n)})}catch(e){for(const e of l.values())e.dispose();throw e}finally{this.activeMaterialSnapshots=null,this.activeObject=null,this.activeDetailDefaults=void 0}const{draws:c,instanceData:u}=this.mergeStaticDraws(a,s),d=c.some(e=>e.transparent),h=c.some(e=>!e.transparent);if(d&&h)throw new Error(`StaticDrawSet "${r}" cannot mix opaque and late materials; register them as separate sets.`);const p=this.createVisibleMaterialBindings(c),f=this.createShadowChunks(c),m=Math.max(4,u.byteLength),g=this.state.device.createBuffer({label:`${r}-static-instance-buffer`,size:256*Math.ceil(m/256),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});u.floatLength>0?this.state.device.queue.writeBuffer(g,0,u.rawData.buffer,0,u.byteLength):this.state.device.queue.writeBuffer(g,0,y,0,w);const v={mode:"packed",buffer:g,colorBuffer:null,sceneBindGroup:null,shadowBindGroup:null,shadowBindGroups:new Map,sceneBindGroupVersion:0,shadowBindGroupVersion:0};for(const e of c)e.residentInstanceBinding=v;const x=this.createStaticDrawMetadataResource(r,c),b=this.createStaticInstanceVisibilityResource(r,c,u),S=new Uint32Array([c.length,this.state.hizMipCount,u.instanceCount,0]),C=this.state.device.createBuffer({label:`${r}-visibility-params-buffer`,size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),P=new Uint32Array([c.length,this.state.hizMipCount,u.instanceCount,0]),M=this.state.device.createBuffer({label:`${r}-post-visibility-params-buffer`,size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});this.state.device.queue.writeBuffer(C,0,S,0,4),this.state.device.queue.writeBuffer(M,0,P,0,4);const B={id:this.nextStaticDrawSetId++,label:r,publicSet:null,ownedMaterials:[...l.values()],draws:c,shadowChunks:f,drawStage:d?"late":"opaque",drawCallCount:c.length,triangleCount:c.reduce((e,t)=>e+Math.floor(Math.max(0,t.count)/3)*Math.max(0,t.instanceCount),0),instanceCount:u.instanceCount,instanceBuffer:g,residentInstanceBinding:v,drawMetadataResource:x,instanceVisibilityResource:b,visibilityParamsBuffer:C,visibilityParamsUpload:S,postVisibilityParamsBuffer:M,postVisibilityParamsUpload:P,visibilityBindGroup:null,postVisibilityBindGroup:null,visibilityClearBindGroup:null,visibilityIndirectBuildBindGroup:null,postVisibilityIndirectBuildBindGroup:null,visibleSceneBindGroup:null,visibleSceneBindGroupVersion:0,visibleDepthSceneBindGroup:null,visibleDepthSceneBindGroupVersion:0,visibleMaterialBindings:p,visibleDrawMaterialResources:new Array(c.length),visibleIndirectSubmissionStreams:null,visibleIndirectStreamsSceneBindGroup:null,visibleIndirectStreamsSampleCount:-1,visibleIndirectStreamsColorFormatsKey:"",visibilityBindGroupHizVersion:0,lastPreVisibilityFrameToken:0,lastVisibilityFrameToken:0,indirectForwardBundleCache:new Map,directForwardBundle:null,directForwardBundleSampleCount:-1,directForwardBundleSceneBindGroup:null,depthPrepassBundle:null,depthPrepassBundleSceneBindGroup:null,indirectDepthPrepassBundles:{prepass:null,postpass:null},shadowBundles:new WeakMap,depthMaterialResources:new Map},D={label:r,enabled:!0,get drawCount(){return B.draws.length},get instanceCount(){return B.instanceCount},dispose:()=>{this.disposeStaticDrawSetResource(B)}};return B.publicSet=D,this.staticDrawSets.push(B),D}createVisibleMaterialBindings(e){const t=new Map;for(let r=0;r<e.length;r+=1){const i=e[r],n=`${ei(i.material)}:${i.receiveShadow?1:0}:${i.usesBatching?1:0}`;let a=t.get(n);a||(a={material:i.material,receiveShadow:i.receiveShadow,usesBatching:i.usesBatching,drawIndices:[],resource:null},t.set(n,a)),a.drawIndices.push(r)}return[...t.values()]}createShadowChunks(e){const t=new Map;for(let r=0;r<e.length;r+=1){const i=e[r];if(!i.castShadow||i.transparent)continue;const n=Na(i.boundsCenter);let a=t.get(n);a||(a=[],t.set(n,a)),a.push(r)}const r=[];for(const i of t.values())for(let t=0;t<i.length;t+=64){const n=i.slice(t,t+64);let a=1/0,s=1/0,o=1/0,l=-1/0,c=-1/0,u=-1/0;for(const t of n){const r=e[t],i=r.boundsCenter,n=r.boundsRadius;a=Math.min(a,i.x-n),s=Math.min(s,i.y-n),o=Math.min(o,i.z-n),l=Math.max(l,i.x+n),c=Math.max(c,i.y+n),u=Math.max(u,i.z+n)}const d=new Wa(.5*(a+l),.5*(s+c),.5*(o+u)),h=l-d.x,p=c-d.y,f=u-d.z;r.push({drawIndices:n,drawCallCount:n.length,triangleCount:n.reduce((t,r)=>{const i=e[r];return t+Math.floor(Math.max(0,i.count)/3)*Math.max(0,i.instanceCount)},0),boundsCenter:d,boundsRadius:Math.sqrt(h*h+p*p+f*f),bundles:new WeakMap})}return r}mergeStaticDraws(e,t){e.sort((e,t)=>ii(e,t)||(e.transparent||t.transparent?0:Na(e.boundsCenter).localeCompare(Na(t.boundsCenter))));const r=[],i=new Mi(Math.max(1024,t.floatLength));for(let n=0;n<e.length;){const a=e[n],s=i.instanceCount;i.appendRange(t,a.instanceStart,a.instanceCount);let o=a.instanceCount,l=a.boundsCenter.x-a.boundsRadius,c=a.boundsCenter.y-a.boundsRadius,u=a.boundsCenter.z-a.boundsRadius,d=a.boundsCenter.x+a.boundsRadius,h=a.boundsCenter.y+a.boundsRadius,p=a.boundsCenter.z+a.boundsRadius,f=n+1;for(;f<e.length&&li(a,e[f])&&(a.transparent||Na(a.boundsCenter)===Na(e[f].boundsCenter));){const r=e[f];i.appendRange(t,r.instanceStart,r.instanceCount),o+=r.instanceCount;const n=r.boundsCenter.x-r.boundsRadius,a=r.boundsCenter.y-r.boundsRadius,s=r.boundsCenter.z-r.boundsRadius,m=r.boundsCenter.x+r.boundsRadius,g=r.boundsCenter.y+r.boundsRadius,v=r.boundsCenter.z+r.boundsRadius;n<l&&(l=n),a<c&&(c=a),s<u&&(u=s),m>d&&(d=m),g>h&&(h=g),v>p&&(p=v),f+=1}const m=.5*(l+d),g=.5*(c+h),v=.5*(u+p),x=d-m,w=h-g,b=p-v;a.instanceStart=s,a.instanceCount=o,a.boundsCenter.set(m,g,v),a.boundsRadius=Math.sqrt(x*x+w*w+b*b),r.push(a),n=f}return{draws:r,instanceData:i}}collectStaticMesh(e,t,r,i,n,a){if(!(null!==e.geometry.index))return void n(e,"non-indexed geometry cannot use the v1 indirect static path");if(Ci(e))return void n(e,"custom depth materials are not supported by StaticDrawSet v1");const s=this.getGeometryResource(e.geometry),o=vi(e.geometry),l=L.copy(o.center).applyMatrix4(e.matrixWorld),c=o.radius*xi(e.matrixWorld),u=Jr(t,e.matrixWorld,1,1,1,1),d=Array.isArray(e.material)?e.material:null,h=Array.isArray(e.material)?null:e.material;if(e.geometry.groups.length>0){for(const t of e.geometry.groups){const i=d?d[t.materialIndex??0]??d[0]:h,p=this.resolveStaticMaterial(i);if(!p){n(e,"all static mesh materials must be WGSLShaderMaterial");continue}if(p.transparent&&!a){n(e,"transparent materials are not supported by StaticDrawSet v1");continue}if(Object.keys(p.getGraphTextureInputs()).length>0&&!a){n(e,"scene-texture materials are not supported by StaticDrawSet v1");continue}const f=_r(e.geometry,!0,t.start,t.count);f<=0||r.push(this.createStaticDrawRecord(e.geometry,e.geometry,s,p,!1,t.start,f,u,1,l.x,l.y,l.z,c,o.center,o.radius,e.matrixWorld.determinant()<0))}return}const p=h??d?.[0]??null,f=this.resolveStaticMaterial(p);if(!f)return void n(e,"all static mesh materials must be WGSLShaderMaterial");if(f.transparent&&!a)return void n(e,"transparent materials are not supported by StaticDrawSet v1");if(Object.keys(f.getGraphTextureInputs()).length>0&&!a)return void n(e,"scene-texture materials are not supported by StaticDrawSet v1");const m=Hr(e.geometry,!0);m.count<=0||r.push(this.createStaticDrawRecord(e.geometry,e.geometry,s,f,!1,m.start,m.count,u,1,l.x,l.y,l.z,c,o.center,o.radius,e.matrixWorld.determinant()<0))}collectStaticInstancedMesh(e,t,r,i,n,a){const s=this.resolveStaticMaterial(e.material);if(!s)return void n(e,"static instanced meshes must use WGSLShaderMaterial");if(s.transparent&&!a)return void n(e,"transparent materials are not supported by StaticDrawSet v1");if(Object.keys(s.getGraphTextureInputs()).length>0&&!a)return void n(e,"scene-texture materials are not supported by StaticDrawSet v1");if(Ci(e))return void n(e,"custom depth materials are not supported by StaticDrawSet v1");if(null===e.geometry.index)return void n(e,"non-indexed geometry cannot use the v1 indirect static path");const o=Hr(e.geometry,!0);if(o.count<=0||e.count<=0)return;const l=vi(e.geometry),c=this.getGeometryResource(e.geometry),u=[];for(let t=0;t<e.count;t+=1){e.getMatrixAt(t,R),G.multiplyMatrices(e.matrixWorld,R);const r=e.instanceColor?e.instanceColor.getComponent(t,0):1,i=e.instanceColor&&e.instanceColor.itemSize>1?e.instanceColor.getComponent(t,1):1,n=e.instanceColor&&e.instanceColor.itemSize>2?e.instanceColor.getComponent(t,2):1,a=e.instanceColor&&e.instanceColor.itemSize>3?e.instanceColor.getComponent(t,3):1,s=A.copy(l.center).applyMatrix4(G),o=l.radius*xi(G);u.push({matrix:new Float32Array(G.elements),color0:r,color1:i,color2:n,color3:a,batchingId:t,boundsCenter:s.clone(),boundsRadius:o})}for(const i of _a(u,!s.transparent&&!s.requiresLatePass())){const n=L.set(1/0,1/0,1/0),a=U.set(-1/0,-1/0,-1/0),u=t.instanceCount;for(const e of i)t.appendMatrixAndColorValues(e.matrix,e.color0,e.color1,e.color2,e.color3),bi(n,a,e.boundsCenter,e.boundsRadius);const d=.5*(n.x+a.x),h=.5*(n.y+a.y),p=.5*(n.z+a.z),f=a.x-d,m=a.y-h,g=a.z-p;r.push(this.createStaticDrawRecord(e.geometry,e.geometry,c,s,!1,o.start,o.count,u,i.length,d,h,p,Math.sqrt(f*f+m*m+g*g),l.center,l.radius))}}collectStaticBatchedMesh(e,t,r,i,n,a){const s=this.resolveStaticMaterial(e.material);if(!s)return void n(e,"static batched meshes must use WGSLShaderMaterial");if(s.transparent&&!a)return void n(e,"transparent materials are not supported by StaticDrawSet v1");if(Object.keys(s.getGraphTextureInputs()).length>0&&!a)return void n(e,"scene-texture materials are not supported by StaticDrawSet v1");if(Ci(e))return void n(e,"custom depth materials are not supported by StaticDrawSet v1");if(null===e.geometry.index)return void n(e,"non-indexed geometry cannot use the v1 indirect static path");const o=e,l=this.getGeometryResource(e.geometry),c=o._geometryCount??0,u=[],d=new Map;for(let t=0;t<c;t+=1){const r=e.getGeometryRangeAt(t);if(!r||r.count<=0)continue;const i=_r(e.geometry,!0,r.start,r.count);if(i<=0)continue;const n=e.getBoundingSphereAt(t,z),a={geometryId:t,start:r.start,count:i,localBoundsCenter:n?n.center.clone():new Wa,localBoundsRadius:n?.radius??1,instances:[]};d.set(t,a),u.push(a)}const h=o._instanceInfo??o._drawInfo??[],p=o._matricesTexture?.image.data,f=o._colorsTexture?.image.data;for(let t=0;t<h.length;t+=1){const r=h[t];if(!r?.active||!r.visible)continue;const i=d.get(r.geometryIndex);if(!i)continue;p?Qr(R,p,16*t):e.getMatrixAt(t,R),G.multiplyMatrices(e.matrixWorld,R);const n=4*t,a=f?f[n+0]??1:1,s=f?f[n+1]??1:1,o=f?f[n+2]??1:1,l=f?f[n+3]??1:1,c=A.copy(i.localBoundsCenter).applyMatrix4(G),u=i.localBoundsRadius*xi(G);i.instances.push({matrix:new Float32Array(G.elements),color0:a,color1:s,color2:o,color3:l,batchingId:t,boundsCenter:c.clone(),boundsRadius:u})}for(const i of u)if(0!==i.instances.length)for(const n of _a(i.instances,!s.transparent&&!s.requiresLatePass())){const a=L.set(1/0,1/0,1/0),o=U.set(-1/0,-1/0,-1/0),c=t.instanceCount;for(const e of n)t.appendMatrixAndColorValues(e.matrix,e.color0,e.color1,e.color2,e.color3,e.batchingId),bi(a,o,e.boundsCenter,e.boundsRadius);const u=.5*(a.x+o.x),d=.5*(a.y+o.y),h=.5*(a.z+o.z),p=o.x-u,f=o.y-d,m=o.z-h,g=Math.sqrt(p*p+f*f+m*m);r.push(this.createStaticDrawRecord(e.geometry,e.geometry,l,s,!0,i.start,i.count,c,n.length,u,d,h,g,i.localBoundsCenter,i.localBoundsRadius))}}createStaticDrawRecord(e,t,r,i,n,a,s,o,l,c,u,d,p,f,m,g=!1){const v=ei(i),x=i.wireframe&&"triangle-list"===i.primitiveTopology;x&&this.ensureWireframeIndex(e,r);const w=ei(t);return{geometry:e,geometryKey:x?r.wireframeIndex:t,geometryResource:r,material:i,customDepthMaterial:null,residentInstanceBinding:null,sourceObject:null,detailCulling:h(this.activeObject,this.activeDetailDefaults),frontFaceCW:g,usesBatching:n,geometryGroup:null,batchKey:ti(i,t,!0,a,s,null),batchHash:ri(v,w,!0,a,s,0),indexed:!0,wireframe:x,start:x?2*a:a,count:x?2*s:s,transparent:i.transparent||i.requiresLatePass(),renderOrder:0,hasRenderCallbacks:!1,castShadow:this.activeObject?.castShadow??!1,receiveShadow:this.activeObject?.receiveShadow??!1,sortMaterialId:v,sortGeometryId:w,sortCustomDepthMaterialId:0,skinning:null,materialResource:null,instanceStart:o,instanceCount:l,boundsCenter:new Wa(c,u,d),boundsRadius:p,sortDepth:0,transparentSortGroup:0,transparentSortOrder:0,staticLocalBoundsCenter:f.clone(),staticLocalBoundsRadius:m}}createStaticDrawMetadataResource(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=Math.max(1,t.length),i=new Float32Array(r*b),n=new Uint32Array(5*r),a=new Uint32Array(5*r);for(let e=0;e<t.length;e+=1){const r=t[e],s=e*b;i[s+0]=r.boundsCenter.x,i[s+1]=r.boundsCenter.y,i[s+2]=r.boundsCenter.z,i[s+3]=r.boundsRadius,i[s+4]=r.count,i[s+5]=r.start,i[s+6]=r.instanceStart,i[s+7]=r.instanceCount,i[s+8]=1,i[s+9]=0,i[s+10]=0,i[s+11]=0;const o=5*e;n[o+0]=r.count,n[o+1]=r.instanceCount,n[o+2]=r.start,n[o+3]=0,n[o+4]=r.instanceStart,a[o+0]=r.count,a[o+1]=0,a[o+2]=r.start,a[o+3]=0,a[o+4]=r.instanceStart}const s=this.state.device.createBuffer({label:`${e}-static-draw-metadata-buffer`,size:r*b*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),o=this.state.device.createBuffer({label:`${e}-static-indirect-draw-buffer`,size:5*r*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.INDIRECT|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC}),l=this.state.device.createBuffer({label:`${e}-static-post-indirect-draw-buffer`,size:5*r*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.INDIRECT|GPUBufferUsage.COPY_DST});return this.state.device.queue.writeBuffer(s,0,i,0,i.length),this.state.device.queue.writeBuffer(o,0,n,0,n.length),this.state.device.queue.writeBuffer(l,0,a,0,a.length),{count:t.length,capacity:r,metadataBuffer:s,indirectBuffer:o,postIndirectBuffer:l}}createStaticInstanceVisibilityResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const i=r.instanceCount,n=Math.max(32,32*i),a=new ArrayBuffer(n),s=new Float32Array(a),o=new Uint32Array(a);for(let e=0;e<t.length;e+=1){const i=t[e],n=i.staticLocalBoundsCenter??vi(i.geometry).center,a=i.staticLocalBoundsRadius??vi(i.geometry).radius;for(let t=0;t<i.instanceCount;t+=1){const l=i.instanceStart+t,c=l*w,u=8*l;R.fromArray(r.rawData,c);const d=L.copy(n).applyMatrix4(R),h=a*xi(R);s[u+0]=d.x,s[u+1]=d.y,s[u+2]=d.z,s[u+3]=h,o[u+4]=e,o[u+5]=l,s[u+6]=i.detailCulling?.minScreenSize??0,s[u+7]=i.detailCulling?.maxDistance??0}}const l=this.state.device.createBuffer({label:`${e}-static-instance-visibility-metadata`,size:256*Math.ceil(n/256),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),c=this.state.device.createBuffer({label:`${e}-static-visible-instance-indices`,size:256*Math.ceil(Math.max(4,4*i)/256),usage:GPUBufferUsage.STORAGE}),u=this.state.device.createBuffer({label:`${e}-static-visible-instance-counts`,size:256*Math.ceil(Math.max(4,4*t.length)/256),usage:GPUBufferUsage.STORAGE}),d=this.state.device.createBuffer({label:`${e}-static-post-visible-instance-counts`,size:256*Math.ceil(Math.max(4,4*t.length)/256),usage:GPUBufferUsage.STORAGE}),h=this.state.device.createBuffer({label:`${e}-static-visible-instance-mask`,size:256*Math.ceil(Math.max(4,4*i)/256),usage:GPUBufferUsage.STORAGE});return i>0&&this.state.device.queue.writeBuffer(l,0,a),{metadata:s,instanceMetadataBuffer:l,visibleInstanceIndicesBuffer:c,visibleCountsBuffer:u,postVisibleCountsBuffer:d,visibleInstanceMaskBuffer:h,instanceCount:i}}disposeStaticDrawSetResource(e){const t=this.staticDrawSets.indexOf(e);if(t<0)return;this.staticDrawSets.splice(t,1);const r=new Set;for(const t of e.draws)t.materialResource&&r.add(t.materialResource);for(const t of e.visibleMaterialBindings)t.resource&&r.add(t.resource);for(const t of e.visibleDrawMaterialResources)t&&r.add(t);for(const t of e.depthMaterialResources.values())for(const e of t)e&&r.add(e);for(const e of r)e.uniformBuffer?.destroy();e.instanceBuffer.destroy(),e.drawMetadataResource.metadataBuffer.destroy(),e.drawMetadataResource.indirectBuffer.destroy(),e.drawMetadataResource.postIndirectBuffer.destroy(),e.instanceVisibilityResource.instanceMetadataBuffer.destroy(),e.instanceVisibilityResource.visibleInstanceIndicesBuffer.destroy(),e.instanceVisibilityResource.visibleCountsBuffer.destroy(),e.instanceVisibilityResource.postVisibleCountsBuffer.destroy(),e.instanceVisibilityResource.visibleInstanceMaskBuffer.destroy(),e.visibilityParamsBuffer.destroy(),e.postVisibilityParamsBuffer.destroy();for(const t of e.ownedMaterials)t.dispose();e.ownedMaterials.length=0,e.residentInstanceBinding.buffer=null,e.residentInstanceBinding.colorBuffer=null,e.residentInstanceBinding.sceneBindGroup=null,e.residentInstanceBinding.shadowBindGroup=null,e.residentInstanceBinding.shadowBindGroups.clear(),e.visibilityBindGroup=null,e.postVisibilityBindGroup=null,e.visibilityClearBindGroup=null,e.visibilityIndirectBuildBindGroup=null,e.postVisibilityIndirectBuildBindGroup=null,e.visibleSceneBindGroup=null,e.visibleDepthSceneBindGroup=null,e.visibleMaterialBindings.length=0,e.visibleDrawMaterialResources.length=0,e.visibleIndirectSubmissionStreams=null,e.visibleIndirectStreamsSceneBindGroup=null,e.visibleIndirectStreamsSampleCount=-1,e.visibleIndirectStreamsColorFormatsKey="",e.indirectForwardBundleCache.clear(),e.directForwardBundle=null,e.directForwardBundleSceneBindGroup=null,e.depthPrepassBundle=null,e.depthPrepassBundleSceneBindGroup=null,e.indirectDepthPrepassBundles.prepass=null,e.indirectDepthPrepassBundles.postpass=null,e.shadowBundles=new WeakMap,e.depthMaterialResources.clear()}},qa=class{constructor(e,t){this.state=e,this.textureCache=t}state;textureCache;skippedExternalTextureWarnings=new WeakSet;destroyTextureResource(e){e?.texture.destroy()}createTextureSampler(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r="non-filtering"===t,i=r?"nearest":Kr(e.magFilter),n=r?"nearest":Kr(e.minFilter),a=r?"nearest":Kr(e.minFilter),s="comparison"===t?function(e){switch(e){case mr:return"never";case cr:return"less";case ar:return"equal";case ur:return"less-equal";case sr:return"greater";case gr:return"not-equal";case or:return"greater-equal";case ir:return"always";default:return}}(e.compareFunction):void 0,o=r||"linear"!==i||"linear"!==n||"linear"!==a?1:Math.max(1,e.anisotropy);return this.state.device.createSampler({label:`${e.uuid}-sampler`,addressModeU:qr(e.wrapS),addressModeV:qr(e.wrapT),addressModeW:qr(e.wrapR??e.wrapT),magFilter:i,minFilter:n,mipmapFilter:a,maxAnisotropy:o,compare:s})}uploadDataTextureResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const i=function(e){switch(e){case"r8unorm":case"r8snorm":case"r8uint":case"r8sint":return 1;case"r16uint":case"r16sint":case"r16float":case"rg8unorm":case"rg8snorm":case"rg8uint":case"rg8sint":case"depth16unorm":return 2;case"r32uint":case"r32sint":case"r32float":case"rg16uint":case"rg16sint":case"rg16float":case"rgba8unorm":case"rgba8unorm-srgb":case"rgba8snorm":case"rgba8uint":case"rgba8sint":case"bgra8unorm":case"bgra8unorm-srgb":case"rgb9e5ufloat":case"rgb10a2unorm":case"rg11b10ufloat":case"depth32float":return 4;case"rg32uint":case"rg32sint":case"rg32float":case"rgba16uint":case"rgba16sint":case"rgba16float":return 8;case"rgba32uint":case"rgba32sint":case"rgba32float":return 16;default:return null}}(r.format);if(null===i)throw new Error(`Texture format "${r.format}" from "${e.constructor.name}" cannot be uploaded with queue.writeTexture.`);const n=e.mipmaps;if(n&&n.length>0){for(let e=0;e<n.length;e+=1){const a=n[e];if(!a?.data)continue;const s=a.width??Math.max(1,r.width>>e),o=a.height??Math.max(1,r.height>>e),l=a.depth??r.depthOrArrayLayers;this.state.device.queue.writeTexture({texture:t,mipLevel:e},Yr(a.data),{bytesPerRow:s*i,rowsPerImage:o},{width:s,height:o,depthOrArrayLayers:l})}return}const a=e.image;a?.data&&this.state.device.queue.writeTexture({texture:t},a.data,{bytesPerRow:r.width*i,rowsPerImage:r.height},{width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers})}uploadCompressedTextureResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const i="bc1-rgba-unorm"===(n=r.format)||"bc1-rgba-unorm-srgb"===n?{byteLength:8,width:4,height:4}:"bc2-rgba-unorm"===n||"bc2-rgba-unorm-srgb"===n||"bc3-rgba-unorm"===n||"bc3-rgba-unorm-srgb"===n?{byteLength:16,width:4,height:4}:"bc4-r-unorm"===n||"bc4-r-snorm"===n?{byteLength:8,width:4,height:4}:"bc5-rg-unorm"===n||"bc5-rg-snorm"===n||"bc6h-rgb-ufloat"===n||"bc6h-rgb-float"===n||"bc7-rgba-unorm"===n||"bc7-rgba-unorm-srgb"===n?{byteLength:16,width:4,height:4}:"etc2-rgb8unorm"===n||"etc2-rgb8unorm-srgb"===n||"etc2-rgb8a1unorm"===n||"etc2-rgb8a1unorm-srgb"===n?{byteLength:8,width:4,height:4}:"etc2-rgba8unorm"===n||"etc2-rgba8unorm-srgb"===n?{byteLength:16,width:4,height:4}:"eac-r11unorm"===n||"eac-r11snorm"===n?{byteLength:8,width:4,height:4}:"eac-rg11unorm"===n||"eac-rg11snorm"===n||"astc-4x4-unorm"===n||"astc-4x4-unorm-srgb"===n?{byteLength:16,width:4,height:4}:"astc-5x4-unorm"===n||"astc-5x4-unorm-srgb"===n?{byteLength:16,width:5,height:4}:"astc-5x5-unorm"===n||"astc-5x5-unorm-srgb"===n?{byteLength:16,width:5,height:5}:"astc-6x5-unorm"===n||"astc-6x5-unorm-srgb"===n?{byteLength:16,width:6,height:5}:"astc-6x6-unorm"===n||"astc-6x6-unorm-srgb"===n?{byteLength:16,width:6,height:6}:"astc-8x5-unorm"===n||"astc-8x5-unorm-srgb"===n?{byteLength:16,width:8,height:5}:"astc-8x6-unorm"===n||"astc-8x6-unorm-srgb"===n?{byteLength:16,width:8,height:6}:"astc-8x8-unorm"===n||"astc-8x8-unorm-srgb"===n?{byteLength:16,width:8,height:8}:"astc-10x5-unorm"===n||"astc-10x5-unorm-srgb"===n?{byteLength:16,width:10,height:5}:"astc-10x6-unorm"===n||"astc-10x6-unorm-srgb"===n?{byteLength:16,width:10,height:6}:"astc-10x8-unorm"===n||"astc-10x8-unorm-srgb"===n?{byteLength:16,width:10,height:8}:"astc-10x10-unorm"===n||"astc-10x10-unorm-srgb"===n?{byteLength:16,width:10,height:10}:"astc-12x10-unorm"===n||"astc-12x10-unorm-srgb"===n?{byteLength:16,width:12,height:10}:"astc-12x12-unorm"===n||"astc-12x12-unorm-srgb"===n?{byteLength:16,width:12,height:12}:null;var n;if(!i)throw new Error(`Compressed texture format "${r.format}" is not supported for upload.`);if(!0===e.isCompressedCubeTexture){const n=e.image;for(let e=0;e<n.length;e+=1){const a=n[e]?.mipmaps??[];for(let n=0;n<a.length;n+=1){const s=a[n];if(!s?.data)continue;const o=s.width??Math.max(1,r.width>>n),l=s.height??Math.max(1,r.height>>n),c=Math.max(1,Math.ceil(o/i.width)),u=Math.max(1,Math.ceil(l/i.height));this.state.device.queue.writeTexture({texture:t,mipLevel:n,origin:{x:0,y:0,z:e}},Yr(s.data),{bytesPerRow:c*i.byteLength,rowsPerImage:u},{width:c*i.width,height:u*i.height,depthOrArrayLayers:1})}}return}const a=e.mipmaps;for(let e=0;e<a.length;e+=1){const n=a[e];if(!n?.data)continue;const s=n.width??Math.max(1,r.width>>e),o=n.height??Math.max(1,r.height>>e),l=Math.max(1,Math.ceil(s/i.width)),c=Math.max(1,Math.ceil(o/i.height));this.state.device.queue.writeTexture({texture:t,mipLevel:e},Yr(n.data),{bytesPerRow:l*i.byteLength,rowsPerImage:c},{width:l*i.width,height:c*i.height,depthOrArrayLayers:r.depthOrArrayLayers})}}uploadExternalTextureResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");if(!0===e.isCubeTexture){const i=e.image;if(!Array.isArray(i)||6!==i.length)return void this.warnSkippedExternalTextureUpload(e,r,"CubeTexture must provide exactly six face images.");for(let n=0;n<i.length;n+=1){const a=Zr(i[n]);if(!a)return void this.warnSkippedExternalTextureUpload(e,r,`CubeTexture face ${n} is not a copyable image source.`);try{this.state.device.queue.copyExternalImageToTexture({source:a,flipY:e.flipY},{texture:t,origin:{x:0,y:0,z:n}},{width:r.width,height:r.height,depthOrArrayLayers:1})}catch(t){return void this.warnSkippedExternalTextureUpload(e,r,`CubeTexture face ${n} could not be copied: ${Ka(t)}`)}}return}const i=function(e){return Zr(e.image)}(e);if(i)try{this.state.device.queue.copyExternalImageToTexture({source:i,flipY:e.flipY},{texture:t},{width:r.width,height:r.height,depthOrArrayLayers:1})}catch(t){this.warnSkippedExternalTextureUpload(e,r,`copyExternalImageToTexture failed: ${Ka(t)}`)}else this.warnSkippedExternalTextureUpload(e,r,"Texture.image is not an HTML image, canvas, video, ImageBitmap, or OffscreenCanvas.")}warnSkippedExternalTextureUpload(e,t,r){if(this.skippedExternalTextureWarnings.has(e))return;this.skippedExternalTextureWarnings.add(e);const i=e.image;console.warn(`[WebGpuRenderer] Skipped upload for texture "${e.name||e.uuid}"; the WebGPU material remains active and samples a zero-cleared fallback texture. ${r}`,{texture:e,textureClass:e.constructor.name,textureName:e.name||void 0,textureUuid:e.uuid,textureFlags:{isRenderTargetTexture:!0===e.isRenderTargetTexture,isVideoTexture:!0===e.isVideoTexture,isCanvasTexture:!0===e.isCanvasTexture,isCubeTexture:!0===e.isCubeTexture},descriptor:t,image:{className:i?.constructor?.name??typeof i,width:i?.width,height:i?.height,depth:i?.depth,src:i?.currentSrc??i?.src,hasData:null!=i?.data,keys:null==i?[]:Object.keys(i).slice(0,16)},userData:e.userData})}uploadTextureResource(e,t,r){!function(e){return!0===e.isCompressedTexture||!0===e.isCompressedArrayTexture}(e)&&!0!==e.isCompressedCubeTexture?!0!==e.isDataTexture&&!0!==e.isDataArrayTexture&&!0!==e.isData3DTexture?this.uploadExternalTextureResource(e,t,r):this.uploadDataTextureResource(e,t,r):this.uploadCompressedTextureResource(e,t,r)}getTextureResource(e){if(!this.state.device)throw new Error("Renderer is not initialized.");const t=this.textureCache.get(e),r=pt(e,this.state.device);if(t&&t.version===e.version&&t.width===r.width&&t.height===r.height&&t.depthOrArrayLayers===r.depthOrArrayLayers&&t.format===r.format&&t.textureDimension===r.textureDimension&&t.viewDimension===r.viewDimension&&t.sampleType===r.sampleType&&t.samplerBindingType===r.samplerBindingType&&t.mipLevelCount===r.mipLevelCount)return t;this.destroyTextureResource(t);const i=this.state.device.createTexture({label:`${e.uuid}-texture`,size:{width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers},dimension:r.textureDimension,format:r.format,mipLevelCount:r.mipLevelCount,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|(r.compressed||"3d"===r.textureDimension?0:GPUTextureUsage.RENDER_ATTACHMENT)});this.uploadTextureResource(e,i,r);const n=this.createTextureSampler(e,r.samplerBindingType),a={version:e.version,width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers,format:r.format,textureDimension:r.textureDimension,viewDimension:r.viewDimension,sampleType:r.sampleType,samplerBindingType:r.samplerBindingType,mipLevelCount:r.mipLevelCount,texture:i,view:i.createView("2d"===r.viewDimension?void 0:"2d-array"===r.viewDimension?{dimension:"2d-array",arrayLayerCount:r.depthOrArrayLayers}:{dimension:r.viewDimension}),sampler:n};return this.textureCache.set(e,a),a}};function Ka(e){return e instanceof Error?e.message:String(e)}var Za="\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\nstruct PointShadowVertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> PointShadowVertexOutput {\n var output: PointShadowVertexOutput;\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n output.position = shadowCamera.viewProj * world;\n output.worldPosition = world.xyz;\n return output;\n}\n\n@fragment\nfn fsMain(input: PointShadowVertexOutput) -> @location(0) vec4<f32> {\n let distanceToLight = length(input.worldPosition - shadowCamera.lightPositionRange.xyz);\n let normalizedDepth = clamp(distanceToLight / shadowCamera.lightPositionRange.w, 0.0, 1.0);\n return vec4(normalizedDepth, normalizedDepth, normalizedDepth, 1.0);\n}\n",Ya="\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\nstruct PointShadowVertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstanceMatrices: array<vec4<f32>>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let base = instanceIndex * 4u;\n return mat4x4<f32>(\n rendererInstanceMatrices[base + 0u],\n rendererInstanceMatrices[base + 1u],\n rendererInstanceMatrices[base + 2u],\n rendererInstanceMatrices[base + 3u]\n );\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> PointShadowVertexOutput {\n var output: PointShadowVertexOutput;\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n output.position = shadowCamera.viewProj * world;\n output.worldPosition = world.xyz;\n return output;\n}\n\n@fragment\nfn fsMain(input: PointShadowVertexOutput) -> @location(0) vec4<f32> {\n let distanceToLight = length(input.worldPosition - shadowCamera.lightPositionRange.xyz);\n let normalizedDepth = clamp(distanceToLight / shadowCamera.lightPositionRange.w, 0.0, 1.0);\n return vec4(normalizedDepth, normalizedDepth, normalizedDepth, 1.0);\n}\n",Xa="\nstruct RendererSkinningUniforms {\n bindMatrix: mat4x4<f32>,\n bindMatrixInverse: mat4x4<f32>,\n};\n\n@group(2) @binding(0) var<storage, read> rendererBoneMatrixColumns: array<vec4<f32>>;\n@group(2) @binding(1) var<uniform> rendererSkinning: RendererSkinningUniforms;\n\nfn rendererBoneMatrix(index: u32) -> mat4x4<f32> {\n let base = index * 4u;\n return mat4x4<f32>(\n rendererBoneMatrixColumns[base + 0u],\n rendererBoneMatrixColumns[base + 1u],\n rendererBoneMatrixColumns[base + 2u],\n rendererBoneMatrixColumns[base + 3u],\n );\n}\n\nfn rendererSkinPosition(position: vec3<f32>, skinIndex: vec4<u32>, skinWeight: vec4<f32>) -> vec3<f32> {\n let boundPosition = rendererSkinning.bindMatrix * vec4(position, 1.0);\n let weightSum = skinWeight.x + skinWeight.y + skinWeight.z + skinWeight.w;\n if (weightSum <= 0.0) {\n return position;\n }\n let skinnedPosition =\n (rendererBoneMatrix(skinIndex.x) * boundPosition) * skinWeight.x +\n (rendererBoneMatrix(skinIndex.y) * boundPosition) * skinWeight.y +\n (rendererBoneMatrix(skinIndex.z) * boundPosition) * skinWeight.z +\n (rendererBoneMatrix(skinIndex.w) * boundPosition) * skinWeight.w;\n let fallbackWeight = max(0.0, 1.0 - weightSum);\n return (rendererSkinning.bindMatrixInverse * (skinnedPosition + boundPosition * fallbackWeight)).xyz;\n}\n",Ja=`\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> rendererLights: array<vec4<f32>, 11>;\n@group(0) @binding(2) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\n${Xa}\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @location(1) skinIndex: vec4<u32>,\n @location(2) skinWeight: vec4<f32>,\n @builtin(instance_index) instanceIndex: u32,\n) -> @builtin(position) @invariant vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(rendererSkinPosition(position, skinIndex, skinWeight), 1.0);\n return rendererCamera.viewProj * world;\n}\n`,Qa=`\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\n${Xa}\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @location(1) skinIndex: vec4<u32>,\n @location(2) skinWeight: vec4<f32>,\n @builtin(instance_index) instanceIndex: u32,\n) -> @builtin(position) vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(rendererSkinPosition(position, skinIndex, skinWeight), 1.0);\n return shadowCamera.viewProj * world;\n}\n`,es=`\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\nstruct PointShadowVertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\n${Xa}\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @location(1) skinIndex: vec4<u32>,\n @location(2) skinWeight: vec4<f32>,\n @builtin(instance_index) instanceIndex: u32,\n) -> PointShadowVertexOutput {\n var output: PointShadowVertexOutput;\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(rendererSkinPosition(position, skinIndex, skinWeight), 1.0);\n output.position = shadowCamera.viewProj * world;\n output.worldPosition = world.xyz;\n return output;\n}\n\n@fragment\nfn fsMain(input: PointShadowVertexOutput) -> @location(0) vec4<f32> {\n let distanceToLight = length(input.worldPosition - shadowCamera.lightPositionRange.xyz);\n let normalizedDepth = clamp(distanceToLight / shadowCamera.lightPositionRange.w, 0.0, 1.0);\n return vec4(normalizedDepth, normalizedDepth, normalizedDepth, 1.0);\n}\n`,ts="\nstruct FullscreenVertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) uv: vec2<f32>,\n};\n\n@group(0) @binding(0) var sourceSampler: sampler;\n@group(0) @binding(1) var sourceTexture: texture_2d<f32>;\n\n@vertex\nfn vsMain(@builtin(vertex_index) vertexIndex: u32) -> FullscreenVertexOutput {\n var output: FullscreenVertexOutput;\n let position = array<vec2<f32>, 3>(\n vec2(-1.0, -3.0),\n vec2(-1.0, 1.0),\n vec2(3.0, 1.0),\n );\n let clip = position[vertexIndex];\n output.position = vec4(clip, 0.0, 1.0);\n output.uv = clip * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n return output;\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let linearColor = textureSample(sourceTexture, sourceSampler, input.uv);\n let low = linearColor.rgb * 12.92;\n let high = 1.055 * pow(max(linearColor.rgb, vec3<f32>(0.0)), vec3<f32>(1.0 / 2.4)) - 0.055;\n let srgb = select(high, low, linearColor.rgb <= vec3<f32>(0.0031308));\n return vec4<f32>(srgb, linearColor.a);\n}\n";function rs(e){return`\nstruct FullscreenVertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) uv: vec2<f32>,\n};\n\n@group(0) @binding(0) var sourceSampler: sampler;\n@group(0) @binding(1) var sourceTexture: texture_2d<f32>;\n\n@vertex\nfn vsMain(@builtin(vertex_index) vertexIndex: u32) -> FullscreenVertexOutput {\n var output: FullscreenVertexOutput;\n let position = array<vec2<f32>, 3>(\n vec2(-1.0, -3.0),\n vec2(-1.0, 1.0),\n vec2(3.0, 1.0),\n );\n let clip = position[vertexIndex];\n output.position = vec4(clip, 0.0, 1.0);\n output.uv = clip * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n return output;\n}\n\n @fragment\n fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let source = textureSample(sourceTexture, sourceSampler, input.uv);\n ${e?"return vec4(source.rgb, 1.0);":"return vec4(clamp(source.rgb, vec3(0.0), vec3(1.0)), clamp(source.a / 3.0, 0.0, 1.0));"}\n }\n`}var is=rs(!1),ns=rs(!0);function as(e){if(e.transparent)switch(e.blending){case Ii:return{color:{srcFactor:"src-alpha",dstFactor:"one",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one",operation:"add"}};case Hi:return{color:{srcFactor:"zero",dstFactor:"one-minus-src",operation:"subtract"},alpha:{srcFactor:"one",dstFactor:"one",operation:"subtract"}};case Ei:return{color:{srcFactor:"zero",dstFactor:"src",operation:"add"},alpha:{srcFactor:"zero",dstFactor:"src-alpha",operation:"add"}};default:return{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}}function ss(e,t,r,i){if(t<0||e[t]!==r)return-1;let n=0;for(let a=t;a<e.length;a+=1)if(e[a]===r&&(n+=1),e[a]===i&&(n-=1,0===n))return a;return-1}function os(e,t,r){const i=function(e,t="fsMain"){const r=e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,""),i=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp(`@fragment\\s+fn\\s+${i}\\s*\\(`).exec(r);if(!n)return null;const a=r.indexOf("(",n.index),s=ss(r,a,"(",")");if(s<0)return null;const o=r.indexOf("{",s+1);if(o<0)return null;const l=r.slice(s+1,o),c=/->\s*@location\s*\(\s*(\d+)\s*\)/.exec(l);if(c)return new Set([Number(c[1])]);const u=/->\s*((?:@\w+(?:\s*\([^)]*\))?\s*)*)([A-Za-z_]\w*)/.exec(l);if(!u)return new Set;const d=u[2].replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),h=new RegExp(`\\bstruct\\s+${d}\\s*\\{`).exec(r);if(!h)return null;const p=r.indexOf("{",h.index),f=ss(r,p,"{","}");if(f<0)return null;const m=new Set,g=/@location\s*\(\s*(\d+)\s*\)/g,v=r.slice(p+1,f);for(const e of v.matchAll(g))m.add(Number(e[1]));return m}(e);return t.map((e,t)=>null===i||i.has(t)?{format:e,blend:r}:{format:e,writeMask:0})}function ls(e){const t=e.userData.motionBlurMode;if(null==t&&e.isSkinnedMesh)return 1;if("number"==typeof t&&Number.isFinite(t))return Math.max(0,Math.min(3,Math.round(t)));switch(t){case"disabled":case"Disabled":return 0;case"cameraOnly":case"CameraOnly":return 1;case"forceObjectBlur":case"ForceObjectBlur":return 3;default:return 2}}function cs(e){const t=Number(e.userData.motionBlurScale??1);return Number.isFinite(t)?Math.max(0,Math.min(t,8)):1}var us="chromium-experimental-multi-draw-indirect";function ds(e,t){return Number(t.castShadow)-Number(e.castShadow)}var hs=[C],ps=[{name:"position",shaderLocation:0,format:"float32x3"},{name:"normal",shaderLocation:1,format:"float32x3",defaultValue:[0,0,1]},{name:"uv",shaderLocation:2,format:"float32x2",defaultValue:[0,0]},{name:"color",shaderLocation:3,format:"float32x4",defaultValue:[1,1,1,1]},{name:"skinIndex",shaderLocation:4,format:"uint32x4"},{name:"skinWeight",shaderLocation:5,format:"float32x4"}];function fs(e){return e.wireframe&&"triangle-list"===e.primitiveTopology?"line-list":e.primitiveTopology}function ms(e,t,r){if(!fs(e).startsWith("triangle"))return"none";if("directionalShadow"===t){if(r&&null===e.shadowSide)return"none";const t=e.shadowSide??(e.side===Vi?Ui:e.side===Li?Li:Vi);return t===Li?"none":t===Vi?"front":"back"}return e.side===Li?"none":e.side===Vi?"front":"back"}function gs(e){if(void 0===e)return 1;if(!Number.isFinite(e)||e<=0||e>1)throw new RangeError("renderScale must be a finite number greater than 0 and at most 1.");return e}var vs=class{pipelineCompilationDiagnostics;canvas;clearColor;powerPreference;shadowMapSize;directionalShadowsEnabled=!0;spotShadowMapSize;pointShadowMapSize;fallbackMaterial;materialResolver;toonOutlineMaterialCache=new WeakMap;fallbackSkinnedMaterial;invokeObjectRenderCallbacks;sampleCount;renderScale;hiZOcclusionCullingEnabled;multiDrawIndirectEnabled;dynamicBatchingEnabled;multiDrawIndirectSupported=!1;tiledPointLights=null;tiledLightingEnabled;renderGraphProfilingEnabled;indirectFirstInstanceSupported=!1;timestampQuerySupported=!1;geometryCache=new WeakMap;skinnedGeometryCache=new Map;skinPaletteCache=new WeakMap;skinPaletteResources=new Set;meshExtractionCache=new WeakMap;resolvedMaterialFrameCache=new WeakMap;repeatedMeshInstances=new WeakMap;repeatedInstanceResources=new Map;instancedMeshExtractionCache=new WeakMap;batchedMeshExtractionCache=new WeakMap;materialCache=new WeakMap;skinnedMaterialCache=new WeakMap;materialCacheVisible=new WeakMap;materialCacheDirect=new WeakMap;materialNoReceiveShadowCache=new WeakMap;skinnedMaterialNoReceiveShadowCache=new WeakMap;materialNoReceiveShadowCacheVisible=new WeakMap;materialNoReceiveShadowCacheDirect=new WeakMap;depthPrepassMaterialCache=new WeakMap;directionalShadowMaterialCache=new WeakMap;skinnedDirectionalShadowMaterialCache=new WeakMap;directionalShadowMaterialCacheDirect=new WeakMap;lineMaterialCache=new WeakMap;lineBasicMaterialCache=new WeakMap;lineProxyCache=new WeakMap;spriteProxyCache=new WeakMap;depthMaterialFrameCache=new WeakMap;forwardMaterialFastCache=new WeakMap;forwardMaterialTargetFastCache=new WeakMap;forwardMaterialFrameCache=new WeakMap;drawMaterialResourceFrameValidation=new WeakMap;depthMaterialFastCache=new WeakMap;sharedForwardPipelineCache=new Map;sharedForwardPipelinePromiseCache=new Map;sharedDepthPipelineCache=new Map;sharedDepthPipelinePromiseCache=new Map;state=function(){return{device:null,context:null,format:null,mainDepthTexture:null,mainDepthView:null,sceneColorTexture:null,sceneColorView:null,sceneColorSnapshotTexture:null,sceneColorSnapshotView:null,sceneDepthSnapshotTexture:null,sceneDepthSnapshotView:null,postProcessColorTexture:null,postProcessColorView:null,cameraBuffer:null,lightBuffer:null,shadowCameraBuffer:null,shadowCameraBufferPool:[],sharedShadowBindGroupByCameraBuffer:new Map,instanceBuffer:null,instanceBufferSize:0,drawMetadataResource:null,sharedSceneBindGroup:null,sharedShadowBindGroup:null,indirectForwardBundleCache:new Map,directForwardBundleCache:new Map,sceneBindGroupLayout:null,directSceneBindGroupLayout:null,visibleSceneBindGroupLayout:null,visibleDepthSceneBindGroupLayout:null,shadowBindGroupLayout:null,directShadowBindGroupLayout:null,emptyBindGroupLayout:null,skinningBindGroupLayout:null,sceneTextureBindGroupLayout:null,sceneTextureBindGroup:null,shadowComparisonSampler:null,linearClampSampler:null,nearestClampSampler:null,fullscreenTextureBindGroupLayout:null,directionalShadowTexture:null,directionalShadowView:null,directionalShadowLayerViews:[],pointShadowTexture:null,pointShadowArrayView:null,pointShadowFaceViews:[],pointShadowDepthTexture:null,pointShadowDepthFaceViews:[],spotShadowTexture:null,spotShadowView:null,spotShadowLayerViews:[],spotLightMapTexture:null,spotLightMapView:null,hizTexture:null,hizView:null,hizMipViews:[],hizCopyBindGroup:null,hizReduceBindGroups:[],visibilityBindGroup:null,visibilityBindGroupMetadataResource:null,presentBindGroups:new WeakMap,hizMipCount:1,temporalHiZHistoryValid:!1,temporalVisibilityBuffer:null,visibilityParamsBuffer:null,hizCopyKernel:null,hizReduceKernel:null,visibilityKernel:null,staticVisibilityClearKernel:null,staticVisibilityCullKernel:null,staticVisibilityIndirectBuildKernel:null,depthPrepassPipeline:null,depthPrepassPipelineVisible:null,depthPrepassPipelineDirect:null,skinnedDepthPrepassPipeline:null,shadowDepthPipeline:null,shadowDepthPipelineDirect:null,skinnedShadowDepthPipeline:null,pointShadowPipeline:null,pointShadowPipelineDirect:null,skinnedPointShadowPipeline:null,presentPipeline:null,sceneColorSnapshotPipeline:null,sceneColorSnapshotBindGroups:new WeakMap,pixelRatio:1,width:1,height:1,presentationWidth:1,presentationHeight:1,frameTimeSeconds:0,frameIndex:0,directionalShadowTextureSize:1,pointShadowTextureSize:1,spotShadowTextureSize:1,latestFrameProfile:null,latestCompletedFrameProfile:null,residentSceneBindGroupVersion:0,residentShadowBindGroupVersion:0,initialized:!1}}();textureCache=new WeakMap;graphTextureBindGroupCache=new WeakMap;materialGraphTextureReadCache=new WeakMap;defaultInstanceAttributeBuffers=new Map;textureManager=new qa(this.state,this.textureCache);renderGraph=new wn;nativePostSubmit;presentationOverlay;presentationOverlayContext={device:null,encoder:null,targetView:null,targetFormat:"bgra8unorm",presentationWidth:1,presentationHeight:1};directionalShadowCameras=Array.from({length:4},()=>new $i(-10,10,10,-10,.1,80));directionalShadowScheduler=new $a(this.directionalShadowCameras);pointShadowCameras=Array.from({length:4},()=>D.map(()=>new Wi(90,1,.1,25)));spotShadowCameras=Array.from({length:4},()=>new Wi(60,1,.5,500));colorTargetCache=new Map;msaaColorTargetCache=new Map;msaaDepthTargetCache=new Map;sourceInstanceDataScratch=new Mi(4096);opaqueInstanceDataScratch=new Mi(4096);finalInstanceDataScratch=new Mi(4096);residentInstanceUploadsScratch=[];gpuOpaqueDrawsScratch=[];directOpaqueDrawsScratch=[];stagedOpaqueDrawsScratch=[];residentOpaqueDrawsScratch=[];retiredGeometryResources=[];retiredGeometryBuffers=[];vertexAttributeBufferKeyCache=new WeakMap;standardVertexAttributeCache=new WeakMap;geometryVertexBufferFastCache=new WeakMap;vertexAttributeGroupCache=new WeakMap;materialVertexAttributeCache=new WeakMap;vertexBufferBindingPlanCache=new WeakMap;preparedVertexBufferCache=new WeakMap;vertexAttributeGroupBufferKeyCache=new WeakMap;compileDrawScratch=[];dynamicIndirectSubmissionCache=new WeakMap;indirectStreamKeyCache=new WeakMap;nextIndirectStreamKey=1;indirectBundleInvalidationVersion=0;colorFormatsIdentityCache=new WeakMap;colorFormatsValueCache=new Map([[C,1]]);nextColorFormatsId=2;renderBundleScratch=[];indirectMaterialResourcesScratch=[];directBundleDrawStatsScratch={drawCallCount:0,triangleCount:0};sortedOpaqueBatchesScratch=[];opaqueBatchPool=[];opaqueBatchPoolCount=0;drawCallPool=[];drawCallPoolCount=0;staticDrawSets=[];materialPassStaticBundleCache=new WeakMap;staticDrawSetManager=new Ha(this.state,this.staticDrawSets,e=>this.getGeometryResource(e),e=>this.resolveMaterial(e),(e,t)=>this.ensureWireframeIndex(e,t));staticFrameToken=0;hizResourceVersion=0;graphTextureResourceVersion=0;transmissionSnapshotTexture=null;transmissionSnapshotView=null;transmissionSnapshotSize={width:0,height:0};transmissionMipViews=[];transmissionMipBindGroups=[];transmissionSourceBindGroups=new WeakMap;transmissionSnapshotPipeline=null;transmissionSampler=null;visibilityParamsUpload=new Uint32Array(4);drawMetadataUpload=new Float32Array(0);indirectDrawUpload=new Uint32Array(0);extractedAmbientScratch=new Zi;extractedHemisphereScratch=this.createExtractedHemisphereLightScratch();extractedBoundsMinScratch=new Ki;extractedBoundsMaxScratch=new Ki;extractedDirectionalLightsScratch=Array.from({length:4},()=>this.createExtractedDirectionalLightScratch());extractedPointLightsScratch=Array.from({length:v},()=>this.createExtractedPointLightScratch());extractedSpotLightsScratch=Array.from({length:x},()=>this.createExtractedSpotLightScratch());activeDirectionalLightsScratch=[];activePointLightsScratch=[];activeSpotLightsScratch=[];fogVolumeObjectsScratch=[];resolvedMeshMaterialsScratch=[];extractedLightsScratch={ambient:this.extractedAmbientScratch,hemisphere:null,directionals:this.activeDirectionalLightsScratch,points:this.activePointLightsScratch,spots:this.activeSpotLightsScratch,directional:null,point:null,spot:null};extractedFrameScratch={scene:null,camera:null,fogVolumeObjects:this.fogVolumeObjectsScratch,gpuOpaqueDraws:this.gpuOpaqueDrawsScratch,directOpaqueDraws:this.directOpaqueDrawsScratch,transparentDraws:[],instanceData:this.finalInstanceDataScratch,residentInstanceUploads:this.residentInstanceUploadsScratch,lights:this.extractedLightsScratch,boundsMin:this.extractedBoundsMinScratch,boundsMax:this.extractedBoundsMaxScratch};cameraUniformScratch=new Float32Array(104);temporalVisibilityUniformScratch=new Float32Array(44);lightUniformScratch=new Float32Array(T);spotLightMapAtlasSignature="";spotLightMapAtlasSize=0;spotLightMapAtlasLayout=null;spotLightMapAtlasPipeline=null;csmCascadeRanges=Array.from({length:4},()=>new qi);csmCascadeCount=0;csmCascadeLights=[];shadowCameraUniformScratch=new Float32Array(64);cameraViewProjScratch=new Oi;cameraProjectionScratch=new Oi;projectionJitterPixels=new qi;temporalVisibilityCurrentViewProj=new Oi;temporalVisibilityPreviousViewProj=new Oi;motionVectorProjection=new Oi;motionVectorCurrentViewProj=new Oi;motionVectorPreviousViewProj=new Oi;motionVectorProjectionPending=!1;motionVectorHistoryValid=!1;motionVectorHistoryGeneration=1;lastMotionVectorTimeSeconds=Number.NaN;objectMotionHistory=new WeakMap;cameraFrustumPlanesScratch=new Float32Array(24);objectTraversalStackScratch=[];shadowDrawsScratch=[];extractingCaster=!1;cameraDetailHistory=new WeakMap;isSphereVisibleScratch=(e,t,r,i,n)=>this.extractingCaster||!n||gi(this.cameraFrustumPlanesScratch,e,t,r,i);isSphereVisibleForCompilationScratch=()=>!0;updateExtractedBoundsFromMatrixScratch=e=>{const t=this.extractedBoundsMinScratch,r=this.extractedBoundsMaxScratch,i=e[12],n=e[13],a=e[14];i<t.x&&(t.x=i),n<t.y&&(t.y=n),a<t.z&&(t.z=a),i>r.x&&(r.x=i),n>r.y&&(r.y=n),a>r.z&&(r.z=a)};transparentSortCameraPositionScratch=new Ki;transparentSortCameraForwardScratch=new Ki;temporalVisibilityCurrentCameraPosition=new Ki;temporalVisibilityPreviousCameraPosition=new Ki;shadowViewProjScratch=new Oi;extractionVersion=0;graphBuilder=(e,t)=>{t.addDirectionalShadowPass(),t.addPointShadowPass(),t.addSpotShadowPass(),t.addDepthPrepass(),t.addHiZPasses(),t.addVisibilityPass(),t.addForwardPass(),t.addPresentPass()};createExtractedDirectionalLightScratch(){return{sourceLight:null,position:new Ki,target:new Ki,direction:new Ki,color:new Ki,intensity:0,volumetricIntensity:1,castShadow:!1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowIntensity:1,shadowMapSize:this.shadowMapSize,shadowCameraLeft:-5,shadowCameraRight:5,shadowCameraTop:5,shadowCameraBottom:-5,shadowCameraNear:.5,shadowCameraFar:500}}createExtractedHemisphereLightScratch(){return{direction:new Ki(0,1,0),skyColor:new Ki,groundColor:new Ki,intensity:0}}createExtractedPointLightScratch(){return{sourceLight:null,position:new Ki,color:new Ki,intensity:0,volumetricIntensity:1,distance:0,range:25,decay:2,castShadow:!1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowIntensity:1,shadowMapSize:this.pointShadowMapSize,shadowCameraNear:.5,shadowCameraFar:500}}createExtractedSpotLightScratch(){return{sourceLight:null,position:new Ki,direction:new Ki(0,-1,0),color:new Ki,intensity:0,volumetricIntensity:1,range:500,angle:Math.PI/3,penumbra:0,decay:2,castShadow:!1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowIntensity:1,shadowMapSize:this.shadowMapSize,shadowCameraNear:.5,shadowCameraFar:500,shadowCameraFov:60,map:null}}skinnedDrawKeys=new Di;skeletonPalettes=new Pi;getSkeletonBoneBufferForPass=e=>{const t=this.getSkinningPalette(e);return this.refreshSkinningPalette(t),this.uploadSkinningPalette(t),t.matrixBuffer};outlineResolvedFrameCache=new WeakMap;opaqueSortMs=0;opaqueSortSamples=new Float64Array(120);opaqueSortSampleIndex=0;opaqueSortSampleCount=0;opaqueSortSampleTotal=0;sortOpaqueDraws(e){const t=this.renderGraphProfilingEnabled?performance.now():0;e.sort(ii),this.renderGraphProfilingEnabled&&(this.opaqueSortMs+=performance.now()-t)}constructor(e){this.canvas=e.canvas,this.nativePostSubmit=e.nativePostSubmit,this.presentationOverlay=e.presentationOverlay,this.clearColor=[...e.clearColor??[0,0,0,1]],this.powerPreference=e.powerPreference,this.directionalShadowScheduler.setOptions(e.directionalShadowUpdates??{}),this.shadowMapSize=e.shadowMapSize??2048,this.spotShadowMapSize=this.shadowMapSize,this.pointShadowMapSize=e.pointShadowMapSize??1024,this.fallbackMaterial=e.fallbackMaterial??null,this.materialResolver=e.materialResolver,this.fallbackSkinnedMaterial=e.fallbackSkinnedMaterial??new Sr({vertexShader:"\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n @location(3) color: vec4<f32>,\n @location(4) skinIndex: vec4<u32>,\n @location(5) skinWeight: vec4<f32>,\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldNormal: vec3<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let skinnedPosition = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight);\n let skinnedNormal = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n output.position = rendererClipPosition(skinnedPosition, input.instanceIndex);\n output.worldNormal = rendererWorldNormal(skinnedNormal, input.instanceIndex);\n return output;\n}\n",fragmentShader:"\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldNormal: vec3<f32>,\n};\n\n@fragment\nfn fsMain(input: VertexOutput) -> @location(0) vec4<f32> {\n let normal = normalize(input.worldNormal);\n let diffuse = max(dot(normal, normalize(rendererDirectionalLightDirection())), 0.0);\n let lighting = rendererIndirectDiffuse(normal) + rendererDirectionalLightColor() * diffuse;\n return vec4<f32>(vec3<f32>(0.72, 0.76, 0.82) * lighting, 1.0);\n}\n",vertexAttributes:ps}),this.invokeObjectRenderCallbacks=e.invokeObjectRenderCallbacks??!0,this.state.directionalShadowTextureSize=this.shadowMapSize,this.state.pointShadowTextureSize=this.pointShadowMapSize,this.state.spotShadowTextureSize=this.shadowMapSize,this.sampleCount=Si(e.sampleCount),this.renderScale=gs(e.renderScale),this.hiZOcclusionCullingEnabled=e.hiZOcclusionCulling??!1,this.multiDrawIndirectEnabled=e.multiDrawIndirect??!0,this.dynamicBatchingEnabled=e.dynamicBatching??!0,this.tiledLightingEnabled=e.tiledLighting??!0,this.renderGraphProfilingEnabled=e.renderGraphProfiling??!1}resolveMaterial(e){if(!1===e?.visible)return null;if(e&&Cr(e))return e;if(!e)return this.fallbackMaterial;if(!0===e.isLineMaterial)return this.resolveLineMaterial(e);const t=this.resolvedMaterialFrameCache.get(e);if(t?.extractionVersion===this.extractionVersion)return t.material;let r=e.transparent||function(e){if(e.transparent||(e.transmission??0)>0)return!0;if(e instanceof Yi)return null!=e.uniforms.hology_depth_map||null!=e.uniforms.hology_scene_map||null!=e.uniforms.hology_transmission_map;if(e instanceof Sr)return e.requiresLatePass();return!1}(e)?"late":"opaque",i=this.materialResolver?.(e,r);"opaque"===r&&i?.requiresLatePass()&&(r="late",i=this.materialResolver?.(e,r));const n=void 0===i?this.fallbackMaterial:i;return t?(t.extractionVersion=this.extractionVersion,t.material=n):this.resolvedMaterialFrameCache.set(e,{extractionVersion:this.extractionVersion,material:n}),void 0!==i?i:n}resolveLineMaterial(e){let t=this.lineMaterialCache.get(e);t||(t=new Sr({vertexShader:"\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(4) instanceStart: vec3<f32>,\n @location(5) instanceEnd: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) color: vec4<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let start = rendererCamera.view * rendererWorldPosition(input.instanceStart, input.instanceIndex);\n let end = rendererCamera.view * rendererWorldPosition(input.instanceEnd, input.instanceIndex);\n let clipStart = rendererCamera.projection * start;\n let clipEnd = rendererCamera.projection * end;\n let ndcStart = clipStart.xy / clipStart.w;\n let ndcEnd = clipEnd.xy / clipEnd.w;\n let aspect = rendererCamera.viewportAndTime.x / max(rendererCamera.viewportAndTime.y, 1.0);\n var direction = ndcEnd - ndcStart;\n direction.x *= aspect;\n direction = normalize(select(vec2<f32>(1.0, 0.0), direction, length(direction) > 0.00001));\n var offset = vec2<f32>(direction.y, -direction.x);\n direction.x /= aspect;\n offset.x /= aspect;\n if (input.position.x < 0.0) { offset = -offset; }\n if (input.position.y < 0.0) {\n offset -= direction;\n } else if (input.position.y > 1.0) {\n offset += direction;\n }\n offset *= materialUniforms.linewidth / max(rendererCamera.viewportAndTime.y, 1.0);\n var clip = select(clipEnd, clipStart, input.position.y < 0.5);\n // clip.xy += offset * clip.w;\n let offsetW = offset * clip.w;\n clip = vec4<f32>(clip.x + offsetW.x, clip.y + offsetW.y, clip.z, clip.w);\n output.position = clip;\n output.color = vec4<f32>(materialUniforms.color, materialUniforms.opacity);\n return output;\n}\n",fragmentShader:"\nstruct FragmentInput {\n @builtin(position) position: vec4<f32>,\n @location(0) color: vec4<f32>,\n};\n\n@fragment\nfn fsMain(input: FragmentInput) -> @location(0) vec4<f32> {\n return input.color;\n}\n",uniforms:{color:new zi(1,1,1),opacity:1,linewidth:1},vertexAttributes:[{name:"position",shaderLocation:0,format:"float32x3"},{name:"instanceStart",shaderLocation:4,format:"float32x3",stepMode:"instance"},{name:"instanceEnd",shaderLocation:5,format:"float32x3",stepMode:"instance"}],transparent:!0,side:Li,depthTest:e.depthTest,depthWrite:e.depthWrite}),this.lineMaterialCache.set(e,t));const r=e,i=r.color;return i&&t.uniforms.color.value.copy(i),t.uniforms.opacity.value=r.opacity??1,t.uniforms.linewidth.value=r.linewidth??1,t.transparent=e.transparent||(r.opacity??1)<1,t.depthTest=e.depthTest,t.depthWrite=e.depthWrite,t}resolveLineBasicMaterial(e,t){let r=this.lineBasicMaterialCache.get(e);r||(r=new Map,this.lineBasicMaterialCache.set(e,r));let i=r.get(t);i||(i=new Sr({vertexShader:"\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32,\n};\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n};\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n return VertexOutput(rendererClipPosition(input.position, input.instanceIndex));\n}\n",fragmentShader:"\n@fragment\nfn fsMain() -> @location(0) vec4<f32> {\n return vec4<f32>(materialUniforms.color, materialUniforms.opacity);\n}\n",uniforms:{color:new zi(1,1,1),opacity:1},primitiveTopology:t,depthTest:e.depthTest,depthWrite:e.depthWrite}),r.set(t,i));const n=e;return n.color&&i.uniforms.color.value.copy(n.color),i.uniforms.opacity.value=n.opacity??1,i.transparent=e.transparent||(n.opacity??1)<1,i.depthTest=e.depthTest,i.depthWrite=e.depthWrite,i}resolveSkinnedMaterial(e){const t=this.resolveMaterial(e);return null===t?null:function(e){const t=e.vertexAttributes.find(e=>"skinIndex"===e.name),r=e.vertexAttributes.find(e=>"skinWeight"===e.name);return e.vertexShader.includes("USE_SKINNING")||"uint32x4"===t?.format&&"float32x4"===r?.format&&e.vertexShader.includes("rendererSkinPosition(")}(t)?t:this.fallbackSkinnedMaterial}hasRenderCallbacks(e){return null!==e&&this.invokeObjectRenderCallbacks&&function(e){return null!==e&&(e.onBeforeRender!==vr.prototype.onBeforeRender||e.onAfterRender!==vr.prototype.onAfterRender)}(e)}async initialize(t){if(!("gpu"in navigator))throw new Error("WebGPU is not available in this browser.");const r=t??await navigator.gpu.requestAdapter({powerPreference:this.powerPreference});if(!r)throw new Error("A WebGPU adapter could not be created.");const i=[];r.features.has("indirect-first-instance")&&i.push("indirect-first-instance"),r.features.has("timestamp-query")&&i.push("timestamp-query"),r.features.has("texture-compression-bc")&&i.push("texture-compression-bc"),r.features.has("texture-compression-etc2")&&i.push("texture-compression-etc2"),r.features.has("texture-compression-astc")&&i.push("texture-compression-astc"),r.features.has("float32-filterable")&&i.push("float32-filterable"),r.features.has(us)&&i.push(us);const o=r.limits;try{this.state.device=await r.requestDevice({requiredFeatures:i,requiredLimits:{maxTextureArrayLayers:o.maxTextureArrayLayers,maxBufferSize:o.maxBufferSize,maxStorageBufferBindingSize:o.maxStorageBufferBindingSize,maxStorageBuffersPerShaderStage:o.maxStorageBuffersPerShaderStage}})}catch(e){throw new Error("A WebGPU device could not be created.")}!function(t){if(e.has(t))return;const r={loading:!0,phase:"initializing",objects:new WeakMap,origins:new Map,descriptorOrigins:new WeakMap,history:new Map};e.set(t,r);for(const e of["createShaderModule","createBindGroupLayout","createPipelineLayout"]){const i=t[e];t[e]=function(s){const o=i.call(t,s);return r.objects.set(o,"createShaderModule"===e?{shaderHash:n(s.code),codeLength:s.code.length}:a(s,r)),o}}for(const e of["createRenderPipeline","createRenderPipelineAsync","createComputePipeline","createComputePipelineAsync"]){const i=t[e];"function"==typeof i&&(t[e]=function(n){const o=r.descriptorOrigins.get(n)??r.origins.get(n.label),l=(e.includes("Render")?"render":"compute")+":"+(o?.key??n.label??"unlabelled"),c=a(n,r),u=r.history.get(l)??[],d=JSON.stringify(c);let h;for(let e=u.length-1;e>=0;e--)if(u[e].signature===d){h=u[e];break}const p=h??u[u.length-1],f={signature:d,state:c,origin:o,label:n.label,phase:r.phase,status:"pending"},m=!r.loading;let g=0;m&&console.warn("[WebGPU pipeline] Created after loading",{method:e,label:n.label,phase:r.phase,origin:o,reason:"failed"===h?.status?"retry after a failed creation request":"pending"===h?.status?"identical descriptor requested while prior compilation is pending":h?"identical descriptor requested again; cache miss, eviction, or another owner":p?"new variant or changed shader/layout/render state":"first recorded pipeline for this origin",previous:p?{label:p.label,phase:p.phase,status:p.status,origin:p.origin}:null,changes:p?s(p.state,c):[],originChanges:p?s(p.origin,o):[],descriptor:c,stack:new Error("Pipeline creation request").stack,historyLimit:"last 16 requests per origin; up to 4096 origins"}),u.push(f),u.length>16&&u.shift(),r.history.size>=4096&&!r.history.has(l)&&r.history.delete(r.history.keys().next().value),r.history.set(l,u);const v=(t,r)=>{f.status=t,m&&console.info("[WebGPU pipeline] Creation result",{method:e,label:n.label,status:t,[e.endsWith("Async")?"readyAfterMs":"creationCallMs"]:performance.now()-g,error:r,timingMeaning:e.endsWith("Async")?"time until pipeline ready":"handle creation only; GPU compilation may stall at first use"})};g=performance.now();try{const r=i.call(t,n);return e.endsWith("Async")?r.then(e=>(v("ready"),e),e=>{throw v("failed",e),e}):(v("handle returned"),r)}catch(e){throw v("failed",e),e}})}}(this.state.device);let l=!1;if("function"==typeof this.state.device.addEventListener&&this.state.device.addEventListener("uncapturederror",e=>{l||(console.error("Uncaptured WebGPU device error",e.error.message,e.error),l=!0)}),this.state.device.lost.then(e=>{"destroyed"!==e.reason&&console.error("WebGPU device lost",e.reason,e.message)}),this.indirectFirstInstanceSupported=i.includes("indirect-first-instance"),this.timestampQuerySupported=i.includes("timestamp-query"),this.multiDrawIndirectSupported=i.includes(us),this.state.context=this.canvas.getContext("webgpu"),!this.state.context)throw new Error("The canvas does not provide a WebGPU context.");this.state.format=navigator.gpu.getPreferredCanvasFormat(),this.state.context.configure({device:this.state.device,format:this.state.format,alphaMode:"premultiplied"}),this.state.cameraBuffer=this.state.device.createBuffer({label:"renderer-camera-buffer",size:416,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.state.temporalVisibilityBuffer=this.state.device.createBuffer({label:"renderer-temporal-visibility-buffer",size:176,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.state.lightBuffer=this.state.device.createBuffer({label:"renderer-light-buffer",size:16016,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});const c=[];c.push(Ti.createAsync(this.state.device,this.state.cameraBuffer,this.state.lightBuffer).then(e=>{this.tiledPointLights=e,e.resize(this.state.width,this.state.height)})),this.state.shadowCameraBuffer=this.state.device.createBuffer({label:"renderer-shadow-camera-buffer",size:256,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.state.sceneBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-scene-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"comparison"}},{binding:4,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:5,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:6,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d-array"}},{binding:7,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:9,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}},{binding:11,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"uint",viewDimension:"2d"}}]}),this.state.directSceneBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-direct-scene-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:4,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"comparison"}},{binding:5,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:6,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:7,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d-array"}},{binding:8,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:10,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}},{binding:11,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"uint",viewDimension:"2d"}}]}),this.state.visibleSceneBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-visible-scene-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"comparison"}},{binding:4,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:5,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:6,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d-array"}},{binding:7,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:8,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:9,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}},{binding:11,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"uint",viewDimension:"2d"}}]}),this.state.visibleDepthSceneBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-visible-depth-scene-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),this.state.shadowBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-shadow-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),this.state.directShadowBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-direct-shadow-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),this.state.emptyBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-empty-layout",entries:[]}),this.state.skinningBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-skinning-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),this.state.sceneTextureBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-scene-texture-layout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"non-filtering"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth"}}]}),this.state.residentSceneBindGroupVersion+=1,this.state.residentShadowBindGroupVersion+=1,this.state.fullscreenTextureBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-fullscreen-texture-layout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}}]}),this.state.shadowComparisonSampler=this.state.device.createSampler({label:"renderer-shadow-comparison-sampler",compare:"less-equal",magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),this.transmissionSampler=this.state.device.createSampler({label:"physical-transmission-sampler",magFilter:"linear",minFilter:"linear",mipmapFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),this.state.linearClampSampler=this.state.device.createSampler({label:"renderer-linear-clamp-sampler",magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",addressModeW:"clamp-to-edge"}),this.state.nearestClampSampler=this.state.device.createSampler({label:"renderer-nearest-clamp-sampler",magFilter:"nearest",minFilter:"nearest",mipmapFilter:"nearest",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",addressModeW:"clamp-to-edge"}),c.push(j.createAsync(this.state.device,{label:"renderer-hiz-copy",code:"\n@group(0) @binding(0) var sourceDepth: texture_depth_2d;\n@group(0) @binding(1) var targetMip: texture_storage_2d<r32float, write>;\n\n@compute @workgroup_size(8, 8, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let dims = textureDimensions(targetMip);\n if (globalId.x >= dims.x || globalId.y >= dims.y) {\n return;\n }\n\n let depthValue = textureLoad(sourceDepth, vec2<i32>(globalId.xy), 0);\n textureStore(targetMip, vec2<i32>(globalId.xy), vec4(depthValue, 0.0, 0.0, 1.0));\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"depth"}},{binding:1,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"r32float"}}]}).then(e=>{this.state.hizCopyKernel=e})),c.push(j.createAsync(this.state.device,{label:"renderer-hiz-reduce",code:"\n@group(0) @binding(0) var sourceMip: texture_2d<f32>;\n@group(0) @binding(1) var targetMip: texture_storage_2d<r32float, write>;\n\nfn readSource(coord: vec2<i32>, dims: vec2<i32>) -> f32 {\n let clamped = clamp(coord, vec2(0, 0), dims - vec2(1, 1));\n return textureLoad(sourceMip, clamped, 0).r;\n}\n\n@compute @workgroup_size(8, 8, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let outDims = textureDimensions(targetMip);\n if (globalId.x >= outDims.x || globalId.y >= outDims.y) {\n return;\n }\n\n let srcOrigin = vec2<i32>(globalId.xy * 2u);\n let srcDims = vec2<i32>(textureDimensions(sourceMip));\n // This renderer uses conventional depth (near = 0, far = 1). Keep the\n // farthest depth in each footprint so an object is rejected only when the\n // whole footprint is covered by closer geometry. A min reduction would let\n // a single nearby texel occlude an otherwise visible object.\n var reduced = max(\n max(readSource(srcOrigin, srcDims), readSource(srcOrigin + vec2(1, 0), srcDims)),\n max(readSource(srcOrigin + vec2(0, 1), srcDims), readSource(srcOrigin + vec2(1, 1), srcDims))\n );\n\n // WebGPU mip dimensions round down. When a source dimension is odd, fold\n // its otherwise-unrepresented final row/column into the last destination\n // texel so no depth coverage disappears from the hierarchy.\n let hasExtraColumn = (srcDims.x & 1) != 0 && globalId.x + 1u == outDims.x;\n let hasExtraRow = (srcDims.y & 1) != 0 && globalId.y + 1u == outDims.y;\n if (hasExtraColumn) {\n reduced = max(reduced, readSource(srcOrigin + vec2(2, 0), srcDims));\n reduced = max(reduced, readSource(srcOrigin + vec2(2, 1), srcDims));\n }\n if (hasExtraRow) {\n reduced = max(reduced, readSource(srcOrigin + vec2(0, 2), srcDims));\n reduced = max(reduced, readSource(srcOrigin + vec2(1, 2), srcDims));\n }\n if (hasExtraColumn && hasExtraRow) {\n reduced = max(reduced, readSource(srcOrigin + vec2(2, 2), srcDims));\n }\n\n textureStore(targetMip, vec2<i32>(globalId.xy), vec4(reduced, 0.0, 0.0, 1.0));\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:1,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"r32float"}}]}).then(e=>{this.state.hizReduceKernel=e})),c.push(j.createAsync(this.state.device,{label:"renderer-visibility-cull",code:"\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\nstruct RendererVisibilityParams {\n drawCount: u32,\n hizMipCount: u32,\n reserved0: u32,\n reserved1: u32,\n};\n\nstruct DrawMetadata {\n centerRadius: vec4<f32>,\n args0: vec4<f32>,\n extra: vec4<f32>,\n};\n\nstruct IndirectIndexedArgs {\n indexCount: u32,\n instanceCount: u32,\n firstIndex: u32,\n baseVertex: i32,\n firstInstance: u32,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> visibilityParams: RendererVisibilityParams;\n@group(0) @binding(2) var drawMetaTextureSampler: sampler;\n@group(0) @binding(3) var hizTexture: texture_2d<f32>;\n@group(0) @binding(4) var<storage, read> drawMetadata: array<DrawMetadata>;\n@group(0) @binding(5) var<storage, read_write> indirectArgs: array<IndirectIndexedArgs>;\n\nfn saturate(value: f32) -> f32 {\n return clamp(value, 0.0, 1.0);\n}\n\nfn projectedSphereRadius(\n viewProj: mat4x4<f32>,\n ndc: vec3<f32>,\n clipW: f32,\n radius: f32,\n) -> vec2<f32> {\n // Account for both numerator and perspective-denominator variation over the\n // sphere. Offsetting along world X/Y is not conservative once the camera is\n // rotated because those axes can also change clip W.\n let rowX = vec3(viewProj[0].x, viewProj[1].x, viewProj[2].x);\n let rowY = vec3(viewProj[0].y, viewProj[1].y, viewProj[2].y);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let denominator = max(clipW - radius * length(rowW), 0.0001);\n return radius * vec2(\n length(rowX) + abs(ndc.x) * length(rowW),\n length(rowY) + abs(ndc.y) * length(rowW),\n ) / denominator;\n}\n\nfn spherePlaneRadius(viewProj: mat4x4<f32>, plane: vec4<f32>, radius: f32) -> f32 {\n let worldNormal = vec3(\n dot(viewProj[0], plane),\n dot(viewProj[1], plane),\n dot(viewProj[2], plane),\n );\n return radius * length(worldNormal);\n}\n\nfn isSphereInFrustum(viewProj: mat4x4<f32>, center: vec3<f32>, radius: f32) -> bool {\n let clip = viewProj * vec4(center, 1.0);\n return\n clip.w + clip.x >= -spherePlaneRadius(viewProj, vec4( 1.0, 0.0, 0.0, 1.0), radius) &&\n clip.w - clip.x >= -spherePlaneRadius(viewProj, vec4(-1.0, 0.0, 0.0, 1.0), radius) &&\n clip.w + clip.y >= -spherePlaneRadius(viewProj, vec4( 0.0, 1.0, 0.0, 1.0), radius) &&\n clip.w - clip.y >= -spherePlaneRadius(viewProj, vec4( 0.0, -1.0, 0.0, 1.0), radius) &&\n clip.z >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, 1.0, 0.0), radius) &&\n clip.w - clip.z >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, -1.0, 1.0), radius);\n}\n\nfn nearestSphereDepth(viewProj: mat4x4<f32>, clip: vec4<f32>, radius: f32) -> f32 {\n let rowZ = vec3(viewProj[0].z, viewProj[1].z, viewProj[2].z);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let minClipZ = clip.z - radius * length(rowZ);\n let maxClipW = clip.w + radius * length(rowW);\n return max(0.0, minClipZ / max(maxClipW, 0.0001));\n}\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let drawIndex = globalId.x;\n if (drawIndex >= visibilityParams.drawCount) {\n return;\n }\n\n let drawData = drawMetadata[drawIndex];\n let center = vec4(drawData.centerRadius.xyz, 1.0);\n let radius = drawData.centerRadius.w;\n var visible = isSphereInFrustum(\n rendererCamera.viewProj,\n drawData.centerRadius.xyz,\n radius,\n );\n\n let clip = rendererCamera.viewProj * center;\n let cameraDistance = distance(drawData.centerRadius.xyz, rendererCamera.cameraPosition.xyz);\n // A sphere that intersects the near plane, surrounds the camera, or has a\n // very large projected extent cannot be safely represented by its center.\n // Keep it rather than allowing a false negative to remove large terrain or\n // nearby geometry.\n let clipWRadius = radius * length(vec3(\n rendererCamera.viewProj[0].w,\n rendererCamera.viewProj[1].w,\n rendererCamera.viewProj[2].w,\n ));\n let needsConservativeVisibility =\n clip.w - clipWRadius <= 0.0001 || radius >= cameraDistance * 0.1;\n\n if (!needsConservativeVisibility) {\n let ndc = clip.xyz / clip.w;\n let projectedRadius = projectedSphereRadius(rendererCamera.viewProj, ndc, clip.w, radius);\n let clipRadiusX = projectedRadius.x;\n let clipRadiusY = projectedRadius.y;\n\n if (\n visible &&\n ndc.x - clipRadiusX >= -1.0 && ndc.x + clipRadiusX <= 1.0 &&\n ndc.y - clipRadiusY >= -1.0 && ndc.y + clipRadiusY <= 1.0\n ) {\n let uvCenter = ndc.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n let uvRadius = vec2(clipRadiusX, clipRadiusY) * 0.5;\n let viewport = rendererCamera.viewportAndTime.xy;\n let screenDiameter = max(\n max(clipRadiusX * viewport.x * 0.5, clipRadiusY * viewport.y * 0.5),\n 1.0,\n ) * 2.0;\n let maxMipLevel = max(f32(visibilityParams.hizMipCount) - 1.0, 0.0);\n // Round up from the full diameter. Using floor(log2(radius)) leaves\n // unsampled texels between the corner probes, especially for small\n // objects, and can turn partial coverage into a false occlusion.\n let mipLevel = clamp(ceil(log2(screenDiameter)), 0.0, maxMipLevel);\n // Cover the projected bounds rather than testing only their center. The\n // max-reduced pyramid makes background or a gap at any corner retain the\n // draw, avoiding false occlusion for partially covered objects.\n let hizDepth = max(\n max(\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2(-uvRadius.x, -uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2( uvRadius.x, -uvRadius.y), mipLevel).r,\n ),\n max(\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2(-uvRadius.x, uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2( uvRadius.x, uvRadius.y), mipLevel).r,\n ),\n );\n let conservativeDepth = nearestSphereDepth(rendererCamera.viewProj, clip, radius);\n visible = conservativeDepth <= hizDepth + 0.0005;\n }\n }\n\n let baseVertex = i32(round(drawData.extra.y));\n indirectArgs[drawIndex].indexCount = u32(round(drawData.args0.x));\n indirectArgs[drawIndex].instanceCount = select(0u, u32(round(drawData.args0.w)), visible);\n indirectArgs[drawIndex].firstIndex = u32(round(drawData.args0.y));\n indirectArgs[drawIndex].baseVertex = baseVertex;\n indirectArgs[drawIndex].firstInstance = u32(round(drawData.args0.z));\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.COMPUTE,sampler:{type:"non-filtering"}},{binding:3,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:5,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}).then(e=>{this.state.visibilityKernel=e})),c.push(j.createAsync(this.state.device,{label:"renderer-static-visibility-clear",code:"\nstruct RendererVisibilityParams {\n drawCount: u32,\n hizMipCount: u32,\n instanceCount: u32,\n flags: u32,\n};\n\n@group(0) @binding(0) var<uniform> visibilityParams: RendererVisibilityParams;\n@group(0) @binding(1) var<storage, read_write> visibleCounts: array<atomic<u32>>;\n@group(0) @binding(2) var<storage, read_write> postVisibleCounts: array<atomic<u32>>;\n@group(0) @binding(3) var<storage, read_write> visibleInstanceMask: array<atomic<u32>>;\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let index = globalId.x;\n if (index < visibilityParams.drawCount) {\n atomicStore(&visibleCounts[index], 0u);\n atomicStore(&postVisibleCounts[index], 0u);\n }\n if (index < visibilityParams.instanceCount) {\n // Bit 2 is persistent detail hysteresis; bit 0 is frame-local visibility.\n atomicStore(&visibleInstanceMask[index], atomicLoad(&visibleInstanceMask[index]) & 4u);\n }\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}).then(e=>{this.state.staticVisibilityClearKernel=e})),c.push(j.createAsync(this.state.device,{label:"renderer-static-visibility-cull",code:"\nstruct RendererTemporalVisibilityUniforms {\n currentViewProj: mat4x4<f32>,\n previousViewProj: mat4x4<f32>,\n currentCameraPosition: vec4<f32>,\n previousCameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\nstruct RendererVisibilityParams {\n drawCount: u32,\n hizMipCount: u32,\n instanceCount: u32,\n flags: u32,\n};\n\nstruct DrawMetadata {\n centerRadius: vec4<f32>,\n args0: vec4<f32>,\n extra: vec4<f32>,\n};\n\nstruct StaticInstanceMetadata {\n centerRadius: vec4<f32>,\n drawAndSourceIndex: vec4<u32>,\n};\n\n@group(0) @binding(0) var<uniform> temporalVisibility: RendererTemporalVisibilityUniforms;\n@group(0) @binding(1) var<uniform> visibilityParams: RendererVisibilityParams;\n@group(0) @binding(2) var hizSampler: sampler;\n@group(0) @binding(3) var hizTexture: texture_2d<f32>;\n@group(0) @binding(4) var<storage, read> instanceMetadata: array<StaticInstanceMetadata>;\n@group(0) @binding(5) var<storage, read> drawMetadata: array<DrawMetadata>;\n@group(0) @binding(6) var<storage, read_write> visibleCounts: array<atomic<u32>>;\n@group(0) @binding(7) var<storage, read_write> visibleInstanceIndices: array<u32>;\n@group(0) @binding(8) var<storage, read_write> visibleInstanceMask: array<atomic<u32>>;\n@group(0) @binding(9) var<storage, read_write> postVisibleCounts: array<atomic<u32>>;\n\nfn spherePlaneRadius(viewProj: mat4x4<f32>, plane: vec4<f32>, radius: f32) -> f32 {\n let worldNormal = vec3(\n dot(viewProj[0], plane),\n dot(viewProj[1], plane),\n dot(viewProj[2], plane),\n );\n return radius * length(worldNormal);\n}\n\nfn projectedSphereRadius(\n viewProj: mat4x4<f32>,\n ndc: vec3<f32>,\n clipW: f32,\n radius: f32,\n) -> vec2<f32> {\n let rowX = vec3(viewProj[0].x, viewProj[1].x, viewProj[2].x);\n let rowY = vec3(viewProj[0].y, viewProj[1].y, viewProj[2].y);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let denominator = max(clipW - radius * length(rowW), 0.0001);\n return radius * vec2(\n length(rowX) + abs(ndc.x) * length(rowW),\n length(rowY) + abs(ndc.y) * length(rowW),\n ) / denominator;\n}\n\nfn nearestSphereDepth(viewProj: mat4x4<f32>, clip: vec4<f32>, radius: f32) -> f32 {\n let rowZ = vec3(viewProj[0].z, viewProj[1].z, viewProj[2].z);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let minClipZ = clip.z - radius * length(rowZ);\n let maxClipW = clip.w + radius * length(rowW);\n return max(0.0, minClipZ / max(maxClipW, 0.0001));\n}\n\nfn isSphereInFrustum(\n viewProj: mat4x4<f32>,\n center: vec3<f32>,\n radius: f32,\n) -> bool {\n let clip = viewProj * vec4(center, 1.0);\n let left = clip.w + clip.x;\n let right = clip.w - clip.x;\n let bottom = clip.w + clip.y;\n let top = clip.w - clip.y;\n let near = clip.z;\n let far = clip.w - clip.z;\n\n return\n left >= -spherePlaneRadius(viewProj, vec4(1.0, 0.0, 0.0, 1.0), radius) &&\n right >= -spherePlaneRadius(viewProj, vec4(-1.0, 0.0, 0.0, 1.0), radius) &&\n bottom >= -spherePlaneRadius(viewProj, vec4(0.0, 1.0, 0.0, 1.0), radius) &&\n top >= -spherePlaneRadius(viewProj, vec4(0.0, -1.0, 0.0, 1.0), radius) &&\n near >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, 1.0, 0.0), radius) &&\n far >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, -1.0, 1.0), radius);\n}\n\nfn isSphereNearFrustumBoundary(\n viewProj: mat4x4<f32>,\n center: vec3<f32>,\n radius: f32,\n) -> bool {\n let clip = viewProj * vec4(center, 1.0);\n return\n clip.w + clip.x <= spherePlaneRadius(viewProj, vec4(1.0, 0.0, 0.0, 1.0), radius) ||\n clip.w - clip.x <= spherePlaneRadius(viewProj, vec4(-1.0, 0.0, 0.0, 1.0), radius) ||\n clip.w + clip.y <= spherePlaneRadius(viewProj, vec4(0.0, 1.0, 0.0, 1.0), radius) ||\n clip.w - clip.y <= spherePlaneRadius(viewProj, vec4(0.0, -1.0, 0.0, 1.0), radius) ||\n clip.z <= spherePlaneRadius(viewProj, vec4(0.0, 0.0, 1.0, 0.0), radius) ||\n clip.w - clip.z <= spherePlaneRadius(viewProj, vec4(0.0, 0.0, -1.0, 1.0), radius);\n}\n\nfn isSphereVisible(center: vec3<f32>, radius: f32) -> bool {\n let currentViewProj = temporalVisibility.currentViewProj;\n if (!isSphereInFrustum(currentViewProj, center, radius)) {\n return false;\n }\n\n let clip = currentViewProj * vec4(center, 1.0);\n // Near-plane intersections are deliberately kept. A false negative here would\n // incorrectly remove geometry surrounding the camera.\n if (clip.w <= 0.0001) {\n return true;\n }\n\n if ((visibilityParams.flags & 1u) == 0u) {\n return true;\n }\n\n let usesPreviousHiZ = (visibilityParams.flags & 2u) != 0u;\n var hizViewProj = temporalVisibility.currentViewProj;\n var hizCameraPosition = temporalVisibility.currentCameraPosition.xyz;\n if (usesPreviousHiZ) {\n hizViewProj = temporalVisibility.previousViewProj;\n hizCameraPosition = temporalVisibility.previousCameraPosition.xyz;\n }\n\n let hizClip = hizViewProj * vec4(center, 1.0);\n let hizClipWRadius = radius * length(vec3(\n hizViewProj[0].w,\n hizViewProj[1].w,\n hizViewProj[2].w,\n ));\n if (hizClip.w - hizClipWRadius <= 0.0001) {\n return true;\n }\n let hizNdc = hizClip.xyz / hizClip.w;\n let hizProjectedRadius = projectedSphereRadius(\n hizViewProj,\n hizNdc,\n hizClip.w,\n radius,\n );\n let hizClipRadiusX = hizProjectedRadius.x;\n let hizClipRadiusY = hizProjectedRadius.y;\n let hizClipRadiusZ = radius / max(distance(center, hizCameraPosition), 0.001);\n\n // Samples close to the viewport boundary cannot cover the whole projected\n // sphere. This also retains newly revealed regions during camera motion.\n if (\n isSphereNearFrustumBoundary(hizViewProj, center, radius) ||\n hizNdc.x - hizClipRadiusX < -1.0 || hizNdc.x + hizClipRadiusX > 1.0 ||\n hizNdc.y - hizClipRadiusY < -1.0 || hizNdc.y + hizClipRadiusY > 1.0 ||\n hizNdc.z < -hizClipRadiusZ || hizNdc.z > 1.0 + hizClipRadiusZ\n ) {\n return true;\n }\n\n let viewport = temporalVisibility.viewportAndTime.xy;\n let screenDiameter = max(\n max(hizClipRadiusX * viewport.x * 0.5, hizClipRadiusY * viewport.y * 0.5),\n 1.0,\n ) * 2.0;\n let maxMipLevel = max(f32(visibilityParams.hizMipCount) - 1.0, 0.0);\n let mipLevel = clamp(ceil(log2(screenDiameter)), 0.0, maxMipLevel);\n let uvCenter = hizNdc.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n let uvRadius = vec2(hizClipRadiusX, hizClipRadiusY) * 0.5;\n let hizDepth = max(\n max(\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2(-uvRadius.x, -uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2( uvRadius.x, -uvRadius.y), mipLevel).r,\n ),\n max(\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2(-uvRadius.x, uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2( uvRadius.x, uvRadius.y), mipLevel).r,\n ),\n );\n let conservativeNearestDepth = nearestSphereDepth(hizViewProj, hizClip, radius);\n return conservativeNearestDepth <= hizDepth + 0.001;\n}\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let instanceIndex = globalId.x;\n if (instanceIndex >= visibilityParams.instanceCount) {\n return;\n }\n\n let instance = instanceMetadata[instanceIndex];\n if ((visibilityParams.flags & 4u) != 0u && (atomicLoad(&visibleInstanceMask[instanceIndex]) & 1u) != 0u) {\n return;\n }\n let drawIndex = instance.drawAndSourceIndex.x;\n let threshold = bitcast<f32>(instance.drawAndSourceIndex.z);\n let maxDistance = bitcast<f32>(instance.drawAndSourceIndex.w);\n let center = instance.centerRadius.xyz;\n let radius = instance.centerRadius.w;\n if (maxDistance > 0.0 && distance(center, temporalVisibility.currentCameraPosition.xyz) - radius > maxDistance) {\n return;\n }\n if (threshold > 0.0) {\n let vp = temporalVisibility.currentViewProj;\n let clip = vp * vec4(center, 1.0);\n let wRadius = radius * length(vec3(vp[0].w, vp[1].w, vp[2].w));\n if (clip.w - wRadius > 0.0001) {\n let projected = projectedSphereRadius(vp, clip.xyz / clip.w, clip.w, radius);\n let diameter = max(projected.x * temporalVisibility.viewportAndTime.x, projected.y * temporalVisibility.viewportAndTime.y);\n let wasDetailed = (atomicLoad(&visibleInstanceMask[instanceIndex]) & 4u) != 0u;\n let boundary = threshold * select(1.15, 0.85, wasDetailed);\n if (diameter < boundary) {\n atomicAnd(&visibleInstanceMask[instanceIndex], ~4u);\n return;\n }\n }\n }\n atomicOr(&visibleInstanceMask[instanceIndex], 4u);\n if (drawIndex >= visibilityParams.drawCount || !isSphereVisible(instance.centerRadius.xyz, instance.centerRadius.w)) {\n return;\n }\n\n let isPostpass = (visibilityParams.flags & 4u) != 0u;\n if (!isPostpass) {\n atomicOr(&visibleInstanceMask[instanceIndex], 1u);\n }\n let firstInstance = u32(round(drawMetadata[drawIndex].args0.z));\n if (isPostpass) {\n let primaryVisibleCount = atomicLoad(&visibleCounts[drawIndex]);\n let postVisibleIndex = atomicAdd(&postVisibleCounts[drawIndex], 1u);\n visibleInstanceIndices[firstInstance + primaryVisibleCount + postVisibleIndex] = instance.drawAndSourceIndex.y;\n } else {\n let visibleIndex = atomicAdd(&visibleCounts[drawIndex], 1u);\n visibleInstanceIndices[firstInstance + visibleIndex] = instance.drawAndSourceIndex.y;\n }\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.COMPUTE,sampler:{type:"non-filtering"}},{binding:3,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:5,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:6,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:7,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:8,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:9,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}).then(e=>{this.state.staticVisibilityCullKernel=e})),c.push(j.createAsync(this.state.device,{label:"renderer-static-visibility-indirect-build",code:"\nstruct RendererVisibilityParams {\n drawCount: u32,\n hizMipCount: u32,\n instanceCount: u32,\n flags: u32,\n};\n\nstruct IndirectIndexedArgs {\n indexCount: u32,\n instanceCount: u32,\n firstIndex: u32,\n baseVertex: i32,\n firstInstance: u32,\n};\n\n@group(0) @binding(0) var<uniform> visibilityParams: RendererVisibilityParams;\n@group(0) @binding(1) var<storage, read_write> visibleCounts: array<atomic<u32>>;\n@group(0) @binding(2) var<storage, read_write> postVisibleCounts: array<atomic<u32>>;\n@group(0) @binding(3) var<storage, read_write> indirectArgs: array<IndirectIndexedArgs>;\n@group(0) @binding(4) var<storage, read_write> postIndirectArgs: array<IndirectIndexedArgs>;\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let drawIndex = globalId.x;\n if (drawIndex >= visibilityParams.drawCount) {\n return;\n }\n\n let primaryVisibleCount = atomicLoad(&visibleCounts[drawIndex]);\n let postVisibleCount = atomicLoad(&postVisibleCounts[drawIndex]);\n indirectArgs[drawIndex].instanceCount = primaryVisibleCount + postVisibleCount;\n if ((visibilityParams.flags & 4u) != 0u) {\n postIndirectArgs[drawIndex].instanceCount = postVisibleCount;\n postIndirectArgs[drawIndex].firstInstance = indirectArgs[drawIndex].firstInstance + primaryVisibleCount;\n }\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}).then(e=>{this.state.staticVisibilityIndirectBuildKernel=e})),this.state.visibilityParamsBuffer=this.state.device.createBuffer({label:"renderer-visibility-params-buffer",size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),c.push(this.createStaticPipelines()),await Promise.all(c),this.setSize(this.canvas.clientWidth||this.canvas.width||1,this.canvas.clientHeight||this.canvas.height||1),this.state.initialized=!0}createComputeKernel(e){if(!this.state.device)throw new Error("WebGpuRenderer.initialize() must complete before creating compute kernels.");return new j(this.state.device,e)}getDevice(){return this.state.device??null}setRenderGraphBuilder(e){this.graphBuilder=e}setCascadedShadowRanges(e,t=[]){this.csmCascadeCount=Math.min(e.length,4),this.csmCascadeLights=t.slice(0,this.csmCascadeCount);for(let t=0;t<this.csmCascadeCount;t+=1)this.csmCascadeRanges[t].set(e[t].x,e[t].y);for(let e=this.csmCascadeCount;e<4;e+=1)this.csmCascadeRanges[e].set(0,0)}setDirectionalShadowMapSize(e){const t=Math.max(1,Math.floor(e));t!==this.shadowMapSize&&(this.shadowMapSize=t,t!==this.state.directionalShadowTextureSize&&(this.state.directionalShadowTextureSize=t,this.recreateDirectionalShadowResources()))}setDirectionalShadowUpdateOptions(e){this.directionalShadowScheduler.setOptions(e)}invalidateDirectionalShadows(){this.directionalShadowScheduler.invalidate()}setDirectionalShadowsEnabled(e){this.directionalShadowsEnabled=e}setRenderGraphProfilingEnabled(e){this.renderGraphProfilingEnabled=e}getRenderGraphProfilingEnabled(){return this.renderGraphProfilingEnabled}getTimestampQuerySupported(){return this.timestampQuerySupported}getSampleCount(){return this.sampleCount}setSampleCount(e){const t=Si(e);t!==this.sampleCount&&(this.sampleCount=t,this.destroyMsaaResources(),this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches())}setRenderScale(e){const t=gs(e);if(t===this.renderScale)return;this.renderScale=t;const r=this.state.pixelRatio;this.setSize(this.state.presentationWidth/r,this.state.presentationHeight/r,r)}getRenderScale(){return this.renderScale}setProjectionJitter(e,t){if(!Number.isFinite(e)||!Number.isFinite(t))throw new RangeError("Projection jitter must contain finite pixel offsets.");this.projectionJitterPixels.set(e,t)}clearProjectionJitter(){this.projectionJitterPixels.set(0,0)}setMotionVectorProjection(e){this.motionVectorProjection.copy(e),this.motionVectorProjectionPending=!0}invalidateObjectMotion(e){this.objectMotionHistory.delete(e)}getLastFrameProfile(){const e=this.state.latestFrameProfile?.timestampQueryActive&&null===this.state.latestFrameProfile.gpuTimeMs&&this.state.latestCompletedFrameProfile?this.state.latestCompletedFrameProfile:this.state.latestFrameProfile;return e?{...e,cpuPhases:{...e.cpuPhases},passes:e.passes.map(e=>({...e})),visibility:e.visibility?{...e.visibility}:null}:null}resetViewHistory(){this.state.temporalHiZHistoryValid=!1,this.motionVectorHistoryValid=!1,this.motionVectorHistoryGeneration+=1}setHiZOcclusionCullingEnabled(e){this.hiZOcclusionCullingEnabled!==e&&(this.state.temporalHiZHistoryValid=!1),this.hiZOcclusionCullingEnabled=e}getHiZOcclusionCullingEnabled(){return this.hiZOcclusionCullingEnabled}getHiZOcclusionCullingActive(){return this.hiZOcclusionCullingEnabled&&this.indirectFirstInstanceSupported}setMultiDrawIndirectEnabled(e){this.multiDrawIndirectEnabled=e}getMultiDrawIndirectEnabled(){return this.multiDrawIndirectEnabled}setTiledLightingEnabled(e){this.tiledLightingEnabled=e}setDynamicBatchingEnabled(e){this.dynamicBatchingEnabled=e}getDynamicBatchingEnabled(){return this.dynamicBatchingEnabled}getMultiDrawIndirectSupported(){return this.multiDrawIndirectSupported}getMultiDrawIndirectActive(){return this.multiDrawIndirectEnabled&&this.multiDrawIndirectSupported&&this.getHiZOcclusionCullingActive()}setSize(e,t,r=window.devicePixelRatio||1){if(this.state.pixelRatio=r,this.state.presentationWidth=Math.max(1,Math.floor(e*r)),this.state.presentationHeight=Math.max(1,Math.floor(t*r)),this.state.width=Math.max(1,Math.floor(this.state.presentationWidth*this.renderScale)),this.state.height=Math.max(1,Math.floor(this.state.presentationHeight*this.renderScale)),this.canvas.width=this.state.presentationWidth,this.canvas.height=this.state.presentationHeight,this.canvas.style.width=`${Math.max(1,Math.floor(e))}px`,this.canvas.style.height=`${Math.max(1,Math.floor(t))}px`,this.state.device){for(const[e,t]of this.colorTargetCache){const r="presentation"===t.resolution?this.state.presentationWidth:this.state.width,i="presentation"===t.resolution?this.state.presentationHeight:this.state.height,n=Math.max(1,Math.floor(r*t.scale)),a=Math.max(1,Math.floor(i*t.scale));t.width===n&&t.height===a||(t.texture.destroy(),this.colorTargetCache.delete(e))}this.destroyMsaaResources(),this.state.mainDepthTexture?.destroy(),this.state.mainDepthTexture=this.state.device.createTexture({label:"renderer-main-depth",size:{width:this.state.width,height:this.state.height},format:"depth32float",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),this.state.mainDepthView=this.state.mainDepthTexture.createView(),this.state.hizCopyBindGroup=null,this.state.sceneColorTexture?.destroy(),this.state.sceneColorTexture=this.state.device.createTexture({label:"renderer-scene-color",size:{width:this.state.width,height:this.state.height},format:C,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),this.state.sceneColorView=this.state.sceneColorTexture.createView(),this.state.sceneColorSnapshotTexture?.destroy(),this.state.sceneColorSnapshotTexture=this.state.device.createTexture({label:"renderer-scene-color-snapshot",size:{width:this.state.width,height:this.state.height},format:P,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),this.state.sceneColorSnapshotView=this.state.sceneColorSnapshotTexture.createView(),this.state.sceneDepthSnapshotTexture?.destroy(),this.state.sceneDepthSnapshotTexture=this.state.device.createTexture({label:"renderer-scene-depth-snapshot",size:{width:this.state.width,height:this.state.height},format:"depth32float",usage:GPUTextureUsage.COPY_DST|GPUTextureUsage.TEXTURE_BINDING}),this.state.sceneDepthSnapshotView=this.state.sceneDepthSnapshotTexture.createView(),this.state.postProcessColorTexture?.destroy(),this.state.postProcessColorTexture=this.state.device.createTexture({label:"renderer-post-process-color",size:{width:this.state.width,height:this.state.height},format:C,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),this.state.postProcessColorView=this.state.postProcessColorTexture.createView(),this.state.sceneTextureBindGroupLayout&&this.state.linearClampSampler&&this.state.nearestClampSampler&&(this.state.sceneTextureBindGroup=this.state.device.createBindGroup({label:"renderer-scene-texture-bind-group",layout:this.state.sceneTextureBindGroupLayout,entries:[{binding:0,resource:this.state.linearClampSampler},{binding:1,resource:this.state.sceneColorSnapshotView},{binding:2,resource:this.state.nearestClampSampler},{binding:3,resource:this.state.sceneDepthSnapshotView}]})),this.state.hizTexture?.destroy(),this.state.hizMipCount=Math.max(1,Math.floor(Math.log2(Math.max(this.state.width,this.state.height)))+1),this.state.hizTexture=this.state.device.createTexture({label:"renderer-hiz-pyramid",size:{width:this.state.width,height:this.state.height},format:"r32float",mipLevelCount:this.state.hizMipCount,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING}),this.state.hizView=this.state.hizTexture.createView(),this.state.hizMipViews=[],this.state.hizCopyBindGroup=null,this.state.hizReduceBindGroups=[],this.state.visibilityBindGroup=null,this.state.visibilityBindGroupMetadataResource=null;for(let e=0;e<this.state.hizMipCount;e+=1)this.state.hizMipViews.push(this.state.hizTexture.createView({baseMipLevel:e,mipLevelCount:1}));this.hizResourceVersion+=1,this.graphTextureResourceVersion+=1,this.state.temporalHiZHistoryValid=!1,this.motionVectorHistoryValid=!1,this.motionVectorHistoryGeneration+=1;for(const e of this.staticDrawSets)e.visibilityBindGroup=null,e.postVisibilityBindGroup=null,e.visibilityBindGroupHizVersion=0;this.recreateShadowResources()}}setClearColor(e){this.clearColor[0]=e[0],this.clearColor[1]=e[1],this.clearColor[2]=e[2],this.clearColor[3]=e[3]}render(e,t,r=.001*performance.now()){this.renderFrame(e,t,r,!1)}async renderAsync(e,t,r=.001*performance.now()){await this.renderFrame(e,t,r,!0)}compile(e,t){this.prepareSceneForCompilation(e,t,!1)}async compileAsync(e,t){this.state.initialized||await this.initialize();const r={startedAt:performance.now(),preparationMs:0,phases:{},drawCount:0,materialRequestCount:0,cpuTotalsMs:{},slowTextureLookups:[],pipelines:[]};this.pipelineCompilationDiagnostics=r;try{const i=this.prepareSceneForCompilation(e,t,!0);r.preparationMs=performance.now()-r.startedAt,await i}finally{this.pipelineCompilationDiagnostics===r&&(this.pipelineCompilationDiagnostics=void 0);const e=performance.now()-r.startedAt,t=r.pipelines,i=[...t].sort((e,t)=>t.durationMs-e.durationMs).slice(0,12);console.info("[WebGPU] Scene compilation",{elapsedMs:Math.round(e),preparationMs:Math.round(r.preparationMs),phasesMs:r.phases,drawCount:r.drawCount,materialRequestCount:r.materialRequestCount,cpuTotalsMs:Object.fromEntries(Object.entries(r.cpuTotalsMs).map(([e,t])=>[e,Math.round(t)])),slowTextureLookups:r.slowTextureLookups.sort((e,t)=>t.durationMs-e.durationMs).slice(0,12).map(e=>({...e,durationMs:Math.round(e.durationMs)})),pipelineCount:t.length,forwardCount:t.filter(e=>"forward"===e.kind).length,depthCount:t.filter(e=>"depth"===e.kind).length,slowestPipelines:i.map(e=>({kind:e.kind,material:e.material,durationMs:Math.round(e.durationMs),vertexCodeLength:e.vertexCodeLength,fragmentCodeLength:e.fragmentCodeLength}))})}}createPMREMGenerator(e=20){if(!this.state.device)throw new Error("WebGpuRenderer.initialize() must complete before creating a PMREM generator.");return new In({device:this.state.device,getTextureResource:e=>this.getTextureResource(e),registerTextureResource:(e,t)=>this.textureCache.set(e,t)},e)}initTexture(e){this.textureManager.getTextureResource(e)}createStaticDrawSet(e,t={}){return this.staticDrawSetManager.createStaticDrawSet(e,t)}disposeStaticDrawSetResource(e){this.staticDrawSetManager.disposeStaticDrawSetResource(e)}renderFrame(e,t,r,i){if(!(this.state.initialized&&this.state.device&&this.state.context&&this.state.mainDepthView&&this.state.sceneColorView&&this.state.postProcessColorView&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.shadowCameraBuffer&&this.state.sceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.shadowComparisonSampler&&this.state.linearClampSampler&&this.state.nearestClampSampler&&this.state.visibilityParamsBuffer&&this.state.directionalShadowView&&this.state.pointShadowArrayView&&this.state.spotShadowView&&this.state.hizCopyKernel&&this.state.hizReduceKernel&&this.state.visibilityKernel&&this.state.presentPipeline))throw new Error("WebGpuRenderer.initialize() must complete before render().");const n=r-this.lastMotionVectorTimeSeconds;Number.isFinite(this.lastMotionVectorTimeSeconds)&&(!Number.isFinite(n)||n<=0||n>.25)&&(this.motionVectorHistoryValid=!1,this.motionVectorHistoryGeneration+=1),this.lastMotionVectorTimeSeconds=r,this.state.frameTimeSeconds=r,this.staticFrameToken+=1,e.matrixWorldAutoUpdate&&e.updateMatrixWorld(),null===t.parent&&t.matrixWorldAutoUpdate&&t.updateMatrixWorld(),this.opaqueSortMs=0;const a=performance.now(),s=this.extractScene(e,t);for(const e of s.gpuOpaqueDraws)this.prepareDrawGeometryVertexBuffers(e);for(const e of s.directOpaqueDraws)this.prepareDrawGeometryVertexBuffers(e);for(const e of s.transparentDraws)this.prepareDrawGeometryVertexBuffers(e);this.ensureShadowTextureSizes(s);const o=performance.now()-a;this.renderGraphProfilingEnabled&&(this.opaqueSortSampleTotal-=this.opaqueSortSamples[this.opaqueSortSampleIndex],this.opaqueSortSamples[this.opaqueSortSampleIndex]=this.opaqueSortMs,this.opaqueSortSampleTotal+=this.opaqueSortMs,this.opaqueSortSampleIndex=(this.opaqueSortSampleIndex+1)%this.opaqueSortSamples.length,this.opaqueSortSampleCount=Math.min(this.opaqueSortSampleCount+1,this.opaqueSortSamples.length));const l={drawCallCount:0,triangleCount:0},c=performance.now();this.uploadInstanceData(s.instanceData),this.uploadResidentInstanceData(s.residentInstanceUploads);const u=this.getHiZOcclusionCullingActive();this.uploadDrawMetadata(u?s.gpuOpaqueDraws:[]),this.ensureTiledLightingSize(),this.updateCameraUniforms(t,e),this.updateTemporalVisibilityUniforms(t),this.updateLightUniforms(s);const d=performance.now()-c,h=this.state.device.createCommandEncoder({label:"renderer-command-encoder"}),p=this.state.context.getCurrentTexture().createView(),f=this.getSharedSceneBindGroup(),m=this.getSharedShadowBindGroup();let g=null;const v=this.state.drawMetadataResource;u&&v&&v.count>0&&this.state.hizView&&(this.state.visibilityBindGroup&&this.state.visibilityBindGroupMetadataResource===v||(this.state.visibilityBindGroup=this.state.visibilityKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:1,resource:{buffer:this.state.visibilityParamsBuffer}},{binding:2,resource:this.state.nearestClampSampler},{binding:3,resource:this.state.hizView},{binding:4,resource:{buffer:v.metadataBuffer}},{binding:5,resource:{buffer:v.indirectBuffer}}],"renderer-visibility-bind-group"),this.state.visibilityBindGroupMetadataResource=v),g=this.state.visibilityBindGroup),this.renderGraph.reset();const x=this.createGraphBuilderContext(this.renderGraph,h,f,m,g,p,s,l);this.graphBuilder(this.renderGraph,x);const w={device:this.state.device,encoder:h},b=function(e,t,r,i,n){if(!t.renderGraphProfilingEnabled||!e.device)return null;const a={frameIndex:e.frameIndex+=1,cpuTimeMs:0,gpuTimeMs:null,drawCallCount:i.drawCallCount,triangleCount:i.triangleCount,cpuPhases:{extractSceneMs:n.extractSceneMs,opaqueSortMs:n.opaqueSortMs,opaqueSortAverageMs:n.opaqueSortAverageMs,uploadMs:n.uploadMs,renderGraphMs:0},passes:[],timestampQuerySupported:t.timestampQuerySupported,timestampQueryActive:t.timestampQuerySupported,gpuProfilingReason:null,hiZOcclusionCullingEnabled:t.hiZOcclusionCullingEnabled,hiZOcclusionCullingActive:r,visibility:null};let s=null,o=0,l=0;const c={begin:(e,r)=>{if(a.passes=e.map(e=>({name:e.name,cpuTimeMs:0,gpuTimeMs:null})),!t.timestampQuerySupported)return a.timestampQueryActive=!1,void(a.gpuProfilingReason="timestamp-query is not supported by this adapter/device");if(0===e.length)return a.timestampQueryActive=!1,void(a.gpuProfilingReason="no render graph passes were recorded");const i=2*e.length,n=Math.max(8,8*i),o=r.device.createQuerySet({label:`renderer-frame-profile-${a.frameIndex}`,type:"timestamp",count:i}),l=r.device.createBuffer({label:`renderer-frame-profile-resolve-${a.frameIndex}`,size:n,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),c=r.device.createBuffer({label:`renderer-frame-profile-read-${a.frameIndex}`,size:n,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});s={profile:a,querySet:o,resolveBuffer:l,readBuffer:c,queryCount:i}},beforePass:(e,t,r)=>{o=i.triangleCount,l=i.drawCallCount,s&&($r(r.encoder,s.querySet,{endOfPassWriteIndex:2*t})||(a.timestampQueryActive=!1,a.gpuProfilingReason="timestampWrites marker pass is not available on this browser/runtime",s.querySet.destroy(),s.resolveBuffer.destroy(),s.readBuffer.destroy(),s=null))},afterPass:(e,t,r,n)=>{a.passes[t].cpuTimeMs=r,a.passes[t].triangleCount=i.triangleCount-o,a.passes[t].drawCallCount=i.drawCallCount-l,s&&($r(n.encoder,s.querySet,{beginningOfPassWriteIndex:2*t+1})||(a.timestampQueryActive=!1,a.gpuProfilingReason="timestampWrites marker pass is not available on this browser/runtime",s.querySet.destroy(),s.resolveBuffer.destroy(),s.readBuffer.destroy(),s=null))},end:(t,r,n)=>{if(a.cpuPhases.renderGraphMs=r,a.cpuTimeMs=a.cpuPhases.extractSceneMs+a.cpuPhases.uploadMs+a.cpuPhases.renderGraphMs,a.drawCallCount=i.drawCallCount,a.triangleCount=i.triangleCount,a.directionalShadows={updatedLayers:i.directionalShadowUpdates??0,reusedLayers:i.directionalShadowReused??0,forcedLayers:i.directionalShadowForced??0,updateMask:i.directionalShadowUpdateMask??0},!s){const t=Hn(a);return e.latestFrameProfile=t,void(e.latestCompletedFrameProfile=t)}n.encoder.resolveQuerySet(s.querySet,0,s.queryCount,s.resolveBuffer,0),n.encoder.copyBufferToBuffer(s.resolveBuffer,0,s.readBuffer,0,8*s.queryCount),e.latestFrameProfile=Hn(a)}};return{profile:a,observer:c,pendingVisibilityRead:null,get pendingGpuRead(){return s},set pendingGpuRead(e){s=e}}}(this.state,{renderGraphProfilingEnabled:this.renderGraphProfilingEnabled,timestampQuerySupported:this.timestampQuerySupported,hiZOcclusionCullingEnabled:this.hiZOcclusionCullingEnabled},u,l,{extractSceneMs:o,opaqueSortMs:this.opaqueSortMs,opaqueSortAverageMs:this.opaqueSortSampleTotal/Math.max(1,this.opaqueSortSampleCount),uploadMs:d}),y=()=>{if(!b||!u)return;const e=[];v&&v.count>0&&e.push({buffer:v.indirectBuffer,drawCount:v.count,totalInstances:s.gpuOpaqueDraws.reduce((e,t)=>e+Math.max(0,t.instanceCount),0),kind:"dynamic"});for(const t of this.staticDrawSets)t.publicSet.enabled&&t.lastVisibilityFrameToken===this.staticFrameToken&&e.push({buffer:t.drawMetadataResource.indirectBuffer,drawCount:t.drawMetadataResource.count,totalInstances:t.instanceCount,kind:"static"});!function(e,t,r,i){const n=i.filter(e=>e.drawCount>0);if(0===n.length)return void(e.profile.visibility={totalInstances:0,visibleInstances:0,culledInstances:0,dynamicTotalInstances:0,dynamicVisibleInstances:0,staticTotalInstances:0,staticVisibleInstances:0});let a=0;const s=n.map(e=>{const t={byteOffset:a,drawCount:e.drawCount,totalInstances:e.totalInstances,kind:e.kind};return a+=5*e.drawCount*Uint32Array.BYTES_PER_ELEMENT,t}),o=t.createBuffer({label:`renderer-visibility-profile-read-${e.profile.frameIndex}`,size:Math.max(4,a),usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});for(let e=0;e<n.length;e+=1){const t=n[e];r.copyBufferToBuffer(t.buffer,0,o,s[e].byteOffset,5*t.drawCount*Uint32Array.BYTES_PER_ELEMENT)}e.pendingVisibilityRead={readBuffer:o,regions:s}}(b,this.state.device,h,e)};if(i)return this.renderGraph.executeAsync(w,b?.observer).then(()=>{y(),null==this.nativePostSubmit&&this.recordPresentationOverlay(h,p),this.state.device.queue.submit([h.finish()]),this.nativePostSubmit?.({device:this.state.device,presentationView:p,presentationWidth:this.state.presentationWidth,presentationHeight:this.state.presentationHeight,present:e=>{const t=this.state.device.createCommandEncoder({label:"native-present-encoder"});this.executePresentPass(t,e,p),this.recordPresentationOverlay(t,p),this.state.device.queue.submit([t.finish()])}}),this.commitTemporalHiZHistory(),this.releaseRetiredGeometryResourcesAfterSubmit(),b&&Wn(this.state,b)});this.renderGraph.execute(w,b?.observer),y(),null==this.nativePostSubmit&&this.recordPresentationOverlay(h,p),this.state.device.queue.submit([h.finish()]),this.nativePostSubmit?.({device:this.state.device,presentationView:p,presentationWidth:this.state.presentationWidth,presentationHeight:this.state.presentationHeight,present:e=>{const t=this.state.device.createCommandEncoder({label:"native-present-encoder"});this.executePresentPass(t,e,p),this.recordPresentationOverlay(t,p),this.state.device.queue.submit([t.finish()])}}),this.commitTemporalHiZHistory(),this.releaseRetiredGeometryResourcesAfterSubmit(),b&&Wn(this.state,b)}recordPresentationOverlay(e,t){if(null==this.presentationOverlay)return;const r=this.presentationOverlayContext;r.device=this.state.device,r.encoder=e,r.targetView=t,r.targetFormat=this.state.format,r.presentationWidth=this.state.presentationWidth,r.presentationHeight=this.state.presentationHeight,this.presentationOverlay(r)}destroy(){for(const e of this.repeatedInstanceResources.values())e();this.skeletonPalettes.dispose(),this.clearIndirectBundleCache();for(const e of this.staticDrawSets.slice())this.disposeStaticDrawSetResource(e);this.sharedForwardPipelineCache.clear(),this.sharedForwardPipelinePromiseCache.clear(),this.sharedDepthPipelineCache.clear(),this.sharedDepthPipelinePromiseCache.clear();for(const e of this.skinnedGeometryCache.values())e.skinning.bindUniformBuffer.destroy();this.skinnedGeometryCache.clear();for(const e of this.skinPaletteResources)e.matrixBuffer.destroy(),e.previousMatrixBuffer.destroy();this.skinPaletteResources.clear();for(const e of this.retiredGeometryResources)this.destroyGeometryResource(e);this.retiredGeometryResources.length=0;for(const e of this.colorTargetCache.values())e.texture.destroy();this.colorTargetCache.clear(),this.destroyMsaaResources(),this.state.mainDepthTexture?.destroy(),this.state.sceneColorTexture?.destroy(),this.state.sceneColorSnapshotTexture?.destroy(),this.transmissionSnapshotTexture?.destroy(),this.transmissionSnapshotTexture=null,this.state.sceneDepthSnapshotTexture?.destroy(),this.state.postProcessColorTexture?.destroy(),this.directionalShadowScheduler.invalidate(),this.state.directionalShadowTexture?.destroy(),this.state.pointShadowTexture?.destroy(),this.state.pointShadowDepthTexture?.destroy(),this.state.spotShadowTexture?.destroy(),this.state.spotLightMapTexture?.destroy(),this.state.hizTexture?.destroy(),this.state.cameraBuffer?.destroy(),this.state.temporalVisibilityBuffer?.destroy(),this.state.lightBuffer?.destroy(),this.tiledPointLights?.destroy(),this.state.shadowCameraBuffer?.destroy();for(const e of this.state.shadowCameraBufferPool)e.destroy();this.state.shadowCameraBufferPool.length=0,this.state.sharedShadowBindGroupByCameraBuffer.clear(),this.state.instanceBuffer?.destroy();for(const e of this.defaultInstanceAttributeBuffers.values())for(const t of e.values())t.destroy();this.defaultInstanceAttributeBuffers.clear(),this.state.visibilityParamsBuffer?.destroy(),this.state.drawMetadataResource?.metadataBuffer.destroy(),this.state.drawMetadataResource?.indirectBuffer.destroy(),this.state.drawMetadataResource?.postIndirectBuffer.destroy(),this.state.initialized=!1;const e=this.state.device?.destroy;"function"==typeof e&&e.call(this.state.device),this.state.device=null}async createStaticPipelines(){if(!(this.state.device&&this.state.sceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.visibleDepthSceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&this.state.emptyBindGroupLayout&&this.state.skinningBindGroupLayout&&this.state.fullscreenTextureBindGroupLayout&&this.state.format))return;const e=[],t=this.state.device.createPipelineLayout({label:"renderer-depth-prepass-layout",bindGroupLayouts:[this.state.sceneBindGroupLayout]});e.push(E(this.state.device,{label:"renderer-depth-prepass-pipeline",layout:t,vertex:{module:this.state.device.createShaderModule({label:"renderer-depth-prepass-module",code:"\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> rendererLights: array<vec4<f32>, 11>;\n@group(0) @binding(2) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> @builtin(position) @invariant vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n return rendererCamera.viewProj * world;\n}\n"}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.depthPrepassPipeline=e}));const r=this.state.device.createPipelineLayout({label:"renderer-depth-prepass-visible-layout",bindGroupLayouts:[this.state.visibleDepthSceneBindGroupLayout]});e.push(E(this.state.device,{label:"renderer-depth-prepass-visible-pipeline",layout:r,vertex:{module:this.state.device.createShaderModule({label:"renderer-depth-prepass-visible-module",code:"\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(2) var<storage, read> rendererInstances: array<RendererInstanceData>;\n@group(0) @binding(3) var<storage, read> rendererVisibleInstanceIndices: array<u32>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[rendererVisibleInstanceIndices[instanceIndex]];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> @builtin(position) @invariant vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n return rendererCamera.viewProj * world;\n}\n"}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.depthPrepassPipelineVisible=e}));const i=this.state.device.createPipelineLayout({label:"renderer-depth-prepass-direct-layout",bindGroupLayouts:[this.state.directSceneBindGroupLayout]});e.push(E(this.state.device,{label:"renderer-depth-prepass-direct-pipeline",layout:i,vertex:{module:this.state.device.createShaderModule({label:"renderer-depth-prepass-direct-module",code:"\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> rendererLights: array<vec4<f32>, 11>;\n@group(0) @binding(2) var<storage, read> rendererInstanceMatrices: array<vec4<f32>>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let base = instanceIndex * 4u;\n return mat4x4<f32>(\n rendererInstanceMatrices[base + 0u],\n rendererInstanceMatrices[base + 1u],\n rendererInstanceMatrices[base + 2u],\n rendererInstanceMatrices[base + 3u]\n );\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> @builtin(position) @invariant vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n return rendererCamera.viewProj * world;\n}\n"}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.depthPrepassPipelineDirect=e}));const n=this.state.device.createPipelineLayout({label:"renderer-skinned-depth-prepass-layout",bindGroupLayouts:[this.state.sceneBindGroupLayout,this.state.emptyBindGroupLayout,this.state.skinningBindGroupLayout]});e.push(E(this.state.device,{label:"renderer-skinned-depth-prepass-pipeline",layout:n,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-depth-prepass-module",code:Ja}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(V)},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.skinnedDepthPrepassPipeline=e}));const a=this.state.device.createPipelineLayout({label:"renderer-shadow-layout",bindGroupLayouts:[this.state.shadowBindGroupLayout]}),s=this.state.device.createPipelineLayout({label:"renderer-direct-shadow-pipeline-layout",bindGroupLayouts:[this.state.directShadowBindGroupLayout]});e.push(E(this.state.device,{label:"renderer-directional-shadow-pipeline",layout:a,vertex:{module:this.state.device.createShaderModule({label:"renderer-directional-shadow-module",code:"\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> @builtin(position) @invariant vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n return shadowCamera.viewProj * world;\n}\n"}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"front",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}}).then(e=>{this.state.shadowDepthPipeline=e})),e.push(E(this.state.device,{label:"renderer-directional-shadow-direct-pipeline",layout:s,vertex:{module:this.state.device.createShaderModule({label:"renderer-directional-shadow-direct-module",code:"\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstanceMatrices: array<vec4<f32>>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let base = instanceIndex * 4u;\n return mat4x4<f32>(\n rendererInstanceMatrices[base + 0u],\n rendererInstanceMatrices[base + 1u],\n rendererInstanceMatrices[base + 2u],\n rendererInstanceMatrices[base + 3u]\n );\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> @builtin(position) vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n return shadowCamera.viewProj * world;\n}\n"}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"front",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}}).then(e=>{this.state.shadowDepthPipelineDirect=e}));const o=this.state.device.createPipelineLayout({label:"renderer-skinned-shadow-layout",bindGroupLayouts:[this.state.shadowBindGroupLayout,this.state.emptyBindGroupLayout,this.state.skinningBindGroupLayout]});e.push(E(this.state.device,{label:"renderer-skinned-directional-shadow-pipeline",layout:o,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-directional-shadow-module",code:Qa}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(V)},primitive:{topology:"triangle-list",cullMode:"front",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}}).then(e=>{this.state.skinnedShadowDepthPipeline=e})),e.push(E(this.state.device,{label:"renderer-point-shadow-pipeline",layout:a,vertex:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-module",code:Za}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},fragment:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-fragment-module",code:Za}),entryPoint:"fsMain",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.pointShadowPipeline=e})),e.push(E(this.state.device,{label:"renderer-point-shadow-direct-pipeline",layout:s,vertex:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-direct-module",code:Ya}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},fragment:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-direct-fragment-module",code:Ya}),entryPoint:"fsMain",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.pointShadowPipelineDirect=e})),e.push(E(this.state.device,{label:"renderer-skinned-point-shadow-pipeline",layout:o,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-point-shadow-module",code:es}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(V)},fragment:{module:this.state.device.createShaderModule({label:"renderer-skinned-point-shadow-fragment-module",code:es}),entryPoint:"fsMain",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.skinnedPointShadowPipeline=e}));const l=this.state.device.createPipelineLayout({label:"renderer-present-layout",bindGroupLayouts:[this.state.fullscreenTextureBindGroupLayout]});e.push(E(this.state.device,{label:"renderer-present-pipeline",layout:l,vertex:{module:this.state.device.createShaderModule({label:"renderer-present-module",code:ts}),entryPoint:"vsMain"},fragment:{module:this.state.device.createShaderModule({label:"renderer-present-fragment-module",code:ts}),entryPoint:"fsMain",targets:[{format:this.state.format}]},primitive:{topology:"triangle-list"}}).then(e=>{this.state.presentPipeline=e}));const c=this.state.device.createShaderModule({label:"renderer-scene-color-snapshot-module",code:is});e.push(E(this.state.device,{label:"renderer-scene-color-snapshot-pipeline",layout:l,vertex:{module:c,entryPoint:"vsMain"},fragment:{module:c,entryPoint:"fsMain",targets:[{format:P}]},primitive:{topology:"triangle-list"}}).then(e=>{this.state.sceneColorSnapshotPipeline=e}));const u=this.state.device.createShaderModule({label:"physical-transmission-snapshot-module",code:ns});e.push(E(this.state.device,{label:"physical-transmission-snapshot-pipeline",layout:l,vertex:{module:u,entryPoint:"vsMain"},fragment:{module:u,entryPoint:"fsMain",targets:[{format:C}]},primitive:{topology:"triangle-list"}}).then(e=>{this.transmissionSnapshotPipeline=e})),await Promise.all(e)}ensureTransmissionSnapshot(){if(this.transmissionSnapshotTexture&&this.transmissionSnapshotSize.width===this.state.width&&this.transmissionSnapshotSize.height===this.state.height)return;this.transmissionSnapshotTexture?.destroy(),this.transmissionSnapshotSize.width=this.state.width,this.transmissionSnapshotSize.height=this.state.height;const e=1+Math.floor(Math.log2(Math.max(this.state.width,this.state.height)));this.transmissionSnapshotTexture=this.state.device.createTexture({label:"physical-transmission-snapshot",size:this.transmissionSnapshotSize,format:C,mipLevelCount:e,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),this.transmissionSnapshotView=this.transmissionSnapshotTexture.createView(),this.transmissionMipViews=[],this.transmissionMipBindGroups=[],this.transmissionSourceBindGroups=new WeakMap;for(let t=0;t<e;t++)this.transmissionMipViews.push(this.transmissionSnapshotTexture.createView({baseMipLevel:t,mipLevelCount:1})),t>0&&this.transmissionMipBindGroups.push(this.state.device.createBindGroup({layout:this.state.fullscreenTextureBindGroupLayout,entries:[{binding:0,resource:this.transmissionSampler},{binding:1,resource:this.transmissionMipViews[t-1]}]}));this.graphTextureResourceVersion++}copyTransmissionSnapshot(e,t){let r=this.transmissionSourceBindGroups.get(t);r||(r=this.state.device.createBindGroup({layout:this.state.fullscreenTextureBindGroupLayout,entries:[{binding:0,resource:this.transmissionSampler},{binding:1,resource:t}]}),this.transmissionSourceBindGroups.set(t,r));for(let t=0;t<this.transmissionMipViews.length;t++){const i=e.beginRenderPass({label:"physical-transmission-snapshot-mip",colorAttachments:[{view:this.transmissionMipViews[t],loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:1}}]});i.setPipeline(this.transmissionSnapshotPipeline),i.setBindGroup(0,0===t?r:this.transmissionMipBindGroups[t-1]),i.draw(3),i.end()}}recreateShadowResources(){if(this.state.device){this.recreateDirectionalShadowResources(),this.state.pointShadowTexture?.destroy(),this.state.pointShadowTexture=this.state.device.createTexture({label:"renderer-point-shadow-texture",size:{width:this.state.pointShadowTextureSize,height:this.state.pointShadowTextureSize,depthOrArrayLayers:24},format:"rgba16float",dimension:"2d",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),this.state.pointShadowArrayView=this.state.pointShadowTexture.createView({dimension:"2d-array"}),this.state.pointShadowFaceViews=[];for(let e=0;e<24;e+=1)this.state.pointShadowFaceViews.push(this.state.pointShadowTexture.createView({dimension:"2d",baseArrayLayer:e,arrayLayerCount:1}));this.state.pointShadowDepthTexture?.destroy(),this.state.pointShadowDepthTexture=this.state.device.createTexture({label:"renderer-point-shadow-depth-texture",size:{width:this.state.pointShadowTextureSize,height:this.state.pointShadowTextureSize,depthOrArrayLayers:24},format:"depth32float",dimension:"2d",usage:GPUTextureUsage.RENDER_ATTACHMENT}),this.state.pointShadowDepthFaceViews=[];for(let e=0;e<24;e+=1)this.state.pointShadowDepthFaceViews.push(this.state.pointShadowDepthTexture.createView({dimension:"2d",baseArrayLayer:e,arrayLayerCount:1}));this.state.spotShadowTexture?.destroy(),this.state.spotShadowTexture=this.state.device.createTexture({label:"renderer-spot-shadow-texture",size:{width:this.state.spotShadowTextureSize,height:this.state.spotShadowTextureSize,depthOrArrayLayers:4},format:"depth32float",dimension:"2d",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),this.state.spotShadowView=this.state.spotShadowTexture.createView({dimension:"2d-array"}),this.state.spotShadowLayerViews=[];for(let e=0;e<4;e+=1)this.state.spotShadowLayerViews.push(this.state.spotShadowTexture.createView({dimension:"2d",baseArrayLayer:e,arrayLayerCount:1}))}}recreateDirectionalShadowResources(){if(this.state.device){this.state.residentSceneBindGroupVersion+=1,this.state.sharedSceneBindGroup=null,this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches(),this.directionalShadowScheduler.invalidate(),this.state.directionalShadowTexture?.destroy(),this.state.directionalShadowTexture=this.state.device.createTexture({label:"renderer-directional-shadow-texture",size:{width:this.state.directionalShadowTextureSize,height:this.state.directionalShadowTextureSize,depthOrArrayLayers:4},format:"depth32float",dimension:"2d",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),this.state.directionalShadowView=this.state.directionalShadowTexture.createView({dimension:"2d-array"}),this.state.directionalShadowLayerViews=[];for(let e=0;e<4;e+=1)this.state.directionalShadowLayerViews.push(this.state.directionalShadowTexture.createView({dimension:"2d",baseArrayLayer:e,arrayLayerCount:1}))}}ensureShadowTextureSizes(e){const t=Math.max(this.shadowMapSize,...e.lights.directionals.map(e=>Math.ceil(e.shadowMapSize))),r=Math.max(this.pointShadowMapSize,...e.lights.points.map(e=>Math.ceil(e.shadowMapSize))),i=Math.max(this.spotShadowMapSize,...e.lights.spots.map(e=>Math.ceil(e.shadowMapSize)));t===this.state.directionalShadowTextureSize&&r===this.state.pointShadowTextureSize&&i===this.state.spotShadowTextureSize||(this.state.directionalShadowTextureSize=t,this.state.pointShadowTextureSize=r,this.state.spotShadowTextureSize=i,this.recreateShadowResources())}ensureColorTarget(e,t={}){if(!this.state.device||!this.state.format)throw new Error("Renderer is not initialized.");if("sceneColor"===e||"postProcessColor"===e)throw new Error(`Color target "${e}" is reserved by the renderer.`);const r=t.scale??1,i=t.resolution??"render",n=t.format??C,a="presentation"===i?this.state.presentationWidth:this.state.width,s="presentation"===i?this.state.presentationHeight:this.state.height,o=Math.max(1,Math.floor(a*r)),l=Math.max(1,Math.floor(s*r)),c=this.colorTargetCache.get(e);if(c&&c.format===n&&c.width===o&&c.height===l&&c.scale===r&&c.resolution===i)return c;c?.texture.destroy();const u=this.state.device.createTexture({label:`renderer-color-target-${e}`,size:{width:o,height:l},format:n,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),d={name:e,format:n,width:o,height:l,scale:r,resolution:i,texture:u,view:u.createView()};return this.colorTargetCache.set(e,d),this.graphTextureResourceVersion+=1,d}ensureMsaaColorTarget(e){if(!this.state.device)throw new Error("Renderer is not initialized.");const t=this.getColorTargetDimensions(e),r=this.getColorTargetFormat(e),i=this.msaaColorTargetCache.get(e);if(i&&i.format===r&&i.width===t.width&&i.height===t.height&&1===i.scale)return i;i?.texture.destroy();const n=this.state.device.createTexture({label:`renderer-msaa-color-target-${e}`,size:{width:t.width,height:t.height},sampleCount:this.sampleCount,format:r,usage:GPUTextureUsage.RENDER_ATTACHMENT}),a={name:e,format:r,width:t.width,height:t.height,scale:1,texture:n,view:n.createView()};return this.msaaColorTargetCache.set(e,a),a}ensureMsaaDepthTarget(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=`${e}x${t}`,i=this.msaaDepthTargetCache.get(r);if(i&&i.width===e&&i.height===t&&i.sampleCount===this.sampleCount)return i;i?.texture.destroy();const n=this.state.device.createTexture({label:`renderer-msaa-depth-${r}`,size:{width:e,height:t},sampleCount:this.sampleCount,format:"depth32float",usage:GPUTextureUsage.RENDER_ATTACHMENT}),a={width:e,height:t,sampleCount:this.sampleCount,texture:n,view:n.createView()};return this.msaaDepthTargetCache.set(r,a),a}destroyMsaaResources(){for(const e of this.msaaColorTargetCache.values())e.texture.destroy();this.msaaColorTargetCache.clear();for(const e of this.msaaDepthTargetCache.values())e.texture.destroy();this.msaaDepthTargetCache.clear()}getColorTargetView(e){if("sceneColor"===e){if(!this.state.sceneColorView)throw new Error("Scene color target is not available.");return this.state.sceneColorView}if("postProcessColor"===e){if(!this.state.postProcessColorView)throw new Error("Post-process color target is not available.");return this.state.postProcessColorView}const t=this.colorTargetCache.get(e);if(!t)throw new Error(`Color target "${e}" has not been defined.`);return t.view}ensureTextureTarget(e,t={}){if("2d"===(t.dimension??"2d")&&null==t.usage)return this.ensureColorTarget(e,t);if(!this.state.device)throw new Error("Renderer is not initialized.");const r=t.scale??1,i=t.resolution??"render",n="presentation"===i?this.state.presentationWidth:this.state.width,a="presentation"===i?this.state.presentationHeight:this.state.height,s=Math.max(1,Math.floor(n*r)),o=Math.max(1,Math.floor(a*r)),l=Math.max(1,t.depthOrArrayLayers??1),c=t.format??C,u=this.colorTargetCache.get(e),d=t.dimension??"2d",h=t.usage??GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.COPY_SRC;if(u&&u.format===c&&u.width===s&&u.height===o&&u.resolution===i&&u.dimension===d&&u.depthOrArrayLayers===l&&u.usage===h)return u;u?.texture.destroy();const p=this.state.device.createTexture({label:`renderer-texture-target-${e}`,size:{width:s,height:o,depthOrArrayLayers:l},dimension:d,format:c,usage:h}),f={name:e,format:c,width:s,height:o,scale:r,resolution:i,dimension:d,depthOrArrayLayers:l,usage:h,texture:p,view:p.createView({dimension:d})};return this.colorTargetCache.set(e,f),this.graphTextureResourceVersion+=1,f}getColorTargetTexture(e){if("sceneColor"===e){if(!this.state.sceneColorTexture)throw new Error("Scene color target is not available.");return this.state.sceneColorTexture}if("postProcessColor"===e){if(!this.state.postProcessColorTexture)throw new Error("Post-process color target is not available.");return this.state.postProcessColorTexture}const t=this.colorTargetCache.get(e);if(!t)throw new Error(`Color target "${e}" has not been defined.`);return t.texture}getColorTargetDimensions(e){if("sceneColor"===e||"postProcessColor"===e)return{width:this.state.width,height:this.state.height};const t=this.colorTargetCache.get(e);if(!t)throw new Error(`Color target "${e}" has not been defined.`);return{width:t.width,height:t.height}}getColorTargetFormat(e){if(!this.state.format)throw new Error("Renderer is not initialized.");if("sceneColor"===e||"postProcessColor"===e)return C;const t=this.colorTargetCache.get(e);if(!t)throw new Error(`Color target "${e}" has not been defined.`);return t.format}getMaterialGraphTextureReads(e){const t=this.materialGraphTextureReadCache.get(e);if(t?.materialVersion===e.version)return t.resources;const r=e.getGraphTextureInputs(),i=[];for(const e in r){const t=r[e].resource;i.includes(t)||i.push(t)}return this.materialGraphTextureReadCache.set(e,{materialVersion:e.version,resources:i}),i}createGraphBuilderContext(e,t,r,i,n,a,s,o,l){let c=!1;const u=()=>{c||(c=!0,e.addPass(new $n("TiledPointLightsPass",()=>{this.tiledLightingEnabled&&s.lights.points.length>0&&this.tiledPointLights.execute(t)},{writes:["tiledPointLights"]})))};let d=!1,h=!1;const p=e=>{const t=new Set;for(let r=0;r<e.length;r+=1){const i=this.getMaterialGraphTextureReads(e[r].material);for(let e=0;e<i.length;e+=1)t.add(i[e])}return Array.from(t)},f={device:this.state.device,encoder:t,camera:s.camera,sceneColorView:this.state.sceneColorView,postProcessColorView:this.state.postProcessColorView,presentationColorView:a,depthView:this.state.mainDepthView,colorFormat:C,width:this.state.width,height:this.state.height,presentationWidth:this.state.presentationWidth,presentationHeight:this.state.presentationHeight,linearClampSampler:this.state.linearClampSampler,nearestClampSampler:this.state.nearestClampSampler,comparisonSampler:this.state.shadowComparisonSampler,getColorView:e=>this.getColorTargetView(e),getTextureView:e=>this.getGraphTextureView(e),getExternalTexture:e=>{const t=this.textureManager.getTextureResource(e);return{view:t.view,sampler:t.sampler}},getGeometryVertexBuffer:(e,t)=>this.getGeometryResource(e)[t],getSkeletonBoneBuffer:this.getSkeletonBoneBufferForPass,getColorFormat:e=>this.getColorTargetFormat(e),getShadowMapDebugInfo:()=>({directional:{view:this.state.directionalShadowView,size:this.state.directionalShadowTextureSize,layerCount:4,activeLightCount:s.lights.directionals.length,activeLayerCount:s.lights.directionals.length},point:{view:this.state.pointShadowArrayView,size:this.state.pointShadowTextureSize,layerCount:24,activeLightCount:Math.min(4,s.lights.points.length),activeLayerCount:6*Math.min(4,s.lights.points.length)},spot:{view:this.state.spotShadowView,size:this.state.spotShadowTextureSize,layerCount:4,activeLightCount:Math.min(4,s.lights.spots.length),activeLayerCount:Math.min(4,s.lights.spots.length)}}),getSceneLightingResources:()=>{if(!(this.state.cameraBuffer&&this.state.lightBuffer&&this.state.shadowComparisonSampler&&this.state.linearClampSampler&&this.state.directionalShadowView&&this.state.pointShadowArrayView&&this.state.spotShadowView&&this.state.spotLightMapView))throw new Error("Renderer scene lighting resources are not initialized.");return{cameraBuffer:this.state.cameraBuffer,lightBuffer:this.state.lightBuffer,shadowSampler:this.state.shadowComparisonSampler,linearSampler:this.state.linearClampSampler,directionalShadowView:this.state.directionalShadowView,pointShadowView:this.state.pointShadowArrayView,spotShadowView:this.state.spotShadowView,spotLightMapView:this.state.spotLightMapView}}};return{fogVolumeObjects:s.fogVolumeObjects,extractedLights:s.lights,addDirectionalShadowPass:()=>{e.addPass(new $n("DirectionalShadowPass",()=>{this.executeDirectionalShadowPass(t,i,s,o)},{writes:["directionalShadow"]}))},addPointShadowPass:()=>{s.lights.points.some(e=>e.castShadow)&&e.addPass(new $n("PointShadowPass",()=>{this.executePointShadowPass(t,i,s,o)},{writes:["pointShadow"]}))},addSpotShadowPass:()=>{s.lights.spots.some(e=>e.castShadow)&&e.addPass(new $n("SpotShadowPass",()=>{this.executeSpotShadowPass(t,i,s,o)},{writes:["spotShadow"]}))},addDepthPrepass:()=>{d=!0,this.getHiZOcclusionCullingActive()&&this.hasEnabledStaticDrawSets()&&e.addPass(new $n("TemporalStaticVisibilityPrepass",()=>{this.executeStaticVisibilityPasses(t,"prepass")},{reads:["hiz"],writes:["staticIndirectArgs"]})),e.addPass(new $n("DepthPrepass",()=>{this.executeDepthPrepass(t,r,s,o)},{writes:["mainDepth"]}))},addHiZPasses:()=>{this.getHiZOcclusionCullingActive()&&e.addPass(new $n("HiZPasses",()=>{this.executeHiZPasses(t)},{reads:["mainDepth"],writes:["hiz"]}))},addVisibilityPass:()=>{this.getHiZOcclusionCullingActive()&&(n||this.hasEnabledStaticDrawSets())&&(e.addPass(new $n("VisibilityPass",()=>{n&&this.executeVisibilityPass(t,n),this.executeStaticVisibilityPasses(t,"postpass")},{reads:["hiz"],writes:["indirectArgs","staticIndirectArgs"]})),this.sampleCount>1&&this.hasEnabledStaticDrawSets()&&e.addPass(new $n("TemporalStaticDepthResolvePass",()=>{this.executeStaticTemporalDepthResolvePass(t)},{reads:["staticIndirectArgs"],writes:["mainDepth"]})))},defineColorTarget:(e,t={})=>{this.ensureColorTarget(e,t)},defineTextureTarget:(e,t={})=>{this.ensureTextureTarget(e,t)},addForwardPass:(i="sceneColor")=>{u();const n=!d,a=[...s.gpuOpaqueDraws,...s.directOpaqueDraws,...s.transparentDraws],c=p(a);if(l?.push({draws:a,colorTargetFormats:[this.getColorTargetFormat(i)],sampleCount:this.sampleCount,staticDrawStage:"all"}),c.includes("mainDepth")){if(!d)throw new Error("Materials that sample mainDepth require a depth prepass.");e.addPass(new $n("ForwardDepthSnapshotPass",()=>{this.state.mainDepthTexture&&this.state.sceneDepthSnapshotTexture&&t.copyTextureToTexture({texture:this.state.mainDepthTexture},{texture:this.state.sceneDepthSnapshotTexture},{width:this.state.width,height:this.state.height})},{reads:["mainDepth"],writes:["sceneDepthSnapshot"]})),h=!0}e.addPass(new $n("ForwardPass",()=>{this.executeForwardPass(t,i,this.getColorTargetView(i),r,s,o,n)},{reads:["tiledPointLights","directionalShadow","pointShadow","spotShadow","mainDepth","indirectArgs",...c.map(e=>"mainDepth"===e?"sceneDepthSnapshot":e)],writes:[i]})),this.getHiZOcclusionCullingActive()&&this.hasEnabledStaticDrawSets()&&e.addPass(new $n("TemporalHiZHistoryPass",()=>{this.executeHiZPasses(t,!0)},{reads:["mainDepth"],writes:["hiz"],dependsOn:["ForwardPass"]}))},addOpaquePass:(i="sceneColor")=>{u();const n=!d,a=[...s.gpuOpaqueDraws,...s.directOpaqueDraws],c=p(a);if(l?.push({draws:a,colorTargetFormats:[this.getColorTargetFormat(i)],sampleCount:this.sampleCount,staticDrawStage:"opaque"}),c.includes("mainDepth")){if(!d)throw new Error("Materials that sample mainDepth require a depth prepass.");e.addPass(new $n("OpaqueDepthSnapshotPass",()=>{this.state.mainDepthTexture&&this.state.sceneDepthSnapshotTexture&&t.copyTextureToTexture({texture:this.state.mainDepthTexture},{texture:this.state.sceneDepthSnapshotTexture},{width:this.state.width,height:this.state.height})},{reads:["mainDepth"],writes:["sceneDepthSnapshot"]})),h=!0}e.addPass(new $n("OpaquePass",()=>{this.executeForwardPass(t,i,this.getColorTargetView(i),r,s,o,n,"opaque")},{reads:["tiledPointLights","directionalShadow","pointShadow","spotShadow","mainDepth","indirectArgs",...c.map(e=>"mainDepth"===e?"sceneDepthSnapshot":e)],writes:[i]}))},addSceneTextureCopyPass:(r="sceneColor",i)=>{const n=this.staticDrawSets.filter(e=>e.publicSet.enabled&&"late"===e.drawStage).flatMap(e=>e.draws),a=[...s.transparentDraws,...n],o=p(a),l=o.includes("physicalTransmissionSnapshot");l&&this.ensureTransmissionSnapshot();const c=!0===i?.sceneColor||a.some(e=>e.material.usesSceneColor()),u=!0===i?.sceneDepth||a.some(e=>e.material.usesSceneDepth()),d=o.includes("mainDepth");if(!(l||c||u||d))return;const f=this.getColorTargetDimensions(r);if(f.width!==this.state.width||f.height!==this.state.height||this.getColorTargetFormat(r)!==C)throw new Error("Scene texture snapshots currently require a full-resolution rgba16float source.");e.addPass(new $n("SceneTextureCopyPass",()=>{if(l&&this.copyTransmissionSnapshot(t,this.getColorTargetView(r)),c){const e=this.getColorTargetView(r);let i=this.state.sceneColorSnapshotBindGroups.get(e);i||(i=this.state.device.createBindGroup({label:"renderer-scene-color-snapshot-bind-group",layout:this.state.fullscreenTextureBindGroupLayout,entries:[{binding:0,resource:this.state.linearClampSampler},{binding:1,resource:e}]}),this.state.sceneColorSnapshotBindGroups.set(e,i));const n=t.beginRenderPass({label:"renderer-scene-color-snapshot-pass",colorAttachments:[{view:this.state.sceneColorSnapshotView,loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}]});n.setPipeline(this.state.sceneColorSnapshotPipeline),n.setBindGroup(0,i),n.draw(3),n.end()}u&&this.executeHiZPasses(t,!1,!0),d&&this.state.mainDepthTexture&&this.state.sceneDepthSnapshotTexture&&t.copyTextureToTexture({texture:this.state.mainDepthTexture},{texture:this.state.sceneDepthSnapshotTexture},{width:this.state.width,height:this.state.height})},{reads:[...c||l?[r]:[],...u||d?["mainDepth"]:[]],writes:[...c?["sceneColorSnapshot"]:[],...l?["physicalTransmissionSnapshot"]:[],...u||d?["sceneDepthSnapshot"]:[]]})),(u||d)&&(h=!0)},addLatePass:(i="sceneColor")=>{const n=this.staticDrawSets.filter(e=>e.publicSet.enabled&&"late"===e.drawStage).flatMap(e=>e.draws);if(0===s.transparentDraws.length&&0===n.length)return;l?.push({draws:s.transparentDraws,colorTargetFormats:[this.getColorTargetFormat(i)],sampleCount:1,staticDrawStage:"late"});const a=[...s.transparentDraws,...n],c=[i,"mainDepth",...p(a)];a.some(e=>e.material.usesSceneColor())&&c.push("sceneColorSnapshot"),a.some(e=>e.material.usesSceneDepth())&&c.push("sceneDepthSnapshot"),e.addPass(new $n("LatePass",()=>{this.executeForwardPass(t,i,this.getColorTargetView(i),r,s,o,!1,"late",!0,1)},{reads:c,writes:[i,"mainDepth"]}))},addHiZHistoryPass:(r="ForwardPass")=>{if(!this.getHiZOcclusionCullingActive()||!this.hasEnabledStaticDrawSets())return;const i="LatePass"===r&&0===s.transparentDraws.length?"OpaquePass":r;e.addPass(new $n("TemporalHiZHistoryPass",()=>{this.executeHiZPasses(t,!0)},{reads:["mainDepth"],writes:["hiz"],dependsOn:[i]}))},addMaterialPass:(i={})=>{u();const n="string"==typeof i.outputs?[i.outputs]:Array.from(i.outputs??["sceneColor"]),a=i.drawStage??"all",c="opaque"===a?[...s.gpuOpaqueDraws,...s.directOpaqueDraws]:"late"===a?s.transparentDraws:[...s.gpuOpaqueDraws,...s.directOpaqueDraws,...s.transparentDraws],d=i.objectFilter?c.filter(e=>i.objectFilter(e.sourceObject)||!0===e.sourceRanges?.some(e=>i.objectFilter(e.sourceObject))):c,h=e=>"function"==typeof i.overrideMaterial?i.overrideMaterial(e.material,null!==e.skinning):i.overrideMaterial,p=i.overrideMaterial?d.map(e=>({...e,material:h(e)})):d;l?.push({draws:p,colorTargetFormats:n.map(e=>this.getColorTargetFormat(e)),sampleCount:this.sampleCount,staticDrawStage:a}),e.addPass(new $n(i.name??"MaterialPass",()=>{this.executeMaterialPass(t,n,r,s,o,i)},{reads:["tiledPointLights","directionalShadow","pointShadow","spotShadow",..."late"!==a?["indirectArgs","staticIndirectArgs"]:[],...i.loadDepth?["mainDepth"]:[],...i.loadColor?n:[]],writes:this.sampleCount>1?n:[...n,"mainDepth"]}))},addCustomPass:t=>{e.addPass(new $n(t.name,()=>{t.execute(f)},{reads:t.reads,writes:t.writes,dependsOn:t.dependsOn}))},addPresentPass:(r="sceneColor")=>{e.addPass(new $n("PresentPass",()=>{const e=this.getColorTargetView(r);this.executePresentPass(t,e,a)},{reads:[r],writes:["mainColor"]}))}}}transparentDraws=[];opaqueBatches=new Map;acquireDrawCall(){const e=this.drawCallPoolCount;this.drawCallPoolCount+=1;let t=this.drawCallPool[e];return t||(t={geometry:null,geometryKey:{},geometryResource:null,material:null,customDepthMaterial:null,residentInstanceBinding:null,sourceObject:null,frontFaceCW:!1,usesBatching:!1,geometryGroup:null,batchKey:"",batchHash:0,indexed:!1,wireframe:!1,start:0,count:0,transparent:!1,renderOrder:0,hasRenderCallbacks:!1,castShadow:!0,receiveShadow:!0,sortMaterialId:0,sortGeometryId:0,sortCustomDepthMaterialId:0,skinning:null,materialResource:null,instanceStart:0,instanceCount:0,boundsCenter:new Ki,boundsRadius:0,sortDepth:0,transparentSortGroup:0,transparentSortOrder:0},this.drawCallPool[e]=t),t}acquireOpaqueBatchBuilder(){const e=this.opaqueBatchPoolCount;this.opaqueBatchPoolCount+=1;let t=this.opaqueBatchPool[e];return t||(t={template:null,totalInstanceCount:0,rangePairCount:0,firstInstanceStart:0,firstInstanceCount:0,sourceRanges:[],boundsMin:new Ki,boundsMax:new Ki},this.opaqueBatchPool[e]=t),t}populateDrawCall(e,t,r,i,n,a,s,o){const l=t.wireframe;l&&this.ensureWireframeIndex(t.geometry,t.geometryResource);const c=t.sourceObject?Boolean(t.sourceObject.receiveShadow):t.receiveShadow;return this.shouldInvalidateDrawMaterialResource(e,t.material,c,t.usesBatching,null)&&(e.materialResource=null),e.geometry=t.geometry,e.geometryKey=l?t.geometryResource.wireframeIndex:t.geometryKey,e.geometryResource=t.geometryResource,e.material=t.material,e.customDepthMaterial=t.customDepthMaterial,e.residentInstanceBinding=t.residentInstanceBinding,e.sourceObject=t.sourceObject,e.cameraDetailRejected=t.cameraDetailRejected,e.detailCulling=h(t.sourceObject),e.frontFaceCW=null!==t.sourceObject&&!0===t.sourceObject.isMesh?t.sourceObject.matrixWorld.determinant()<0:t.frontFaceCW,e.usesBatching=t.usesBatching,e.geometryGroup=t.geometryGroup,e.batchKey=t.batchKey,e.batchHash=t.batchHash,e.indexed=l||t.indexed,e.wireframe=l,e.start=l?2*t.start:t.start,e.count=l?2*t.count:t.count,e.transparent=t.transparent,e.renderOrder=t.sourceObject?.renderOrder??t.renderOrder,e.hasRenderCallbacks=this.hasRenderCallbacks(t.sourceObject),e.castShadow=t.sourceObject?Boolean(t.sourceObject.castShadow):t.castShadow,e.receiveShadow=c,e.sortMaterialId=t.sortMaterialId,e.sortGeometryId=t.sortGeometryId,e.sortCustomDepthMaterialId=t.sortCustomDepthMaterialId,e.skinning=null,e.instanceStart=r,e.instanceCount=i,e.boundsCenter.set(n,a,s),e.boundsRadius=o,e.sortDepth=0,e.transparentSortGroup=0,e.transparentSortOrder=0,e.sourceRanges=void 0,e}populateDynamicDrawCall(e,t,r,i,n,a,s,o,l,c,u,d,p,f,m,g,v,x,w,b,y,S,C,P,M,B,D,T,I=null){const V=!0===o?.isBatchedMesh,R=n.wireframe&&"triangle-list"===n.primitiveTopology;return R&&this.ensureWireframeIndex(t,i),this.shouldInvalidateDrawMaterialResource(e,n,w,V,I)&&(e.materialResource=null),e.geometry=t,e.geometryKey=R?i.wireframeIndex:r,e.geometryResource=i,e.material=n,e.customDepthMaterial=a,e.residentInstanceBinding=s,e.sourceObject=o,e.cameraDetailRejected=void 0,e.detailCulling=h(o),e.frontFaceCW=null!==o&&!0===o.isMesh&&o.matrixWorld.determinant()<0,e.usesBatching=V,e.geometryGroup=l,e.batchKey=c,e.batchHash=u,e.indexed=R||d,e.wireframe=R,e.start=R?2*p:p,e.count=R?2*f:f,e.transparent=m,e.renderOrder=g,e.hasRenderCallbacks=v,e.castShadow=x,e.receiveShadow=w,e.sortMaterialId=b,e.sortGeometryId=y,e.sortCustomDepthMaterialId=S,e.skinning=I,e.instanceStart=C,e.instanceCount=P,e.boundsCenter.set(M,B,D),e.boundsRadius=T,e.sortDepth=0,e.transparentSortGroup=0,e.transparentSortOrder=0,e.sourceRanges=void 0,e}pushOpaqueDrawTemplate(e,t,r,i,n,a,s){e.detailCulling=h(e.sourceObject),e.cameraDetailRejected=!p(L.set(i,n,a),s,this.cameraViewProjScratch,this.state.width,this.state.height,this.transparentSortCameraPositionScratch,e.detailCulling.minScreenSize*(e.sourceObject&&this.cameraDetailHistory.get(e.sourceObject)?.85:1.15),e.detailCulling.maxDistance),e.sourceObject&&this.cameraDetailHistory.set(e.sourceObject,!e.cameraDetailRejected);const o=e.batchHash,l=this.opaqueBatches.get(o);let c=null;if(l)if(Array.isArray(l))for(let t=0;t<l.length;t+=1){const r=l[t];if(oi(r.template,e)){c=r;break}}else oi(l.template,e)&&(c=l);if(c){if(c.totalInstanceCount+=r,1===c.rangePairCount){const e=c.sourceRanges;e.length=4,e[0]=c.firstInstanceStart,e[1]=c.firstInstanceCount,e[2]=t,e[3]=r}else{const e=c.sourceRanges,i=2*c.rangePairCount;e[i]=t,e[i+1]=r}c.rangePairCount+=1;const e=c.boundsMin,o=c.boundsMax,l=i-s,u=n-s,d=a-s,h=i+s,p=n+s,f=a+s;return l<e.x&&(e.x=l),u<e.y&&(e.y=u),d<e.z&&(e.z=d),h>o.x&&(o.x=h),p>o.y&&(o.y=p),void(f>o.z&&(o.z=f))}const u=this.acquireOpaqueBatchBuilder();u.template=e,u.totalInstanceCount=r,u.rangePairCount=1,u.firstInstanceStart=t,u.firstInstanceCount=r,u.sourceRanges.length=0,u.boundsMin.set(i-s,n-s,a-s),u.boundsMax.set(i+s,n+s,a+s),l?Array.isArray(l)?l.push(u):this.opaqueBatches.set(o,[l,u]):this.opaqueBatches.set(o,u)}pushDraw(e){e.transparent?this.transparentDraws.push(e):e.skinning||e.hasRenderCallbacks&&e.residentInstanceBinding?this.directOpaqueDrawsScratch.push(e):e.residentInstanceBinding?this.residentOpaqueDrawsScratch.push(e):this.stagedOpaqueDrawsScratch.push(e)}getToonOutlineParameters(e){if(!e||!e.visible||!0===e.wireframe||!e.depthTest)return null;const t=e.userData?.outlineParameters;return t&&!1!==t.visible?t:null}getToonOutlineMaterial(e,t){const r=this.getToonOutlineParameters(e);if(!r)return null;if("darkenedAlbedo"===r.colorMode){let t=this.outlineResolvedFrameCache.get(e);if(!t||t.extractionVersion!==this.extractionVersion){const r=this.materialResolver?.(e,"outline");t?(t.extractionVersion=this.extractionVersion,t.material=r):(t={extractionVersion:this.extractionVersion,material:r},this.outlineResolvedFrameCache.set(e,t))}const r=t.material;if(r)return r}let i=this.toonOutlineMaterialCache.get(e);if(!i){const t=t=>new Sr({vertexShader:t?"\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @location(4) skinIndex: vec4<u32>,\n @location(5) skinWeight: vec4<f32>,\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n let localPosition = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight);\n let localNormal = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n let worldPosition = rendererWorldPosition(localPosition, input.instanceIndex);\n let viewPosition = rendererCamera.view * worldPosition;\n let worldNormal = rendererWorldNormal(localNormal, input.instanceIndex);\n let viewNormal = normalize((rendererCamera.view * vec4(worldNormal, 0.0)).xyz);\n let distanceScale = sqrt(max(length(viewPosition.xyz), 0.0001)) * 0.5;\n let displaced = viewPosition.xyz + viewNormal * materialUniforms.outlineThickness * distanceScale;\n return VertexOutput(rendererCamera.projection * vec4(displaced, 1.0));\n}\n":"\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n let worldPosition = rendererWorldPosition(input.position, input.instanceIndex);\n let viewPosition = rendererCamera.view * worldPosition;\n let worldNormal = rendererWorldNormal(input.normal, input.instanceIndex);\n let viewNormal = normalize((rendererCamera.view * vec4(worldNormal, 0.0)).xyz);\n let distanceScale = sqrt(max(length(viewPosition.xyz), 0.0001)) * 0.5;\n let displaced = viewPosition.xyz + viewNormal * materialUniforms.outlineThickness * distanceScale;\n return VertexOutput(rendererCamera.projection * vec4(displaced, 1.0));\n}\n",fragmentShader:"\n@fragment\nfn fsMain() -> @location(0) vec4<f32> {\n return vec4(materialUniforms.outlineColor, materialUniforms.outlineAlpha);\n}\n",vertexAttributes:t?ps:[{name:"position",shaderLocation:0,format:"float32x3"},{name:"normal",shaderLocation:1,format:"float32x3",defaultValue:[0,0,1]}],uniforms:{outlineThickness:r.thickness??.003,outlineColor:(new zi).fromArray(r.color??[0,0,0]),outlineAlpha:r.alpha??e.opacity},side:Vi,depthTest:!0,depthWrite:!0,transparent:!0});i={regular:t(!1),skinned:t(!0)},this.toonOutlineMaterialCache.set(e,i)}const n=t?i.skinned:i.regular;return n.uniforms.outlineThickness.value=r.thickness??.003,n.uniforms.outlineColor.value.fromArray(r.color??[0,0,0]),n.uniforms.outlineAlpha.value=r.alpha??e.opacity,n}pushToonOutlineDraw(e,t){const r=t?this.getToonOutlineMaterial(t,null!==e.skinning):null;if(!r||e.usesBatching)return;const i=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e.geometryKey,e.geometryResource,r,null,e.residentInstanceBinding,e.sourceObject,e.geometryGroup,"",0,e.indexed,e.start,e.count,!0,e.renderOrder,!1,!1,!1,ei(r),e.sortGeometryId,0,e.instanceStart,e.instanceCount,e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius,e.skinning);this.transparentDraws.push(i)}updateTransparentDrawSortDepths(e,t,r){for(let i=0;i<e.length;i+=1){const n=e[i];0===n.transparentSortGroup&&(n.sortDepth=(n.boundsCenter.x-t.x)*r.x+(n.boundsCenter.y-t.y)*r.y+(n.boundsCenter.z-t.z)*r.z)}}extractScene(e,t,r=!1){this.extractionVersion+=1,this.drawCallPoolCount=0,this.opaqueBatchPoolCount=0;this.opaqueBatches.clear();const i=this.transparentDraws;i.length=0;const n=this.residentInstanceUploadsScratch;n.length=0;const a=this.sourceInstanceDataScratch;a.reset();const s=this.gpuOpaqueDrawsScratch;s.length=0;const o=this.directOpaqueDrawsScratch;o.length=0;const l=this.stagedOpaqueDrawsScratch;l.length=0;const c=this.residentOpaqueDrawsScratch;c.length=0;const u=this.opaqueInstanceDataScratch;u.reset();const d=this.finalInstanceDataScratch;d.reset();const f=this.extractedAmbientScratch;f.set(0,0,0,0);let m=null;const g=this.activeDirectionalLightsScratch,w=this.activePointLightsScratch,b=this.activeSpotLightsScratch,y=this.fogVolumeObjectsScratch;g.length=0,w.length=0,b.length=0,y.length=0;const S=this.extractedBoundsMinScratch;S.set(1/0,1/0,1/0);const C=this.extractedBoundsMaxScratch;C.set(-1/0,-1/0,-1/0),function(e,t){const r=e.elements,i=r[0],n=r[1],a=r[2],s=r[3],o=r[4],l=r[5],c=r[6],u=r[7],d=r[8],h=r[9],p=r[10],f=r[11],m=r[12],g=r[13],v=r[14],x=r[15];mi(t,0,s-i,u-o,f-d,x-m),mi(t,4,s+i,u+o,f+d,x+m),mi(t,8,s+n,u+l,f+h,x+g),mi(t,12,s-n,u-l,f-h,x-g),mi(t,16,s-a,u-c,f-p,x-v),mi(t,20,a,c,p,v)}(fi(t,this.cameraViewProjScratch),this.cameraFrustumPlanesScratch);const P=this.transparentSortCameraPositionScratch,M=this.transparentSortCameraForwardScratch;t.getWorldPosition(P),t.getWorldDirection(M);const B=r?this.isSphereVisibleForCompilationScratch:this.isSphereVisibleScratch,D=this.updateExtractedBoundsFromMatrixScratch,T=this.objectTraversalStackScratch;T.length=0,T.push(e);for(let e=this.csmCascadeLights.length-1;e>=0;e-=1)T.push(this.csmCascadeLights[e]);for(;T.length>0;){const e=T.pop();if(this.extractingCaster=e.castShadow,!e.visible)continue;const r=0!==(e.layers.mask&t.layers.mask);if(!0===e.isFogVolumeObject&&null!=e.volume)y.push(e);else if(e.isAmbientLight){if(r){const t=e;f.x+=t.color.r*t.intensity,f.y+=t.color.g*t.intensity,f.z+=t.color.b*t.intensity,f.w=1}}else if(e.isHemisphereLight){if(r&&null==m){const t=e,r=this.extractedHemisphereScratch;L.setFromMatrixPosition(t.matrixWorld),r.direction.copy(L),r.direction.lengthSq()<=1e-10?r.direction.set(0,1,0):r.direction.normalize(),r.skyColor.set(t.color.r,t.color.g,t.color.b),r.groundColor.set(t.groundColor.r,t.groundColor.g,t.groundColor.b),r.intensity=t.intensity,m=r}}else if(e.isDirectionalLight){if(r&&g.length<4&&!this.hasExtractedDirectionalLight(g,e)){const t=e,r=t.shadow,i=r.camera,n=this.extractedDirectionalLightsScratch[g.length];n.sourceLight=t,t.target.matrixWorldAutoUpdate&&t.target.updateMatrixWorld(!0),L.setFromMatrixPosition(t.matrixWorld),U.setFromMatrixPosition(t.target.matrixWorld),n.position.copy(L),n.target.copy(U),n.direction.copy(U).sub(L).normalize(),n.color.set(t.color.r,t.color.g,t.color.b),n.intensity=t.intensity,n.volumetricIntensity=t.userData?.volumetricIntensity??0,n.castShadow=t.castShadow&&this.directionalShadowsEnabled,n.shadowBias=r.bias,n.shadowNormalBias=r.normalBias,n.shadowRadius=r.radius,n.shadowIntensity=r.intensity,n.shadowMapSize=Math.max(1,r.mapSize.width,r.mapSize.height),n.shadowCameraLeft=i.left,n.shadowCameraRight=i.right,n.shadowCameraTop=i.top,n.shadowCameraBottom=i.bottom,n.shadowCameraNear=i.near,n.shadowCameraFar=i.far,g.push(n)}}else if(e.isPointLight){if(r&&w.length<v){const t=e,r=t.shadow,i=r.camera;L.setFromMatrixPosition(t.matrixWorld);const n=t.distance>0?t.distance:Math.max(i.far,25);if(!gi(this.cameraFrustumPlanesScratch,L.x,L.y,L.z,n))continue;const a=this.extractedPointLightsScratch[w.length];a.sourceLight=t,a.position.copy(L),a.color.set(t.color.r,t.color.g,t.color.b),a.intensity=t.intensity,a.volumetricIntensity=t.userData?.volumetricIntensity??0,a.distance=t.distance,a.range=n,a.decay=t.decay,a.castShadow=t.castShadow,a.shadowBias=r.bias,a.shadowNormalBias=r.normalBias,a.shadowRadius=r.radius,a.shadowIntensity=r.intensity,a.shadowMapSize=Math.max(1,r.mapSize.width,r.mapSize.height),a.shadowCameraNear=i.near,a.shadowCameraFar=t.distance>0?t.distance:i.far,w.push(a)}}else if(e.isSpotLight){if(r&&b.length<x){const t=e,r=t.shadow,i=r.camera,n=this.extractedSpotLightsScratch[b.length];n.sourceLight=t,t.target.matrixWorldAutoUpdate&&t.target.updateMatrixWorld(!0),L.setFromMatrixPosition(t.matrixWorld),U.setFromMatrixPosition(t.target.matrixWorld);const a=t.distance>0?t.distance:i.far;if(!gi(this.cameraFrustumPlanesScratch,L.x,L.y,L.z,a))continue;n.position.copy(L),n.direction.copy(U).sub(L).normalize(),n.color.set(t.color.r,t.color.g,t.color.b),n.intensity=t.intensity,n.volumetricIntensity=t.userData?.volumetricIntensity??0,n.range=a,n.angle=t.angle,n.penumbra=t.penumbra,n.decay=t.decay,n.castShadow=t.castShadow,n.shadowBias=r.bias,n.shadowNormalBias=r.normalBias,n.shadowRadius=r.radius,n.shadowIntensity=r.intensity,n.shadowMapSize=Math.max(1,r.mapSize.width,r.mapSize.height),n.shadowCameraNear=i.near,n.shadowCameraFar=t.distance>0?t.distance:i.far,n.shadowCameraFov=t.angle*(360/Math.PI)*r.focus,n.map=t.map??null,b.push(n)}}else r&&e.isBatchedMesh?this.collectBatchedMesh(e,a,D,B,t,P,M):r&&e.isInstancedMesh?this.collectInstancedMesh(e,a,D,B):r&&e.isSkinnedMesh?this.collectSkinnedMesh(e,a,D,B):r&&e.isLine?this.collectLine(e,a,D,B):r&&e.isSprite?this.collectSprite(e,a,D,B):r&&e.isMesh&&this.collectMesh(e,a,D,B);const i=e.children;for(let e=i.length-1;e>=0;e-=1)T.push(i[e])}if(this.csmCascadeLights.length>0){const e=new Map;for(let t=0;t<this.csmCascadeLights.length;t+=1)e.set(this.csmCascadeLights[t],t);g.sort((t,r)=>((null==t.sourceLight?void 0:e.get(t.sourceLight))??4)-((null==r.sourceLight?void 0:e.get(r.sourceLight))??4))}const I=o.length;this.updateTransparentDrawSortDepths(i,P,M),i.sort(ni),Number.isFinite(S.x)||(S.set(-6,-6,-6),C.set(6,6,6)),this.sortOpaqueDraws(l);for(let e=0;e<l.length;){const t=l[e],r=u.instanceCount;u.appendRange(a,t.instanceStart,t.instanceCount);let i,n=t.instanceCount,c=t.boundsCenter.x-t.boundsRadius,d=t.boundsCenter.y-t.boundsRadius,h=t.boundsCenter.z-t.boundsRadius,p=t.boundsCenter.x+t.boundsRadius,f=t.boundsCenter.y+t.boundsRadius,m=t.boundsCenter.z+t.boundsRadius,g=e+1;for(;this.dynamicBatchingEnabled&&g<l.length&&li(t,l[g]);){const e=l[g];u.appendRange(a,e.instanceStart,e.instanceCount),i??=[{sourceObject:t.sourceObject,instanceStart:r,instanceCount:t.instanceCount}],i.push({sourceObject:e.sourceObject,instanceStart:r+n,instanceCount:e.instanceCount}),n+=e.instanceCount;const s=e.boundsCenter.x-e.boundsRadius,o=e.boundsCenter.y-e.boundsRadius,v=e.boundsCenter.z-e.boundsRadius,x=e.boundsCenter.x+e.boundsRadius,w=e.boundsCenter.y+e.boundsRadius,b=e.boundsCenter.z+e.boundsRadius;s<c&&(c=s),o<d&&(d=o),v<h&&(h=v),x>p&&(p=x),w>f&&(f=w),b>m&&(m=b),g+=1}const v=.5*(c+p),x=.5*(d+f),w=.5*(h+m),b=p-v,y=f-x,S=m-w;t.instanceStart=r,t.instanceCount=n,t.sourceRanges=i,t.boundsCenter.set(v,x,w),t.boundsRadius=Math.sqrt(b*b+y*y+S*S),t.indexed&&!t.hasRenderCallbacks?s.push(t):o.push(t),e=g}this.sortOpaqueDraws(c);for(let e=0;e<c.length;e+=1){const t=c[e];t.indexed&&!t.hasRenderCallbacks?s.push(t):o.push(t)}d.appendBuilder(u);for(let e=0;e<I;e+=1){const t=o[e];if(t.residentInstanceBinding)continue;const r=d.instanceCount;d.appendRange(a,t.instanceStart,t.instanceCount),t.instanceStart=r}this.sortOpaqueDraws(s),this.sortOpaqueDraws(o);for(let e=0;e<i.length;e+=1){const t=i[e];if(t.residentInstanceBinding)continue;const r=d.instanceCount;d.appendRange(a,t.instanceStart,t.instanceCount),t.instanceStart=r}w.sort(ds),b.sort(ds);for(let e=4;e<w.length;e+=1)w[e].castShadow=!1;for(let e=4;e<b.length;e+=1)b[e].castShadow=!1;const V=this.extractedLightsScratch;V.hemisphere=m,V.directional=g[0]??null,V.point=w[0]??null,V.spot=b[0]??null;const R=this.extractedFrameScratch;R.scene=e,R.camera=t,R.fogVolumeObjects=y,R.transparentDraws=i,R.instanceData=d,R.residentInstanceUploads=n,this.extractingCaster=!1;const G=this.shadowDrawsScratch;G.length=0;for(const e of[s,o,i]){for(const t of e)t.castShadow&&!t.transparent&&G.push(t);if(!r){let t=0;for(const r of e){const i=r.detailCulling??h(r.sourceObject);!r.cameraDetailRejected&&this.isSphereVisibleScratch(r.boundsCenter.x,r.boundsCenter.y,r.boundsCenter.z,r.boundsRadius,r.sourceObject?.frustumCulled??!0)&&p(r.boundsCenter,r.boundsRadius,this.cameraViewProjScratch,this.state.width,this.state.height,P,!1===r.cameraDetailRejected?0:i.minScreenSize,i.maxDistance)&&(e[t++]=r)}e.length=t}}return R.shadowDraws=G,R}collectLine(e,t,r,i){if(Array.isArray(e.material)||!e.geometry.getAttribute("position"))return;const n=e.geometry,a=e.material;if(!1===a.visible)return;if((!0===a.isLineBasicMaterial||!0===a.isMeshBasicMaterial)&&!0!==a.isLineMaterial){const s=e.isLineSegments?"line-list":"line-strip",o=this.resolveLineBasicMaterial(a,s),l=`${Gr(n)}:${s}`;let c=this.lineProxyCache.get(e);c&&c.sourceGeometry===n?c.signature!==l&&(c.signature=l):(c={signature:l,sourceGeometry:n,mesh:new ji(n,o)},this.lineProxyCache.set(e,c));const u=c.mesh;return u.material=o,u.matrixWorld.copy(e.matrixWorld),u.frustumCulled=e.frustumCulled,u.renderOrder=e.renderOrder,u.castShadow=!1,u.receiveShadow=!1,u.onBeforeRender=(...t)=>e.onBeforeRender(...t),void this.collectMesh(u,t,r,i)}const s=Gr(n);let o=this.lineProxyCache.get(e);if(!o||o.sourceGeometry!==n||o.signature!==s){const t=n.getAttribute("position"),r=n.index,i=r?.count??t.count,a=Math.max(0,Math.min(i,n.drawRange.start)),l=Number.isFinite(n.drawRange.count)?n.drawRange.count:i-a,c=Math.max(a,Math.min(i,a+l)),u=e.isLineSegments?2:1,d=[],h=[],p=e=>r?r.getX(e):e;for(let e=a;e+1<c;e+=u){const r=p(e),i=p(e+1);d.push(t.getX(r),t.getY(r),t.getZ(r)),h.push(t.getX(i),t.getY(i),t.getZ(i))}const f=new Gi;f.setIndex([0,2,1,2,3,1,2,4,3,4,5,3,4,6,5,6,7,5]),f.setAttribute("position",new Ri(new Float32Array([-1,2,0,1,2,0,-1,1,0,1,1,0,-1,0,0,1,0,0,-1,-1,0,1,-1,0]),3)),f.setAttribute("instanceStart",new Ai(new Float32Array(d),3)),f.setAttribute("instanceEnd",new Ai(new Float32Array(h),3)),f.instanceCount=d.length/3;const m=vi(n);f.boundingSphere=new _i(m.center.clone(),m.radius),o={signature:s,sourceGeometry:n,mesh:new ji(f,e.material)},this.lineProxyCache.set(e,o)}const l=o.mesh;l.matrixWorld.copy(e.matrixWorld),l.frustumCulled=e.frustumCulled,l.renderOrder=e.renderOrder,l.castShadow=e.castShadow??!1,l.receiveShadow=e.receiveShadow??!1,l.onBeforeRender=(...t)=>e.onBeforeRender(...t),this.collectMesh(l,t,r,i)}collectSprite(e,t,r,i){let n=this.spriteProxyCache.get(e);if(!n){const t=e.geometry.clone();n={mesh:new ji(t,e.material),centerX:Number.NaN,centerY:Number.NaN},this.spriteProxyCache.set(e,n)}if(n.centerX!==e.center.x||n.centerY!==e.center.y){const t=n.mesh.geometry.getAttribute("position"),r=e.geometry.getAttribute("position");for(let i=0;i<t.count;i+=1)t.setXYZ(i,r.getX(i)+.5-e.center.x,r.getY(i)+.5-e.center.y,r.getZ(i));t.needsUpdate=!0,n.mesh.geometry.computeBoundingSphere(),n.centerX=e.center.x,n.centerY=e.center.y}const a=n.mesh;a.material=e.material,a.matrixWorld.copy(e.matrixWorld),a.frustumCulled=e.frustumCulled,a.renderOrder=e.renderOrder,a.castShadow=e.castShadow,a.receiveShadow=e.receiveShadow,a.onBeforeRender=(...t)=>e.onBeforeRender(...t),a.onAfterRender=(...t)=>e.onAfterRender(...t),this.collectMesh(a,t,r,i)}hasExtractedDirectionalLight(e,t){for(let r=0;r<e.length;r+=1)if(e[r].sourceLight===t)return!0;return!1}getObjectMotionHistory(e,t){let r=this.objectMotionHistory.get(e);if(!r)return r={matrix:new Float32Array(16),generation:this.motionVectorHistoryGeneration,lastExtractionVersion:-1,valid:!1},r.matrix.set(t),this.objectMotionHistory.set(e,r),r;const i=!0===e.userData.motionBlurTeleported;i&&(e.userData.motionBlurTeleported=!1);const n=(t[12]??0)-r.matrix[12],a=(t[13]??0)-r.matrix[13],s=(t[14]??0)-r.matrix[14],o=Math.max(0,Number(e.userData.motionBlurTeleportDistance??10));return r.valid=this.motionVectorHistoryValid&&r.generation===this.motionVectorHistoryGeneration&&r.lastExtractionVersion===this.extractionVersion-1&&!i&&n*n+a*a+s*s<=o*o,r}commitObjectMotionHistory(e,t){e.matrix.set(t),e.generation=this.motionVectorHistoryGeneration,e.lastExtractionVersion=this.extractionVersion}collectMesh(e,t,r,i){const n=e.geometry;if(void 0===n.attributes.position)return;const a=e.material,s=Array.isArray(a);if(!s&&!1===a.visible||s&&a.every(e=>!1===e.visible))return;const o=this.getGeometryResource(n),l=this.meshExtractionCache.get(e),c=l?.geometryResource===o?l:null,u=c?null:vi(n),d=c?c.localBoundsCenter:u.center,h=c?c.localBoundsRadius:u.radius,p=e.matrixWorld.elements,f=d.x,m=d.y,g=d.z,v=p[0]*f+p[4]*m+p[8]*g+p[12],x=p[1]*f+p[5]*m+p[9]*g+p[13],w=p[2]*f+p[6]*m+p[10]*g+p[14],b=p[0]*p[0]+p[1]*p[1]+p[2]*p[2],y=p[4]*p[4]+p[5]*p[5]+p[6]*p[6],S=p[8]*p[8]+p[9]*p[9]+p[10]*p[10],C=h*Math.sqrt(Math.max(b,y,S,1e-10));if(!i(v,x,w,C,e.frustumCulled))return;const P=this.resolvedMeshMaterialsScratch;P.length=0;let M=null;if(s)for(let e=0;e<a.length;e+=1)P[e]=this.resolveMaterial(a[e]);else{if(!a.visible)return;M=this.resolveMaterial(a)}const B=Ci(e),D=l&&l.customDepthMaterial===B&&l.geometryResource.lastValidatedExtractionVersion===this.extractionVersion&&(!s&&l.material===a&&l.resolvedMaterial===M||s&&null!==l.materials&&null!==l.resolvedMaterials&&Fr(l.materials,a)&&Or(l.resolvedMaterials,P))?l:this.getMeshExtractionCacheEntry(e,a,M,P,B,o),T=D.templates.length;if(0===T)return;const I=function(e){const t=e.attributes;let r=!1,i=1/0;for(const e in t){const n=t[e];!0!==n.isInstancedBufferAttribute&&!0!==n.data?.isInstancedInterleavedBuffer||(r=!0,n.count<i&&(i=n.count))}if(!r)return 1;const n=e.instanceCount;return Number.isFinite(n)?Math.max(0,Math.floor(n)):Math.max(0,i)}(n),V=this.getObjectMotionHistory(e,p),R=ls(e),G=cs(e);let z=0,L=null;if(!(n instanceof Fi&&I>1)||e instanceof Ni||this.hasRenderCallbacks(e))for(let e=0;e<I;e+=1){const r=Xr(t,p,1,1,1,1,void 0,V.matrix,R,G,V.valid?1:0);0===e&&(z=r)}else{let t=this.repeatedMeshInstances.get(e);if(!t||t.geometry!==n||t.data.disposed){t&&this.repeatedInstanceResources.get(t.data)?.();const r=new Bi,i=()=>{n.removeEventListener("dispose",i),r.dispose(),this.repeatedInstanceResources.delete(r)};n.addEventListener("dispose",i),this.repeatedInstanceResources.set(r,i),t={geometry:n,data:r},this.repeatedMeshInstances.set(e,t)}L=t.data,L.update(I,p,V.matrix,R,G,V.valid?1:0),!L.residentBufferDirty&&L.residentInstanceBinding.buffer||this.residentInstanceUploadsScratch.push(L)}this.commitObjectMotionHistory(V,p),r(p);for(let e=0;e<T;e+=1){const t=D.templates[e],r=this.populateDrawCall(this.acquireDrawCall(),t,z,I,v,x,w,C);L&&(r.residentInstanceBinding=L.residentInstanceBinding),t.transparent?this.transparentDraws.push(r):this.pushDraw(r);const i=s?a[t.geometryGroup?.materialIndex??0]:a;this.pushToonOutlineDraw(r,i)}}prepareSceneForCompilation(e,t,r){if(!(this.state.initialized&&this.state.device&&this.state.context&&this.state.mainDepthView&&this.state.sceneColorView&&this.state.postProcessColorView&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.shadowCameraBuffer&&this.state.sceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.shadowComparisonSampler&&this.state.linearClampSampler&&this.state.nearestClampSampler&&this.state.visibilityParamsBuffer&&this.state.directionalShadowView&&this.state.pointShadowArrayView&&this.state.spotShadowView&&this.state.hizCopyKernel&&this.state.hizReduceKernel&&this.state.visibilityKernel&&this.state.presentPipeline))throw new Error("WebGpuRenderer.initialize() must complete before compile().");const i=r?this.pipelineCompilationDiagnostics:void 0;let n=performance.now();const a=e=>{i&&(i.phases[e]=Math.round(performance.now()-n)),n=performance.now()};e.matrixWorldAutoUpdate&&e.updateMatrixWorld(),null===t.parent&&t.matrixWorldAutoUpdate&&t.updateMatrixWorld(),a("worldMatrices");const s=this.extractScene(e,t,!0);a("extractScene"),this.ensureShadowTextureSizes(s),this.uploadInstanceData(s.instanceData),this.uploadResidentInstanceData(s.residentInstanceUploads),this.uploadDrawMetadata(this.getHiZOcclusionCullingActive()?s.gpuOpaqueDraws:[]),this.ensureTiledLightingSize(),this.updateCameraUniforms(t,e),this.updateLightUniforms(s),a("sceneUploads");const o=this.compileDrawScratch;o.length=0,o.push(...s.gpuOpaqueDraws,...s.directOpaqueDraws,...s.transparentDraws);for(const e of o)this.prepareDrawGeometryVertexBuffers(e);if(i&&(i.drawCount=o.length),a("geometryBuffers"),r){const e=[];this.renderGraph.reset();const t=this.state.device.createCommandEncoder({label:"renderer-graph-compilation-encoder"}),r=this.createGraphBuilderContext(this.renderGraph,t,this.getSharedSceneBindGroup(),this.getSharedShadowBindGroup(),null,this.state.sceneColorView,s,{drawCallCount:0,triangleCount:0},e);this.graphBuilder(this.renderGraph,r),i&&(i.materialRequestCount=e.length),a("renderGraph");const n=[],o=new Set;for(const t of e){n.push(this.compileDrawMaterialsAsync(t.draws,t.colorTargetFormats,t.sampleCount));const e=`${t.sampleCount}:${t.colorTargetFormats.join("|")}:${t.staticDrawStage}`;o.has(e)||(o.add(e),n.push(this.compileStaticDrawMaterialsAsync(t.colorTargetFormats,t.sampleCount,t.staticDrawStage)))}return a("scheduleMaterials"),Promise.all(n).then(()=>{})}this.compileDrawMaterials(o)}collectInstancedMesh(e,t,r,i){if(void 0===e.geometry?.getAttribute("position"))return;const n=e.material;if(!1===n.visible)return;const a=this.instancedMeshExtractionCache.get(e),s=!0===e.userData.webGpuCacheMaterial&&a?.sourceMaterial===n&&a.sourceMaterialVersion===n.version&&a.material!==this.fallbackMaterial?a.material:this.resolveMaterial(n);if(!s)return;const o=Ci(e),l=this.getGeometryResource(e.geometry),c=this.getInstancedMeshExtractionCacheEntry(e,s,o,l),u=e.instanceMatrix.array,d=e.instanceMatrix.version,h=e.instanceColor?.array,p=e.instanceColor?.itemSize??0,f=e.instanceColor?.version??-1,m=c.cacheValid&&c.cachedCount===e.count&&c.cachedInstanceMatrixVersion===d&&c.cachedInstanceColorVersion===f&&di(c.cachedMatrixWorld,e.matrixWorld.elements),g=hi(e.matrixWorld.elements),v=g&&!e.frustumCulled;if(!m){const t=c.cachedInstanceMatrixVersion!==d||c.cachedCount!==e.count,r=c.cachedInstanceColorVersion!==f||c.cachedCount!==e.count;if(v){const i=e.matrixWorld.elements,n=i[12]??0,a=i[13]??0,s=i[14]??0;c.cachedDrawBoundsCenter.set(n,a,s),c.cachedDrawBoundsRadius=0,c.cachedBoundsMin.set(n,a,s),c.cachedBoundsMax.set(n,a,s),c.cachedInstanceMatrixVersion=d,c.cachedInstanceColorVersion=f,c.cachedCount=e.count,c.cachedDefaultColorData=null,ui(e.matrixWorld.elements,c.cachedMatrixWorld),c.residentBufferDirty||=t,c.residentColorBufferDirty||=r,c.cacheValid=!0}else{const t=c.cachedInstanceData.beginWriteInstances(e.count),r=c.cachedBoundsMin,i=c.cachedBoundsMax;r.set(1/0,1/0,1/0),i.set(-1/0,-1/0,-1/0);const n=c.localBoundsCenter,a=c.localBoundsRadius,s=e.matrixWorld.elements,o=hi(s),l=n.x,m=n.y,g=n.z,v=s[0],x=s[4],b=s[8],y=s[12],S=s[1],C=s[5],P=s[9],M=s[13],B=s[2],D=s[6],T=s[10],I=s[14],V=s[3],R=s[7],G=s[11],z=s[15];for(let n=0;n<e.count;n+=1){const e=16*n,s=n*w,c=u[e+0]??0,d=u[e+1]??0,f=u[e+2]??0,U=u[e+3]??0,A=u[e+4]??0,F=u[e+5]??0,k=u[e+6]??0,E=u[e+7]??0,O=u[e+8]??0,j=u[e+9]??0,$=u[e+10]??0,W=u[e+11]??0,N=u[e+12]??0,_=u[e+13]??0,H=u[e+14]??0,q=u[e+15]??0;let K,Z,Y,X,J,Q,ee,te,re,ie,ne,ae,se,oe,le,ce;o?(K=c,Z=d,Y=f,X=U,J=A,Q=F,ee=k,te=E,re=O,ie=j,ne=$,ae=W,se=N,oe=_,le=H,ce=q):(K=v*c+x*d+b*f+y*U,J=v*A+x*F+b*k+y*E,re=v*O+x*j+b*$+y*W,se=v*N+x*_+b*H+y*q,Z=S*c+C*d+P*f+M*U,Q=S*A+C*F+P*k+M*E,ie=S*O+C*j+P*$+M*W,oe=S*N+C*_+P*H+M*q,Y=B*c+D*d+T*f+I*U,ee=B*A+D*F+T*k+I*E,ne=B*O+D*j+T*$+I*W,le=B*N+D*_+T*H+I*q,X=V*c+R*d+G*f+z*U,te=V*A+R*F+G*k+z*E,ae=V*O+R*j+G*$+z*W,ce=V*N+R*_+G*H+z*q),t[s+0]=K,t[s+1]=Z,t[s+2]=Y,t[s+3]=X,t[s+4]=J,t[s+5]=Q,t[s+6]=ee,t[s+7]=te,t[s+8]=re,t[s+9]=ie,t[s+10]=ne,t[s+11]=ae,t[s+12]=se,t[s+13]=oe,t[s+14]=le,t[s+15]=ce;const ue=n*p;t[s+16]=h?h[ue+0]??1:1,t[s+17]=h?h[ue+1]??1:1,t[s+18]=h?h[ue+2]??1:1,t[s+19]=h&&p>=4?h[ue+3]??1:1,t[s+20]=n,t[s+21]=1,t[s+22]=1,t[s+23]=0;for(let e=0;e<16;e+=1)t[s+24+e]=t[s+e];const de=K*l+J*m+re*g+se,he=Z*l+Q*m+ie*g+oe,pe=Y*l+ee*m+ne*g+le,fe=Math.sqrt(K*K+Z*Z+Y*Y),me=Math.sqrt(J*J+Q*Q+ee*ee),ge=Math.sqrt(re*re+ie*ie+ne*ne),ve=a*Math.max(fe,me,ge,1e-5);bi(r,i,L.set(de,he,pe),ve)}c.cachedDrawBoundsCenter.copy(r).add(i).multiplyScalar(.5);const U=i.x-c.cachedDrawBoundsCenter.x,A=i.y-c.cachedDrawBoundsCenter.y,F=i.z-c.cachedDrawBoundsCenter.z;c.cachedDrawBoundsRadius=Math.sqrt(U*U+A*A+F*F),c.cachedInstanceMatrixVersion=d,c.cachedInstanceColorVersion=f,c.cachedCount=e.count,c.cachedDefaultColorData=null,ui(e.matrixWorld.elements,c.cachedMatrixWorld),c.residentBufferDirty=!0,c.residentColorBufferDirty=!0,c.cacheValid=!0}}if(!i(c.cachedDrawBoundsCenter.x,c.cachedDrawBoundsCenter.y,c.cachedDrawBoundsCenter.z,c.cachedDrawBoundsRadius,e.frustumCulled))return;c.residentInstanceBinding&&c.residentInstanceBinding.mode!==(g?"instanced-direct":"packed")&&(c.residentInstanceBinding.mode=g?"instanced-direct":"packed",c.residentInstanceBinding.sceneBindGroup=null,c.residentInstanceBinding.shadowBindGroup=null,c.residentInstanceBinding.shadowBindGroups.clear(),c.residentInstanceBinding.sceneBindGroupVersion=0,c.residentInstanceBinding.shadowBindGroupVersion=0,c.residentBufferDirty=!0,c.residentColorBufferDirty=!0),(c.residentBufferDirty||c.residentColorBufferDirty||!c.residentInstanceBinding)&&this.residentInstanceUploadsScratch.push(c),pi(this.extractedBoundsMinScratch,this.extractedBoundsMaxScratch,c.cachedBoundsMin,c.cachedBoundsMax);const x=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e.geometry,l,s,o,c.residentInstanceBinding,e,null,c.batchKey,c.batchHash,c.indexed,c.drawRangeStart,c.drawRangeCount,s.transparent||s.requiresLatePass(),e.renderOrder,this.hasRenderCallbacks(e),e.castShadow,e.receiveShadow,c.sortMaterialId,c.sortGeometryId,c.sortCustomDepthMaterialId,0,e.count,c.cachedDrawBoundsCenter.x,c.cachedDrawBoundsCenter.y,c.cachedDrawBoundsCenter.z,c.cachedDrawBoundsRadius);v&&!x.transparent?this.directOpaqueDrawsScratch.push(x):this.pushDraw(x)}collectSkinnedMesh(e,t,r,i){if(void 0===e.geometry?.getAttribute("position"))return;const n=e.boundingSphere,a=L;let s=0;if(null!==n){const t=n.center,r=e.matrixWorld.elements,a=r[0]*t.x+r[4]*t.y+r[8]*t.z+r[12],o=r[1]*t.x+r[5]*t.y+r[9]*t.z+r[13],l=r[2]*t.x+r[6]*t.y+r[10]*t.z+r[14];if(s=n.radius*xi(e.matrixWorld),e.frustumCulled&&!i(a,o,l,s,!0))return}const o=Array.isArray(e.material)?e.material:null,l=o?o[0]:e.material,c=Ci(e),u=null!==e.geometry.index,d=this.getSkinnedGeometryResource(e);if(this.refreshSkinningPalette(d.skinning.palette),this.refreshSkinningBindMatrices(e,d.skinning),null===n){if(this.updateSkinnedBounds(e,d),a.copy(d.localBoundsCenter).applyMatrix4(e.matrixWorld),s=d.localBoundsRadius*xi(e.matrixWorld),!i(a.x,a.y,a.z,s,e.frustumCulled))return}else a.copy(n.center).applyMatrix4(e.matrixWorld);this.uploadSkinningResources(d.skinning);const h=this.getObjectMotionHistory(e,e.matrixWorld.elements),p=Jr(t,e.matrixWorld,1,1,1,1,void 0,h.matrix,ls(e),cs(e),h.valid?1:0);if(this.commitObjectMotionHistory(h,e.matrixWorld.elements),r(e.matrixWorld.elements),e.geometry.groups.length>0&&(null===o||o.length>0)){for(let t=0;t<e.geometry.groups.length;t++){const r=e.geometry.groups[t],i=o?o[r.materialIndex??0]??l:l,n=this.resolveSkinnedMaterial(i);if(!n)continue;const h=_r(e.geometry,u,r.start,r.count),f=this.skinnedDrawKeys.get(e,t,n,u,r.start,h,c),m=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e,d.resource,n,c,null,e,r,f.batchKey,f.batchHash,u,r.start,h,n.transparent,e.renderOrder,this.hasRenderCallbacks(e),e.castShadow,e.receiveShadow,f.materialId,f.geometryId,f.depthMaterialId,p,1,a.x,a.y,a.z,s,d.skinning);this.pushDraw(m),this.pushToonOutlineDraw(m,i)}return}const f=this.resolveSkinnedMaterial(l);if(!f)return;const m=Hr(e.geometry,u),g=this.skinnedDrawKeys.get(e,0,f,u,m.start,m.count,c),v=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e,d.resource,f,c,null,e,null,g.batchKey,g.batchHash,u,m.start,m.count,f.transparent,e.renderOrder,this.hasRenderCallbacks(e),e.castShadow,e.receiveShadow,g.materialId,g.geometryId,g.depthMaterialId,p,1,a.x,a.y,a.z,s,d.skinning);this.pushDraw(v),this.pushToonOutlineDraw(v,l)}collectBatchedMesh(e,t,r,i,n,a,s){if(void 0===e.geometry?.getAttribute("position"))return;const o=this.resolveMaterial(e.material);if(!o)return;const l=Ci(e),c=(e.geometry.index,this.getGeometryResource(e.geometry)),u=e,d=u._instanceInfo??u._drawInfo??[],h=d.length,p=u._matricesTexture?.image.data,f=u._colorsTexture?.image.data,m=this.getBatchedMeshExtractionCacheEntry(e,o,l,c,u),g=e.matrixWorld.elements,v=u._matricesTexture?.version??0,x=u._colorsTexture?.version??-1;if(m.cacheValid&&!o.transparent&&m.cachedMatricesVersion===v&&m.cachedColorsVersion===x&&m.cachedInstanceInfoLength===d.length&&m.cachedGeometryCount===(u._geometryCount??0)&&di(m.cachedMatrixWorld,g)&&this.batchedGeometryIdsMatchSnapshot(m.geometryIdsSnapshot,d)){let t=!1;for(let r=0;r<m.cachedDraws.length;r+=1){const n=m.cachedDraws[r];i(n.boundsCenter.x,n.boundsCenter.y,n.boundsCenter.z,n.boundsRadius,e.frustumCulled)&&(t=!0,this.pushDraw(this.populateDynamicDrawCall(this.acquireDrawCall(),n.template.geometry,n.template.geometryKey,n.template.geometryResource,n.template.material,n.template.customDepthMaterial,m.residentInstanceBinding,n.template.sourceObject,n.template.geometryGroup,n.template.batchKey,n.template.batchHash,n.template.indexed,n.template.start,n.template.count,n.template.transparent,n.template.sourceObject?.renderOrder??n.template.renderOrder,this.hasRenderCallbacks(n.template.sourceObject),n.template.sourceObject?Boolean(n.template.sourceObject.castShadow):n.template.castShadow,n.template.sourceObject?Boolean(n.template.sourceObject.receiveShadow):n.template.receiveShadow,n.template.sortMaterialId,n.template.sortGeometryId,n.template.sortCustomDepthMaterialId,n.instanceStart,n.instanceCount,n.boundsCenter.x,n.boundsCenter.y,n.boundsCenter.z,n.boundsRadius)))}if(!t)return;return!m.residentBufferDirty&&m.residentInstanceBinding||this.residentInstanceUploadsScratch.push(m),void pi(this.extractedBoundsMinScratch,this.extractedBoundsMaxScratch,m.cachedBoundsMin,m.cachedBoundsMax)}if(o.transparent){const o=[],l=!e.sortObjects||null!==e.customSort;for(let n=0;n<h;n+=1){const c=d[n];if(!c?.active||!c.visible)continue;const u=m.templates[c.geometryIndex];if(!u)continue;p?R.fromArray(p,16*n):e.getMatrixAt(n,R),G.multiplyMatrices(e.matrixWorld,R);const h=u.localBoundsCenter,g=G.elements,v=g[0]*h.x+g[4]*h.y+g[8]*h.z+g[12],x=g[1]*h.x+g[5]*h.y+g[9]*h.z+g[13],w=g[2]*h.x+g[6]*h.y+g[10]*h.z+g[14],b=Math.sqrt(g[0]*g[0]+g[1]*g[1]+g[2]*g[2]),y=Math.sqrt(g[4]*g[4]+g[5]*g[5]+g[6]*g[6]),S=Math.sqrt(g[8]*g[8]+g[9]*g[9]+g[10]*g[10]),C=u.localBoundsRadius*Math.max(b,y,S,1e-5);if(!i(v,x,w,C,e.frustumCulled&&e.perObjectFrustumCulled))continue;const P=f?f[4*n+0]??1:1,M=f?f[4*n+1]??1:1,B=f?f[4*n+2]??1:1,D=f?f[4*n+3]??1:1,T=Jr(t,G,P,M,B,D,n);r(G.elements);const I=this.populateDrawCall(this.acquireDrawCall(),u,T,1,v,x,w,C),V=(v-a.x)*s.x+(x-a.y)*s.y+(w-a.z)*s.z;l?o.push({start:u.start,count:u.count,z:V,index:n,draw:I}):(I.sortDepth=V,this.transparentDraws.push(I))}if(l&&o.length>0){e.sortObjects&&e.customSort?e.customSort.call(e,o,n):e.sortObjects&&o.sort((e,t)=>t.z-e.z);let t=0;for(let e=0;e<o.length;e+=1)t+=o[e].z;t/=o.length;const r=ei(e);for(let e=0;e<o.length;e+=1){const i=o[e].draw;i.sortDepth=t,i.transparentSortGroup=r,i.transparentSortOrder=e,this.transparentDraws.push(i)}}return}const b=m.activeGroups;for(let e=0;e<b.length;e+=1){const t=b[e];t.activeInFrame=!1,t.activeCount=0}b.length=0;const y=m.cachedBoundsMin,S=m.cachedBoundsMax;y.set(1/0,1/0,1/0),S.set(-1/0,-1/0,-1/0),m.geometryIdsSnapshot.length!==d.length&&(m.geometryIdsSnapshot=new Int32Array(d.length));let C=0;for(let e=0;e<h;e+=1){const t=d[e];if(!t?.active||!t.visible){m.geometryIdsSnapshot[e]=-1;continue}const r=m.groups[t.geometryIndex];r?(m.geometryIdsSnapshot[e]=t.geometryIndex,r.activeInFrame||(r.activeInFrame=!0,r.activeCount=0,r.boundsMin.set(1/0,1/0,1/0),r.boundsMax.set(-1/0,-1/0,-1/0),b.push(r)),r.activeCount+=1,C+=1):m.geometryIdsSnapshot[e]=-1}const P=m.cachedInstanceData.beginWriteInstances(C);let M=0;for(let e=0;e<b.length;e+=1){const t=b[e];t.instanceStart=M,t.writeOffset=M*w,M+=t.activeCount}const B=hi(g),D=g[0],T=g[4],I=g[8],V=g[12],z=g[1],L=g[5],U=g[9],A=g[13],F=g[2],k=g[6],E=g[10],O=g[14],j=g[3],$=g[7],W=g[11],N=g[15];for(let t=0;t<h;t+=1){const r=m.geometryIdsSnapshot[t]??-1;if(r<0)continue;const i=m.groups[r];if(!i)continue;let n,a,s,o,l,c,u,d,h,g,v,x,b,C,M,G,_,H,q,K,Z,Y,X,J,Q,ee,te,re,ie,ne,ae,se;if(p){const e=16*t;n=p[e+0]??0,a=p[e+1]??0,s=p[e+2]??0,o=p[e+3]??0,l=p[e+4]??0,c=p[e+5]??0,u=p[e+6]??0,d=p[e+7]??0,h=p[e+8]??0,g=p[e+9]??0,v=p[e+10]??0,x=p[e+11]??0,b=p[e+12]??0,C=p[e+13]??0,M=p[e+14]??0,G=p[e+15]??0}else{e.getMatrixAt(t,R);const r=R.elements;n=r[0]??0,a=r[1]??0,s=r[2]??0,o=r[3]??0,l=r[4]??0,c=r[5]??0,u=r[6]??0,d=r[7]??0,h=r[8]??0,g=r[9]??0,v=r[10]??0,x=r[11]??0,b=r[12]??0,C=r[13]??0,M=r[14]??0,G=r[15]??0}B?(_=n,H=a,q=s,K=o,Z=l,Y=c,X=u,J=d,Q=h,ee=g,te=v,re=x,ie=b,ne=C,ae=M,se=G):(_=D*n+T*a+I*s+V*o,Z=D*l+T*c+I*u+V*d,Q=D*h+T*g+I*v+V*x,ie=D*b+T*C+I*M+V*G,H=z*n+L*a+U*s+A*o,Y=z*l+L*c+U*u+A*d,ee=z*h+L*g+U*v+A*x,ne=z*b+L*C+U*M+A*G,q=F*n+k*a+E*s+O*o,X=F*l+k*c+E*u+O*d,te=F*h+k*g+E*v+O*x,ae=F*b+k*C+E*M+O*G,K=j*n+$*a+W*s+N*o,J=j*l+$*c+W*u+N*d,re=j*h+$*g+W*v+N*x,se=j*b+$*C+W*M+N*G);const oe=f?f[4*t+0]??1:1,le=f?f[4*t+1]??1:1,ce=f?f[4*t+2]??1:1,ue=f?f[4*t+3]??1:1,de=i.writeOffset;P[de+0]=_,P[de+1]=H,P[de+2]=q,P[de+3]=K,P[de+4]=Z,P[de+5]=Y,P[de+6]=X,P[de+7]=J,P[de+8]=Q,P[de+9]=ee,P[de+10]=te,P[de+11]=re,P[de+12]=ie,P[de+13]=ne,P[de+14]=ae,P[de+15]=se,P[de+16]=oe,P[de+17]=le,P[de+18]=ce,P[de+19]=ue,P[de+20]=t,P[de+21]=1,P[de+22]=1,P[de+23]=0;for(let e=0;e<16;e+=1)P[de+24+e]=P[de+e];i.writeOffset+=w;const he=i.template.localBoundsCenter,pe=_*he.x+Z*he.y+Q*he.z+ie,fe=H*he.x+Y*he.y+ee*he.z+ne,me=q*he.x+X*he.y+te*he.z+ae,ge=Math.sqrt(_*_+H*H+q*q),ve=Math.sqrt(Z*Z+Y*Y+X*X),xe=Math.sqrt(Q*Q+ee*ee+te*te),we=i.template.localBoundsRadius*Math.max(ge,ve,xe,1e-5),be=pe-we,ye=fe-we,Se=me-we,Ce=pe+we,Pe=fe+we,Me=me+we;be<i.boundsMin.x&&(i.boundsMin.x=be),ye<i.boundsMin.y&&(i.boundsMin.y=ye),Se<i.boundsMin.z&&(i.boundsMin.z=Se),Ce>i.boundsMax.x&&(i.boundsMax.x=Ce),Pe>i.boundsMax.y&&(i.boundsMax.y=Pe),Me>i.boundsMax.z&&(i.boundsMax.z=Me),be<y.x&&(y.x=be),ye<y.y&&(y.y=ye),Se<y.z&&(y.z=Se),Ce>S.x&&(S.x=Ce),Pe>S.y&&(S.y=Pe),Me>S.z&&(S.z=Me)}const _=m.cachedDraws;let H=0;for(let e=0;e<b.length;e+=1){const t=b[e],r=.5*(t.boundsMin.x+t.boundsMax.x),i=.5*(t.boundsMin.y+t.boundsMax.y),n=.5*(t.boundsMin.z+t.boundsMax.z),a=t.boundsMax.x-r,s=t.boundsMax.y-i,o=t.boundsMax.z-n,l=Math.sqrt(a*a+s*s+o*o);let c=_[H];c||(c={template:t.template,instanceStart:0,instanceCount:0,boundsCenter:new Ki,boundsRadius:0},_[H]=c),c.template=t.template,c.instanceStart=t.instanceStart,c.instanceCount=t.activeCount,c.boundsCenter.set(r,i,n),c.boundsRadius=l,H+=1}_.length=H,m.cachedMatricesVersion=v,m.cachedColorsVersion=x,m.cachedInstanceInfoLength=d.length,m.cachedGeometryCount=u._geometryCount??0,ui(g,m.cachedMatrixWorld),m.residentBufferDirty=!0,m.cacheValid=!0;let q=!1;for(let t=0;t<_.length;t+=1){const r=_[t];i(r.boundsCenter.x,r.boundsCenter.y,r.boundsCenter.z,r.boundsRadius,e.frustumCulled)&&(q=!0,this.pushDraw(this.populateDynamicDrawCall(this.acquireDrawCall(),r.template.geometry,r.template.geometryKey,r.template.geometryResource,r.template.material,r.template.customDepthMaterial,m.residentInstanceBinding,r.template.sourceObject,r.template.geometryGroup,r.template.batchKey,r.template.batchHash,r.template.indexed,r.template.start,r.template.count,r.template.transparent,r.template.sourceObject?.renderOrder??r.template.renderOrder,this.hasRenderCallbacks(r.template.sourceObject),r.template.sourceObject?Boolean(r.template.sourceObject.castShadow):r.template.castShadow,r.template.sourceObject?Boolean(r.template.sourceObject.receiveShadow):r.template.receiveShadow,r.template.sortMaterialId,r.template.sortGeometryId,r.template.sortCustomDepthMaterialId,r.instanceStart,r.instanceCount,r.boundsCenter.x,r.boundsCenter.y,r.boundsCenter.z,r.boundsRadius)))}q&&(this.residentInstanceUploadsScratch.push(m),pi(this.extractedBoundsMinScratch,this.extractedBoundsMaxScratch,y,S))}uploadInstanceData(e){if(!this.state.device)return;const t=Math.max(4,e.byteLength);(!this.state.instanceBuffer||t>this.state.instanceBufferSize)&&(this.state.instanceBuffer?.destroy(),this.state.instanceBufferSize=256*Math.ceil(t/256),this.state.instanceBuffer=this.state.device.createBuffer({label:"renderer-instance-buffer",size:this.state.instanceBufferSize,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.state.sharedSceneBindGroup=null,this.state.sharedShadowBindGroup=null,this.state.sharedShadowBindGroupByCameraBuffer.clear(),this.clearIndirectBundleCache()),e.floatLength>0?this.state.device.queue.writeBuffer(this.state.instanceBuffer,0,e.rawData.buffer,0,e.byteLength):this.state.device.queue.writeBuffer(this.state.instanceBuffer,0,y,0,w)}uploadResidentInstanceData(e){if(this.state.device)for(let t=0;t<e.length;t+=1){const r=e[t],i=r.residentInstanceBinding;if(!i)continue;if("instanced-direct"===i.mode){const e=r,t=e.sourceMesh,n=t.instanceMatrix.array,a=Math.max(4,16*t.count*Float32Array.BYTES_PER_ELEMENT),s=Math.max(t.count,1),o=Math.max(16,4*s*Float32Array.BYTES_PER_ELEMENT);if((!i.buffer||a>r.residentBufferSize)&&(i.buffer?.destroy(),r.residentBufferSize=256*Math.ceil(a/256),i.buffer=this.state.device.createBuffer({label:"renderer-instanced-mesh-matrix-buffer",size:r.residentBufferSize,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),i.sceneBindGroup=null,i.shadowBindGroup=null,i.shadowBindGroups.clear(),i.sceneBindGroupVersion=0,i.shadowBindGroupVersion=0,r.residentBufferDirty=!0),(!i.colorBuffer||o>r.residentColorBufferSize)&&(i.colorBuffer?.destroy(),r.residentColorBufferSize=256*Math.ceil(o/256),i.colorBuffer=this.state.device.createBuffer({label:"renderer-instanced-mesh-color-buffer",size:r.residentColorBufferSize,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),i.sceneBindGroup=null,i.shadowBindGroup=null,i.shadowBindGroups.clear(),i.sceneBindGroupVersion=0,i.shadowBindGroupVersion=0,r.residentColorBufferDirty=!0),r.residentBufferDirty&&i.buffer&&(t.count>0?this.state.device.queue.writeBuffer(i.buffer,0,Yr(n),0,16*t.count):this.state.device.queue.writeBuffer(i.buffer,0,S,0,4),r.residentBufferDirty=!1),r.residentColorBufferDirty&&i.colorBuffer){if(t.instanceColor&&4===t.instanceColor.itemSize&&t.instanceColor.array instanceof Float32Array)this.state.device.queue.writeBuffer(i.colorBuffer,0,Yr(t.instanceColor.array),0,4*s);else{let r=e.cachedDefaultColorData;r&&r.length===4*s||(r=new Float32Array(4*s),e.cachedDefaultColorData=r);for(let e=0;e<s;e+=1){const i=4*e;t.instanceColor?(r[i+0]=t.instanceColor.getComponent(e,0),r[i+1]=t.instanceColor.itemSize>1?t.instanceColor.getComponent(e,1):1,r[i+2]=t.instanceColor.itemSize>2?t.instanceColor.getComponent(e,2):1,r[i+3]=t.instanceColor.itemSize>3?t.instanceColor.getComponent(e,3):1):(r[i+0]=1,r[i+1]=1,r[i+2]=1,r[i+3]=1)}this.state.device.queue.writeBuffer(i.colorBuffer,0,Yr(r),0,r.length)}r.residentColorBufferDirty=!1}continue}const n=Math.max(4,r.cachedInstanceData.byteLength);if((!i.buffer||n>r.residentBufferSize)&&(i.buffer?.destroy(),r.residentBufferSize=256*Math.ceil(n/256),i.buffer=this.state.device.createBuffer({label:"renderer-instanced-mesh-buffer",size:r.residentBufferSize,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),i.sceneBindGroup=null,i.shadowBindGroup=null,i.shadowBindGroups.clear(),i.sceneBindGroupVersion=0,i.shadowBindGroupVersion=0,r.residentBufferDirty=!0),r.residentBufferDirty){if(!i.buffer)continue;r.cachedInstanceData.floatLength>0?this.state.device.queue.writeBuffer(i.buffer,0,r.cachedInstanceData.rawData.buffer,0,r.cachedInstanceData.byteLength):this.state.device.queue.writeBuffer(i.buffer,0,y,0,w),r.residentBufferDirty=!1}}}clearIndirectBundleCache(){this.state.indirectForwardBundleCache.clear(),this.state.directForwardBundleCache.clear(),this.indirectBundleInvalidationVersion+=1}clearStaticDrawSetBundleCaches(){this.materialPassStaticBundleCache=new WeakMap;for(const e of this.staticDrawSets){for(const t of e.visibleIndirectSubmissionStreams??[])t.forwardBundle=null;e.indirectForwardBundleCache.clear(),e.directForwardBundle=null,e.directForwardBundleSceneBindGroup=null,e.depthPrepassBundle=null,e.depthPrepassBundleSceneBindGroup=null,e.indirectDepthPrepassBundles.prepass=null,e.indirectDepthPrepassBundles.postpass=null,e.shadowBundles=new WeakMap;for(const t of e.shadowChunks)t.bundles=new WeakMap;e.depthMaterialResources.clear()}}getViewport(e){return e.set(0,0,this.state.width,this.state.height)}getSharedSceneBindGroup(){if(!(this.state.device&&this.state.sceneBindGroupLayout&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.instanceBuffer&&this.state.shadowComparisonSampler&&this.state.directionalShadowView&&this.state.linearClampSampler&&this.state.pointShadowArrayView&&this.state.spotShadowView&&this.state.spotLightMapView))throw new Error("Renderer scene bind group resources are not initialized.");return this.state.sharedSceneBindGroup||(this.state.sharedSceneBindGroup=this.state.device.createBindGroup({label:"renderer-scene-bind-group",layout:this.state.sceneBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:1,resource:{buffer:this.state.lightBuffer}},{binding:2,resource:{buffer:this.state.instanceBuffer}},{binding:3,resource:this.state.shadowComparisonSampler},{binding:4,resource:this.state.directionalShadowView},{binding:5,resource:this.state.linearClampSampler},{binding:6,resource:this.state.pointShadowArrayView},{binding:7,resource:this.state.spotShadowView},{binding:9,resource:this.state.spotLightMapView},{binding:11,resource:this.tiledPointLights.view}]})),this.state.sharedSceneBindGroup}getSharedShadowBindGroup(){if(!(this.state.device&&this.state.shadowBindGroupLayout&&this.state.shadowCameraBuffer&&this.state.instanceBuffer))throw new Error("Renderer shadow bind group resources are not initialized.");return this.state.sharedShadowBindGroup||(this.state.sharedShadowBindGroup=this.state.device.createBindGroup({label:"renderer-shadow-bind-group",layout:this.state.shadowBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.shadowCameraBuffer}},{binding:1,resource:{buffer:this.state.instanceBuffer}}]})),this.state.sharedShadowBindGroup}getShadowCameraBuffer(e){if(!this.state.device)throw new Error("Renderer is not initialized.");for(;this.state.shadowCameraBufferPool.length<=e;)this.state.shadowCameraBufferPool.push(this.state.device.createBuffer({label:`renderer-shadow-camera-buffer-${this.state.shadowCameraBufferPool.length}`,size:256,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}));return this.state.shadowCameraBufferPool[e]}getSharedShadowBindGroupForCameraBuffer(e){if(!(this.state.device&&this.state.sceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.instanceBuffer))throw new Error("Renderer shadow bind group resources are not initialized.");const t=this.state.sharedShadowBindGroupByCameraBuffer.get(e);if(t)return t;const r=this.state.device.createBindGroup({label:"renderer-shadow-bind-group-per-camera",layout:this.state.shadowBindGroupLayout,entries:[{binding:0,resource:{buffer:e}},{binding:1,resource:{buffer:this.state.instanceBuffer}}]});return this.state.sharedShadowBindGroupByCameraBuffer.set(e,r),r}buildIndirectSubmissionStreams(e,t,r,i){let n=this.dynamicIndirectSubmissionCache.get(e);n||(n=[],this.dynamicIndirectSubmissionCache.set(e,n));const a=void 0!==i;let s=n.find(e=>e.lastUsedExtractionVersion!==this.extractionVersion&&e.sceneBindGroup===t&&e.instanceAccessMode===r&&e.usesExplicitMaterialResources===a);s||(s={sceneBindGroup:t,instanceAccessMode:r,usesExplicitMaterialResources:a,lastUsedExtractionVersion:-1,streams:[]},n.push(s)),s.lastUsedExtractionVersion=this.extractionVersion;const o=s.streams;let l=0,c=null,u=0;for(let n=0;n<e.length;n+=1){const a=e[n],s=i?.[n]??(r?this.getMaterialResource(a.material,r,a.receiveShadow,void 0,null!==a.skinning,this.drawUsesBatching(a)):this.getMaterialResourceForDraw(a)),d=r?t:this.resolveSceneBindGroupForDraw(a,t),h=this.getIndirectStreamKey(s.pipeline,s.bindGroup,d,a.geometryKey),p=yi(a);if(c&&c.key===h&&c.indirectStartIndex+c.indirectCount===n){c.indirectCount+=1,c.drawCallCount+=1,c.triangleCount+=p;continue}c&&c.indirectCount!==u&&(c.forwardBundle=null,c.forwardBundleColorFormatsId=0,c.forwardBundleDrawMetadataResource=null,c.forwardBundleCandidateExtractionVersion=-1),c=o[l],u=c?.indirectCount??0;const f=void 0!==c&&c.key===h&&c.material===a.material&&c.materialResource===s&&c.sceneBindGroup===d&&c.geometry===a.geometry&&c.geometryKey===a.geometryKey&&c.geometryResource===a.geometryResource&&c.indirectStartIndex===n;c?(f||(c.forwardBundle=null,c.forwardBundleColorFormatsId=0,c.forwardBundleDrawMetadataResource=null,c.forwardBundleCandidateExtractionVersion=-1),c.key=h,c.material=a.material,c.materialResource=s,c.sceneBindGroup=d,c.geometry=a.geometry,c.geometryKey=a.geometryKey,c.geometryResource=a.geometryResource,c.indirectStartIndex=n,c.indirectCount=1,c.drawCallCount=1,c.triangleCount=p):(c={key:h,material:a.material,materialResource:s,sceneBindGroup:d,geometry:a.geometry,geometryKey:a.geometryKey,geometryResource:a.geometryResource,indirectStartIndex:n,indirectCount:1,drawCallCount:1,triangleCount:p,forwardBundle:null,forwardBundleMaterialVersion:-1,forwardBundleGraphTextureResourceVersion:-1,forwardBundleInvalidationVersion:-1,forwardBundleDrawMetadataResource:null,forwardBundleSampleCount:0,forwardBundleColorFormatsId:0,forwardBundleCandidateExtractionVersion:-1},o[l]=c),l+=1}return c&&c.indirectCount!==u&&(c.forwardBundle=null,c.forwardBundleColorFormatsId=0,c.forwardBundleDrawMetadataResource=null,c.forwardBundleCandidateExtractionVersion=-1),o.length!==l&&(o.length=l),o}getIndirectStreamKey(e,t,r,i){let n=this.indirectStreamKeyCache.get(e);n||(n=new WeakMap,this.indirectStreamKeyCache.set(e,n));let a=n.get(t);a||(a=new WeakMap,n.set(t,a));let s=a.get(r);s||(s=new WeakMap,a.set(r,s));let o=s.get(i);return void 0===o&&(o=this.nextIndirectStreamKey,this.nextIndirectStreamKey+=1,s.set(i,o)),o}getOrCreateStaticIndirectSubmissionStreams(e,t,r=hs){const i=r.join("|"),n=null!==e.visibleIndirectSubmissionStreams&&e.visibleIndirectStreamsSceneBindGroup===t&&e.visibleIndirectStreamsSampleCount===this.sampleCount&&e.visibleIndirectStreamsColorFormatsKey===i;if(n)return e.visibleIndirectSubmissionStreams;let a=!n;for(const t of e.visibleMaterialBindings){const i=this.getMaterialResource(t.material,"packed-visible",t.receiveShadow,r,!1,t.usesBatching),n=t.resource;t.resource=i,n!==i&&(a=!0);for(const r of t.drawIndices)e.visibleDrawMaterialResources[r]!==i&&(a=!0),e.visibleDrawMaterialResources[r]=i}return!a&&e.visibleIndirectSubmissionStreams||(e.visibleIndirectSubmissionStreams=this.buildIndirectSubmissionStreams(e.draws,t,"packed-visible",e.visibleDrawMaterialResources).slice(),e.visibleIndirectStreamsSceneBindGroup=t,e.visibleIndirectStreamsSampleCount=this.sampleCount,e.visibleIndirectStreamsColorFormatsKey=i,e.indirectForwardBundleCache.clear()),e.visibleIndirectSubmissionStreams}getOrCreateIndirectForwardBundle(e,t=this.state.drawMetadataResource,r=this.state.indirectForwardBundleCache,i="renderer-indirect-forward-bundle",n=hs,a=!1,s=this.getColorFormatsId(n)){if(!this.state.device||!this.state.format)throw new Error("Renderer is not initialized.");if(!t)throw new Error("Indirect draw metadata is not available.");if(null!==e.forwardBundle&&e.forwardBundleMaterialVersion===e.material.version&&e.forwardBundleGraphTextureResourceVersion===this.graphTextureResourceVersion&&e.forwardBundleInvalidationVersion===this.indirectBundleInvalidationVersion&&e.forwardBundleDrawMetadataResource===t&&e.forwardBundleSampleCount===this.sampleCount&&e.forwardBundleColorFormatsId===s)return e.forwardBundle;e.forwardBundle=null;const o=this.getIndirectBundleHash(e,t,s),l=r.get(o),c=l?.find(r=>r.streamKey===e.key&&r.positionBuffer===e.geometryResource.position&&r.indexBuffer===e.geometryResource.index&&r.indirectBuffer===t.indirectBuffer&&r.indirectStartIndex===e.indirectStartIndex&&r.indirectCount===e.indirectCount&&r.sampleCount===this.sampleCount&&r.materialVersion===e.material.version&&r.graphTextureResourceVersion===this.graphTextureResourceVersion&&r.colorFormatsId===s);if(c)return this.setRetainedIndirectBundleState(e,c.bundle,t,s),c.bundle;if(a&&e.forwardBundleCandidateExtractionVersion<0)return e.forwardBundleCandidateExtractionVersion=this.extractionVersion,null;if(a&&e.forwardBundleCandidateExtractionVersion===this.extractionVersion)return null;const u=this.state.device.createRenderBundleEncoder({label:`${i}-${o}`,colorFormats:n,depthStencilFormat:"depth32float",sampleCount:this.sampleCount});if(u.setPipeline(e.materialResource.pipeline),this.bindGeometryVertexBuffers(u,e.geometry,e.geometryResource,e.materialResource.vertexAttributes,0,1,e.material.wireframe),u.setBindGroup(0,e.sceneBindGroup),u.setBindGroup(1,e.materialResource.bindGroup),!e.materialResource.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");u.setBindGroup(3,this.createGraphTextureBindGroup(e.material,e.materialResource.graphTextureBindGroupLayout));for(let r=0;r<e.indirectCount;r+=1)u.drawIndexedIndirect(t.indirectBuffer,20*(e.indirectStartIndex+r));const d=u.finish({label:`${i}-${o}`}),h={streamKey:e.key,positionBuffer:e.geometryResource.position,indexBuffer:e.geometryResource.index,indirectBuffer:t.indirectBuffer,indirectStartIndex:e.indirectStartIndex,indirectCount:e.indirectCount,sampleCount:this.sampleCount,materialVersion:e.material.version,graphTextureResourceVersion:this.graphTextureResourceVersion,colorFormatsId:s,bundle:d};return l?l.push(h):r.set(o,[h]),this.setRetainedIndirectBundleState(e,d,t,s),d}submitIndirectStreamDirect(e,t,r){e.setPipeline(t.materialResource.pipeline),this.bindGeometryVertexBuffers(e,t.geometry,t.geometryResource,t.materialResource.vertexAttributes,0,1,t.material.wireframe),e.setBindGroup(0,t.sceneBindGroup),e.setBindGroup(1,t.materialResource.bindGroup);const i=t.materialResource.graphTextureBindGroupLayout;if(!i)throw new Error("Graph texture layout is missing.");e.setBindGroup(3,this.createGraphTextureBindGroup(t.material,i));for(let i=0;i<t.indirectCount;i+=1)e.drawIndexedIndirect(r.indirectBuffer,20*(t.indirectStartIndex+i))}setRetainedIndirectBundleState(e,t,r,i){e.forwardBundle=t,e.forwardBundleMaterialVersion=e.material.version,e.forwardBundleGraphTextureResourceVersion=this.graphTextureResourceVersion,e.forwardBundleInvalidationVersion=this.indirectBundleInvalidationVersion,e.forwardBundleDrawMetadataResource=r,e.forwardBundleSampleCount=this.sampleCount,e.forwardBundleColorFormatsId=i}getIndirectBundleHash(e,t,r){let i=2166136261;return i=si(i,e.key),i=si(i,ei(e.geometryResource.position)),i=si(i,e.geometryResource.index?ei(e.geometryResource.index):0),i=si(i,ei(t.indirectBuffer)),i=si(i,e.indirectStartIndex),i=si(i,e.indirectCount),i=si(i,this.sampleCount),i=si(i,e.material.version),i=si(i,this.graphTextureResourceVersion),i=si(i,r),i>>>0}getColorFormatsId(e){if(e===hs)return 1;const t=this.colorFormatsIdentityCache.get(e);if(void 0!==t)return t;const r=1===e.length?e[0]:e.join("|");let i=this.colorFormatsValueCache.get(r);return void 0===i&&(i=this.nextColorFormatsId,this.nextColorFormatsId+=1,this.colorFormatsValueCache.set(r,i)),this.colorFormatsIdentityCache.set(e,i),i}getDirectForwardBundleKey(e,t,r){let i=2166136261;i=si(i,e.length),i=si(i,this.sampleCount),i=si(i,ei(t));for(let n=0;n<e.length;n+=1){const a=e[n],s=this.getMaterialResourceForDraw(a,r),o=this.resolveSceneBindGroupForDraw(a,t);i=si(i,ei(a.material)),i=si(i,a.receiveShadow?1:0),i=si(i,a.material.version??0),i=si(i,ei(s.pipeline)),i=si(i,ei(s.bindGroup)),i=si(i,ei(o)),i=si(i,ei(a.geometryKey)),i=si(i,ei(a.geometryResource.position)),i=si(i,ei(a.geometryResource.normal)),i=si(i,ei(a.geometryResource.uv)),i=si(i,ei(a.geometryResource.color)),i=si(i,a.geometryResource.index?ei(a.geometryResource.index):0);for(const e of a.geometryResource.extraAttributeBuffers.values())i=si(i,ei(e));i=si(i,a.indexed?1:0),i=si(i,a.start),i=si(i,a.count),i=si(i,a.instanceStart),i=si(i,a.instanceCount);const l=a.material.getTexturesList();i=si(i,l.length);for(let e=0;e<l.length;e+=1){const t=l[e];i=si(i,ei(t)),i=si(i,t.version)}}return`forward-direct:${i}:${e.length}:samples=${this.sampleCount}:formats=${r.join("|")}`}getOrCreateDirectForwardBundle(e,t,r,i=hs){if(!this.state.device||!this.state.format||0===e.length)return null;const n=this.getDirectForwardBundleKey(e,t,i),a=this.state.directForwardBundleCache.get(n);if(a){for(let t=0;t<e.length;t+=1){const i=e[t];i.materialResource&&this.updateMaterialUniformBuffer(i.material,i.materialResource),this.recordDraw(i,r)}return a}const s=this.state.device.createRenderBundleEncoder({label:`renderer-direct-forward-bundle-${n}`,colorFormats:i,depthStencilFormat:"depth32float",sampleCount:this.sampleCount});let o=null,l=null,c=null,u=null;for(let n=0;n<e.length;n+=1){const a=e[n],d=a.geometryResource,h=this.getMaterialResourceForDraw(a,i),p=this.resolveSceneBindGroupForDraw(a,t);if(o!==h.pipeline&&(o=h.pipeline,c=null,s.setPipeline(o)),c!==a.geometryKey&&(c=a.geometryKey,this.bindGeometryVertexBuffers(s,a.geometry,d,h.vertexAttributes,a.instanceStart,a.instanceCount,a.wireframe)),u!==p&&(u=p,s.setBindGroup(0,p)),l!==a.material){if(l=a.material,s.setBindGroup(1,h.bindGroup),!h.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");s.setBindGroup(3,this.createGraphTextureBindGroup(a.material,h.graphTextureBindGroupLayout))}a.indexed&&(a.wireframe?d.wireframeIndex:d.index)?s.drawIndexed(a.count,a.instanceCount,a.start,0,a.instanceStart):s.draw(a.count,a.instanceCount,a.start,a.instanceStart),this.recordDraw(a,r)}const d=s.finish({label:`renderer-direct-forward-bundle-${n}`});return this.state.directForwardBundleCache.set(n,d),d}getOrCreateStaticMaterialBundle(e,t,r,i){const n=`${ei(t)}:${this.sampleCount}:${i.join("|")}`,a=this.materialPassStaticBundleCache.get(e)?.get(n);if(a)return this.recordStaticDrawStats(e,r),a;const s=this.getOrCreateDirectForwardBundle(e.draws,t,r,i);if(!s)return null;let o=this.materialPassStaticBundleCache.get(e);return o||(o=new Map,this.materialPassStaticBundleCache.set(e,o)),o.set(n,s),s}resolveSceneBindGroupForDraw(e,t){if(!(e.residentInstanceBinding&&this.state.device&&this.state.sceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.shadowComparisonSampler&&this.state.directionalShadowView&&this.state.linearClampSampler&&this.state.pointShadowArrayView&&this.state.spotShadowView&&e.residentInstanceBinding.buffer))return t;const r=e.residentInstanceBinding,i=r.buffer,n=r.colorBuffer??r.buffer;return i&&n?(r.sceneBindGroup&&r.sceneBindGroupVersion===this.state.residentSceneBindGroupVersion||(r.sceneBindGroup=this.state.device.createBindGroup("instanced-direct"===r.mode?{label:"renderer-resident-direct-scene-bind-group",layout:this.state.directSceneBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:1,resource:{buffer:this.state.lightBuffer}},{binding:2,resource:{buffer:i}},{binding:3,resource:{buffer:n}},{binding:4,resource:this.state.shadowComparisonSampler},{binding:5,resource:this.state.directionalShadowView},{binding:6,resource:this.state.linearClampSampler},{binding:7,resource:this.state.pointShadowArrayView},{binding:8,resource:this.state.spotShadowView},{binding:10,resource:this.state.spotLightMapView},{binding:11,resource:this.tiledPointLights.view}]}:{label:"renderer-resident-scene-bind-group",layout:this.state.sceneBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:1,resource:{buffer:this.state.lightBuffer}},{binding:2,resource:{buffer:i}},{binding:3,resource:this.state.shadowComparisonSampler},{binding:4,resource:this.state.directionalShadowView},{binding:5,resource:this.state.linearClampSampler},{binding:6,resource:this.state.pointShadowArrayView},{binding:7,resource:this.state.spotShadowView},{binding:9,resource:this.state.spotLightMapView},{binding:11,resource:this.tiledPointLights.view}]}),r.sceneBindGroupVersion=this.state.residentSceneBindGroupVersion),r.sceneBindGroup):t}resolveShadowBindGroupForDraw(e,t,r=this.state.shadowCameraBuffer){if(!(e.residentInstanceBinding&&this.state.device&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&r&&e.residentInstanceBinding.buffer))return t;const i=e.residentInstanceBinding,n=i.buffer,a=i.colorBuffer??i.buffer;if(!n||!a)return t;if(i.shadowBindGroupVersion!==this.state.residentShadowBindGroupVersion&&(i.shadowBindGroup=null,i.shadowBindGroups.clear(),i.shadowBindGroupVersion=this.state.residentShadowBindGroupVersion),r===this.state.shadowCameraBuffer&&i.shadowBindGroup)return i.shadowBindGroup;const s=i.shadowBindGroups.get(r);if(s)return s;const o=this.state.device.createBindGroup("instanced-direct"===i.mode?{label:"renderer-resident-direct-shadow-bind-group",layout:this.state.directShadowBindGroupLayout,entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:n}},{binding:2,resource:{buffer:a}}]}:{label:"renderer-resident-shadow-bind-group",layout:this.state.shadowBindGroupLayout,entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:n}}]});return i.shadowBindGroups.set(r,o),r===this.state.shadowCameraBuffer&&(i.shadowBindGroup=o),o}uploadDrawMetadata(e){if(!this.state.device||!this.state.visibilityParamsBuffer)return;if(0===e.length)return this.visibilityParamsUpload[0]=0,this.visibilityParamsUpload[1]=this.state.hizMipCount,this.visibilityParamsUpload[2]=0,this.visibilityParamsUpload[3]=0,this.state.device.queue.writeBuffer(this.state.visibilityParamsBuffer,0,this.visibilityParamsUpload,0,4),void(this.state.drawMetadataResource&&(this.state.drawMetadataResource.count=0));const t=e.length*b;this.drawMetadataUpload.length<t&&(this.drawMetadataUpload=new Float32Array(Math.max(t,2*this.drawMetadataUpload.length,768)));const r=5*e.length;this.indirectDrawUpload.length<r&&(this.indirectDrawUpload=new Uint32Array(Math.max(r,2*this.indirectDrawUpload.length,320)));const i=this.drawMetadataUpload,n=this.indirectDrawUpload;for(let t=0;t<e.length;t+=1){const r=e[t],a=t*b;i[a+0]=r.boundsCenter.x,i[a+1]=r.boundsCenter.y,i[a+2]=r.boundsCenter.z,i[a+3]=r.boundsRadius,i[a+4]=r.count,i[a+5]=r.start,i[a+6]=r.instanceStart,i[a+7]=r.instanceCount,i[a+8]=1,i[a+9]=0,i[a+10]=0,i[a+11]=0;const s=5*t;n[s+0]=r.count,n[s+1]=r.instanceCount,n[s+2]=r.start,n[s+3]=0,n[s+4]=r.instanceStart}const a=e.length;if(!(this.state.drawMetadataResource&&this.state.drawMetadataResource.capacity>=a)){this.state.drawMetadataResource?.metadataBuffer.destroy(),this.state.drawMetadataResource?.indirectBuffer.destroy(),this.state.drawMetadataResource?.postIndirectBuffer.destroy();const t=Math.max(64,1<<Math.ceil(Math.log2(a)));this.state.drawMetadataResource={count:e.length,capacity:t,metadataBuffer:this.state.device.createBuffer({label:"renderer-draw-metadata-buffer",size:t*b*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),indirectBuffer:this.state.device.createBuffer({label:"renderer-indirect-draw-buffer",size:5*t*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.INDIRECT|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC}),postIndirectBuffer:this.state.device.createBuffer({label:"renderer-post-indirect-draw-buffer",size:5*t*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.INDIRECT|GPUBufferUsage.COPY_DST})},this.state.visibilityBindGroup=null,this.state.visibilityBindGroupMetadataResource=null,this.clearIndirectBundleCache()}this.state.drawMetadataResource.count=e.length,this.state.device.queue.writeBuffer(this.state.drawMetadataResource.metadataBuffer,0,i,0,t),this.state.device.queue.writeBuffer(this.state.drawMetadataResource.indirectBuffer,0,n,0,r),this.visibilityParamsUpload[0]=e.length,this.visibilityParamsUpload[1]=this.state.hizMipCount,this.visibilityParamsUpload[2]=0,this.visibilityParamsUpload[3]=0,this.state.device.queue.writeBuffer(this.state.visibilityParamsBuffer,0,this.visibilityParamsUpload,0,4)}recordDraw(e,t){t.drawCallCount+=1,t.triangleCount+=yi(e)}executeVisibilityPass(e,t){la.call(this,e,t)}executeStaticVisibilityPasses(e,t){ua.call(this,e,t)}getOrCreateStaticVisibilityBindGroup(e,t){return da.call(this,e,t)}executeDirectionalShadowPass(e,t,r,i){ha.call(this,e,t,r,i)}executePointShadowPass(e,t,r,i){pa.call(this,e,t,r,i)}executeSpotShadowPass(e,t,r,i){fa.call(this,e,t,r,i)}executeDepthPrepass(e,t,r,i){ma.call(this,e,t,r,i)}executeStaticDepthPrepass(e,t,r){ga.call(this,e,t,r)}executeStaticTemporalDepthResolvePass(e){xa.call(this,e)}getOrCreateStaticDepthPrepassBundle(e,t){return ba.call(this,e,t)}executeHiZPasses(e,t=!1,r=!1){Ca.call(this,e,t,r)}getOrCreateStaticVisibleSceneBindGroup(e){if(!(this.state.device&&this.state.visibleSceneBindGroupLayout&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.shadowComparisonSampler&&this.state.directionalShadowView&&this.state.linearClampSampler&&this.state.pointShadowArrayView&&this.state.spotShadowView&&this.state.spotLightMapView))throw new Error("Renderer visible scene bind group resources are not initialized.");return e.visibleSceneBindGroup&&e.visibleSceneBindGroupVersion===this.state.residentSceneBindGroupVersion||(e.visibleSceneBindGroup=this.state.device.createBindGroup({label:`${e.label}-static-visible-scene-bind-group`,layout:this.state.visibleSceneBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:1,resource:{buffer:this.state.lightBuffer}},{binding:2,resource:{buffer:e.instanceBuffer}},{binding:3,resource:this.state.shadowComparisonSampler},{binding:4,resource:this.state.directionalShadowView},{binding:5,resource:this.state.linearClampSampler},{binding:6,resource:this.state.pointShadowArrayView},{binding:7,resource:this.state.spotShadowView},{binding:8,resource:{buffer:e.instanceVisibilityResource.visibleInstanceIndicesBuffer}},{binding:9,resource:this.state.spotLightMapView},{binding:11,resource:this.tiledPointLights.view}]}),e.visibleSceneBindGroupVersion=this.state.residentSceneBindGroupVersion),e.visibleSceneBindGroup}getOrCreateStaticVisibleDepthSceneBindGroup(e){if(!this.state.device||!this.state.visibleDepthSceneBindGroupLayout||!this.state.cameraBuffer)throw new Error("Renderer visible depth scene bind group resources are not initialized.");return e.visibleDepthSceneBindGroup&&e.visibleDepthSceneBindGroupVersion===this.state.residentSceneBindGroupVersion||(e.visibleDepthSceneBindGroup=this.state.device.createBindGroup({label:`${e.label}-static-visible-depth-scene-bind-group`,layout:this.state.visibleDepthSceneBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:2,resource:{buffer:e.instanceBuffer}},{binding:3,resource:{buffer:e.instanceVisibilityResource.visibleInstanceIndicesBuffer}}]}),e.visibleDepthSceneBindGroupVersion=this.state.residentSceneBindGroupVersion),e.visibleDepthSceneBindGroup}executeMaterialPass(e,t,r,i,n,a={}){if(!this.state.mainDepthView||0===t.length)return;const s=t.map(e=>this.getColorTargetFormat(e)),o=this.getColorFormatsId(s),l=t.map(e=>this.getColorTargetView(e)),c=this.sampleCount>1,u=c?t.map(e=>this.ensureMsaaColorTarget(e)):[],d=this.getColorTargetDimensions(t[0]),h=c?this.ensureMsaaDepthTarget(d.width,d.height):null,p=e.beginRenderPass({label:"renderer-material-pass",colorAttachments:t.map((e,t)=>({view:u[t]?.view??l[t],resolveTarget:u[t]?l[t]:void 0,clearValue:1===t?{r:.5,g:.5,b:1,a:1}:t>=2?{r:0,g:0,b:0,a:1}:{r:a.clearColor?.[0]??this.clearColor[0],g:a.clearColor?.[1]??this.clearColor[1],b:a.clearColor?.[2]??this.clearColor[2],a:a.clearColor?.[3]??this.clearColor[3]},loadOp:a.loadColor?"load":"clear",storeOp:u[t]?"discard":"store"})),depthStencilAttachment:{view:h?.view??this.state.mainDepthView,depthClearValue:1,depthLoadOp:h?"clear":a.loadDepth?"load":"clear",depthStoreOp:h?"discard":"store"}});let f=null,m=null,g=null,v=null,x=null;const w=e=>{e.sourceObject&&e.hasRenderCallbacks&&e.sourceObject.onBeforeRender(this,i.scene,i.camera,e.geometry,e.material,e.geometryGroup);const t=e.geometryResource;let a=e.material;const o=this.getMaterialResourceForDraw(e,s),l=this.resolveSceneBindGroupForDraw(e,r);if(f!==o.pipeline&&(f=o.pipeline,g=null,x=null,p.setPipeline(f)),g!==e.geometryKey&&(g=e.geometryKey,this.bindGeometryVertexBuffers(p,e.geometry,t,o.vertexAttributes,e.instanceStart,e.instanceCount,e.wireframe)),v!==l&&(v=l,p.setBindGroup(0,l)),m!==a){if(m=a,p.setBindGroup(1,o.bindGroup),!o.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");p.setBindGroup(3,this.createGraphTextureBindGroup(a,o.graphTextureBindGroupLayout))}o.usesSkinning&&e.skinning&&x!==e.skinning.bindGroup&&(x=e.skinning.bindGroup,p.setBindGroup(2,x)),e.indexed&&(e.wireframe?t.wireframeIndex:t.index)?p.drawIndexed(e.count,e.instanceCount,e.start,0,e.instanceStart):p.draw(e.count,e.instanceCount,e.start,e.instanceStart),this.recordDraw(e,n),e.sourceObject&&e.hasRenderCallbacks&&e.sourceObject.onAfterRender(this,i.scene,i.camera,e.geometry,e.material,e.geometryGroup)},b=a.drawStage??"all";if(a.objectFilter||a.overrideMaterial){const e=e=>{if(a.objectFilter){const t=e.sourceRanges?.filter(e=>a.objectFilter(e.sourceObject));if(null!=t&&t.length>0){const r="function"==typeof a.overrideMaterial?a.overrideMaterial(e.material,null!==e.skinning):a.overrideMaterial;for(const i of t)w({...e,sourceObject:i.sourceObject,instanceStart:i.instanceStart,instanceCount:i.instanceCount,material:r??e.material,sourceRanges:void 0});return}if(!a.objectFilter(e.sourceObject))return}const t="function"==typeof a.overrideMaterial?a.overrideMaterial(e.material,null!==e.skinning):a.overrideMaterial;w(t?{...e,material:t}:e)};if("late"!==b){for(const t of this.staticDrawSets)if(t.publicSet.enabled&&"opaque"===t.drawStage)for(const r of t.draws)e(r);for(const t of i.gpuOpaqueDraws)e(t);for(const t of i.directOpaqueDraws)e(t)}if("opaque"!==b)for(const t of i.transparentDraws)e(t);return void p.end()}if("late"!==b){for(const e of this.staticDrawSets){if(!e.publicSet.enabled||0===e.draws.length||"opaque"!==e.drawStage)continue;if(this.getHiZOcclusionCullingActive()&&e.lastVisibilityFrameToken===this.staticFrameToken){const t=this.getOrCreateStaticVisibleSceneBindGroup(e),r=this.getOrCreateStaticIndirectSubmissionStreams(e,t,s);for(const t of r){if(this.getMultiDrawIndirectActive()){if(p.setPipeline(t.materialResource.pipeline),this.bindGeometryVertexBuffers(p,t.geometry,t.geometryResource,t.materialResource.vertexAttributes,0,1,t.material.wireframe),p.setBindGroup(0,t.sceneBindGroup),p.setBindGroup(1,t.materialResource.bindGroup),!t.materialResource.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");p.setBindGroup(3,this.createGraphTextureBindGroup(t.material,t.materialResource.graphTextureBindGroupLayout)),p.multiDrawIndexedIndirect(e.drawMetadataResource.indirectBuffer,5*t.indirectStartIndex*Uint32Array.BYTES_PER_ELEMENT,t.indirectCount)}else this.renderBundleScratch[0]=this.getOrCreateIndirectForwardBundle(t,e.drawMetadataResource,e.indirectForwardBundleCache,`${e.label}-static-indirect-material-bundle`,s,!1,o),p.executeBundles(this.renderBundleScratch);n.drawCallCount+=t.drawCallCount,n.triangleCount+=t.triangleCount}continue}const t=this.getOrCreateStaticMaterialBundle(e,r,n,s);t&&(this.renderBundleScratch[0]=t,p.executeBundles(this.renderBundleScratch))}if(this.getHiZOcclusionCullingActive()&&this.state.drawMetadataResource){const e=this.indirectMaterialResourcesScratch;e.length=i.gpuOpaqueDraws.length;for(let t=0;t<i.gpuOpaqueDraws.length;t+=1)e[t]=this.getMaterialResourceForDraw(i.gpuOpaqueDraws[t],s);const t=this.buildIndirectSubmissionStreams(i.gpuOpaqueDraws,r,void 0,e);for(const e of t){const t=this.getOrCreateIndirectForwardBundle(e,this.state.drawMetadataResource,this.state.indirectForwardBundleCache,"renderer-indirect-material-bundle",s,!0,o);t?(this.renderBundleScratch[0]=t,p.executeBundles(this.renderBundleScratch)):this.submitIndirectStreamDirect(p,e,this.state.drawMetadataResource),n.drawCallCount+=e.drawCallCount,n.triangleCount+=e.triangleCount}}else{const e=ai(i.gpuOpaqueDraws)||i.gpuOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(i.gpuOpaqueDraws,r,n,s);if(e)this.renderBundleScratch[0]=e,p.executeBundles(this.renderBundleScratch);else for(const e of i.gpuOpaqueDraws)w(e)}const e=ai(i.directOpaqueDraws)||i.directOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(i.directOpaqueDraws,r,n,s);if(e)this.renderBundleScratch[0]=e,p.executeBundles(this.renderBundleScratch);else for(const e of i.directOpaqueDraws)w(e)}if("opaque"!==b)for(const e of i.transparentDraws)w(e);p.end()}executeForwardPass(e,t,r,i,n,a,s=!1,o="all",l=!1,c=this.sampleCount){Pa.call(this,e,t,r,i,n,a,s,o,l,c)}executeStaticForwardPass(e,t,r,i="all",n=this.sampleCount){Ma.call(this,e,t,r,i,n)}getOrCreateStaticDirectForwardBundle(e,t,r=this.sampleCount){return Ba.call(this,e,t,r)}refreshStaticDrawMaterialResources(e){Ta.call(this,e)}syncStaticVisibleMaterialBindingCaches(e){Da.call(this,e)}recordStaticDrawStats(e,t){Ia.call(this,e,t)}hasEnabledStaticDrawSets(){return Va.call(this)}executePresentPass(e,t,r){Ra.call(this,e,t,r)}clearDirectionalShadow(e){Ga.call(this,e)}clearPointShadow(e){za.call(this,e)}clearSpotShadow(e){La.call(this,e)}drawDepthLike(e,t,r,i){Ua.call(this,e,t,r,i)}getGeometryResource(e){if(!this.state.device)throw new Error("Renderer is not initialized.");const t=this.geometryCache.get(e);if(!this.invokeObjectRenderCallbacks&&t&&t.lastValidatedExtractionVersion===this.extractionVersion)return t;if(t&&this.updateDynamicGeometryAttributes(e,t))return t.lastValidatedExtractionVersion=this.extractionVersion,t;if(t&&t.lastValidatedExtractionVersion===this.extractionVersion)return t;if(t&&function(e,t){if(t.indexVersion!==(e.index?.version??0)||t.drawRangeStart!==e.drawRange.start||t.drawRangeCount!==e.drawRange.count)return!1;if(t.groups.length!==e.groups.length)return!1;for(let r=0;r<t.groups.length;r+=1){const i=t.groups[r],n=e.groups[r];if(i.start!==n?.start||i.count!==n?.count||i.materialIndex!==(n?.materialIndex??0))return!1}for(let r=0;r<t.attributes.length;r+=1){const i=t.attributes[r],n=e.getAttribute(i.name);if(n?n!==i.source||Rr(n)!==i.version||n.itemSize!==i.itemSize||n.count!==i.count:0!==i.version||0!==i.itemSize||0!==i.count)return!1}return!0}(e,t))return t.lastValidatedExtractionVersion=this.extractionVersion,t;t&&(this.clearIndirectBundleCache(),this.retireGeometryResource(t));const r=e.getAttribute("position");if(!r)throw new Error("BufferGeometry is missing the required position attribute.");const i=r.count,n=Wr(r,i,3,[0,0,0]),a=Wr(e.getAttribute("normal"),i,3,[0,0,1]),s=Wr(e.getAttribute("uv"),i,2,[0,0]),o=Wr(e.getAttribute("color"),i,4,[1,1,1,1]),l=e.getAttribute("skinIndex"),c=e.getAttribute("skinWeight"),u=l?Nr(l,i,"uint32x4",[]):void 0,d=c?Nr(c,i,"float32x4",[]):void 0;let h=null,p=null;if(e.index){const t=e.index.array,r=t instanceof Uint32Array?t:new Uint16Array(t);p=t instanceof Uint32Array?"uint32":"uint16",h=kr(this.state.device,r,GPUBufferUsage.INDEX,`${e.uuid}-index`)}const f={signature:Gr(e),indexVersion:e.index?.version??0,drawRangeStart:e.drawRange.start,drawRangeCount:e.drawRange.count,vertexCount:i,attributes:["position","normal","uv","color",...l?["skinIndex"]:[],...c?["skinWeight"]:[]].map(t=>{const r=e.getAttribute(t);return{name:t,source:r,version:Rr(r),itemSize:r?.itemSize??0,count:r?.count??0}}),lastValidatedExtractionVersion:this.extractionVersion,groups:e.groups.map(e=>({start:e.start,count:e.count,materialIndex:e.materialIndex??0})),...this.createGeometryBuffers(e.uuid,n,a,s,o,u,d,e.index?.array),extraAttributeBuffers:new Map,extraAttributeBufferVersions:new Map,wireframeIndex:null,wireframeIndexFormat:null};return this.geometryCache.set(e,f),f}updateDynamicGeometryAttributes(e,t){if(!this.state.device)return!1;let r=!1;for(const i of t.attributes){const t=e.getAttribute(i.name),n=t?.itemSize??0,a=t?.count??0;if(n!==i.itemSize||a!==i.count)return!1;r||=t!==i.source||Rr(t)!==i.version}if(!r)return!1;if(t.indexVersion!==(e.index?.version??0)||t.drawRangeStart!==e.drawRange.start||t.drawRangeCount!==e.drawRange.count||t.groups.length!==e.groups.length)return!1;for(let r=0;r<t.groups.length;r++){const i=t.groups[r],n=e.groups[r];if(i.start!==n?.start||i.count!==n?.count||i.materialIndex!==(n?.materialIndex??0))return!1}const i={position:{buffer:t.position,format:"float32x3",defaults:[0,0,0]},normal:{buffer:t.normal,format:"float32x3",defaults:[0,0,1]},uv:{buffer:t.uv,format:"float32x2",defaults:[0,0]},color:{buffer:t.color,format:"float32x4",defaults:[1,1,1,1]},skinIndex:{buffer:t.skinIndex,format:"uint32x4",defaults:[0,0,0,0]},skinWeight:{buffer:t.skinWeight,format:"float32x4",defaults:[0,0,0,0]}};for(const r of t.attributes){const t=e.getAttribute(r.name),n=Rr(t),a=t!==r.source;if(!a&&n===r.version)continue;const s=i[r.name];if(!t||!s?.buffer)return!1;const o=Number(s.format.at(-1)),l=!a&&"updateRanges"in t&&t.updateRanges.length>0?t.updateRanges:[{start:0,count:t.count*t.itemSize}];for(const e of l){const r=Math.max(0,Math.floor(e.start/t.itemSize)),i=Math.min(t.count,Math.ceil((e.start+e.count)/t.itemSize));if(i<=r)continue;if(t instanceof Ri&&!t.normalized&&t.itemSize===o&&("uint32x4"===s.format&&t.array instanceof Uint32Array||"uint32x4"!==s.format&&t.array instanceof Float32Array)){this.state.device.queue.writeBuffer(s.buffer,r*o*4,t.array.buffer,t.array.byteOffset+r*o*4,(i-r)*o*4);continue}const n="uint32x4"===s.format?new Uint32Array((i-r)*o):new Float32Array((i-r)*o);for(let e=r;e<i;e++){const i=(e-r)*o;for(let r=0;r<o;r++){const a=0===r?t.getX(e):1===r&&t.itemSize>1?t.getY(e):2===r&&t.itemSize>2?t.getZ(e):3===r&&t.itemSize>3?t.getW(e):void 0;n[i+r]=a??s.defaults[r]??0}}this.state.device.queue.writeBuffer(s.buffer,r*o*4,n)}"clearUpdateRanges"in t&&t.clearUpdateRanges(),r.version=n,r.source=t}return t.signature=Gr(e),!0}getSkinnedGeometryResource(e){if(!this.state.device)throw new Error("Renderer is not initialized.");const t=e.geometry.getAttribute("skinIndex"),r=e.geometry.getAttribute("skinWeight"),i=e.geometry.getAttribute("position");if(!t||!r||!i)throw new Error("SkinnedMesh requires position, skinIndex, and skinWeight attributes.");if(0===e.skeleton.bones.length)throw new Error("SkinnedMesh requires a skeleton with at least one bone.");const n=this.getGeometryResource(e.geometry);let a=this.skinnedGeometryCache.get(e);if(!a||a.resource!==n||a.positionAttribute!==i||a.positionVersion!==Rr(i)||a.skinIndexAttribute!==t||a.skinIndexVersion!==Rr(t)||a.skinWeightAttribute!==r||a.skinWeightVersion!==Rr(r)||a.boneCount!==e.skeleton.bones.length||a.skinning.palette.skeleton!==e.skeleton){a&&a.skinning.bindUniformBuffer.destroy();const s=this.getSkinningPalette(e.skeleton),o=this.state.device.createBuffer({label:`${e.uuid}-skinning-bind-matrices`,size:32*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),l=new Float32Array(32);l.set(e.bindMatrix.elements,0),l.set(e.bindMatrixInverse.elements,16);const c={bindGroup:this.state.device.createBindGroup({label:`${e.uuid}-skinning-bind-group`,layout:this.state.skinningBindGroupLayout,entries:[{binding:0,resource:{buffer:s.matrixBuffer}},{binding:1,resource:{buffer:o}},{binding:2,resource:{buffer:s.previousMatrixBuffer}}]}),bindUniformBuffer:o,bindMatrices:l,palette:s,bindUniformDirty:!0},u={positionAttribute:i,positionVersion:Rr(i),skinIndexAttribute:t,skinIndexVersion:Rr(t),skinWeightAttribute:r,skinWeightVersion:Rr(r),boneCount:e.skeleton.bones.length,resource:n,skinning:c,boneBounds:this.createSkinningBoneBounds(e,i,t,r),localBoundsMin:new Ki,localBoundsMax:new Ki,localBoundsCenter:new Ki,localBoundsRadius:1};a=u,this.skinnedGeometryCache.set(e,u)}if(!a)throw new Error("Skinned geometry cache entry could not be created.");return a}getSkinningPalette(e){const t=this.skinPaletteCache.get(e);if(t&&t.previousMatrices.length===16*e.bones.length)return t;if(!this.state.device||0===e.bones.length)throw new Error("A non-empty skeleton is required to create a GPU skinning palette.");const r=16*e.bones.length;t&&(t.matrixBuffer.destroy(),t.previousMatrixBuffer.destroy(),this.skinPaletteResources.delete(t)),e.boneMatrices.length<r&&(e.boneMatrices=new Float32Array(r)),this.skeletonPalettes.update(e);const i=new Float32Array(r);for(let t=0;t<r;t++)i[t]=e.boneMatrices[t];const n={skeleton:e,matrixBuffer:this.state.device.createBuffer({label:"renderer-skinning-bone-palette",size:r*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),previousMatrixBuffer:this.state.device.createBuffer({label:"renderer-skinning-previous-bone-palette",size:r*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),previousMatrices:i,dirty:!0,previousDirty:!0,previousNeedsAdvance:!1,lastRefreshExtractionVersion:-1};return this.skinPaletteCache.set(e,n),this.skinPaletteResources.add(n),n}refreshSkinningPalette(e){if(e.lastRefreshExtractionVersion===this.extractionVersion)return;e.lastRefreshExtractionVersion=this.extractionVersion;const t=this.skeletonPalettes.update(e.skeleton);e.dirty||=t,e.previousDirty||=t||e.previousNeedsAdvance,e.previousNeedsAdvance=t}refreshSkinningBindMatrices(e,t){const r=t.bindMatrices;let i=!1;for(let t=0;t<16;t+=1){const n=Math.fround(e.bindMatrix.elements[t]),a=Math.fround(e.bindMatrixInverse.elements[t]);r[t]===n&&r[t+16]===a||(i=!0),r[t]=n,r[t+16]=a}t.bindUniformDirty||=i}uploadSkinningPalette(e){if(this.state.device&&(e.previousDirty&&(this.state.device.queue.writeBuffer(e.previousMatrixBuffer,0,e.previousMatrices.buffer,e.previousMatrices.byteOffset,e.previousMatrices.byteLength),e.previousDirty=!1),e.dirty)){const t=e.skeleton.boneMatrices;this.state.device.queue.writeBuffer(e.matrixBuffer,0,t.buffer,t.byteOffset,16*e.skeleton.bones.length*Float32Array.BYTES_PER_ELEMENT);for(let r=0;r<e.previousMatrices.length;r++)e.previousMatrices[r]=t[r];e.dirty=!1}}uploadSkinningResources(e){this.state.device&&(this.uploadSkinningPalette(e.palette),e.bindUniformDirty&&(this.state.device.queue.writeBuffer(e.bindUniformBuffer,0,e.bindMatrices.buffer,e.bindMatrices.byteOffset,e.bindMatrices.byteLength),e.bindUniformDirty=!1))}createSkinningBoneBounds(e,t,r,i){const n=Array.from({length:e.skeleton.bones.length},()=>new Ki(1/0,1/0,1/0)),a=Array.from({length:e.skeleton.bones.length},()=>new Ki(-1/0,-1/0,-1/0));for(let e=0;e<t.count;e+=1){L.set(t.getX(e),t.getY(e),t.getZ(e));for(let t=0;t<4;t+=1){if(i.getComponent(e,t)<=0)continue;const s=Math.round(r.getComponent(e,t)),o=n[s],l=a[s];o&&l&&(o.min(L),l.max(L))}}return n.map((e,t)=>{if(!Number.isFinite(e.x))return null;const r=a[t],i=e.clone().add(r).multiplyScalar(.5);return{center:i,radius:r.distanceTo(i)}})}updateSkinnedBounds(e,t){const r=t.localBoundsMin,i=t.localBoundsMax,n=vi(e.geometry);r.set(n.center.x-n.radius,n.center.y-n.radius,n.center.z-n.radius),i.set(n.center.x+n.radius,n.center.y+n.radius,n.center.z+n.radius);for(let n=0;n<t.boneBounds.length;n+=1){const a=t.boneBounds[n];if(!a)continue;const s=wi(a.center,a.radius,e.bindMatrix,t.skinning.palette.skeleton.boneMatrices,16*n,e.bindMatrixInverse,L);r.min(U.copy(L).addScalar(-s)),i.max(U.copy(L).addScalar(s))}t.localBoundsCenter.copy(r).add(i).multiplyScalar(.5),t.localBoundsRadius=i.distanceTo(t.localBoundsCenter)}createGeometryBuffers(e,t,r,i,n,a,s,o,l=GPUBufferUsage.VERTEX,c=GPUBufferUsage.VERTEX){if(!this.state.device)throw new Error("Renderer is not initialized.");let u=null,d=null;if(o){const t=o instanceof Uint32Array?o:new Uint16Array(o);d=o instanceof Uint32Array?"uint32":"uint16",u=kr(this.state.device,t,GPUBufferUsage.INDEX,`${e}-index`)}return{position:kr(this.state.device,t,l|GPUBufferUsage.COPY_DST,`${e}-position`),normal:kr(this.state.device,r,c|GPUBufferUsage.COPY_DST,`${e}-normal`),uv:kr(this.state.device,i,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-uv`),color:kr(this.state.device,n,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-color`),skinIndex:a?kr(this.state.device,a,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-skin-index`):null,skinWeight:s?kr(this.state.device,s,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-skin-weight`):null,index:u,indexFormat:d}}createVertexBufferLayouts(e){return this.getVertexAttributeGroups(e).map(e=>{let t=0;const r=e.map(e=>{const r={shaderLocation:e.shaderLocation,offset:t,format:e.format};return t+=Lr(e.format),r});return{arrayStride:t,stepMode:e[0].stepMode??"vertex",attributes:r}})}getVertexAttributeGroups(e){const t=this.vertexAttributeGroupCache.get(e);if(t)return t;const r=this.state.device?.limits.maxVertexBuffers??8;if(e.length<=r){const t=e.map(e=>[e]);return this.vertexAttributeGroupCache.set(e,t),t}let i=e.length-r;const n=[],a=new Set;for(const t of["vertex","instance"]){if(0===i)break;const r=e.filter(e=>(e.stepMode??"vertex")===t),s=Math.min(r.length,i+1);if(s<2)continue;const o=r.slice(0,s);n.push(o);for(const e of o)a.add(e);i-=s-1}if(i>0)throw new Error(`Vertex attributes cannot be packed into the device's ${r} vertex-buffer slots.`);const s=[];for(const t of e){if(!a.has(t)){s.push([t]);continue}const e=n.find(e=>e[0]===t);e&&s.push(e)}return this.vertexAttributeGroupCache.set(e,s),s}getGeometryAttributeBufferKey(e){const t=this.vertexAttributeBufferKeyCache.get(e);if(void 0!==t)return t;const r=function(e){const t=e.defaultValue?Array.from(e.defaultValue).join(","):"";return`${e.name}:${e.format}:${e.stepMode??"vertex"}:${t}`}(e);return this.vertexAttributeBufferKeyCache.set(e,r),r}getGeometryAttributeGroupBufferKey(e){const t=this.vertexAttributeGroupBufferKeyCache.get(e);if(void 0!==t)return t;const r=e.map(e=>this.getGeometryAttributeBufferKey(e)).join("|");return this.vertexAttributeGroupBufferKeyCache.set(e,r),r}getMaterialVertexAttributes(e,t){let r=this.materialVertexAttributeCache.get(e);if(r&&r.version===e.version||(r={version:e.version,unskinned:e.vertexAttributes.slice()},this.materialVertexAttributeCache.set(e,r)),!t)return r.unskinned;if(r.skinned)return r.skinned;const i=r.unskinned.slice(),n=[{name:"skinIndex",shaderLocation:4,format:"uint32x4"},{name:"skinWeight",shaderLocation:5,format:"float32x4"}];for(const e of n){const t=i.find(t=>t.name===e.name);if(t){if(t.shaderLocation!==e.shaderLocation||t.format!==e.format)throw new Error(`Skinned material attribute "${e.name}" must use ${e.format} at location ${e.shaderLocation}.`);continue}const r=i.find(t=>t.shaderLocation===e.shaderLocation);if(r)throw new Error(`Skinned material requires location ${e.shaderLocation} for "${e.name}", but it is used by "${r.name}".`);i.push(e)}return r.skinned=i,r.skinned}getGeometryVertexBuffer(e,t,r,i=0,n=1){if(!this.state.device)throw new Error("Renderer is not initialized.");const a=this.getStandardVertexAttribute(r);if(a){const e=t[a];if(e)return e}const s=e.getAttribute(r.name),o="instance"===r.stepMode,l=o?Math.max(0,Math.trunc(i)):0;if(o&&!s)return this.getDefaultInstanceAttributeBuffer(r,l+Math.max(1,n));const c=Rr(s),u=this.geometryVertexBufferFastCache.get(t),d=u?.get(r),h=d?.get(l);if(h&&h.source===s&&h.version===c&&h.itemSize===(s?.itemSize??0)&&h.count===(s?.count??0))return h.buffer;const p=`${this.getGeometryAttributeBufferKey(r)}${o?`:instance-start=${l}`:""}`,f=s?`${c}:${s.itemSize}:${s.count}`:"default",m=t.extraAttributeBuffers.get(p);if(m&&t.extraAttributeBufferVersions.get(p)===f)return this.cacheGeometryVertexBufferFast(t,r,l,s,c,m),m;if(!s&&!r.defaultValue)throw new Error(`Geometry "${e.uuid}" is missing required vertex attribute "${r.name}".`);const g=Nr(s,o?l+Math.max(1,s?.count??1,n):t.vertexCount,r.format,r.defaultValue??[],o?l:0);if(m&&m.size>=Math.max(4,g.byteLength))return this.state.device.queue.writeBuffer(m,0,g.buffer,g.byteOffset,g.byteLength),t.extraAttributeBufferVersions.set(p,f),this.cacheGeometryVertexBufferFast(t,r,l,s,c,m),m;const v=kr(this.state.device,g,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e.uuid}-${r.name}-${r.format}`);return m&&(this.clearIndirectBundleCache(),this.retiredGeometryBuffers.push(m)),t.extraAttributeBuffers.set(p,v),t.extraAttributeBufferVersions.set(p,f),this.cacheGeometryVertexBufferFast(t,r,l,s,c,v),v}cacheGeometryVertexBufferFast(e,t,r,i,n,a){let s=this.geometryVertexBufferFastCache.get(e);s||(s=new WeakMap,this.geometryVertexBufferFastCache.set(e,s));let o=s.get(t);o||(o=new Map,s.set(t,o));const l=i;o.set(r,{source:i,version:n,itemSize:l?.itemSize??0,count:l?.count??0,buffer:a})}getInterleavedGeometryVertexBuffer(e,t,r,i,n){if(!this.state.device)throw new Error("Renderer is not initialized.");const a=r[0].stepMode??"vertex",s=Math.max(0,Math.trunc(i)),o="instance"===a?s+Math.max(1,n,...r.map(t=>e.getAttribute(t.name)?.count??1)):t.vertexCount,l=`interleaved:${this.getGeometryAttributeGroupBufferKey(r)}:instance-start=${"instance"===a?s:0}`,c=r.map(t=>{const r=e.getAttribute(t.name);return r?`${Rr(r)}:${r.itemSize}:${r.count}`:"default"}).join("|"),u=t.extraAttributeBuffers.get(l);if(u&&t.extraAttributeBufferVersions.get(l)===c)return u;const d=[];let h=0;for(const e of r)d.push(h),h+=Lr(e.format);const p=new Uint8Array(o*h);for(let t=0;t<r.length;t+=1){const i=r[t],n=Nr(e.getAttribute(i.name),o,i.format,i.defaultValue??[],"instance"===a?s:0),l=new Uint8Array(n.buffer,n.byteOffset,n.byteLength),c=Lr(i.format);for(let e=0;e<o;e+=1)p.set(l.subarray(e*c,(e+1)*c),e*h+d[t])}if(u&&u.size>=Math.max(4,p.byteLength))return this.state.device.queue.writeBuffer(u,0,p.buffer,p.byteOffset,p.byteLength),t.extraAttributeBufferVersions.set(l,c),u;const f=kr(this.state.device,p,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e.uuid}-interleaved-${a}`);return u&&(this.clearIndirectBundleCache(),this.retiredGeometryBuffers.push(u)),t.extraAttributeBuffers.set(l,f),t.extraAttributeBufferVersions.set(l,c),f}ensureWireframeIndex(e,t){if(t.wireframeIndex)return;if(!this.state.device)throw new Error("Renderer is not initialized.");const r=e.index?.array,i=r?.length??t.vertexCount,n=Math.floor(i/3),a=t.vertexCount>65535,s=a?new Uint32Array(6*n):new Uint16Array(6*n);for(let e=0;e<n;e+=1){const t=3*e,i=6*e,n=r?r[t]:t,a=r?r[t+1]:t+1,o=r?r[t+2]:t+2;s[i]=n,s[i+1]=a,s[i+2]=a,s[i+3]=o,s[i+4]=o,s[i+5]=n}t.wireframeIndexFormat=a?"uint32":"uint16",t.wireframeIndex=kr(this.state.device,s,GPUBufferUsage.INDEX,`${e.uuid}-wireframe-index`)}bindGeometryVertexBuffers(e,t,r,i,n=0,a=1,s=!1){const o=this.prepareGeometryVertexBuffers(t,r,i,n,a);for(let t=0;t<o.length;t+=1)e.setVertexBuffer(t,o[t]);s&&r.wireframeIndex&&r.wireframeIndexFormat?e.setIndexBuffer(r.wireframeIndex,r.wireframeIndexFormat):r.index&&r.indexFormat&&e.setIndexBuffer(r.index,r.indexFormat)}prepareGeometryVertexBuffers(e,t,r,i,n){let a=this.preparedVertexBufferCache.get(t);a||(a=new WeakMap,this.preparedVertexBufferCache.set(t,a));let s=a.get(r);s||(s={instanced:r.some(e=>"instance"===e.stepMode),ranges:new Map},a.set(r,s));const o=s.instanced?Math.max(0,Math.trunc(i)):0,l=s.instanced?n:1;let c=s.ranges.get(o);if(!this.invokeObjectRenderCallbacks&&c&&c.extractionVersion===this.extractionVersion&&c.instanceCount===l&&c.instanceBufferSize===this.state.instanceBufferSize)return c.buffers;c||(c={extractionVersion:-1,instanceCount:l,instanceBufferSize:0,buffers:[]},s.ranges.set(o,c));let u=this.vertexBufferBindingPlanCache.get(r);u||(u=this.getVertexAttributeGroups(r).map(e=>({group:e,standardAttribute:1===e.length?this.getStandardVertexAttribute(e[0]):null})),this.vertexBufferBindingPlanCache.set(r,u));for(let r=0;r<u.length;r+=1){const{group:a,standardAttribute:s}=u[r],o=s?t[s]:null;c.buffers[r]=o??(1===a.length?this.getGeometryVertexBuffer(e,t,a[0],i,n):this.getInterleavedGeometryVertexBuffer(e,t,a,i,n))}return c.extractionVersion=this.extractionVersion,c.instanceCount=l,c.instanceBufferSize=this.state.instanceBufferSize,c.buffers}getStandardVertexAttribute(e){let t=this.standardVertexAttributeCache.get(e);return void 0!==t||(t="position"===e.name&&"float32x3"===e.format?"position":"normal"!==e.name||"float32x3"!==e.format||void 0!==e.defaultValue&&!jr(e.defaultValue,ws)?"uv"!==e.name||"float32x2"!==e.format||void 0!==e.defaultValue&&!jr(e.defaultValue,xs)?"color"!==e.name||"float32x4"!==e.format||void 0!==e.defaultValue&&!jr(e.defaultValue,bs)?"skinIndex"===e.name&&"uint32x4"===e.format?"skinIndex":"skinWeight"===e.name&&"float32x4"===e.format?"skinWeight":null:"color":"uv":"normal",this.standardVertexAttributeCache.set(e,t)),t}prepareDrawGeometryVertexBuffers(e){for(let t=0;t<(e.customDepthMaterial?2:1);t++){const r=0===t?e.material:e.customDepthMaterial,i=this.getMaterialVertexAttributes(r,null!==e.skinning);this.prepareGeometryVertexBuffers(e.geometry,e.geometryResource,i,e.instanceStart,e.instanceCount)}}getDefaultInstanceAttributeBuffer(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=Math.max(1,t,Math.ceil(this.state.instanceBufferSize/(Float32Array.BYTES_PER_ELEMENT*w))),i=2**Math.ceil(Math.log2(r)),n=`${e.format}:${(e.defaultValue??[]).join(",")}`;let a=this.defaultInstanceAttributeBuffers.get(n);a||(a=new Map,this.defaultInstanceAttributeBuffers.set(n,a));const s=a.get(i);if(s)return s;const o=kr(this.state.device,Nr(void 0,i,e.format,e.defaultValue??[]),GPUBufferUsage.VERTEX,`renderer-default-instance-${e.format}`);return a.set(i,o),o}getMeshExtractionCacheEntry(e,t,r,i,n,a){const s=this.meshExtractionCache.get(e),o=Array.isArray(t)?t:null,l=Array.isArray(t)?null:t;if(s&&s.geometryResource===a&&s.customDepthMaterial===n&&(null!==l&&s.material===l&&s.resolvedMaterial===r||null!==o&&null!==s.materials&&null!==s.resolvedMaterials&&Fr(s.materials,o)&&Or(s.resolvedMaterials,i)))return s;const c=null!==e.geometry.index,u=vi(e.geometry),d=[];if(e.geometry.groups.length>0)for(const t of e.geometry.groups){const s=o?i[t.materialIndex??0]??i[0]:r;if(!s)continue;const l=_r(e.geometry,c,t.start,t.count),u=ti(s,e.geometry,c,t.start,l,n),h=ei(s),p=ei(e.geometry),f=n?ei(n):0;d.push({geometry:e.geometry,geometryKey:e.geometry,geometryResource:a,material:s,customDepthMaterial:n,residentInstanceBinding:null,sourceObject:e,frontFaceCW:e.matrixWorld.determinant()<0,usesBatching:!1,geometryGroup:t,batchKey:u,batchHash:ri(h,p,c,t.start,l,f),indexed:c,wireframe:s.wireframe&&"triangle-list"===s.primitiveTopology,start:t.start,count:l,transparent:s.transparent||s.requiresLatePass(),renderOrder:e.renderOrder,hasRenderCallbacks:this.hasRenderCallbacks(e),castShadow:e.castShadow,receiveShadow:e.receiveShadow,sortMaterialId:h,sortGeometryId:p,sortCustomDepthMaterialId:f})}else{const t=r??i?.[0]??null;if(t){const r=Hr(e.geometry,c),i=ti(t,e.geometry,c,r.start,r.count,n),s=ei(t),o=ei(e.geometry),l=n?ei(n):0;d.push({geometry:e.geometry,geometryKey:e.geometry,geometryResource:a,material:t,customDepthMaterial:n,residentInstanceBinding:null,sourceObject:e,frontFaceCW:e.matrixWorld.determinant()<0,usesBatching:!1,geometryGroup:null,batchKey:i,batchHash:ri(s,o,c,r.start,r.count,l),indexed:c,wireframe:t.wireframe&&"triangle-list"===t.primitiveTopology,start:r.start,count:r.count,transparent:t.transparent||t.requiresLatePass(),renderOrder:e.renderOrder,hasRenderCallbacks:this.hasRenderCallbacks(e),castShadow:e.castShadow,receiveShadow:e.receiveShadow,sortMaterialId:s,sortGeometryId:o,sortCustomDepthMaterialId:l})}}const h={geometryResource:a,material:l,materials:o?o.slice():null,resolvedMaterial:r,resolvedMaterials:o?i.slice():null,customDepthMaterial:n,indexed:c,templates:d,localBoundsCenter:u.center.clone(),localBoundsRadius:u.radius};return this.meshExtractionCache.set(e,h),h}getInstancedMeshExtractionCacheEntry(e,t,r,i){const n=null!==e.geometry.index,a=Hr(e.geometry,n),s=vi(e.geometry),o=this.instancedMeshExtractionCache.get(e);if(o&&o.geometryResource===i&&o.material===t&&o.customDepthMaterial===r&&o.indexed===n&&o.drawRangeStart===a.start&&o.drawRangeCount===a.count)return o.sourceMaterial=e.material,o.sourceMaterialVersion=e.material.version,o;o?.residentInstanceBinding?.buffer?.destroy(),o?.residentInstanceBinding?.colorBuffer?.destroy();const l=ei(t),c=ei(e.geometry),u=r?ei(r):0,d={geometryResource:i,sourceMesh:e,sourceMaterial:e.material,sourceMaterialVersion:e.material.version,material:t,customDepthMaterial:r,indexed:n,drawRangeStart:a.start,drawRangeCount:a.count,batchKey:ti(t,e,n,a.start,a.count,r),batchHash:ri(l,c,n,a.start,a.count,u),sortMaterialId:l,sortGeometryId:c,sortCustomDepthMaterialId:u,localBoundsCenter:s.center.clone(),localBoundsRadius:s.radius,cachedInstanceData:new Mi(1024),cachedBoundsMin:new Ki,cachedBoundsMax:new Ki,cachedDrawBoundsCenter:new Ki,cachedDrawBoundsRadius:0,cachedMatrixWorld:new Float64Array(16),cachedInstanceMatrixVersion:-1,cachedInstanceColorVersion:-1,cachedCount:0,cachedDefaultColorData:null,residentInstanceBinding:{mode:"packed",buffer:null,colorBuffer:null,sceneBindGroup:null,shadowBindGroup:null,shadowBindGroups:new Map,sceneBindGroupVersion:0,shadowBindGroupVersion:0},residentBufferSize:0,residentColorBufferSize:0,residentBufferDirty:!1,residentColorBufferDirty:!1,cacheValid:!1};return this.instancedMeshExtractionCache.set(e,d),d}getBatchedMeshExtractionCacheEntry(e,t,r,i,n){const a=n._geometryCount??0,s=this.batchedMeshExtractionCache.get(e);if(s&&s.geometryResource===i&&s.material===t&&s.customDepthMaterial===r&&s.indexed===(null!==e.geometry.index)&&s.cachedGeometryCount===a)return s;s?.residentInstanceBinding?.buffer?.destroy(),s?.residentInstanceBinding?.colorBuffer?.destroy();const o=null!==e.geometry.index,l=new Array(a).fill(null),c=new Array(a).fill(null);for(let n=0;n<a;n+=1){const a=e.getGeometryRangeAt(n);if(!a||a.count<=0)continue;const s=_r(e.geometry,o,a.start,a.count),u=ti(t,e.geometry,o,a.start,s,r),d=ei(t),h=ei(e.geometry),p=r?ei(r):0,f=e.getBoundingSphereAt(n,z),m={geometry:e.geometry,geometryKey:e.geometry,geometryResource:i,material:t,customDepthMaterial:r,residentInstanceBinding:null,sourceObject:e,frontFaceCW:!1,usesBatching:!0,geometryGroup:null,batchKey:u,batchHash:ri(d,h,o,a.start,s,p),indexed:o,wireframe:t.wireframe&&"triangle-list"===t.primitiveTopology,start:a.start,count:s,transparent:t.transparent||t.requiresLatePass(),renderOrder:e.renderOrder,hasRenderCallbacks:this.hasRenderCallbacks(e),castShadow:e.castShadow,receiveShadow:e.receiveShadow,sortMaterialId:d,sortGeometryId:h,sortCustomDepthMaterialId:p,geometryId:n,localBoundsCenter:f?f.center.clone():new Ki,localBoundsRadius:f?.radius??1};l[n]=m,c[n]={template:m,boundsMin:new Ki,boundsMax:new Ki,activeInFrame:!1,activeCount:0,instanceStart:0,writeOffset:0}}const u={geometryResource:i,material:t,customDepthMaterial:r,indexed:o,templates:l,groups:c,activeGroups:[],cachedInstanceData:new Mi(1024),cachedDraws:[],cachedBoundsMin:new Ki,cachedBoundsMax:new Ki,cachedMatrixWorld:new Float64Array(16),geometryIdsSnapshot:new Int32Array(0),cachedMatricesVersion:-1,cachedColorsVersion:-1,cachedGeometryCount:a,cachedInstanceInfoLength:0,residentInstanceBinding:{mode:"packed",buffer:null,colorBuffer:null,sceneBindGroup:null,shadowBindGroup:null,shadowBindGroups:new Map,sceneBindGroupVersion:0,shadowBindGroupVersion:0},residentBufferSize:0,residentColorBufferSize:0,residentBufferDirty:!1,residentColorBufferDirty:!1,cacheValid:!1};return this.batchedMeshExtractionCache.set(e,u),u}batchedGeometryIdsMatchSnapshot(e,t){if(e.length!==t.length)return!1;for(let r=0;r<t.length;r+=1){const i=t[r];if((e[r]??-1)!==(i?.active&&i.visible?i.geometryIndex:-1))return!1}return!0}destroyGeometryResource(e){e.position.destroy(),e.normal.destroy(),e.uv.destroy(),e.color.destroy(),e.skinIndex?.destroy(),e.skinWeight?.destroy();for(const t of e.extraAttributeBuffers.values())t.destroy();e.extraAttributeBuffers.clear(),e.extraAttributeBufferVersions.clear(),e.index?.destroy(),e.wireframeIndex?.destroy()}retireGeometryResource(e){this.retiredGeometryResources.push(e)}releaseRetiredGeometryResourcesAfterSubmit(){const e=this.retiredGeometryResources.splice(0),t=this.retiredGeometryBuffers.splice(0);if(0!==e.length||0!==t.length)if(this.state.device)this.state.device.queue.onSubmittedWorkDone().then(()=>{for(const t of e)this.destroyGeometryResource(t);for(const e of t)e.destroy()},()=>{for(const t of e)this.destroyGeometryResource(t);for(const e of t)e.destroy()});else{for(const t of e)this.destroyGeometryResource(t);for(const e of t)e.destroy()}}destroyTextureResource(e){this.textureManager.destroyTextureResource(e)}createTextureSampler(e,t){return this.textureManager.createTextureSampler(e,t)}uploadDataTextureResource(e,t,r){this.textureManager.uploadDataTextureResource(e,t,r)}uploadCompressedTextureResource(e,t,r){this.textureManager.uploadCompressedTextureResource(e,t,r)}uploadExternalTextureResource(e,t,r){this.textureManager.uploadExternalTextureResource(e,t,r)}uploadTextureResource(e,t,r){this.textureManager.uploadTextureResource(e,t,r)}getTextureResource(e){return this.textureManager.getTextureResource(e)}updateMaterialUniformBuffer(e,t){if(!this.state.device||!t.uniformBuffer)return;const r=e.getUniformLayout();if(0===r.entries.length)return;let i=t.uniformValueHash;if(e.uniformValuesAutoUpdate){if(i=e.getUniformValueHash(),t.uniformValueHash===i)return}else if(t.uniformValuesAutoVersion===e.uniformValuesAutoVersion)return;const n=kt(e.uniforms,r);!t.uniformBuffer||n.byteLength>t.uniformBuffer.size||(t.uniformValueHash=i,t.uniformValuesAutoVersion=e.uniformValuesAutoVersion,this.state.device.queue.writeBuffer(t.uniformBuffer,0,n))}materialResourceMatches(e,t,r,i=this.sampleCount){if(e.key!==r)return!1;if(e.materialVersion===t.version&&e.textureVersionHash===t.getTextureVersionHash()&&e.rendererSampleCount===i&&e.uniformBufferSize===t.getUniformLayout().byteLength)return!0;const n=Or(e.textures,t.getTexturesList())&&jr(e.textureVersions,t.getTextureVersionsList())&&Or(e.storageBuffers,t.getStorageBufferList())&&e.rendererSampleCount===i&&e.uniformBufferSize===t.getUniformLayout().byteLength;return n&&(e.materialVersion=t.version,e.textureVersionHash=t.getTextureVersionHash()),n}destroyMaterialResource(e){e?.uniformBuffer?.destroy()}createMaterialBindGroupData(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const i=this.pipelineCompilationDiagnostics,n=i?performance.now():0,a=[],s=[],o=Array.from(e.getTexturesList()),l=Array.from(e.getTextureVersionsList()),c=e.getStorageBufferBindingList();let u=null;const d=i?performance.now():0;if(Object.keys(e.uniforms).length>0){const r=kt(e.uniforms,e.getUniformLayout());u=this.state.device.createBuffer({label:`${t}-uniforms`,size:r.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.state.device.queue.writeBuffer(u,0,r),a.push({binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}),s.push({binding:0,resource:{buffer:u}})}i&&(i.cpuTotalsMs.uniformBuffer=(i.cpuTotalsMs.uniformBuffer??0)+performance.now()-d);for(const[t,n]of o.entries()){const o=1+2*t,l=i?performance.now():0,c=this.getTextureResource(n);if(i){const t=performance.now()-l;i.cpuTotalsMs.textureLookup=(i.cpuTotalsMs.textureLookup??0)+t,t>=1&&i.slowTextureLookups.push({material:e.name||e.uuid,texture:n.name||n.uuid,durationMs:t})}a.push({binding:o,visibility:r,sampler:{type:c.samplerBindingType}},{binding:o+1,visibility:r,texture:{sampleType:c.sampleType,viewDimension:c.viewDimension}}),s.push({binding:o,resource:c.sampler},{binding:o+1,resource:c.view})}const h=1+2*o.length,p=Array.from(e.getStorageBufferList());for(const[e,t]of c.entries()){const r=h+e;a.push({binding:r,visibility:Er(t.visibility),buffer:{type:"read-only-storage"}}),s.push({binding:r,resource:{buffer:t.buffer}})}return i&&(i.cpuTotalsMs.bindGroupData=(i.cpuTotalsMs.bindGroupData??0)+performance.now()-n),{bindGroupLayoutEntries:a,bindGroupEntries:s,uniformBuffer:u,textures:o,textureVersions:l,storageBuffers:p}}createGraphTextureBindGroupLayout(e){if(!this.state.device)throw new Error("Renderer is not initialized.");const t=[];return Object.values(e.getGraphTextureInputs()).forEach((e,r)=>{t.push({binding:2*r,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,sampler:{type:e.sampler??("depth-2d"===e.dimension?"non-filtering":"filtering")}},{binding:2*r+1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,texture:{sampleType:e.sampleType??("depth-2d"===e.dimension?"depth":"float"),viewDimension:"3d"===e.dimension?"3d":"2d"}})}),this.state.device.createBindGroupLayout({label:`${e.uuid}-graph-textures-layout`,entries:t})}createGraphTextureBindGroup(e,t){if(!(this.state.device&&this.state.linearClampSampler&&this.state.nearestClampSampler&&this.state.shadowComparisonSampler))throw new Error("Renderer graph texture bindings are not initialized.");let r=this.graphTextureBindGroupCache.get(e);const i=r?.get(t);if(i&&i.materialVersion===e.version&&i.resourceVersion===this.graphTextureResourceVersion)return i.bindGroup;const n=[];Object.values(e.getGraphTextureInputs()).forEach((e,t)=>{const r="comparison"===e.sampler?this.state.shadowComparisonSampler:"non-filtering"===e.sampler||"depth-2d"===e.dimension?this.state.nearestClampSampler:"physicalTransmissionSnapshot"===e.resource?this.transmissionSampler:this.state.linearClampSampler,i="mainDepth"===e.resource?this.state.sceneDepthSnapshotView:this.getGraphTextureView(e.resource);n.push({binding:2*t,resource:r},{binding:2*t+1,resource:i})});const a=this.state.device.createBindGroup({label:`${e.uuid}-graph-textures`,layout:t,entries:n});return r||(r=new WeakMap,this.graphTextureBindGroupCache.set(e,r)),r.set(t,{materialVersion:e.version,resourceVersion:this.graphTextureResourceVersion,bindGroup:a}),a}getGraphTextureView(e){return"physicalTransmissionSnapshot"===e?this.transmissionSnapshotView:"mainDepth"===e?this.state.mainDepthView:"sceneColorSnapshot"===e?this.state.sceneColorSnapshotView:"sceneDepthSnapshot"===e?this.state.hizMipViews[0]:this.getColorTargetView(e)}compileDrawMaterials(e){const t=new Set;for(const r of e){const e=this.getDrawInstanceAccessMode(r),i=null!==r.skinning,n=this.drawUsesBatching(r),a=`${r.material.uuid}:${e}:receiveShadow=${r.receiveShadow?1:0}:skinning=${i?1:0}:batching=${n?1:0}`;t.has(a)||(r.materialResource=this.getMaterialResource(r.material,e,r.receiveShadow,void 0,i,n),t.add(a))}}async compileDrawMaterialsAsync(e,t=hs,r=this.sampleCount,i=!0){const n=new Set,a=new Set,s=[],o=[];for(const l of e){const e=this.getDrawInstanceAccessMode(l);i&&l.residentInstanceBinding&&l.sourceObject instanceof ki&&o.push({...l,materialResource:null,residentInstanceBinding:{...l.residentInstanceBinding,mode:"packed"===e?"instanced-direct":"packed"}});const c=null!==l.skinning,u=this.drawUsesBatching(l),d=`${l.material.uuid}:${e}:receiveShadow=${l.receiveShadow?1:0}:skinning=${c?1:0}:batching=${u?1:0}`;if(n.has(d)||(s.push(this.getMaterialResourceAsync(l.material,e,l.receiveShadow,t,c,u,r).then(e=>(l.materialResource=e,e))),n.add(d)),l.customDepthMaterial){const t=`${l.customDepthMaterial.uuid}:${e}:skinning=${c?1:0}`;a.has(t)||(s.push(this.getDepthPassMaterialResourceAsyncForDraw(l.customDepthMaterial,"directionalShadow",l)),a.add(t))}if(null!==l.material.depthVertexShader||u){const t=null!==l.material.depthVertexShader?["prepass","directionalShadow","pointShadow"]:["prepass","directionalShadow"];for(const r of t){const t=`${l.material.uuid}:${r}:${e}:skinning=${c?1:0}:batching=${u?1:0}`;a.has(t)||(s.push(this.getDepthPassMaterialResourceAsyncForDraw(l.material,r,l)),a.add(t))}}}o.length>0&&s.push(this.compileDrawMaterialsAsync(o,t,r,!1)),await Promise.all(s)}async compileStaticDrawMaterialsAsync(e,t=this.sampleCount,r="all"){const i=[],n=new Set;for(const a of this.staticDrawSets)if(a.publicSet.enabled&&("all"===r||a.drawStage===r)){i.push(this.compileDrawMaterialsAsync(a.draws,e,t));for(const r of a.visibleMaterialBindings){const a=`${r.material.uuid}:receiveShadow=${r.receiveShadow?1:0}:batching=${r.usesBatching?1:0}`;n.has(a)||(n.add(a),i.push(this.getMaterialResourceAsync(r.material,"packed-visible",r.receiveShadow,e,!1,r.usesBatching,t)))}}await Promise.all(i)}getDepthPassMaterialKey(e,t,r,i,n,a=!1){if(!this.state.device)throw new Error("Renderer is not initialized.");return`${e.customProgramCacheKey()}:${t}:instance=${r}:skinning=${i?1:0}:batching=${n?1:0}:frontFace=${a?"cw":"ccw"}:textures=${e.getTextureLayoutKey(this.state.device)}`}getForwardMaterialKey(e,t,r,i,n,a,s=!1,o=this.sampleCount){return`${e.customProgramCacheKey()}:instance=${t}:receiveShadow=${r?1:0}:skinning=${n?1:0}:batching=${a?1:0}:frontFace=${s?"cw":"ccw"}:textures=${e.getTextureLayoutKey(this.state.device)}:samples=${o}:targets=${i.join("|")}`}getInstanceAccessModeIndex(e){return"packed"===e?0:"packed-visible"===e?1:2}getForwardMaterialFastCacheIndex(e,t,r,i,n=!1){return this.getInstanceAccessModeIndex(e)|(t?4:0)|(r?8:0)|(i?16:0)|(n?32:0)}getDepthMaterialFastCacheIndex(e,t,r,i,n=!1){return("prepass"===e?0:"directionalShadow"===e?1:2)+3*this.getInstanceAccessModeIndex(t)+(r?9:0)+(i?18:0)+(n?36:0)}fastMaterialResourceMatches(e,t,r=this.sampleCount){return e.materialVersion===t.version&&e.textureVersionHash===t.getTextureVersionHash()&&e.rendererSampleCount===r}setForwardMaterialFastCache(e,t,r){let i=this.forwardMaterialFastCache.get(e);i||(i=[],this.forwardMaterialFastCache.set(e,i)),i[t]=r}getForwardMaterialTargetFastCacheKey(e,t){return 32*this.getColorFormatsId(e)+t}setForwardMaterialTargetFastCache(e,t,r){let i=this.forwardMaterialTargetFastCache.get(e);i||(i=new Map,this.forwardMaterialTargetFastCache.set(e,i)),i.set(t,r)}setForwardMaterialFrameCache(e,t,r){let i=this.forwardMaterialFrameCache.get(e);i||(i=[],this.forwardMaterialFrameCache.set(e,i)),i[t]={extractionVersion:this.extractionVersion,resource:r}}setDepthMaterialFastCache(e,t,r){let i=this.depthMaterialFastCache.get(e);i||(i=[],this.depthMaterialFastCache.set(e,i)),i[t]=r}getDrawInstanceAccessMode(e){return"instanced-direct"===e.residentInstanceBinding?.mode?"instanced-direct":"packed"}drawUsesBatching(e){return e.usesBatching}buildMaterialShaderCode(e,t,r,i,n=!1,a=!1){const s=this.pipelineCompilationDiagnostics,o=s?performance.now():0,l=Ji(`${t}\n${r}`,this.createMaterialPreprocessorDefines(e,i,n,a),{sourceName:i}),c=i.includes("vertex")?function(e){let t=0,r=0,i=null;for(;;){const n=e.indexOf("@builtin",t);if(n<0)break;t=n+8;let a=t;for(;xn(e.charCodeAt(a));)a++;if("("!==e[a++])continue;for(;xn(e.charCodeAt(a));)a++;if(!e.startsWith("position",a))continue;for(a+=8;xn(e.charCodeAt(a));)a++;if(")"!==e[a++])continue;vn.lastIndex=a;const s=vn.exec(e);s&&(i??=[],i.push(e.slice(r,n),"@builtin(position) @invariant "),r=a+s[0].length,t=r)}return null===i?e:(i.push(e.slice(r)),i.join(""))}(l):l;return s&&(s.cpuTotalsMs.shaderPreprocess=(s.cpuTotalsMs.shaderPreprocess??0)+performance.now()-o),c}createMaterialPreprocessorDefines(e,t,r=!1,i=!1){const n={HIGH_PRECISION:!0,WEBGPU_RENDERER:!0,WGSL_SHADER_MATERIAL:!0,USE_BATCHING:i,USE_COLOR:!0,USE_COLOR_ALPHA:!0,NUM_DIR_LIGHTS:4,NUM_POINT_LIGHTS:v,NUM_SPOT_LIGHTS:x,NUM_DIR_LIGHT_SHADOWS:4,NUM_POINT_LIGHT_SHADOWS:v,NUM_SPOT_LIGHT_SHADOWS:x,NUM_CLIPPING_PLANES:0,UNION_CLIPPING_PLANES:0,USE_SKINNING:r,RENDERER_MOTION_VECTORS:!t.includes("shared-depth"),...this.createTexturePreprocessorDefines(e)};return e.side===Li?n.DOUBLE_SIDED=!0:e.side===Vi&&(n.FLIP_SIDED=!0),!t.includes("receiveShadow=1")&&t.includes("receiveShadow=0")||(n.USE_SHADOWMAP=!0,n.SHADOWMAP_TYPE_PCF=!0),{...n,...e.defines,USE_BATCHING:i}}createTexturePreprocessorDefines(e){const t={},r={map:"USE_MAP",matcap:"USE_MATCAP",lightMap:"USE_LIGHTMAP",aoMap:"USE_AOMAP",bumpMap:"USE_BUMPMAP",normalMap:"USE_NORMALMAP",displacementMap:"USE_DISPLACEMENTMAP",emissiveMap:"USE_EMISSIVEMAP",anisotropyMap:"USE_ANISOTROPYMAP",clearcoatMap:"USE_CLEARCOATMAP",clearcoatRoughnessMap:"USE_CLEARCOAT_ROUGHNESSMAP",clearcoatNormalMap:"USE_CLEARCOAT_NORMALMAP",iridescenceMap:"USE_IRIDESCENCEMAP",iridescenceThicknessMap:"USE_IRIDESCENCE_THICKNESSMAP",specularMap:"USE_SPECULARMAP",specularColorMap:"USE_SPECULAR_COLORMAP",specularIntensityMap:"USE_SPECULAR_INTENSITYMAP",roughnessMap:"USE_ROUGHNESSMAP",metalnessMap:"USE_METALNESSMAP",alphaMap:"USE_ALPHAMAP",sheenColorMap:"USE_SHEEN_COLORMAP",sheenRoughnessMap:"USE_SHEEN_ROUGHNESSMAP",transmissionMap:"USE_TRANSMISSIONMAP",thicknessMap:"USE_THICKNESSMAP"};for(const[i,n]of Object.entries(r))e.textures[i]&&(t[n]=!0);return t}shouldInvalidateDrawMaterialResource(e,t,r,i,n){return!!e.materialResource&&(e.material!==t||e.receiveShadow!==r||e.usesBatching!==i||e.skinning!==n)}cachedDrawMaterialResourceMatches(e,t,r,i=this.sampleCount){const n=this.getDrawInstanceAccessMode(e),a=null!==e.skinning,s=this.drawUsesBatching(e),o=this.getColorFormatsId(r);return t.instanceAccessMode===n&&t.receiveShadow===e.receiveShadow&&t.useBatching===s&&t.frontFaceCW===ci(e)&&t.usesSkinning===a&&t.rendererSampleCount===i&&t.colorTargetFormatsId===o&&(this.drawMaterialResourceFrameValidation.get(t)===this.extractionVersion||(t.materialVersion===e.material.version&&t.textureVersionHash===e.material.getTextureVersionHash()||this.materialResourceMatches(t,e.material,t.key,i)))}getMaterialResourceForDraw(e,t=hs,r=this.sampleCount){const i=e.materialResource;if(i&&this.cachedDrawMaterialResourceMatches(e,i,t,r))return this.drawMaterialResourceFrameValidation.get(i)!==this.extractionVersion&&(this.updateMaterialUniformBuffer(e.material,i),this.drawMaterialResourceFrameValidation.set(i,this.extractionVersion)),i;const n=this.getDrawInstanceAccessMode(e),a=null!==e.skinning,s=this.drawUsesBatching(e),o=this.getMaterialResource(e.material,n,e.receiveShadow,t,a,s,r,ci(e));return e.materialResource=o,this.drawMaterialResourceFrameValidation.set(o,this.extractionVersion),o}getMaterialResourceAsyncForDraw(e){return this.getMaterialResourceAsync(e.material,this.getDrawInstanceAccessMode(e),e.receiveShadow,void 0,null!==e.skinning,this.drawUsesBatching(e),this.sampleCount,ci(e))}resolveForwardMaterialResources(e){for(let t=0;t<e.length;t+=1){const r=e[t];r.materialResource=this.getMaterialResource(r.material,this.getDrawInstanceAccessMode(r),r.receiveShadow,void 0,null!==r.skinning,this.drawUsesBatching(r),this.sampleCount,ci(r))}}getDepthPassMaterialResourceForDraw(e,t,r){return this.getDepthPassMaterialResource(e,t,this.getDrawInstanceAccessMode(r),null!==r.skinning,this.drawUsesBatching(r),ci(r))}getDepthPassMaterialResourceAsyncForDraw(e,t,r){return this.getDepthPassMaterialResourceAsync(e,t,this.getDrawInstanceAccessMode(r),null!==r.skinning,this.drawUsesBatching(r),ci(r))}getOrCreateSharedDepthPipeline(e,t,i,n,a,s,o,l){if(!(this.state.device&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&this.state.skinningBindGroupLayout))throw new Error("Renderer is not initialized.");const c=this.sharedDepthPipelineCache.get(e);if(c)return c;const u=`${t.uuid}-shared-depth-${i}-${n}`;r(this.state.device,u+"-pipeline",{key:String(t.userData.pipelineOrigin?.assetId??t.userData.assetId??t.userData.pipelineOrigin?.sourceUuid??t.uuid)+":depth:"+i,material:{name:t.name,uuid:t.uuid,version:t.version,assetId:t.userData.assetId,assetName:t.userData.assetName,...t.userData.pipelineOrigin},variant:{instanceAccessMode:n,useSkinning:s,useBatching:o,passKind:i,frontFaceCW:l},defines:{...t.defines}});const d=this.state.device.createBindGroupLayout({label:`${u}-material-layout`,entries:a}),h="prepass"===i?"instanced-direct"===n?this.state.directSceneBindGroupLayout:this.state.sceneBindGroupLayout:"instanced-direct"===n?this.state.directShadowBindGroupLayout:this.state.shadowBindGroupLayout,p=this.state.device.createPipelineLayout({label:`${u}-pipeline-layout`,bindGroupLayouts:[h,d,...s?[this.state.skinningBindGroupLayout]:[]]}),f=jn(t,"prepass"===i?"camera":"shadow",this.state.device,n,s),m=this.buildMaterialShaderCode(t,f,"pointShadow"===i?t.pointShadowVertexShader??t.vertexShader:t.depthVertexShader??t.vertexShader,`${u}-vertex`,s,o),g="pointShadow"===i?t.pointShadowFragmentShader:t.depthFragmentShader,v=g?this.buildMaterialShaderCode(t,f,g,`${u}-fragment`,s,o):null,x={bindGroupLayout:d,pipeline:this.state.device.createRenderPipeline({label:`${u}-pipeline`,layout:p,vertex:{module:this.state.device.createShaderModule({label:`${u}-vertex`,code:m}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,s))},...v?{fragment:{module:this.state.device.createShaderModule({label:`${u}-fragment`,code:v}),entryPoint:"fsMain",targets:"pointShadow"===i?[{format:"rgba16float"}]:[]}}:{},primitive:{topology:fs(t),cullMode:ms(t,i,o),frontFace:l?"cw":"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",..."directionalShadow"===i?{depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}:{}}})};return this.sharedDepthPipelineCache.set(e,x),x}async getOrCreateSharedDepthPipelineAsync(e,t,i,n,a,s,o,l){if(!(this.state.device&&this.state.sceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&this.state.skinningBindGroupLayout))throw new Error("Renderer is not initialized.");const c=this.sharedDepthPipelineCache.get(e);if(c)return c;const u=this.sharedDepthPipelinePromiseCache.get(e);if(u)return u;const d=`${t.uuid}-shared-depth-${i}-${n}`;r(this.state.device,d+"-pipeline",{key:String(t.userData.pipelineOrigin?.assetId??t.userData.assetId??t.userData.pipelineOrigin?.sourceUuid??t.uuid)+":depth:"+i,material:{name:t.name,uuid:t.uuid,version:t.version,assetId:t.userData.assetId,assetName:t.userData.assetName,...t.userData.pipelineOrigin},variant:{instanceAccessMode:n,useSkinning:s,useBatching:o,passKind:i,frontFaceCW:l},defines:{...t.defines}});const h=(async()=>{const r=this.state.device.createBindGroupLayout({label:`${d}-material-layout`,entries:a}),c="prepass"===i?"instanced-direct"===n?this.state.directSceneBindGroupLayout:this.state.sceneBindGroupLayout:"instanced-direct"===n?this.state.directShadowBindGroupLayout:this.state.shadowBindGroupLayout,u=this.state.device.createPipelineLayout({label:`${d}-pipeline-layout`,bindGroupLayouts:[c,r,...s?[this.state.skinningBindGroupLayout]:[]]}),h=jn(t,"prepass"===i?"camera":"shadow",this.state.device,n,s),p=this.buildMaterialShaderCode(t,h,"pointShadow"===i?t.pointShadowVertexShader??t.vertexShader:t.depthVertexShader??t.vertexShader,`${d}-vertex`,s,o),f="pointShadow"===i?t.pointShadowFragmentShader:t.depthFragmentShader,m=f?this.buildMaterialShaderCode(t,h,f,`${d}-fragment`,s,o):null,g={bindGroupLayout:r,pipeline:await ys(this.state.device,{label:`${d}-pipeline`,layout:u,vertex:{module:this.state.device.createShaderModule({label:`${d}-vertex`,code:p}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,s))},...m?{fragment:{module:this.state.device.createShaderModule({label:`${d}-fragment`,code:m}),entryPoint:"fsMain",targets:"pointShadow"===i?[{format:"rgba16float"}]:[]}}:{},primitive:{topology:fs(t),cullMode:ms(t,i,o),frontFace:l?"cw":"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",..."directionalShadow"===i?{depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}:{}}},this.pipelineCompilationDiagnostics,"depth",`${t.name||"unnamed"} [${t.uuid}] (${i}, ${n})`,p.length,m?.length??0)};return this.sharedDepthPipelineCache.set(e,g),this.sharedDepthPipelinePromiseCache.delete(e),g})();return this.sharedDepthPipelinePromiseCache.set(e,h),h}getOrCreateSharedForwardPipeline(e,t,i,n,a,s,o,l,c,u=this.sampleCount){if(!(this.state.device&&this.state.format&&this.state.sceneBindGroupLayout&&this.state.visibleSceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.skinningBindGroupLayout&&this.state.emptyBindGroupLayout))throw new Error("Renderer is not initialized.");const d=this.sharedForwardPipelineCache.get(e);if(d)return d;const h=`${t.uuid}-shared-forward-${i}-${u}-receiveShadow=${a?1:0}`;r(this.state.device,h+"-pipeline",{key:String(t.userData.pipelineOrigin?.assetId??t.userData.assetId??t.userData.pipelineOrigin?.sourceUuid??t.uuid)+":forward",material:{name:t.name,uuid:t.uuid,version:t.version,assetId:t.userData.assetId,assetName:t.userData.assetName,...t.userData.pipelineOrigin},variant:{instanceAccessMode:i,useSkinning:o,useBatching:l,receiveShadow:a,sampleCount:u,colorTargetFormats:s},defines:{...t.defines}});const p=this.state.device.createBindGroupLayout({label:`${h}-material-layout`,entries:n}),f=this.createGraphTextureBindGroupLayout(t),m=this.state.device.createPipelineLayout({label:`${h}-pipeline-layout`,bindGroupLayouts:["instanced-direct"===i?this.state.directSceneBindGroupLayout:"packed-visible"===i?this.state.visibleSceneBindGroupLayout:this.state.sceneBindGroupLayout,p,o?this.state.skinningBindGroupLayout:this.state.emptyBindGroupLayout,f]}),g=En(t,this.state.device,i,a,o),v=this.buildMaterialShaderCode(t,g,t.vertexShader,`${h}-vertex`,o,l),x=this.buildMaterialShaderCode(t,g,t.fragmentShader,`${h}-fragment`,o,l),w={bindGroupLayout:p,graphTextureBindGroupLayout:f,pipeline:this.state.device.createRenderPipeline({label:`${h}-pipeline`,layout:m,vertex:{module:this.state.device.createShaderModule({label:`${h}-vertex`,code:v}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,o))},fragment:{module:this.state.device.createShaderModule({label:`${h}-fragment`,code:x}),entryPoint:"fsMain",targets:os(x,s,as(t))},primitive:{topology:fs(t),cullMode:fs(t).startsWith("triangle")&&t.side!==Li?t.side===Vi?"front":"back":"none",frontFace:c?"cw":"ccw"},multisample:{count:u},depthStencil:{format:"depth32float",depthWriteEnabled:t.depthWrite,depthCompare:t.depthTest?"less-equal":"always"}})};return this.sharedForwardPipelineCache.set(e,w),w}async getOrCreateSharedForwardPipelineAsync(e,t,i,n,a,s,o,l,c,u=this.sampleCount){if(!(this.state.device&&this.state.format&&this.state.sceneBindGroupLayout&&this.state.visibleSceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.skinningBindGroupLayout&&this.state.emptyBindGroupLayout))throw new Error("Renderer is not initialized.");const d=this.sharedForwardPipelineCache.get(e);if(d)return d;const h=this.sharedForwardPipelinePromiseCache.get(e);if(h)return h;const p=`${t.uuid}-shared-forward-${i}-${u}-receiveShadow=${a?1:0}`;r(this.state.device,p+"-pipeline",{key:String(t.userData.pipelineOrigin?.assetId??t.userData.assetId??t.userData.pipelineOrigin?.sourceUuid??t.uuid)+":forward",material:{name:t.name,uuid:t.uuid,version:t.version,assetId:t.userData.assetId,assetName:t.userData.assetName,...t.userData.pipelineOrigin},variant:{instanceAccessMode:i,useSkinning:o,useBatching:l,receiveShadow:a,sampleCount:u,colorTargetFormats:s},defines:{...t.defines}});const f=(async()=>{const r=this.state.device.createBindGroupLayout({label:`${p}-material-layout`,entries:n}),d=this.createGraphTextureBindGroupLayout(t),h=this.state.device.createPipelineLayout({label:`${p}-pipeline-layout`,bindGroupLayouts:["instanced-direct"===i?this.state.directSceneBindGroupLayout:"packed-visible"===i?this.state.visibleSceneBindGroupLayout:this.state.sceneBindGroupLayout,r,o?this.state.skinningBindGroupLayout:this.state.emptyBindGroupLayout,d]}),f=En(t,this.state.device,i,a,o),m=this.buildMaterialShaderCode(t,f,t.vertexShader,`${p}-vertex`,o,l),g=this.buildMaterialShaderCode(t,f,t.fragmentShader,`${p}-fragment`,o,l),v={bindGroupLayout:r,graphTextureBindGroupLayout:d,pipeline:await ys(this.state.device,{label:`${p}-pipeline`,layout:h,vertex:{module:this.state.device.createShaderModule({label:`${p}-vertex`,code:m}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,o))},fragment:{module:this.state.device.createShaderModule({label:`${p}-fragment`,code:g}),entryPoint:"fsMain",targets:os(g,s,as(t))},primitive:{topology:fs(t),cullMode:fs(t).startsWith("triangle")&&t.side!==Li?t.side===Vi?"front":"back":"none",frontFace:c?"cw":"ccw"},multisample:{count:u},depthStencil:{format:"depth32float",depthWriteEnabled:t.depthWrite,depthCompare:t.depthTest?"less-equal":"always"}},this.pipelineCompilationDiagnostics,"forward",`${t.name||"unnamed"} [${t.uuid}] (${i}, ${u}x)`,m.length,g.length)};return this.sharedForwardPipelineCache.set(e,v),this.sharedForwardPipelinePromiseCache.delete(e),v})();return this.sharedForwardPipelinePromiseCache.set(e,f),f}getDepthPassMaterialResource(e,t,r,i,n,a=!1){if(!(this.state.device&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&this.state.skinningBindGroupLayout))throw new Error("Renderer is not initialized.");if("prepass"===t&&null===e.depthVertexShader||"pointShadow"===t&&(null===e.pointShadowVertexShader||null===e.pointShadowFragmentShader))return null;const s=this.getDepthMaterialFastCacheIndex(t,r,i,n,a),o=this.depthMaterialFrameCache.get(e)?.[s];if(o?.extractionVersion===this.extractionVersion)return o.resource;const l=this.depthMaterialFastCache.get(e)?.[s];if(l&&this.fastMaterialResourceMatches(l,e))return this.updateMaterialUniformBuffer(e,l),this.setDepthMaterialFrameCache(e,s,l),l;const c="prepass"===t?this.depthPrepassMaterialCache:i?this.skinnedDirectionalShadowMaterialCache:"instanced-direct"===r?this.directionalShadowMaterialCacheDirect:this.directionalShadowMaterialCache,u=this.getDepthPassMaterialKey(e,t,r,i,n,a),d=c.get(e),h=d?.get(u);if(h&&this.materialResourceMatches(h,e,u))return this.setDepthMaterialFastCache(e,s,h),this.updateMaterialUniformBuffer(e,h),this.setDepthMaterialFrameCache(e,s,h),h;this.destroyMaterialResource(h),d&&d.delete(u);const{bindGroupLayoutEntries:p,bindGroupEntries:f,uniformBuffer:m,textures:g,textureVersions:v,storageBuffers:x}=this.createMaterialBindGroupData(e,`${e.uuid}-${t}-${r}-material`,GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT),w=this.getOrCreateSharedDepthPipeline(u,e,t,r,p,i,n,a),b=this.state.device.createBindGroup({label:`${e.uuid}-${t}-${r}-material-bind-group`,layout:w.bindGroupLayout,entries:f}),y={key:u,materialVersion:e.version,textureVersionHash:e.getTextureVersionHash(),rendererSampleCount:this.sampleCount,instanceAccessMode:r,receiveShadow:!0,useBatching:n,frontFaceCW:a,colorTargetFormatsId:0,pipeline:w.pipeline,graphTextureBindGroupLayout:w.graphTextureBindGroupLayout,bindGroup:b,uniformBuffer:m,uniformBufferSize:m?.size??0,uniformValueHash:e.uniformValuesAutoUpdate?e.getUniformValueHash():0,uniformValuesAutoVersion:e.uniformValuesAutoVersion,textures:g,textureVersions:v,storageBuffers:x,vertexAttributes:this.getMaterialVertexAttributes(e,i),usesSkinning:i};let S=c.get(e);return S||(S=new Map,c.set(e,S)),S.set(u,y),this.setDepthMaterialFastCache(e,s,y),this.setDepthMaterialFrameCache(e,s,y),y}setDepthMaterialFrameCache(e,t,r){let i=this.depthMaterialFrameCache.get(e);i||(i=[],this.depthMaterialFrameCache.set(e,i)),i[t]={extractionVersion:this.extractionVersion,resource:r}}async getDepthPassMaterialResourceAsync(e,t,r,i,n,a=!1){if(!(this.state.device&&this.state.sceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&this.state.skinningBindGroupLayout))throw new Error("Renderer is not initialized.");if("prepass"===t&&null===e.depthVertexShader||"pointShadow"===t&&(null===e.pointShadowVertexShader||null===e.pointShadowFragmentShader))return null;const s=this.getDepthMaterialFastCacheIndex(t,r,i,n,a),o=this.depthMaterialFastCache.get(e)?.[s];if(o&&this.fastMaterialResourceMatches(o,e))return this.updateMaterialUniformBuffer(e,o),o;const l="prepass"===t?this.depthPrepassMaterialCache:i?this.skinnedDirectionalShadowMaterialCache:"instanced-direct"===r?this.directionalShadowMaterialCacheDirect:this.directionalShadowMaterialCache,c=this.getDepthPassMaterialKey(e,t,r,i,n,a),u=l.get(e),d=u?.get(c);if(d&&this.materialResourceMatches(d,e,c))return this.setDepthMaterialFastCache(e,s,d),this.updateMaterialUniformBuffer(e,d),d;this.destroyMaterialResource(d),u&&u.delete(c);const{bindGroupLayoutEntries:h,bindGroupEntries:p,uniformBuffer:f,textures:m,textureVersions:g,storageBuffers:v}=this.createMaterialBindGroupData(e,`${e.uuid}-${t}-${r}-material`,GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT),x=await this.getOrCreateSharedDepthPipelineAsync(c,e,t,r,h,i,n,a),w=this.state.device.createBindGroup({label:`${e.uuid}-${t}-${r}-material-bind-group`,layout:x.bindGroupLayout,entries:p}),b={key:c,materialVersion:e.version,textureVersionHash:e.getTextureVersionHash(),rendererSampleCount:this.sampleCount,instanceAccessMode:r,receiveShadow:!0,useBatching:n,frontFaceCW:a,colorTargetFormatsId:0,pipeline:x.pipeline,graphTextureBindGroupLayout:x.graphTextureBindGroupLayout,bindGroup:w,uniformBuffer:f,uniformBufferSize:f?.size??0,uniformValueHash:e.uniformValuesAutoUpdate?e.getUniformValueHash():0,uniformValuesAutoVersion:e.uniformValuesAutoVersion,textures:m,textureVersions:g,storageBuffers:v,vertexAttributes:this.getMaterialVertexAttributes(e,i),usesSkinning:i};let y=l.get(e);return y||(y=new Map,l.set(e,y)),y.set(c,b),this.setDepthMaterialFastCache(e,s,b),b}getMaterialResource(e,t,r=!0,i,n=!1,a=!1,s=this.sampleCount,o=!1){if(!(this.state.device&&this.state.format&&this.state.sceneBindGroupLayout&&this.state.visibleSceneBindGroupLayout&&this.state.directSceneBindGroupLayout))throw new Error("Renderer is not initialized.");const l=n?r?this.skinnedMaterialCache:this.skinnedMaterialNoReceiveShadowCache:r?"instanced-direct"===t?this.materialCacheDirect:"packed-visible"===t?this.materialCacheVisible:this.materialCache:"instanced-direct"===t?this.materialNoReceiveShadowCacheDirect:"packed-visible"===t?this.materialNoReceiveShadowCacheVisible:this.materialNoReceiveShadowCache,c=i??hs,u=void 0===i||1===i.length&&i[0]===C,d=this.getForwardMaterialFastCacheIndex(t,r,n,a,o),h=u?null:this.getForwardMaterialTargetFastCacheKey(c,d);if(u){const t=this.forwardMaterialFrameCache.get(e)?.[d];if(t?.extractionVersion===this.extractionVersion&&t.resource.rendererSampleCount===s)return t.resource;const r=this.forwardMaterialFastCache.get(e)?.[d];if(r&&this.fastMaterialResourceMatches(r,e,s))return this.updateMaterialUniformBuffer(e,r),this.setForwardMaterialFrameCache(e,d,r),r}else{const t=this.forwardMaterialTargetFastCache.get(e)?.get(h);if(t&&this.fastMaterialResourceMatches(t,e,s))return this.updateMaterialUniformBuffer(e,t),t}const p=this.getForwardMaterialKey(e,t,r,c,n,a,o,s),f=l.get(e),m=f?.get(p);if(m&&this.materialResourceMatches(m,e,p,s))return u?(this.setForwardMaterialFastCache(e,d,m),this.setForwardMaterialFrameCache(e,d,m)):this.setForwardMaterialTargetFastCache(e,h,m),this.updateMaterialUniformBuffer(e,m),m;this.destroyMaterialResource(m),f&&f.delete(p);const{bindGroupLayoutEntries:g,bindGroupEntries:v,uniformBuffer:x,textures:w,textureVersions:b,storageBuffers:y}=this.createMaterialBindGroupData(e,`${e.uuid}-${t}-material`,GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT),S=this.getOrCreateSharedForwardPipeline(p,e,t,g,r,c,n,a,o,s),P=this.state.device.createBindGroup({label:`${e.uuid}-${t}-material-bind-group`,layout:S.bindGroupLayout,entries:v}),M={key:p,materialVersion:e.version,textureVersionHash:e.getTextureVersionHash(),rendererSampleCount:s,instanceAccessMode:t,receiveShadow:r,useBatching:a,frontFaceCW:o,colorTargetFormatsId:this.getColorFormatsId(c),pipeline:S.pipeline,graphTextureBindGroupLayout:S.graphTextureBindGroupLayout,bindGroup:P,uniformBuffer:x,uniformBufferSize:x?.size??0,uniformValueHash:e.uniformValuesAutoUpdate?e.getUniformValueHash():0,uniformValuesAutoVersion:e.uniformValuesAutoVersion,textures:w,textureVersions:b,storageBuffers:y,vertexAttributes:this.getMaterialVertexAttributes(e,n),usesSkinning:n};let B=l.get(e);return B||(B=new Map,l.set(e,B)),B.set(p,M),u?(this.setForwardMaterialFastCache(e,d,M),this.setForwardMaterialFrameCache(e,d,M)):this.setForwardMaterialTargetFastCache(e,h,M),M}async getMaterialResourceAsync(e,t,r=!0,i,n=!1,a=!1,s=this.sampleCount,o=!1){if(!(this.state.device&&this.state.format&&this.state.sceneBindGroupLayout&&this.state.visibleSceneBindGroupLayout&&this.state.directSceneBindGroupLayout))throw new Error("Renderer is not initialized.");const l=n?r?this.skinnedMaterialCache:this.skinnedMaterialNoReceiveShadowCache:r?"instanced-direct"===t?this.materialCacheDirect:"packed-visible"===t?this.materialCacheVisible:this.materialCache:"instanced-direct"===t?this.materialNoReceiveShadowCacheDirect:"packed-visible"===t?this.materialNoReceiveShadowCacheVisible:this.materialNoReceiveShadowCache,c=i??hs,u=void 0===i||1===i.length&&i[0]===C,d=this.getForwardMaterialFastCacheIndex(t,r,n,a,o);if(u){const t=this.forwardMaterialFrameCache.get(e)?.[d];if(t?.extractionVersion===this.extractionVersion&&t.resource.rendererSampleCount===s)return t.resource;const r=this.forwardMaterialFastCache.get(e)?.[d];if(r&&this.fastMaterialResourceMatches(r,e,s))return this.updateMaterialUniformBuffer(e,r),this.setForwardMaterialFrameCache(e,d,r),r}const h=this.getForwardMaterialKey(e,t,r,c,n,a,o,s),p=l.get(e),f=p?.get(h);if(f&&this.materialResourceMatches(f,e,h,s))return u&&(this.setForwardMaterialFastCache(e,d,f),this.setForwardMaterialFrameCache(e,d,f)),this.updateMaterialUniformBuffer(e,f),f;this.destroyMaterialResource(f),p&&p.delete(h);const{bindGroupLayoutEntries:m,bindGroupEntries:g,uniformBuffer:v,textures:x,textureVersions:w,storageBuffers:b}=this.createMaterialBindGroupData(e,`${e.uuid}-${t}-material`,GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT),y=await this.getOrCreateSharedForwardPipelineAsync(h,e,t,m,r,c,n,a,o,s),S=this.state.device.createBindGroup({label:`${e.uuid}-${t}-material-bind-group`,layout:y.bindGroupLayout,entries:g}),P={key:h,materialVersion:e.version,textureVersionHash:e.getTextureVersionHash(),rendererSampleCount:s,instanceAccessMode:t,receiveShadow:r,useBatching:a,frontFaceCW:o,colorTargetFormatsId:this.getColorFormatsId(c),pipeline:y.pipeline,graphTextureBindGroupLayout:y.graphTextureBindGroupLayout,bindGroup:S,uniformBuffer:v,uniformBufferSize:v?.size??0,uniformValueHash:e.uniformValuesAutoUpdate?e.getUniformValueHash():0,uniformValuesAutoVersion:e.uniformValuesAutoVersion,textures:x,textureVersions:w,storageBuffers:b,vertexAttributes:this.getMaterialVertexAttributes(e,n),usesSkinning:n};let M=l.get(e);return M||(M=new Map,l.set(e,M)),M.set(h,P),u&&(this.setForwardMaterialFastCache(e,d,P),this.setForwardMaterialFrameCache(e,d,P)),P}ensureTiledLightingSize(){this.tiledPointLights?.resize(this.state.width,this.state.height)&&(this.state.sharedSceneBindGroup=null,this.state.residentSceneBindGroupVersion+=1,this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches())}updateCameraUniforms(e,t){if(!this.state.device||!this.state.cameraBuffer)return;const r=this.cameraProjectionScratch.copy(e.projectionMatrix);0===this.projectionJitterPixels.x&&0===this.projectionJitterPixels.y||(r.elements[8]-=2*this.projectionJitterPixels.x/this.state.width,r.elements[9]-=2*this.projectionJitterPixels.y/this.state.height);const i=this.cameraViewProjScratch.copy(M).multiply(r).multiply(e.matrixWorldInverse);e.getWorldPosition(L);const n=this.cameraUniformScratch;n.set(i.elements,0),n[16]=L.x,n[17]=L.y,n[18]=L.z,n[19]=1,n[20]=this.state.width,n[21]=this.state.height,n[22]=this.state.pixelRatio,n[23]=this.state.frameTimeSeconds,n.set(e.matrixWorldInverse.elements,24),n.set(G.multiplyMatrices(M,r).elements,40),n[56]=e.near,n[57]=e.far,n[58]=1/Math.max(e.far-e.near,1e-4),n[59]=this.tiledLightingEnabled?1:0;const a=t.fog;null!=a?(n[60]=a.color.r,n[61]=a.color.g,n[62]=a.color.b,n[63]=1,"density"in a?(n[64]=0,n[65]=0,n[66]=a.density,n[67]=1):(n[64]=a.near,n[65]=a.far,n[66]=0,n[67]=0)):(n.fill(0,60,68),n[67]=-1);const s=this.motionVectorProjectionPending?this.motionVectorProjection:e.projectionMatrix,o=this.motionVectorCurrentViewProj.copy(M).multiply(s).multiply(e.matrixWorldInverse);n.set(o.elements,68),n.set((this.motionVectorHistoryValid?this.motionVectorPreviousViewProj:o).elements,84),n[100]=this.motionVectorHistoryValid?1:0,n[101]=this.state.width,n[102]=this.state.height,n[103]=0,this.motionVectorProjectionPending=!1,this.state.device.queue.writeBuffer(this.state.cameraBuffer,0,n,0,104)}updateTemporalVisibilityUniforms(e){if(!this.state.device||!this.state.temporalVisibilityBuffer)return;const t=fi(e,this.temporalVisibilityCurrentViewProj);e.getWorldPosition(this.temporalVisibilityCurrentCameraPosition);const r=this.temporalVisibilityUniformScratch;r.set(t.elements,0),r.set((this.state.temporalHiZHistoryValid?this.temporalVisibilityPreviousViewProj:t).elements,16),r[32]=this.temporalVisibilityCurrentCameraPosition.x,r[33]=this.temporalVisibilityCurrentCameraPosition.y,r[34]=this.temporalVisibilityCurrentCameraPosition.z,r[35]=1;const i=this.state.temporalHiZHistoryValid?this.temporalVisibilityPreviousCameraPosition:this.temporalVisibilityCurrentCameraPosition;r[36]=i.x,r[37]=i.y,r[38]=i.z,r[39]=1,r[40]=this.state.width,r[41]=this.state.height,r[42]=this.state.pixelRatio,r[43]=this.state.frameTimeSeconds,this.state.device.queue.writeBuffer(this.state.temporalVisibilityBuffer,0,r,0,44)}commitTemporalHiZHistory(){this.temporalVisibilityPreviousViewProj.copy(this.temporalVisibilityCurrentViewProj),this.temporalVisibilityPreviousCameraPosition.copy(this.temporalVisibilityCurrentCameraPosition),this.state.temporalHiZHistoryValid=!0,this.motionVectorPreviousViewProj.copy(this.motionVectorCurrentViewProj),this.motionVectorHistoryValid=!0}updateLightUniforms(e){if(!this.state.device||!this.state.lightBuffer)return;let t=17;for(const e of this.staticDrawSets)t=Math.imul(t,31)+2*e.id+Number(e.publicSet.enabled)|0;this.directionalShadowScheduler.prepare(e.lights.directionals,e.camera,this.csmCascadeRanges,this.csmCascadeCount,performance.now(),t);const r=this.lightUniformScratch;this.updateSpotLightMapAtlas(e.lights.spots),r.fill(0),r[0]=e.lights.ambient.x,r[1]=e.lights.ambient.y,r[2]=e.lights.ambient.z,r[3]=e.lights.ambient.w,r[4]=e.lights.directionals.length,r[5]=e.lights.points.length,r[6]=e.lights.spots.length,r[7]=Math.min(this.csmCascadeCount,e.lights.directionals.length);for(let e=0;e<this.csmCascadeCount;e+=1){const t=this.csmCascadeRanges[e],i=3976+4*e;r[i+0]=t.x,r[i+1]=t.y}const i=e.lights.hemisphere;null!=i&&(r[3992]=i.skyColor.x,r[3993]=i.skyColor.y,r[3994]=i.skyColor.z,r[3995]=i.intensity,r[3996]=i.groundColor.x,r[3997]=i.groundColor.y,r[3998]=i.groundColor.z,r[3999]=i.intensity,r[4e3]=i.direction.x,r[4001]=i.direction.y,r[4002]=i.direction.z,r[4003]=1);for(let t=0;t<e.lights.directionals.length;t+=1){const i=e.lights.directionals[t],n=this.directionalShadowCameras[t],a=8+4*t;r[a+0]=i.direction.x,r[a+1]=i.direction.y,r[a+2]=i.direction.z,r[a+3]=1;const s=24+4*t;r[s+0]=i.color.x,r[s+1]=i.color.y,r[s+2]=i.color.z,r[s+3]=i.intensity;const o=40+4*t;r[o+0]=i.shadowBias,r[o+1]=i.castShadow?1:0,r[o+2]=this.state.directionalShadowTextureSize,r[o+3]=i.shadowNormalBias;const l=56+4*t;r[l+0]=i.shadowRadius,r[l+1]=i.shadowIntensity;const c=i.shadowViewProjection??=new Oi;r.set(fi(n,c).elements,72+16*t)}for(let t=0;t<e.lights.points.length;t+=1){const i=e.lights.points[t],n=136+4*t;r[n+0]=i.position.x,r[n+1]=i.position.y,r[n+2]=i.position.z,r[n+3]=i.range;const a=392+4*t;r[a+0]=i.color.x,r[a+1]=i.color.y,r[a+2]=i.color.z,r[a+3]=i.intensity;const s=648+4*t;r[s+0]=i.distance,r[s+1]=i.decay;const o=904+4*t;r[o+0]=i.shadowBias,r[o+1]=i.castShadow?1:0,r[o+2]=this.state.pointShadowTextureSize,r[o+3]=i.shadowNormalBias;const l=1160+4*t;r[l+0]=i.shadowRadius,r[l+1]=i.shadowIntensity,r[l+2]=i.shadowCameraNear,r[l+3]=i.shadowCameraFar}for(let t=0;t<e.lights.spots.length;t+=1){const i=e.lights.spots[t],n=1416+4*t;r[n+0]=i.position.x,r[n+1]=i.position.y,r[n+2]=i.position.z,r[n+3]=i.range;const a=1672+4*t;r[a+0]=i.direction.x,r[a+1]=i.direction.y,r[a+2]=i.direction.z,r[a+3]=Math.cos(i.angle);const s=1928+4*t;r[s+0]=i.color.x,r[s+1]=i.color.y,r[s+2]=i.color.z,r[s+3]=i.intensity;const o=2184+4*t;r[o+0]=i.shadowBias,r[o+1]=i.castShadow?1:0,r[o+2]=this.state.spotShadowTextureSize,r[o+3]=i.shadowNormalBias;const l=2440+4*t;r[l+0]=i.shadowRadius,r[l+1]=i.shadowIntensity;const c=2696+4*t;if(r[c+0]=i.range,r[c+1]=Math.cos(i.angle*(1-i.penumbra)),r[c+2]=i.decay,r[c+3]=null!=i.map?1:0,i.castShadow||null!=i.map){const e=this.spotShadowCameras[t];e.near=i.shadowCameraNear,e.far=i.shadowCameraFar,e.fov=i.shadowCameraFov,e.aspect=1,e.position.copy(i.position),U.copy(i.position).add(i.direction),e.lookAt(U),e.updateMatrixWorld(!0),e.updateProjectionMatrix(),r.set(fi(e,this.shadowViewProjScratch).elements,2952+16*t)}}this.state.device.queue.writeBuffer(this.state.lightBuffer,0,r,0,T)}updateSpotLightMapAtlas(e){const t=this.state.device;if(null==t)return;const r=e.some(e=>null!=e.map),i=r?2048:1,n=r?i/8:1,a=r?e.map(e=>null==e.map?"-":`${e.map.uuid}:${e.map.version}`).join("|"):"fallback";if(null!=this.state.spotLightMapTexture&&i===this.spotLightMapAtlasSize&&a===this.spotLightMapAtlasSignature)return;if(null==this.state.spotLightMapTexture||i!==this.spotLightMapAtlasSize){const e=this.state.spotLightMapTexture,n=t.createTexture({label:r?"spot-light-map-atlas":"spot-light-map-fallback",size:{width:i,height:i},format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.COPY_DST});this.state.spotLightMapTexture=n,this.state.spotLightMapView=n.createView(),this.spotLightMapAtlasSize=i,e?.destroy(),this.state.sharedSceneBindGroup=null,this.state.residentSceneBindGroupVersion+=1,this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches()}if(!r)return t.queue.writeTexture({texture:this.state.spotLightMapTexture},new Uint8Array([255,255,255,255]),{},{width:1,height:1}),void(this.spotLightMapAtlasSignature=a);if(null==this.spotLightMapAtlasLayout||null==this.spotLightMapAtlasPipeline){this.spotLightMapAtlasLayout=t.createBindGroupLayout({label:"spot-light-map-atlas-layout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}}]});const e=t.createShaderModule({label:"spot-light-map-atlas-shader",code:"\n struct VertexOutput { @builtin(position) position: vec4<f32>, @location(0) uv: vec2<f32> };\n @vertex fn vertexMain(@builtin(vertex_index) index: u32) -> VertexOutput {\n let positions = array<vec2<f32>, 3>(vec2(-1.0, -1.0), vec2(3.0, -1.0), vec2(-1.0, 3.0));\n var output: VertexOutput;\n output.position = vec4(positions[index], 0.0, 1.0);\n output.uv = positions[index] * vec2(0.5, -0.5) + vec2(0.5);\n return output;\n }\n @group(0) @binding(0) var mapSampler: sampler;\n @group(0) @binding(1) var mapTexture: texture_2d<f32>;\n @fragment fn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {\n return textureSample(mapTexture, mapSampler, input.uv);\n }\n "});this.spotLightMapAtlasPipeline=t.createRenderPipeline({label:"spot-light-map-atlas-pipeline",layout:t.createPipelineLayout({bindGroupLayouts:[this.spotLightMapAtlasLayout]}),vertex:{module:e,entryPoint:"vertexMain"},fragment:{module:e,entryPoint:"fragmentMain",targets:[{format:"rgba8unorm"}]}})}const s=t.createCommandEncoder({label:"spot-light-map-atlas-upload"}),o=s.beginRenderPass({colorAttachments:[{view:this.state.spotLightMapView,clearValue:{r:1,g:1,b:1,a:1},loadOp:"clear",storeOp:"store"}]});o.setPipeline(this.spotLightMapAtlasPipeline);for(let r=0;r<e.length;r+=1){const i=e[r].map;if(null==i)continue;const a=this.getTextureResource(i),s=r%8*n,l=Math.floor(r/8)*n;o.setViewport(s,l,n,n,0,1),o.setScissorRect(s,l,n,n),o.setBindGroup(0,t.createBindGroup({layout:this.spotLightMapAtlasLayout,entries:[{binding:0,resource:this.state.linearClampSampler},{binding:1,resource:a.view}]})),o.draw(3)}o.end(),t.queue.submit([s.finish()]),this.spotLightMapAtlasSignature=a}writeShadowCameraBuffer(e,t,r,i,n,a=this.state.shadowCameraBuffer,s){if(!this.state.device||!a)return;const o=this.shadowCameraUniformScratch;o.set(e.elements,0),o[16]=t,o[17]=r,o[18]=i,o[19]=n,o[60]=this.state.frameTimeSeconds,o[61]=this.state.width,o[62]=this.state.height,o[63]=0,s&&(o.set(s.matrixWorldInverse.elements,20),o.set(s.projectionMatrix.elements,36),o[52]=s.position.x,o[53]=s.position.y,o[54]=s.position.z,o[55]=1,o[56]=s.near,o[57]=s.far,o[58]=0,o[59]=0),this.state.device.queue.writeBuffer(a,0,o,0,64)}};var xs=[0,0],ws=[0,0,1],bs=[1,1,1,1];async function ys(e,t,r,i,n,a=0,s=0){if(null==e)throw new Error("WebGPU device is not initialized");const o=performance.now();try{return await E(e,t)}finally{r&&i&&n&&r.pipelines.push({kind:i,material:n,durationMs:performance.now()-o,vertexCodeLength:a,fragmentCodeLength:s})}}import{DataTexture as Ss,Matrix4 as Cs,RepeatWrapping as Ps}from"three";var Ms={off:{enabled:!1,temporal:{}},low:{enabled:!0,resolutionScale:.35,directions:2,steps:3,temporal:{historyWeight:.92,depthRejection:.1},denoise:{samples:4,radius:4}},medium:{enabled:!0,resolutionScale:.5,directions:2,steps:4,temporal:{historyWeight:.9,depthRejection:.08},denoise:{samples:8,radius:6}},high:{enabled:!0,resolutionScale:.5,directions:3,steps:5,temporal:{historyWeight:.88,depthRejection:.06},denoise:{samples:12,radius:8}}},Bs=class{options;noiseTexture=function(){const e=new Array(25).fill(0);let t=Math.floor(2.5),r=4;for(let i=1;i<=25;){-1===t&&5===r?(t=0,r=3):(5===r&&(r=0),t<0&&(t=4));const n=5*t+r;0===e[n]?(e[n]=i++,t-=1,r+=1):(t+=1,r-=2)}const i=new Uint8Array(100);for(let t=0;t<e.length;t+=1){const r=2*Math.PI*e[t]/e.length;i[4*t]=Math.round(255*(.5*Math.cos(r)+.5)),i[4*t+1]=Math.round(255*(.5*Math.sin(r)+.5)),i[4*t+2]=127,i[4*t+3]=255}const n=new Ss(i,5,5);return n.wrapS=Ps,n.wrapT=Ps,n.needsUpdate=!0,n}();gtaoPasses=new Map;temporalPasses=new Map;denoisePasses=new Map;compositePasses=new Map;writeIndex=0;frameIndex=0;historyValid=!1;constructor(e={}){this.options=zs(e)}get enabled(){return this.options.enabled}get temporalEnabled(){return!1!==this.options.temporal}setOptions(e){Object.assign(this.options,zs({...this.options,...e,denoise:e.denoise??this.options.denoise,temporal:e.temporal??this.options.temporal,targetPrefix:this.options.targetPrefix})),this.gtaoPasses.clear(),this.temporalPasses.clear(),this.denoisePasses.clear(),this.compositePasses.clear(),this.reset()}applyPreset(e){this.setOptions(Ms[e])}reset(){this.writeIndex=0,this.frameIndex=0,this.historyValid=!1}addPasses(e,t){const r=e.createColorTarget(`${this.options.targetPrefix}Raw`,{format:"r16float",scale:this.options.resolutionScale}),i=`${t.depth}:${t.normal}:${r}`;let n=this.gtaoPasses.get(i);n||(n=new Ds(t.depth,t.normal,r,this.noiseTexture,this.options),this.gtaoPasses.set(i,n));const a=!1!==this.options.temporal&&null!=t.velocity;n.frameIndex=a?this.frameIndex:0,e.addFullscreenPass(n);let s=r;if(a&&!1!==this.options.temporal&&null!=t.velocity){const i=e.createColorTarget(`${this.options.targetPrefix}TemporalA`,{format:"r16float",scale:this.options.resolutionScale}),n=e.createColorTarget(`${this.options.targetPrefix}TemporalB`,{format:"r16float",scale:this.options.resolutionScale}),a=e.createColorTarget(`${this.options.targetPrefix}TemporalDepthA`,{format:"r16float",scale:this.options.resolutionScale}),o=e.createColorTarget(`${this.options.targetPrefix}TemporalDepthB`,{format:"r16float",scale:this.options.resolutionScale}),l=0===this.writeIndex?n:i,c=0===this.writeIndex?i:n,u=0===this.writeIndex?o:a,d=0===this.writeIndex?a:o,h=`${r}:${t.depth}:${t.velocity}:${l}:${u}:${c}:${d}`;let p=this.temporalPasses.get(h);p||(p=new Ts(r,t.depth,t.velocity,l,u,c,d,this.options.temporal,this),this.temporalPasses.set(h,p)),e.addFullscreenPass(p),s=c,this.writeIndex=1-this.writeIndex}if(a&&(this.frameIndex+=1),!1===this.options.denoise)return s;const o=e.createColorTarget(`${this.options.targetPrefix}Denoised`,{format:"r16float",scale:this.options.resolutionScale}),l=`${s}:${t.depth}:${t.normal}:${o}`;let c=this.denoisePasses.get(l);return c||(c=new Is(s,t.depth,t.normal,o,this.options.normalSpace,this.options.denoise),this.denoisePasses.set(l,c)),e.addFullscreenPass(c),o}addCompositePass(e,t,r,i={}){const n=i.output??e.createColorTarget(`${this.options.targetPrefix}Composite`,{format:"rgba16float"}),a=Math.max(0,i.intensity??this.options.intensity),s=Math.max(1e-4,i.power??this.options.power),o=`${t}:${r}:${n}:${a}:${s}`;let l=this.compositePasses.get(o);return l||(l=new Vs(t,r,n,a,s),this.compositePasses.set(o,l)),e.addFullscreenPass(l),n}dispose(){this.noiseTexture.dispose(),this.gtaoPasses.clear(),this.temporalPasses.clear(),this.denoisePasses.clear(),this.compositePasses.clear()}consumeHistoryValid(){const e=this.historyValid;return this.historyValid=!0,e}},Ds=class{constructor(e,t,r,i,n){this.options=n,this.inputs={sceneDepth:e,sceneNormal:t},this.outputs=r,this.textures={gtaoNoise:i},this.fragmentShader=function(e){const t="world"===e.normalSpace?"normalize(viewRotation() * decodedNormal)":"decodedNormal";return`\nconst PI = 3.14159265359;\nconst DIRECTIONS: i32 = ${e.directions};\nconst STEPS: i32 = ${e.steps};\n\nfn projectionMatrix() -> mat4x4<f32> {\n return mat4x4<f32>(fullscreenUniforms[0], fullscreenUniforms[1], fullscreenUniforms[2], fullscreenUniforms[3]);\n}\nfn inverseProjectionMatrix() -> mat4x4<f32> {\n return mat4x4<f32>(fullscreenUniforms[4], fullscreenUniforms[5], fullscreenUniforms[6], fullscreenUniforms[7]);\n}\nfn viewRotation() -> mat3x3<f32> {\n return mat3x3<f32>(fullscreenUniforms[8].xyz, fullscreenUniforms[9].xyz, fullscreenUniforms[10].xyz);\n}\nfn getViewPosition(uv: vec2<f32>, depth: f32) -> vec3<f32> {\n let clip = vec4<f32>(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, depth, 1.0);\n let view = inverseProjectionMatrix() * clip;\n return view.xyz / view.w;\n}\nfn projectViewPosition(position: vec3<f32>) -> vec2<f32> {\n let clip = projectionMatrix() * vec4<f32>(position, 1.0);\n let ndc = clip.xy / clip.w;\n return vec2<f32>(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);\n}\nfn loadDepth(uv: vec2<f32>, size: vec2<i32>) -> f32 {\n let pixel = clamp(vec2<i32>(uv * vec2<f32>(size)), vec2<i32>(0), size - vec2<i32>(1));\n return textureLoad(sceneDepthTexture, pixel, 0);\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let depthSize = vec2<i32>(textureDimensions(sceneDepthTexture));\n let pixel = clamp(vec2<i32>(input.uv * vec2<f32>(depthSize)), vec2<i32>(0), depthSize - vec2<i32>(1));\n let depth = textureLoad(sceneDepthTexture, pixel, 0);\n if (depth >= 1.0) { return vec4<f32>(1.0); }\n\n let viewPosition = getViewPosition(input.uv, depth);\n let decodedNormal = normalize(textureLoad(sceneNormalTexture, pixel, 0).rgb * 2.0 - vec3<f32>(1.0));\n let viewNormal = ${t};\n let viewDirection = normalize(-viewPosition);\n let radius = fullscreenUniforms[12].x;\n let thickness = fullscreenUniforms[12].y;\n let distanceExponent = fullscreenUniforms[12].z;\n let distanceFalloff = fullscreenUniforms[12].w;\n let noiseSize = vec2<f32>(textureDimensions(gtaoNoiseTexture));\n let noiseUv = input.uv * vec2<f32>(depthSize) / noiseSize;\n let noiseTexel = textureSampleLevel(gtaoNoiseTexture, gtaoNoiseSampler, noiseUv, 0.0);\n let baseTangent = normalize(noiseTexel.xy * 2.0 - vec2<f32>(1.0));\n let temporalAngle = f32(i32(fullscreenUniforms[13].x) & 7) * 2.39996323;\n let temporalRotation = mat2x2<f32>(\n vec2<f32>(cos(temporalAngle), sin(temporalAngle)),\n vec2<f32>(-sin(temporalAngle), cos(temporalAngle))\n );\n let rotatedTangent = temporalRotation * baseTangent;\n let tangent = vec3<f32>(rotatedTangent, 0.0);\n let bitangent = vec3<f32>(-tangent.y, tangent.x, 0.0);\n var ao = 0.0;\n\n for (var i = 0; i < DIRECTIONS; i += 1) {\n let angle = (f32(i) / f32(DIRECTIONS)) * PI;\n let sampleDirection = normalize(tangent * cos(angle) + bitangent * sin(angle));\n let sliceBitangent = normalize(cross(sampleDirection, viewDirection));\n let sliceTangent = cross(sliceBitangent, viewDirection);\n let normalInSlice = normalize(viewNormal - sliceBitangent * dot(viewNormal, sliceBitangent));\n let tangentToNormal = cross(normalInSlice, sliceBitangent);\n var cosHorizons = vec2<f32>(dot(viewDirection, tangentToNormal), dot(viewDirection, -tangentToNormal));\n for (var j = 0; j < STEPS; j += 1) {\n let distance = radius * pow(f32(j + 1) / f32(STEPS), distanceExponent);\n for (var side = 0; side < 2; side += 1) {\n let sign = select(-1.0, 1.0, side == 0);\n let sampleUv = projectViewPosition(viewPosition + sampleDirection * distance * sign);\n if (all(sampleUv >= vec2<f32>(0.0)) && all(sampleUv <= vec2<f32>(1.0))) {\n let sampleDepth = loadDepth(sampleUv, depthSize);\n if (sampleDepth < 1.0) {\n let viewDelta = getViewPosition(sampleUv, sampleDepth) - viewPosition;\n if (abs(viewDelta.z) < thickness) {\n let horizon = dot(viewDirection, normalize(viewDelta));\n let update = max(0.0, (horizon - cosHorizons[side]) * mix(1.0, 2.0 / f32(j + 2), distanceFalloff));\n cosHorizons[side] += update;\n }\n }\n }\n }\n }\n let sinHorizons = sqrt(max(vec2<f32>(0.0), vec2<f32>(1.0) - cosHorizons * cosHorizons));\n let nx = dot(normalInSlice, sliceTangent);\n let ny = dot(normalInSlice, viewDirection);\n let nxb = 0.5 * (acos(cosHorizons.y) - acos(cosHorizons.x) + sinHorizons.x * cosHorizons.x - sinHorizons.y * cosHorizons.y);\n let nyb = 0.5 * (2.0 - cosHorizons.x * cosHorizons.x - cosHorizons.y * cosHorizons.y);\n ao += nx * nxb + ny * nyb;\n }\n return vec4<f32>(vec3<f32>(clamp(ao / f32(DIRECTIONS), 0.0, 1.0)), 1.0);\n}\n`}(n)}options;name="GTAOPass";sampler="nearest";uniformBufferSize=224;inputs;outputs;textures;fragmentShader;uniforms=new Float32Array(this.uniformBufferSize/4);webGpuProjection=new Cs;webGpuProjectionInverse=new Cs;frameIndex=0;updateUniforms=e=>(this.webGpuProjection.copy(Rs).multiply(e.camera.projectionMatrix),this.webGpuProjectionInverse.copy(this.webGpuProjection).invert(),this.uniforms.set(this.webGpuProjection.elements,0),this.uniforms.set(this.webGpuProjectionInverse.elements,16),this.uniforms.set(e.camera.matrixWorldInverse.elements,32),this.uniforms.set([this.options.radius,this.options.thickness,this.options.distanceExponent,this.options.distanceFalloff],48),this.uniforms.set([this.frameIndex,0,0,0],52),this.uniforms)},Ts=class{constructor(e,t,r,i,n,a,s,o,l){this.options=o,this.state=l,this.inputs={currentAo:e,sceneDepth:t,velocity:r,historyAo:i,historyDepth:n},this.outputs=[a,s]}options;state;name="GTAOTemporalPass";sampler="linear";uniformBufferSize=80;inputs;outputs;fragmentShader=Gs;uniforms=new Float32Array(this.uniformBufferSize/4);inverseProjection=new Cs;updateUniforms=e=>(this.inverseProjection.copy(Rs).multiply(e.camera.projectionMatrix).invert(),this.uniforms.set(this.inverseProjection.elements,0),this.uniforms.set([this.options.historyWeight,this.options.depthRejection,this.options.neighborhoodClamp?1:0,this.state.consumeHistoryValid()?1:0],16),this.uniforms)},Is=class{constructor(e,t,r,i,n,a){this.options=a,this.inputs={aoInput:e,sceneDepth:t,sceneNormal:r},this.outputs=i,this.fragmentShader=function(e,t){const r="world"===e?"normalize(viewRotation() * decoded)":"decoded";return`\nconst PI = 3.14159265359;\nconst MAGIC_SQUARE: array<u32, 25> = array<u32, 25>(9u, 3u, 22u, 16u, 15u, 2u, 21u, 20u, 14u, 8u, 25u, 19u, 13u, 7u, 1u, 18u, 12u, 6u, 5u, 24u, 11u, 10u, 4u, 23u, 17u);\nconst POISSON_DISK: array<vec3<f32>, 16> = array<vec3<f32>, 16>(\n vec3<f32>(1.0, 0.0, 0.0), vec3<f32>(0.707106781, 0.707106781, 0.066666667), vec3<f32>(0.0, 1.0, 0.133333333), vec3<f32>(-0.707106781, 0.707106781, 0.2),\n vec3<f32>(-1.0, 0.0, 0.266666667), vec3<f32>(-0.707106781, -0.707106781, 0.333333333), vec3<f32>(0.0, -1.0, 0.4), vec3<f32>(0.707106781, -0.707106781, 0.466666667),\n vec3<f32>(1.0, 0.0, 0.533333333), vec3<f32>(0.707106781, 0.707106781, 0.6), vec3<f32>(0.0, 1.0, 0.666666667), vec3<f32>(-0.707106781, 0.707106781, 0.733333333),\n vec3<f32>(-1.0, 0.0, 0.8), vec3<f32>(-0.707106781, -0.707106781, 0.866666667), vec3<f32>(0.0, -1.0, 0.933333333), vec3<f32>(0.707106781, -0.707106781, 1.0));\nfn inverseProjectionMatrix() -> mat4x4<f32> { return mat4x4<f32>(fullscreenUniforms[0], fullscreenUniforms[1], fullscreenUniforms[2], fullscreenUniforms[3]); }\nfn viewRotation() -> mat3x3<f32> { return mat3x3<f32>(fullscreenUniforms[4].xyz, fullscreenUniforms[5].xyz, fullscreenUniforms[6].xyz); }\nfn viewPosition(pixel: vec2<i32>, depth: f32, size: vec2<i32>) -> vec3<f32> {\n let uv = (vec2<f32>(pixel) + vec2<f32>(0.5)) / vec2<f32>(size);\n let view = inverseProjectionMatrix() * vec4<f32>(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, depth, 1.0);\n return view.xyz / view.w;\n}\nfn viewNormal(pixel: vec2<i32>) -> vec3<f32> {\n let decoded = normalize(textureLoad(sceneNormalTexture, pixel, 0).rgb * 2.0 - vec3<f32>(1.0));\n return ${r};\n}\nfn magicSquareAngle(pixel: vec2<i32>) -> f32 { return f32(MAGIC_SQUARE[u32((pixel.y % 5) * 5 + pixel.x % 5)]) * (2.0 * PI / 25.0); }\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let aoSize = vec2<i32>(textureDimensions(aoInputTexture));\n let depthSize = vec2<i32>(textureDimensions(sceneDepthTexture));\n let pixel = clamp(vec2<i32>(input.position.xy), vec2<i32>(0), aoSize - vec2<i32>(1));\n let depthPixel = clamp(vec2<i32>(input.uv * vec2<f32>(depthSize)), vec2<i32>(0), depthSize - vec2<i32>(1));\n let depth = textureLoad(sceneDepthTexture, depthPixel, 0);\n if (depth >= 1.0) { return vec4<f32>(1.0); }\n let center = textureLoad(aoInputTexture, pixel, 0).r;\n let normal = viewNormal(depthPixel);\n let position = viewPosition(depthPixel, depth, depthSize);\n let radius = fullscreenUniforms[8].x;\n let depthPhi = fullscreenUniforms[8].y;\n let normalPhi = fullscreenUniforms[8].z;\n let lumaPhi = fullscreenUniforms[8].w;\n let angle = magicSquareAngle(pixel);\n let rotation = mat2x2<f32>(vec2<f32>(cos(angle), sin(angle)), vec2<f32>(-sin(angle), cos(angle)));\n var denoised = center;\n var totalWeight = 1.0;\n for (var i = 0; i < ${t}; i += 1) {\n let sampleIndex = (i * 16) / ${t};\n let sample = POISSON_DISK[sampleIndex];\n let samplePixel = vec2<i32>(round(vec2<f32>(pixel) + rotation * sample.xy * (1.0 + sample.z * (radius - 1.0))));\n if (all(samplePixel >= vec2<i32>(0)) && all(samplePixel < aoSize)) {\n let sampleUv = (vec2<f32>(samplePixel) + vec2<f32>(0.5)) / vec2<f32>(aoSize);\n let sampleDepthPixel = clamp(vec2<i32>(sampleUv * vec2<f32>(depthSize)), vec2<i32>(0), depthSize - vec2<i32>(1));\n let sampleDepth = textureLoad(sceneDepthTexture, sampleDepthPixel, 0);\n if (sampleDepth < 1.0) {\n let neighbor = textureLoad(aoInputTexture, samplePixel, 0).r;\n let sampleNormal = viewNormal(sampleDepthPixel);\n let samplePosition = viewPosition(sampleDepthPixel, sampleDepth, depthSize);\n let normalSimilarity = pow(max(dot(normal, sampleNormal), 0.0), normalPhi);\n let lumaSimilarity = max(1.0 - abs(neighbor - center) / lumaPhi, 0.0);\n let depthSimilarity = max(1.0 - abs(dot(position - samplePosition, normal)) / depthPhi, 0.0);\n let weight = normalSimilarity * lumaSimilarity * depthSimilarity;\n denoised += neighbor * weight;\n totalWeight += weight;\n }\n }\n }\n return vec4<f32>(vec3<f32>(denoised / totalWeight), 1.0);\n}\n`}(n,a.samples)}options;name="GTAODenoisePass";sampler="nearest";uniformBufferSize=144;inputs;outputs;fragmentShader;uniforms=new Float32Array(this.uniformBufferSize/4);webGpuProjectionInverse=new Cs;updateUniforms=e=>(this.webGpuProjectionInverse.copy(Rs).multiply(e.camera.projectionMatrix).invert(),this.uniforms.set(this.webGpuProjectionInverse.elements,0),this.uniforms.set(e.camera.matrixWorldInverse.elements,16),this.uniforms.set([this.options.radius,this.options.depthPhi,this.options.normalPhi,this.options.lumaPhi],32),this.uniforms)},Vs=class{name="GTAOCompositePass";sampler="nearest";uniformBufferSize=16;inputs;outputs;uniforms;constructor(e,t,r,i,n){this.inputs={sceneColor:e,ambientOcclusion:t},this.outputs=r,this.uniforms=new Float32Array([i,n,0,0])}updateUniforms=()=>this.uniforms;fragmentShader="\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let color = textureLoad(sceneColorTexture, vec2<i32>(input.position.xy), 0);\n let aoSize = vec2<i32>(textureDimensions(ambientOcclusionTexture));\n let aoPixel = clamp(vec2<i32>(input.uv * vec2<f32>(aoSize)), vec2<i32>(0), aoSize - vec2<i32>(1));\n let ao = textureLoad(ambientOcclusionTexture, aoPixel, 0).r;\n let materialFlags = u32(round(color.a));\n let isAlphaTested = (materialFlags & 1u) != 0u;\n let visibility = select(mix(1.0, pow(clamp(ao, 0.0, 1.0), fullscreenUniforms[0].y), fullscreenUniforms[0].x), 1.0, isAlphaTested);\n return vec4<f32>(color.rgb * visibility, color.a);\n}\n"},Rs=(new Cs).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);var Gs="\nstruct GTAOTemporalOutput {\n @location(0) ao: vec4<f32>,\n @location(1) depth: vec4<f32>,\n};\n\nfn inverseProjectionMatrix() -> mat4x4<f32> {\n return mat4x4<f32>(\n fullscreenUniforms[0], fullscreenUniforms[1],\n fullscreenUniforms[2], fullscreenUniforms[3]\n );\n}\n\nfn loadSceneDepth(uv: vec2<f32>) -> f32 {\n let size = vec2<i32>(textureDimensions(sceneDepthTexture));\n let pixel = clamp(\n vec2<i32>(uv * vec2<f32>(size)),\n vec2<i32>(0),\n size - vec2<i32>(1)\n );\n return textureLoad(sceneDepthTexture, pixel, 0);\n}\n\nfn linearViewDepth(uv: vec2<f32>, depth: f32) -> f32 {\n let clip = vec4<f32>(\n uv.x * 2.0 - 1.0,\n 1.0 - uv.y * 2.0,\n depth,\n 1.0\n );\n let view = inverseProjectionMatrix() * clip;\n return abs(view.z / max(abs(view.w), 1e-6));\n}\n\nfn loadVelocity(uv: vec2<f32>) -> vec2<f32> {\n let size = vec2<i32>(textureDimensions(velocityTexture));\n let pixel = clamp(\n vec2<i32>(uv * vec2<f32>(size)),\n vec2<i32>(0),\n size - vec2<i32>(1)\n );\n return textureLoad(velocityTexture, pixel, 0).xy;\n}\n\nfn loadCurrentAo(pixel: vec2<i32>, size: vec2<i32>) -> f32 {\n return textureLoad(\n currentAoTexture,\n clamp(pixel, vec2<i32>(0), size - vec2<i32>(1)),\n 0\n ).r;\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> GTAOTemporalOutput {\n let aoSize = vec2<i32>(textureDimensions(currentAoTexture));\n let pixel = clamp(\n vec2<i32>(input.position.xy),\n vec2<i32>(0),\n aoSize - vec2<i32>(1)\n );\n let currentAo = loadCurrentAo(pixel, aoSize);\n let currentDepthRaw = loadSceneDepth(input.uv);\n let currentDepth = linearViewDepth(input.uv, currentDepthRaw);\n let previousUv = input.uv - loadVelocity(input.uv);\n let inBounds =\n all(previousUv >= vec2<f32>(0.0)) &&\n all(previousUv <= vec2<f32>(1.0));\n let historySize = vec2<i32>(textureDimensions(historyDepthTexture));\n let historyPixel = clamp(\n vec2<i32>(previousUv * vec2<f32>(historySize)),\n vec2<i32>(0),\n historySize - vec2<i32>(1)\n );\n let previousDepth = textureLoad(historyDepthTexture, historyPixel, 0).r;\n let relativeDepthDifference =\n abs(previousDepth - currentDepth) / max(currentDepth, 1e-3);\n let historyAccepted =\n fullscreenUniforms[4].w > 0.5 &&\n inBounds &&\n currentDepthRaw < 1.0 &&\n relativeDepthDifference <= fullscreenUniforms[4].y;\n\n var historyAo = textureSampleLevel(\n historyAoTexture,\n fullscreenSampler,\n clamp(previousUv, vec2<f32>(0.0), vec2<f32>(1.0)),\n 0.0\n ).r;\n if (fullscreenUniforms[4].z > 0.5) {\n let left = loadCurrentAo(pixel + vec2<i32>(-1, 0), aoSize);\n let right = loadCurrentAo(pixel + vec2<i32>(1, 0), aoSize);\n let up = loadCurrentAo(pixel + vec2<i32>(0, -1), aoSize);\n let down = loadCurrentAo(pixel + vec2<i32>(0, 1), aoSize);\n let neighborhoodMin = min(currentAo, min(min(left, right), min(up, down)));\n let neighborhoodMax = max(currentAo, max(max(left, right), max(up, down)));\n historyAo = clamp(historyAo, neighborhoodMin, neighborhoodMax);\n }\n let historyWeight = select(\n 0.0,\n fullscreenUniforms[4].x,\n historyAccepted\n );\n let accumulated = mix(currentAo, historyAo, historyWeight);\n\n var output: GTAOTemporalOutput;\n output.ao = vec4<f32>(accumulated);\n output.depth = vec4<f32>(currentDepth);\n return output;\n}\n";function zs(e){return{intensity:Math.max(0,e.intensity??.6),power:Math.max(1e-4,e.power??1),enabled:e.enabled??!0,radius:Math.max(.001,e.radius??.25),resolutionScale:Us(e.resolutionScale??1,.25,1),thickness:Math.max(.001,e.thickness??1),distanceExponent:Math.max(.01,e.distanceExponent??1),distanceFalloff:Us(e.distanceFalloff??1,0,1),directions:As(e.directions??3,1,8),steps:As(e.steps??6,1,16),normalSpace:e.normalSpace??"world",targetPrefix:e.targetPrefix??"gtao",denoise:!1!==e.denoise&&{radius:Math.max(1,e.denoise?.radius??8),samples:Ls(e.denoise?.samples??16),depthPhi:Math.max(1e-4,e.denoise?.depthPhi??2),normalPhi:Math.max(1e-4,e.denoise?.normalPhi??3),lumaPhi:Math.max(1e-4,e.denoise?.lumaPhi??10)},temporal:!1!==e.temporal&&{historyWeight:Us(e.temporal?.historyWeight??.9,0,.98),depthRejection:Us(e.temporal?.depthRejection??.08,.001,1),neighborhoodClamp:e.temporal?.neighborhoodClamp??!0}}}function Ls(e){return e<=4?4:e<=8?8:e<=12?12:16}function Us(e,t,r){return Math.min(r,Math.max(t,e))}function As(e,t,r){return Math.floor(Us(e,t,r))}import{Matrix4 as Fs}from"three";var ks=class{options;passes=new Map;constructor(e={}){var t,r,i;this.options={resolutionScale:Ws(e.resolutionScale??.5,.25,1),maxDistance:Math.max(.01,e.maxDistance??50),thickness:Math.max(.001,e.thickness??.15),intensity:Math.max(0,e.intensity??.65),distanceAttenuation:e.distanceAttenuation??!0,maxRoughness:Ws(e.maxRoughness??.8,.01,1),steps:(t=e.steps??2048,r=8,i=2048,Math.round(Ws(t,r,i))),pixelStride:Ws(e.pixelStride??1,1,4),normalSpace:e.normalSpace??"world",blur:e.blur??!0,blurRadius:Ws(e.blurRadius??6,1,12),targetPrefix:e.targetPrefix??"ssr"}}addPasses(e,t){const r=e.createColorTarget(`${this.options.targetPrefix}Raw`,{format:"rgba16float",scale:this.options.resolutionScale}),i=`trace:${t.sceneColor}:${t.depth}:${t.normalRoughness}:${r}`;let n=this.passes.get(i);n||(n=new Es(t,r,this.options),this.passes.set(i,n)),e.addFullscreenPass(n);let a=r;if(this.options.blur)for(let r=0;r<2;r++){const i=e.createColorTarget(`${this.options.targetPrefix}Blur${r}`,{format:"rgba16float",scale:this.options.resolutionScale}),n=`blur:${a}:${t.depth}:${t.normalRoughness}:${i}:${r}:${this.options.blurRadius}`;let s=this.passes.get(n);s||(s=new Os(a,t.depth,t.normalRoughness,i,r,this.options.blurRadius),this.passes.set(n,s)),e.addFullscreenPass(s),a=i}const s=e.createColorTarget(`${this.options.targetPrefix}Composite`,{format:"rgba16float"}),o=`composite:${t.sceneColor}:${a}:${s}`;let l=this.passes.get(o);return l||(l=new js(t.sceneColor,a,s,this.options.intensity),this.passes.set(o,l)),e.addFullscreenPass(l),s}},Es=class{constructor(e,t,r){this.options=r,this.inputs={sceneColor:e.sceneColor,sceneDepth:e.depth,normalRoughness:e.normalRoughness},this.outputs=t,this.fragmentShader=function(e){const t="world"===e.normalSpace?"normalize(viewRotation() * encodedNormal)":"encodedNormal",r=e.distanceAttenuation?"pow(clamp(1.0 - hitDistance / maxDistance, 0.0, 1.0), 2.0)":"1.0";return`\nconst STEPS: i32 = ${e.steps};\nfn projectionMatrix() -> mat4x4<f32> { return mat4x4<f32>(fullscreenUniforms[0], fullscreenUniforms[1], fullscreenUniforms[2], fullscreenUniforms[3]); }\nfn inverseProjectionMatrix() -> mat4x4<f32> { return mat4x4<f32>(fullscreenUniforms[4], fullscreenUniforms[5], fullscreenUniforms[6], fullscreenUniforms[7]); }\nfn viewRotation() -> mat3x3<f32> { return mat3x3<f32>(fullscreenUniforms[8].xyz, fullscreenUniforms[9].xyz, fullscreenUniforms[10].xyz); }\nfn viewPosition(uv: vec2<f32>, depth: f32) -> vec3<f32> {\n let p = inverseProjectionMatrix() * vec4<f32>(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, depth, 1.0);\n return p.xyz / p.w;\n}\nfn projectUv(position: vec3<f32>) -> vec2<f32> {\n let p = projectionMatrix() * vec4<f32>(position, 1.0);\n return vec2<f32>(p.x / p.w * 0.5 + 0.5, 0.5 - p.y / p.w * 0.5);\n}\nfn depthAt(uv: vec2<f32>) -> f32 {\n let size = vec2<i32>(textureDimensions(sceneDepthTexture));\n return textureLoad(sceneDepthTexture, clamp(vec2<i32>(uv * vec2<f32>(size)), vec2<i32>(0), size - vec2<i32>(1)), 0);\n}\nfn viewZFromDepth(depth: f32) -> f32 {\n let projection = projectionMatrix();\n return (projection[3].z - depth * projection[3].w)\n / (depth * projection[2].w - projection[2].z);\n}\nfn pointToLineDistanceSquared(point: vec3<f32>, start: vec3<f32>, end: vec3<f32>) -> f32 {\n let line = end - start;\n let perpendicular = cross(point - start, point - end);\n return dot(perpendicular, perpendicular) / max(dot(line, line), 0.0000001);\n}\nfn pointPlaneDistance(point: vec3<f32>, planePoint: vec3<f32>, planeNormal: vec3<f32>) -> f32 {\n return dot(point - planePoint, planeNormal);\n}\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let depth = depthAt(input.uv);\n if (depth >= 1.0) { return vec4<f32>(0.0); }\n let normalSize = vec2<i32>(textureDimensions(normalRoughnessTexture));\n let normalPixel = clamp(vec2<i32>(input.uv * vec2<f32>(normalSize)), vec2<i32>(0), normalSize - vec2<i32>(1));\n let material = textureLoad(normalRoughnessTexture, normalPixel, 0);\n let encodedNormal = normalize(material.rgb * 2.0 - vec3<f32>(1.0));\n let normal = ${t};\n let roughness = clamp(material.a, 0.0, 1.0);\n let maxRoughness = fullscreenUniforms[12].z;\n let reflectivity = 1.0 - roughness;\n if (roughness >= maxRoughness || reflectivity <= 0.0) { return vec4<f32>(0.0); }\n let origin = viewPosition(input.uv, depth);\n let incident = normalize(origin);\n let direction = normalize(reflect(incident, normal));\n let maxDistance = fullscreenUniforms[12].x;\n let thickness = fullscreenUniforms[12].y;\n let pixelStride = fullscreenUniforms[12].w;\n let near = fullscreenUniforms[13].x;\n let resolutionScale = fullscreenUniforms[13].z;\n let perspective = fullscreenUniforms[13].w > 0.5;\n let incidence = max(dot(-incident, normal), 0.001);\n let rayLength = maxDistance / incidence;\n var endpoint = origin + direction * rayLength;\n if (perspective && endpoint.z > -near && direction.z > 0.0) {\n endpoint = origin + direction * ((-near - origin.z) / direction.z);\n }\n let traceSize = vec2<f32>(textureDimensions(sceneDepthTexture)) * resolutionScale;\n let startPixel = input.position.xy;\n let endPixel = projectUv(endpoint) * traceSize;\n let pixelDelta = endPixel - startPixel;\n let totalSteps = max(abs(pixelDelta.x), abs(pixelDelta.y));\n if (totalSteps < 1.0) { return vec4<f32>(0.0); }\n let pixelStep = pixelDelta / totalSteps;\n let reciprocalOriginZ = 1.0 / origin.z;\n for (var i = 1; i <= STEPS; i += 1) {\n let traversedPixels = f32(i) * pixelStride;\n if (traversedPixels >= totalSteps) { break; }\n let samplePixel = startPixel + traversedPixels * pixelStep;\n if (any(samplePixel < vec2<f32>(0.0)) || any(samplePixel >= traceSize)) { break; }\n let sampleUv = samplePixel / traceSize;\n let sampleDepth = depthAt(sampleUv);\n if (sampleDepth < 1.0) {\n let progress = traversedPixels / totalSteps;\n let rayZ = select(\n mix(origin.z, endpoint.z, progress),\n 1.0 / mix(reciprocalOriginZ, 1.0 / endpoint.z, progress),\n perspective,\n );\n let sceneZ = viewZFromDepth(sampleDepth);\n if (rayZ <= sceneZ) {\n let scene = viewPosition(sampleUv, sampleDepth);\n let neighborUv = sampleUv + vec2<f32>(1.0 / traceSize.x, 0.0);\n let neighbor = viewPosition(neighborUv, sampleDepth);\n let minimumThickness = abs(neighbor.x - scene.x) * 3.0;\n let hitThickness = max(minimumThickness, thickness);\n if (pointToLineDistanceSquared(scene, origin, endpoint) <= hitThickness * hitThickness) {\n let hitPixel = clamp(vec2<i32>(sampleUv * vec2<f32>(normalSize)), vec2<i32>(0), normalSize - vec2<i32>(1));\n let hitEncodedNormal = normalize(textureLoad(normalRoughnessTexture, hitPixel, 0).rgb * 2.0 - vec3<f32>(1.0));\n let hitNormal = ${t.replace("encodedNormal","hitEncodedNormal")};\n if (dot(direction, hitNormal) < 0.0) {\n let hitDistance = pointPlaneDistance(scene, origin, normal);\n if (hitDistance > maxDistance) { break; }\n let distanceFade = ${r};\n let fresnel = (dot(incident, direction) + 1.0) * 0.5;\n let reflected = textureSampleLevel(sceneColorTexture, fullscreenSampler, sampleUv, 0.0).rgb;\n return vec4<f32>(reflected, reflectivity * distanceFade * fresnel);\n }\n }\n }\n }\n }\n return vec4<f32>(0.0);\n}`}(r)}options;name="SSRTracePass";sampler="linear";uniformBufferSize=224;inputs;outputs;fragmentShader;uniforms=new Float32Array(56);projection=new Fs;inverseProjection=new Fs;updateUniforms=e=>(this.projection.copy($s).multiply(e.camera.projectionMatrix),this.inverseProjection.copy(this.projection).invert(),this.uniforms.set(this.projection.elements,0),this.uniforms.set(this.inverseProjection.elements,16),this.uniforms.set(e.camera.matrixWorldInverse.elements,32),this.uniforms.set([this.options.maxDistance,this.options.thickness,this.options.maxRoughness,this.options.pixelStride],48),this.uniforms.set([e.camera.near,e.camera.far,this.options.resolutionScale,"isPerspectiveCamera"in e.camera&&e.camera.isPerspectiveCamera?1:0],52),this.uniforms)},Os=class{name;sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms;constructor(e,t,r,i,n,a){this.name=0===n?"SSRBlurHorizontalPass":"SSRBlurVerticalPass",this.inputs={reflection:e,sceneDepth:t,normalRoughness:r},this.outputs=i,this.uniforms=new Float32Array([0===n?1:0,1===n?1:0,a,0])}updateUniforms=()=>this.uniforms;fragmentShader="\nconst MIN_BLUR = 0.02; // Helps reducing artifacts\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let reflectionSize = vec2<i32>(textureDimensions(reflectionTexture));\n let depthSize = vec2<i32>(textureDimensions(sceneDepthTexture));\n let p = clamp(vec2<i32>(input.position.xy), vec2<i32>(0), reflectionSize - vec2<i32>(1));\n let fullP = clamp(vec2<i32>(input.uv * vec2<f32>(depthSize)), vec2<i32>(0), depthSize - vec2<i32>(1));\n let centerDepth = textureLoad(sceneDepthTexture, fullP, 0);\n let centerMaterial = textureLoad(normalRoughnessTexture, fullP, 0);\n let centerNormal = normalize(centerMaterial.rgb * 2.0 - vec3<f32>(1.0));\n let blurAmount = smoothstep(0.03, 0.75, centerMaterial.a);\n // A tiny base radius antialiases trace silhouettes on perfect mirrors. The\n // outer Gaussian tap reaches blurRadius pixels on a fully rough receiver.\n let radiusPixels = mix(0.75, fullscreenUniforms[0].z, max(MIN_BLUR, blurAmount));\n let axis = fullscreenUniforms[0].xy;\n let tapSpacing = radiusPixels / 4.0;\n var premultiplied = vec3<f32>(0.0);\n var alphaSum = 0.0;\n var weightSum = 0.0;\n for (var i = -4; i <= 4; i += 1) {\n let fi = f32(i);\n let sampleUv = clamp(\n input.uv + axis * fi * tapSpacing / vec2<f32>(reflectionSize),\n vec2<f32>(0.0),\n vec2<f32>(1.0),\n );\n let sampleFullP = clamp(vec2<i32>(sampleUv * vec2<f32>(depthSize)), vec2<i32>(0), depthSize - vec2<i32>(1));\n let sampleDepth = textureLoad(sceneDepthTexture, sampleFullP, 0);\n let sampleNormal = normalize(textureLoad(normalRoughnessTexture, sampleFullP, 0).rgb * 2.0 - vec3<f32>(1.0));\n let geometryWeight = select(\n exp(-abs(sampleDepth - centerDepth) * 350.0) * pow(max(dot(centerNormal, sampleNormal), 0.0), 16.0),\n 1.0,\n i == 0,\n );\n let reflected = textureSampleLevel(reflectionTexture, fullscreenSampler, sampleUv, 0.0);\n let gaussianWeight = exp(-0.5 * fi * fi / 4.0);\n let weight = geometryWeight * gaussianWeight;\n premultiplied += reflected.rgb * reflected.a * weight;\n alphaSum += reflected.a * weight;\n weightSum += weight;\n }\n let alpha = alphaSum / max(weightSum, 0.0001);\n let color = select(vec3<f32>(0.0), premultiplied / max(alphaSum, 0.0001), alphaSum > 0.0001);\n return vec4<f32>(color, alpha);\n}"},js=class{name="SSRCompositePass";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms;constructor(e,t,r,i){this.inputs={sceneColor:e,reflection:t},this.outputs=r,this.uniforms=new Float32Array([i,0,0,0])}updateUniforms=()=>this.uniforms;fragmentShader="\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let color = textureLoad(sceneColorTexture, vec2<i32>(input.position.xy), 0);\n let reflection = textureSampleLevel(reflectionTexture, fullscreenSampler, input.uv, 0.0);\n let reflectionWeight = clamp(reflection.a * fullscreenUniforms[0].x, 0.0, 1.0);\n return vec4<f32>(mix(color.rgb, reflection.rgb, reflectionWeight), color.a);\n}"};var $s=(new Fs).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);function Ws(e,t,r){return Math.min(r,Math.max(t,e))}import{Matrix4 as Ns,Vector2 as _s}from"three";var Hs=(new Ns).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),qs=class{renderScale;sampleCount;minCurrentWeight;motionWeightScale;depthThreshold;relativeDepthThreshold;targetPrefix;writeIndex=0;historyValid=!1;frameIndex=0;renderWidth=1;renderHeight=1;outputWidth=1;outputHeight=1;jitter=new _s;unjitteredProjection=new Ns;previousJitterUv=new _s;currentJitterUv=new _s;previousViewProjection=new Ns;resolvePasses=new Map;constructor(e={}){this.renderScale=Ys(e.renderScale??1,.25,1),this.sampleCount=Math.max(1,Math.floor(e.sampleCount??32)),this.minCurrentWeight=Ys(e.minCurrentWeight??.06,0,1),this.motionWeightScale=Math.max(.001,e.motionWeightScale??24),this.depthThreshold=Math.max(0,e.depthThreshold??.001),this.relativeDepthThreshold=Math.max(0,e.relativeDepthThreshold??.002),this.targetPrefix=e.targetPrefix??"taa"}prepareCamera(e,t,r){this.setSize(t,r),e.updateProjectionMatrix(),this.unjitteredProjection.copy(e.projectionMatrix),this.jitter.set(Zs(this.frameIndex%this.sampleCount+1,2)-.5,Zs(this.frameIndex%this.sampleCount+1,3)-.5),this.currentJitterUv.set(this.jitter.x/this.renderWidth,-this.jitter.y/this.renderHeight),e.projectionMatrix.elements[8]-=2*this.jitter.x/this.renderWidth,e.projectionMatrix.elements[9]-=2*this.jitter.y/this.renderHeight,e.projectionMatrixInverse?.copy(e.projectionMatrix).invert()}finishCamera(e){e.projectionMatrix.copy(this.unjitteredProjection),e.projectionMatrixInverse?.copy(e.projectionMatrix).invert()}addPass(e,t,r=e.mainDepth,i){const n=e.createColorTarget(`${this.targetPrefix}HistoryColorA`,{format:"rgba16float",resolution:"presentation"}),a=e.createColorTarget(`${this.targetPrefix}HistoryColorB`,{format:"rgba16float",resolution:"presentation"}),s=e.createColorTarget(`${this.targetPrefix}HistoryDepthA`,{format:"r32float",resolution:"presentation"}),o=e.createColorTarget(`${this.targetPrefix}HistoryDepthB`,{format:"r32float",resolution:"presentation"}),l=0===this.writeIndex?a:n,c=0===this.writeIndex?n:a,u=0===this.writeIndex?o:s,d=0===this.writeIndex?s:o,h=`${t}:${r}:${i??"camera"}:${l}:${u}:${c}:${d}`;let p=this.resolvePasses.get(h);return p||(p=new Ks(t,r,i,l,u,c,d,this),this.resolvePasses.set(h,p)),e.addFullscreenPass(p),this.writeIndex=1-this.writeIndex,this.frameIndex+=1,c}reset(){this.frameIndex=0,this.writeIndex=0,this.historyValid=!1,this.previousViewProjection.identity(),this.currentJitterUv.set(0,0),this.previousJitterUv.set(0,0)}setRenderScale(e){const t=Ys(e,.25,1);t!==this.renderScale&&(this.renderScale=t,this.renderWidth=Math.max(1,Math.floor(this.outputWidth*this.renderScale)),this.renderHeight=Math.max(1,Math.floor(this.outputHeight*this.renderScale)),this.reset())}setSize(e,t){const r=Math.max(1,Math.floor(e)),i=Math.max(1,Math.floor(t));r===this.outputWidth&&i===this.outputHeight||(this.outputWidth=r,this.outputHeight=i,this.renderWidth=Math.max(1,Math.floor(r*this.renderScale)),this.renderHeight=Math.max(1,Math.floor(i*this.renderScale)),this.reset())}updateResolveUniforms(e,t,r,i){t.copy(Hs).multiply(i.camera.projectionMatrix).multiply(i.camera.matrixWorldInverse),r.copy(t).invert(),e.set(r.elements,0),e.set((this.historyValid?this.previousViewProjection:t).elements,16),e.set([i.presentationWidth,i.presentationHeight,this.historyValid?1:0,0],32),e.set([this.currentJitterUv.x,this.currentJitterUv.y,this.previousJitterUv.x,this.previousJitterUv.y],36),e.set([this.minCurrentWeight,this.motionWeightScale,this.depthThreshold,this.relativeDepthThreshold],40),this.previousViewProjection.copy(t),this.previousJitterUv.copy(this.currentJitterUv),this.historyValid=!0}},Ks=class{constructor(e,t,r,i,n,a,s,o){var l;this.state=o,this.inputs=null==r?{currentColor:e,currentDepth:t,historyColor:i,historyDepth:n}:{currentColor:e,currentDepth:t,historyColor:i,historyDepth:n,velocity:r},this.outputs=[a,s],this.fragmentShader=`\nstruct TAAOutput {\n @location(0) color: vec4<f32>,\n @location(1) depth: vec4<f32>,\n};\n\nfn currentViewProjectionInverse() -> mat4x4<f32> {\n return mat4x4<f32>(fullscreenUniforms[0], fullscreenUniforms[1], fullscreenUniforms[2], fullscreenUniforms[3]);\n}\n\nfn previousViewProjection() -> mat4x4<f32> {\n return mat4x4<f32>(fullscreenUniforms[4], fullscreenUniforms[5], fullscreenUniforms[6], fullscreenUniforms[7]);\n}\n\nfn loadCurrentDepth(pixel: vec2<i32>, size: vec2<i32>) -> f32 {\n return textureLoad(currentDepthTexture, clamp(pixel, vec2<i32>(0), size - vec2<i32>(1)), 0);\n}\n\nfn loadCurrentColor(pixel: vec2<i32>, size: vec2<i32>) -> vec3<f32> {\n return textureLoad(currentColorTexture, clamp(pixel, vec2<i32>(0), size - vec2<i32>(1)), 0).rgb;\n}\n\nfn sampleCurrentColorBilinear(uv: vec2<f32>) -> vec3<f32> {\n let size = vec2<i32>(textureDimensions(currentColorTexture));\n let position = uv * vec2<f32>(size) - 0.5;\n let base = vec2<i32>(floor(position));\n let fraction = fract(position);\n let c00 = loadCurrentColor(base, size);\n let c10 = loadCurrentColor(base + vec2<i32>(1, 0), size);\n let c01 = loadCurrentColor(base + vec2<i32>(0, 1), size);\n let c11 = loadCurrentColor(base + vec2<i32>(1, 1), size);\n return mix(mix(c00, c10, fraction.x), mix(c01, c11, fraction.x), fraction.y);\n}\n\nfn sampleHistoryColorBilinear(uv: vec2<f32>) -> vec3<f32> {\n let size = vec2<i32>(textureDimensions(historyColorTexture));\n let position = uv * vec2<f32>(size) - 0.5;\n let base = vec2<i32>(floor(position));\n let fraction = fract(position);\n let maximum = size - vec2<i32>(1);\n let c00 = textureLoad(historyColorTexture, clamp(base, vec2<i32>(0), maximum), 0).rgb;\n let c10 = textureLoad(historyColorTexture, clamp(base + vec2<i32>(1, 0), vec2<i32>(0), maximum), 0).rgb;\n let c01 = textureLoad(historyColorTexture, clamp(base + vec2<i32>(0, 1), vec2<i32>(0), maximum), 0).rgb;\n let c11 = textureLoad(historyColorTexture, clamp(base + vec2<i32>(1, 1), vec2<i32>(0), maximum), 0).rgb;\n return mix(mix(c00, c10, fraction.x), mix(c01, c11, fraction.x), fraction.y);\n}\n\nfn sampleHistoryDepthNearest(uv: vec2<f32>) -> f32 {\n let size = vec2<i32>(textureDimensions(historyDepthTexture));\n let pixel = clamp(vec2<i32>(uv * vec2<f32>(size)), vec2<i32>(0), size - vec2<i32>(1));\n return textureLoad(historyDepthTexture, pixel, 0).r;\n}\n\nfn historyUvFor(currentUv: vec2<f32>, depth: f32) -> vec2<f32> {\n let clip = vec4<f32>(currentUv.x * 2.0 - 1.0, 1.0 - currentUv.y * 2.0, depth, 1.0);\n let worldH = currentViewProjectionInverse() * clip;\n let world = worldH / worldH.w;\n let previousClip = previousViewProjection() * world;\n let previousNdc = previousClip.xy / previousClip.w;\n let previousRasterUv = vec2<f32>(previousNdc.x * 0.5 + 0.5, 0.5 - previousNdc.y * 0.5);\n return previousRasterUv - fullscreenUniforms[9].zw;\n}\n${(l=null!=r)?"\nfn loadPackedVelocity(pixel: vec2<i32>, renderSize: vec2<i32>) -> vec4<f32> {\n let velocitySize = vec2<i32>(textureDimensions(velocityTexture));\n let velocityPixel = clamp(\n vec2<i32>((vec2<f32>(pixel) + 0.5) * vec2<f32>(velocitySize) / vec2<f32>(renderSize)),\n vec2<i32>(0),\n velocitySize - vec2<i32>(1)\n );\n return textureLoad(velocityTexture, velocityPixel, 0);\n}\n":""}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> TAAOutput {\n let renderSize = vec2<i32>(textureDimensions(currentDepthTexture));\n let outputSize = vec2<i32>(fullscreenUniforms[8].xy);\n let centerPixel = clamp(vec2<i32>(input.position.xy), vec2<i32>(0), outputSize - vec2<i32>(1));\n let centerUv = (vec2<f32>(centerPixel) + 0.5) / vec2<f32>(outputSize);\n let currentJitterUv = fullscreenUniforms[9].xy;\n let currentSampleUv = centerUv + currentJitterUv;\n let currentSamplePixel = clamp(vec2<i32>(currentSampleUv * vec2<f32>(renderSize)), vec2<i32>(0), renderSize - vec2<i32>(1));\n let centerDepth = loadCurrentDepth(currentSamplePixel, renderSize);\n\n var closestDepth = centerDepth;\n var closestPixel = currentSamplePixel;\n var mean = vec3<f32>(0.0);\n var meanSquared = vec3<f32>(0.0);\n for (var y = -1; y <= 1; y += 1) {\n for (var x = -1; x <= 1; x += 1) {\n let samplePixel = clamp(currentSamplePixel + vec2<i32>(x, y), vec2<i32>(0), renderSize - vec2<i32>(1));\n let sampleDepth = loadCurrentDepth(samplePixel, renderSize);\n if (sampleDepth < closestDepth) {\n closestDepth = sampleDepth;\n closestPixel = samplePixel;\n }\n let sampleColor = sampleCurrentColorBilinear(currentSampleUv + vec2<f32>(f32(x), f32(y)) / vec2<f32>(renderSize));\n mean += sampleColor;\n meanSquared += sampleColor * sampleColor;\n }\n }\n mean /= 9.0;\n let sigma = sqrt(max(meanSquared / 9.0 - mean * mean, vec3<f32>(0.0)));\n\n let currentColor = sampleCurrentColorBilinear(currentSampleUv);\n let closestUv = (vec2<f32>(closestPixel) + 0.5) / vec2<f32>(renderSize);\n let closestHistoryUv = historyUvFor(closestUv, closestDepth);\n let closestOutputUv = closestUv - currentJitterUv;\n let cameraHistoryUv = centerUv - (closestOutputUv - closestHistoryUv);\n${l?"\n // RG stores unjittered previous-to-current displacement in top-left-origin\n // UV units. History therefore lies opposite the velocity. Sampling at the\n // closest-depth pixel avoids borrowing background motion at silhouettes.\n let packedVelocity = loadPackedVelocity(closestPixel, renderSize);\n let rawVelocity = packedVelocity.xy;\n let finiteVelocity = all(rawVelocity == rawVelocity) && all(abs(rawVelocity) < vec2<f32>(2.0));\n // B=CameraOnly with exactly zero RG is the explicit fallback emitted by a\n // custom-position material that did not provide previous-frame deformation.\n let needsCameraFallback =\n abs(packedVelocity.z - 1.0) < 0.25 &&\n dot(rawVelocity, rawVelocity) < 1e-12;\n let historyUv = select(\n cameraHistoryUv,\n centerUv - rawVelocity,\n finiteVelocity && !needsCameraFallback\n );\n":"\n let historyUv = cameraHistoryUv;\n"}\n let validUv = all(historyUv >= vec2<f32>(0.0)) && all(historyUv <= vec2<f32>(1.0));\n let historyWasValid = fullscreenUniforms[8].z > 0.5;\n\n var validHistory = historyWasValid && validUv && centerDepth < 1.0;\n var historyColor = currentColor;\n if (validHistory) {\n historyColor = sampleHistoryColorBilinear(historyUv);\n let previousDepth = sampleHistoryDepthNearest(historyUv);\n let expectedPreviousDepth = previousViewProjection() *\n (currentViewProjectionInverse() * vec4<f32>(closestUv.x * 2.0 - 1.0, 1.0 - closestUv.y * 2.0, closestDepth, 1.0));\n let expectedDepth = expectedPreviousDepth.z / expectedPreviousDepth.w;\n let depthThreshold = fullscreenUniforms[10].z;\n let relativeDepthThreshold = fullscreenUniforms[10].w;\n validHistory = abs(previousDepth - expectedDepth) < max(depthThreshold, abs(expectedDepth) * relativeDepthThreshold);\n }\n\n let clippedHistory = clamp(historyColor, mean - sigma, mean + sigma);\n let motionPixels = length((centerUv - historyUv) * vec2<f32>(outputSize));\n let minCurrentWeight = fullscreenUniforms[10].x;\n let currentWeight = clamp(minCurrentWeight + motionPixels / fullscreenUniforms[10].y, minCurrentWeight, 1.0);\n let resolved = select(currentColor, mix(clippedHistory, currentColor, currentWeight), validHistory);\n\n var output: TAAOutput;\n output.color = vec4<f32>(resolved, 1.0);\n output.depth = vec4<f32>(centerDepth, 0.0, 0.0, 1.0);\n return output;\n}\n`}state;name="TemporalAAResolvePass";sampler="nearest";uniformBufferSize=176;inputs;outputs;fragmentShader;uniforms=new Float32Array(this.uniformBufferSize/4);currentViewProjection=new Ns;currentViewProjectionInverse=new Ns;updateUniforms=e=>(this.state.updateResolveUniforms(this.uniforms,this.currentViewProjection,this.currentViewProjectionInverse,e),this.uniforms)};function Zs(e,t){let r=1,i=0;for(;e>0;)r/=t,i+=r*(e%t),e=Math.floor(e/t);return i}function Ys(e,t,r){return Math.min(r,Math.max(t,e))}var Xs=class{contrastThreshold;relativeThreshold;subpixelBlending;targetPrefix;passes=new Map;constructor(e={}){this.contrastThreshold=Math.max(0,e.contrastThreshold??.0312),this.relativeThreshold=Math.max(0,e.relativeThreshold??.063),this.subpixelBlending=Qs(e.subpixelBlending??.75,0,1),this.targetPrefix=e.targetPrefix??"fxaa"}addPass(e,t,r={}){const i=r.output??e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float",resolution:"presentation"}),n=`${t}:${i}`;let a=this.passes.get(n);return a||(a=new Js(t,i,this),this.passes.set(n,a)),e.addFullscreenPass(a),i}},Js=class{constructor(e,t,r){this.state=r,this.inputs={source:e},this.outputs=t}state;name="FXAAPass";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([Math.max(0,this.state.contrastThreshold),Math.max(0,this.state.relativeThreshold),Qs(this.state.subpixelBlending,0,1),0]),this.uniforms);fragmentShader="\nconst EDGE_STEP_COUNT: i32 = 6;\nconst EDGE_GUESS: f32 = 8.0;\nconst EDGE_STEPS = array<f32, 6>(1.0, 1.5, 2.0, 2.0, 2.0, 4.0);\n\nstruct LuminanceData {\n m: f32,\n n: f32,\n e: f32,\n s: f32,\n w: f32,\n ne: f32,\n nw: f32,\n se: f32,\n sw: f32,\n highest: f32,\n lowest: f32,\n contrast: f32,\n};\n\nstruct EdgeData {\n isHorizontal: bool,\n pixelStep: f32,\n oppositeLuminance: f32,\n gradient: f32,\n};\n\nfn sampleColor(uv: vec2<f32>) -> vec4<f32> {\n return textureSampleLevel(sourceTexture, fullscreenSampler, uv, 0.0);\n}\n\nfn sampleLuminance(uv: vec2<f32>) -> f32 {\n // The renderer's intermediate buffers are linear. FXAA thresholds are tuned\n // for perceptual luminance, so sqrt is a cheap gamma approximation here.\n return sqrt(max(dot(sampleColor(uv).rgb, vec3<f32>(0.299, 0.587, 0.114)), 0.0));\n}\n\nfn offsetLuminance(uv: vec2<f32>, texel: vec2<f32>, offset: vec2<f32>) -> f32 {\n return sampleLuminance(uv + texel * offset);\n}\n\nfn sampleNeighborhood(uv: vec2<f32>, texel: vec2<f32>) -> LuminanceData {\n var l: LuminanceData;\n l.m = sampleLuminance(uv);\n l.n = offsetLuminance(uv, texel, vec2<f32>(0.0, -1.0));\n l.e = offsetLuminance(uv, texel, vec2<f32>(1.0, 0.0));\n l.s = offsetLuminance(uv, texel, vec2<f32>(0.0, 1.0));\n l.w = offsetLuminance(uv, texel, vec2<f32>(-1.0, 0.0));\n l.ne = offsetLuminance(uv, texel, vec2<f32>(1.0, -1.0));\n l.nw = offsetLuminance(uv, texel, vec2<f32>(-1.0, -1.0));\n l.se = offsetLuminance(uv, texel, vec2<f32>(1.0, 1.0));\n l.sw = offsetLuminance(uv, texel, vec2<f32>(-1.0, 1.0));\n l.highest = max(max(max(max(l.n, l.e), l.s), l.w), l.m);\n l.lowest = min(min(min(min(l.n, l.e), l.s), l.w), l.m);\n l.contrast = l.highest - l.lowest;\n return l;\n}\n\nfn pixelBlendFactor(l: LuminanceData) -> f32 {\n var filterAmount = 2.0 * (l.n + l.e + l.s + l.w);\n filterAmount += l.ne + l.nw + l.se + l.sw;\n filterAmount = abs(filterAmount / 12.0 - l.m);\n filterAmount = clamp(filterAmount / max(l.contrast, 1e-5), 0.0, 1.0);\n let blend = smoothstep(0.0, 1.0, filterAmount);\n return blend * blend * fullscreenUniforms[0].z;\n}\n\nfn determineEdge(texel: vec2<f32>, l: LuminanceData) -> EdgeData {\n let horizontal =\n abs(l.n + l.s - 2.0 * l.m) * 2.0 +\n abs(l.ne + l.se - 2.0 * l.e) +\n abs(l.nw + l.sw - 2.0 * l.w);\n let vertical =\n abs(l.e + l.w - 2.0 * l.m) * 2.0 +\n abs(l.ne + l.nw - 2.0 * l.n) +\n abs(l.se + l.sw - 2.0 * l.s);\n\n var edge: EdgeData;\n edge.isHorizontal = horizontal >= vertical;\n let positiveLuminance = select(l.e, l.n, edge.isHorizontal);\n let negativeLuminance = select(l.w, l.s, edge.isHorizontal);\n let positiveGradient = abs(positiveLuminance - l.m);\n let negativeGradient = abs(negativeLuminance - l.m);\n edge.pixelStep = select(texel.x, texel.y, edge.isHorizontal);\n if (positiveGradient < negativeGradient) {\n edge.pixelStep = -edge.pixelStep;\n edge.oppositeLuminance = negativeLuminance;\n edge.gradient = negativeGradient;\n } else {\n edge.oppositeLuminance = positiveLuminance;\n edge.gradient = positiveGradient;\n }\n return edge;\n}\n\nfn edgeBlendFactor(uv: vec2<f32>, texel: vec2<f32>, l: LuminanceData, edge: EdgeData) -> f32 {\n var edgeUv = uv;\n var edgeStep: vec2<f32>;\n if (edge.isHorizontal) {\n edgeUv.y += edge.pixelStep * 0.5;\n edgeStep = vec2<f32>(texel.x, 0.0);\n } else {\n edgeUv.x += edge.pixelStep * 0.5;\n edgeStep = vec2<f32>(0.0, texel.y);\n }\n\n let edgeLuminance = (l.m + edge.oppositeLuminance) * 0.5;\n let gradientThreshold = edge.gradient * 0.25;\n var positiveUv = edgeUv + edgeStep * EDGE_STEPS[0];\n var positiveDelta = sampleLuminance(positiveUv) - edgeLuminance;\n var positiveAtEnd = abs(positiveDelta) >= gradientThreshold;\n for (var i = 1; i < EDGE_STEP_COUNT; i += 1) {\n if (!positiveAtEnd) {\n positiveUv += edgeStep * EDGE_STEPS[i];\n positiveDelta = sampleLuminance(positiveUv) - edgeLuminance;\n positiveAtEnd = abs(positiveDelta) >= gradientThreshold;\n }\n }\n if (!positiveAtEnd) {\n positiveUv += edgeStep * EDGE_GUESS;\n }\n\n var negativeUv = edgeUv - edgeStep * EDGE_STEPS[0];\n var negativeDelta = sampleLuminance(negativeUv) - edgeLuminance;\n var negativeAtEnd = abs(negativeDelta) >= gradientThreshold;\n for (var i = 1; i < EDGE_STEP_COUNT; i += 1) {\n if (!negativeAtEnd) {\n negativeUv -= edgeStep * EDGE_STEPS[i];\n negativeDelta = sampleLuminance(negativeUv) - edgeLuminance;\n negativeAtEnd = abs(negativeDelta) >= gradientThreshold;\n }\n }\n if (!negativeAtEnd) {\n negativeUv -= edgeStep * EDGE_GUESS;\n }\n\n let positiveDistance = select(positiveUv.y - uv.y, positiveUv.x - uv.x, edge.isHorizontal);\n let negativeDistance = select(uv.y - negativeUv.y, uv.x - negativeUv.x, edge.isHorizontal);\n var shortestDistance = negativeDistance;\n var deltaSign = negativeDelta >= 0.0;\n if (positiveDistance <= negativeDistance) {\n shortestDistance = positiveDistance;\n deltaSign = positiveDelta >= 0.0;\n }\n if (deltaSign == (l.m - edgeLuminance >= 0.0)) {\n return 0.0;\n }\n return 0.5 - shortestDistance / max(positiveDistance + negativeDistance, 1e-5);\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let texel = 1.0 / vec2<f32>(textureDimensions(sourceTexture));\n let luminance = sampleNeighborhood(input.uv, texel);\n let threshold = max(fullscreenUniforms[0].x, fullscreenUniforms[0].y * luminance.highest);\n if (luminance.contrast < threshold) {\n return sampleColor(input.uv);\n }\n\n let edge = determineEdge(texel, luminance);\n let blend = max(pixelBlendFactor(luminance), edgeBlendFactor(input.uv, texel, luminance, edge));\n var sampleUv = input.uv;\n if (edge.isHorizontal) {\n sampleUv.y += edge.pixelStep * blend;\n } else {\n sampleUv.x += edge.pixelStep * blend;\n }\n return sampleColor(sampleUv);\n}\n"};function Qs(e,t,r){return Math.min(r,Math.max(t,e))}import{ClampToEdgeWrapping as eo,DataTexture as to,LinearFilter as ro,NoColorSpace as io,RGFormat as no,UnsignedByteType as ao}from"three";var so={low:{searchSteps:4,diagonalSteps:0},medium:{searchSteps:8,diagonalSteps:0},high:{searchSteps:16,diagonalSteps:8},ultra:{searchSteps:32,diagonalSteps:16}},oo=class{threshold;localContrastAdaptation;edgeDetection;cornerRounding;sharpness;quality;targetPrefix;areaTexture;edgePasses=new Map;weightPasses=new Map;blendPasses=new Map;constructor(e={}){this.threshold=Math.max(0,e.threshold??.08),this.localContrastAdaptation=Math.max(0,e.localContrastAdaptation??.5),this.edgeDetection=e.edgeDetection??"color",this.cornerRounding=bo(e.cornerRounding??.25,0,1),this.sharpness=bo(e.sharpness??0,0,1),this.quality=so[e.quality??"high"],this.targetPrefix=e.targetPrefix??"smaa",this.areaTexture=function(){const e=new to(function(){if(ho)return ho;const e=new Uint8Array(25600),t=[[0,0],[3,0],[0,3],[3,3],[1,0],[4,0],[1,3],[4,3],[0,1],[3,1],[0,4],[3,4],[1,1],[4,1],[1,4],[4,4]],r=[[0,0],[1,0],[0,2],[1,2],[2,0],[3,0],[2,2],[3,2],[0,1],[1,1],[0,3],[1,3],[2,1],[3,1],[2,3],[3,3]];for(let i=0;i<16;i+=1){const[n,a]=t[i];for(let t=0;t<16;t+=1)for(let r=0;r<16;r+=1){po(e,16*n+r,16*a+t,fo(i,r*r,t*t))}const[s,o]=r[i];for(let t=0;t<20;t+=1)for(let r=0;r<20;r+=1){po(e,80+20*s+r,20*o+t,vo(i,r,t))}}return ho=e,e}(),160,80,no,ao);return e.name="SMAA-Area-Lookup",e.colorSpace=io,e.minFilter=ro,e.magFilter=ro,e.wrapS=eo,e.wrapT=eo,e.generateMipmaps=!1,e.needsUpdate=!0,e}()}addPass(e,t,r={}){const i=e.createColorTarget(`${this.targetPrefix}Edges`,{format:"rg8unorm",resolution:"render"}),n=e.createColorTarget(`${this.targetPrefix}Weights`,{format:"rgba8unorm",resolution:"render"}),a=r.output??e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float",resolution:"render"}),s=`${t}:${i}`;let o=this.edgePasses.get(s);o||(o=new lo(t,i,this),this.edgePasses.set(s,o));const l=`${i}:${n}`;let c=this.weightPasses.get(l);c||(c=new co(i,n,this.areaTexture,this),this.weightPasses.set(l,c));const u=`${t}:${n}:${a}`;let d=this.blendPasses.get(u);return d||(d=new uo(t,n,a,this),this.blendPasses.set(u,d)),e.addFullscreenPass(o),e.addFullscreenPass(c),e.addFullscreenPass(d),a}dispose(){this.areaTexture.dispose()}get searchSteps(){return this.quality.searchSteps}get diagonalSteps(){return this.quality.diagonalSteps}},lo=class{constructor(e,t,r){this.state=r,this.inputs={source:e},this.outputs=t}state;name="SMAAEdgeDetectionPass";sampler="nearest";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([Math.max(0,this.state.threshold),Math.max(0,this.state.localContrastAdaptation),"color"===this.state.edgeDetection?1:0,0]),this.uniforms);fragmentShader="\nfn loadColor(pixel: vec2<i32>, size: vec2<i32>) -> vec3<f32> {\n let color = textureLoad(sourceTexture, clamp(pixel, vec2<i32>(0), size - vec2<i32>(1)), 0).rgb;\n // Intermediate buffers are linear. This inexpensive transfer makes the\n // threshold perceptual and keeps black toon strokes from being missed.\n return sqrt(max(color, vec3<f32>(0.0)));\n}\n\nfn colorDelta(a: vec3<f32>, b: vec3<f32>) -> f32 {\n let difference = abs(a - b);\n let colorDelta = max(difference.r, max(difference.g, difference.b));\n let lumaDelta = abs(dot(a - b, vec3<f32>(0.299, 0.587, 0.114)));\n return select(lumaDelta, colorDelta, fullscreenUniforms[0].z > 0.5);\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let size = vec2<i32>(textureDimensions(sourceTexture));\n let pixel = clamp(vec2<i32>(input.position.xy), vec2<i32>(0), size - vec2<i32>(1));\n let center = loadColor(pixel, size);\n let leftColor = loadColor(pixel + vec2<i32>(-1, 0), size);\n let topColor = loadColor(pixel + vec2<i32>(0, -1), size);\n let left = colorDelta(center, leftColor);\n let top = colorDelta(center, topColor);\n let right = colorDelta(center, loadColor(pixel + vec2<i32>(1, 0), size));\n let bottom = colorDelta(center, loadColor(pixel + vec2<i32>(0, 1), size));\n let left2 = colorDelta(leftColor, loadColor(pixel + vec2<i32>(-2, 0), size));\n let top2 = colorDelta(topColor, loadColor(pixel + vec2<i32>(0, -2), size));\n let maximum = max(max(max(left, top), max(right, bottom)), max(left2, top2));\n let threshold = fullscreenUniforms[0].x;\n let adaptation = fullscreenUniforms[0].y * maximum;\n let westEdge = left >= threshold && left >= adaptation;\n let northEdge = top >= threshold && top >= adaptation;\n return vec4<f32>(\n select(0.0, 1.0, westEdge),\n select(0.0, 1.0, northEdge),\n 0.0,\n 0.0\n );\n}\n"},co=class{constructor(e,t,r,i){this.state=i,this.inputs={edges:e},this.outputs=t,this.textures={area:r}}state;name="SMAABlendingWeightPass";sampler="nearest";uniformBufferSize=16;inputs;outputs;textures;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([this.state.searchSteps,this.state.diagonalSteps,bo(this.state.cornerRounding,0,1),0]),this.uniforms);fragmentShader="\nconst MAX_SEARCH_STEPS: i32 = 32;\nconst MAX_DIAGONAL_STEPS: i32 = 16;\n\nfn edgeAt(pixel: vec2<i32>, size: vec2<i32>) -> vec2<f32> {\n if (any(pixel < vec2<i32>(0)) || any(pixel >= size)) {\n return vec2<f32>(0.0);\n }\n return textureLoad(edgesTexture, pixel, 0).rg;\n}\n\nfn areaOrthogonal(distance: vec2<f32>, e1: f32, e2: f32) -> vec2<f32> {\n let pattern = vec2<f32>(round(4.0 * vec2<f32>(e1, e2)));\n let texel = vec2<f32>(16.0) * pattern + sqrt(max(distance, vec2<f32>(0.0)));\n let uv = (texel + vec2<f32>(0.5)) / vec2<f32>(160.0, 80.0);\n return textureSampleLevel(areaTexture, areaSampler, uv, 0.0).rg;\n}\n\nfn areaDiagonal(distance: vec2<f32>, e: vec2<f32>) -> vec2<f32> {\n let pattern = round(e);\n let texel = vec2<f32>(80.0, 0.0) + vec2<f32>(20.0) * pattern + distance;\n let uv = (texel + vec2<f32>(0.5)) / vec2<f32>(160.0, 80.0);\n return textureSampleLevel(areaTexture, areaSampler, uv, 0.0).rg;\n}\n\nfn searchHorizontal(pixel: vec2<i32>, direction: i32, size: vec2<i32>) -> i32 {\n var distance = 0;\n let limit = i32(fullscreenUniforms[0].x);\n for (var step = 1; step <= MAX_SEARCH_STEPS; step += 1) {\n if (step > limit) { break; }\n let candidate = pixel + vec2<i32>(direction * step, 0);\n let edge = edgeAt(candidate, size);\n if (edge.g < 0.5 || (step > 1 && edge.r > 0.5)) { break; }\n distance = step;\n }\n return distance;\n}\n\nfn searchVertical(pixel: vec2<i32>, direction: i32, size: vec2<i32>) -> i32 {\n var distance = 0;\n let limit = i32(fullscreenUniforms[0].x);\n for (var step = 1; step <= MAX_SEARCH_STEPS; step += 1) {\n if (step > limit) { break; }\n let candidate = pixel + vec2<i32>(0, direction * step);\n let edge = edgeAt(candidate, size);\n if (edge.r < 0.5 || (step > 1 && edge.g > 0.5)) { break; }\n distance = step;\n }\n return distance;\n}\n\nfn horizontalCrossing(pixel: vec2<i32>, size: vec2<i32>) -> f32 {\n let near = edgeAt(pixel, size).r;\n let far = edgeAt(pixel + vec2<i32>(0, -1), size).r;\n return (3.0 * near + far) * 0.25;\n}\n\nfn verticalCrossing(pixel: vec2<i32>, size: vec2<i32>) -> f32 {\n let near = edgeAt(pixel, size).g;\n let far = edgeAt(pixel + vec2<i32>(-1, 0), size).g;\n return (3.0 * near + far) * 0.25;\n}\n\nfn attenuateHorizontalCorners(\n weights: vec2<f32>,\n leftPixel: vec2<i32>,\n rightPixel: vec2<i32>,\n leftDistance: i32,\n rightDistance: i32,\n size: vec2<i32>\n) -> vec2<f32> {\n let rounding = fullscreenUniforms[0].z;\n var result = weights;\n if (leftDistance <= rightDistance) {\n let extended = max(edgeAt(leftPixel + vec2<i32>(0, 1), size).r, edgeAt(leftPixel + vec2<i32>(0, -2), size).r);\n result *= clamp(vec2<f32>(rounding + 1.0 - extended), vec2<f32>(0.0), vec2<f32>(1.0));\n } else {\n let extended = max(edgeAt(rightPixel + vec2<i32>(1, 1), size).r, edgeAt(rightPixel + vec2<i32>(1, -2), size).r);\n result *= clamp(vec2<f32>(rounding + 1.0 - extended), vec2<f32>(0.0), vec2<f32>(1.0));\n }\n return result;\n}\n\nfn attenuateVerticalCorners(\n weights: vec2<f32>,\n topPixel: vec2<i32>,\n bottomPixel: vec2<i32>,\n topDistance: i32,\n bottomDistance: i32,\n size: vec2<i32>\n) -> vec2<f32> {\n let rounding = fullscreenUniforms[0].z;\n var result = weights;\n if (topDistance <= bottomDistance) {\n let extended = max(edgeAt(topPixel + vec2<i32>(1, 0), size).g, edgeAt(topPixel + vec2<i32>(-2, 0), size).g);\n result *= clamp(vec2<f32>(rounding + 1.0 - extended), vec2<f32>(0.0), vec2<f32>(1.0));\n } else {\n let extended = max(edgeAt(bottomPixel + vec2<i32>(1, 1), size).g, edgeAt(bottomPixel + vec2<i32>(-2, 1), size).g);\n result *= clamp(vec2<f32>(rounding + 1.0 - extended), vec2<f32>(0.0), vec2<f32>(1.0));\n }\n return result;\n}\n\nfn searchDiagonal(\n pixel: vec2<i32>,\n direction: vec2<i32>,\n size: vec2<i32>\n) -> vec2<f32> {\n var distance = 0;\n var lastEdge = vec2<f32>(0.0);\n let limit = i32(fullscreenUniforms[0].y);\n for (var step = 1; step <= MAX_DIAGONAL_STEPS; step += 1) {\n if (step > limit) { break; }\n let candidate = pixel + direction * step;\n let edge = edgeAt(candidate, size);\n let adjacent = edgeAt(candidate + vec2<i32>(1, 0), size).r;\n lastEdge = vec2<f32>(edge.g, adjacent);\n if (edge.g + adjacent < 1.5) { break; }\n distance = step;\n }\n return vec2<f32>(f32(distance), lastEdge.g);\n}\n\nfn diagonalWeights(pixel: vec2<i32>, edges: vec2<f32>, size: vec2<i32>) -> vec2<f32> {\n if (fullscreenUniforms[0].y < 1.0 || edges.g < 0.5) {\n return vec2<f32>(0.0);\n }\n var result = vec2<f32>(0.0);\n var negative = vec2<f32>(0.0);\n if (edges.r > 0.5) {\n negative = searchDiagonal(pixel, vec2<i32>(-1, 1), size);\n }\n let positive = searchDiagonal(pixel, vec2<i32>(1, -1), size);\n if (negative.x + positive.x >= 2.0) {\n let leftPixel = pixel + vec2<i32>(-i32(negative.x), i32(negative.x));\n let rightPixel = pixel + vec2<i32>(i32(positive.x), -i32(positive.x));\n let c1 = edgeAt(leftPixel + vec2<i32>(-1, 0), size).g;\n let c2 = edgeAt(leftPixel, size).r;\n let c3 = edgeAt(rightPixel + vec2<i32>(1, 0), size).g;\n let c4 = edgeAt(rightPixel + vec2<i32>(1, -1), size).r;\n result += areaDiagonal(vec2<f32>(negative.x, positive.x), vec2<f32>(2.0 * c1 + c2, 2.0 * c3 + c4));\n }\n\n let negativeOpposite = searchDiagonal(pixel, vec2<i32>(-1, -1), size);\n var positiveOpposite = vec2<f32>(0.0);\n if (edgeAt(pixel + vec2<i32>(1, 0), size).r > 0.5) {\n positiveOpposite = searchDiagonal(pixel, vec2<i32>(1, 1), size);\n }\n if (negativeOpposite.x + positiveOpposite.x >= 2.0) {\n let leftPixel = pixel + vec2<i32>(-i32(negativeOpposite.x), -i32(negativeOpposite.x));\n let rightPixel = pixel + vec2<i32>(i32(positiveOpposite.x), i32(positiveOpposite.x));\n let c1 = edgeAt(leftPixel + vec2<i32>(-1, 0), size).g;\n let c2 = edgeAt(leftPixel + vec2<i32>(0, -1), size).r;\n let rightEdges = edgeAt(rightPixel + vec2<i32>(1, 0), size);\n result += areaDiagonal(\n vec2<f32>(negativeOpposite.x, positiveOpposite.x),\n vec2<f32>(2.0 * c1 + c2, 2.0 * rightEdges.g + rightEdges.r)\n ).gr;\n }\n return result;\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let size = vec2<i32>(textureDimensions(edgesTexture));\n let pixel = clamp(vec2<i32>(input.position.xy), vec2<i32>(0), size - vec2<i32>(1));\n let edges = edgeAt(pixel, size);\n var weights = vec4<f32>(0.0);\n\n if (edges.g > 0.5) {\n let diagonal = diagonalWeights(pixel, edges, size);\n if (dot(diagonal, vec2<f32>(1.0)) > 1e-5) {\n weights.r = diagonal.x;\n weights.g = diagonal.y;\n } else {\n let leftDistance = searchHorizontal(pixel, -1, size);\n let rightDistance = searchHorizontal(pixel, 1, size);\n let leftPixel = pixel + vec2<i32>(-leftDistance, 0);\n let rightPixel = pixel + vec2<i32>(rightDistance, 0);\n let e1 = horizontalCrossing(leftPixel, size);\n let e2 = horizontalCrossing(rightPixel + vec2<i32>(1, 0), size);\n let area = areaOrthogonal(vec2<f32>(f32(leftDistance), f32(rightDistance)), e1, e2);\n let a = attenuateHorizontalCorners(area, leftPixel, rightPixel, leftDistance, rightDistance, size);\n weights.r = a.x;\n weights.g = a.y;\n }\n }\n\n if (edges.r > 0.5) {\n let topDistance = searchVertical(pixel, -1, size);\n let bottomDistance = searchVertical(pixel, 1, size);\n let topPixel = pixel + vec2<i32>(0, -topDistance);\n let bottomPixel = pixel + vec2<i32>(0, bottomDistance);\n let e1 = verticalCrossing(topPixel, size);\n let e2 = verticalCrossing(bottomPixel + vec2<i32>(0, 1), size);\n let area = areaOrthogonal(vec2<f32>(f32(topDistance), f32(bottomDistance)), e1, e2);\n let a = attenuateVerticalCorners(area, topPixel, bottomPixel, topDistance, bottomDistance, size);\n weights.b = a.x;\n weights.a = a.y;\n }\n\n return weights;\n}\n"},uo=class{constructor(e,t,r,i){this.state=i,this.inputs={source:e,weights:t},this.outputs=r}state;name="SMAANeighborhoodBlendPass";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([bo(this.state.sharpness,0,1),0,0,0]),this.uniforms);fragmentShader="\nfn loadSource(pixel: vec2<i32>, size: vec2<i32>) -> vec4<f32> {\n return textureLoad(sourceTexture, clamp(pixel, vec2<i32>(0), size - vec2<i32>(1)), 0);\n}\n\nfn loadWeights(pixel: vec2<i32>, size: vec2<i32>) -> vec4<f32> {\n return textureLoad(weightsTexture, clamp(pixel, vec2<i32>(0), size - vec2<i32>(1)), 0);\n}\n\nfn sharpen(center: vec3<f32>, pixel: vec2<i32>, size: vec2<i32>, edgeAmount: f32) -> vec3<f32> {\n let strength = fullscreenUniforms[0].x * (1.0 - clamp(edgeAmount * 2.0, 0.0, 1.0));\n if (strength <= 1e-5) { return center; }\n let left = loadSource(pixel + vec2<i32>(-1, 0), size).rgb;\n let right = loadSource(pixel + vec2<i32>(1, 0), size).rgb;\n let top = loadSource(pixel + vec2<i32>(0, -1), size).rgb;\n let bottom = loadSource(pixel + vec2<i32>(0, 1), size).rgb;\n let minimum = min(center, min(min(left, right), min(top, bottom)));\n let maximum = max(center, max(max(left, right), max(top, bottom)));\n let average = (left + right + top + bottom) * 0.25;\n let contrast = max(maximum.r - minimum.r, max(maximum.g - minimum.g, maximum.b - minimum.b));\n let adaptive = strength * (1.0 - clamp(contrast, 0.0, 1.0)) * 0.5;\n return clamp(center + (center - average) * adaptive, minimum, maximum);\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let size = vec2<i32>(textureDimensions(sourceTexture));\n let pixel = clamp(vec2<i32>(input.position.xy), vec2<i32>(0), size - vec2<i32>(1));\n let center = loadSource(pixel, size);\n let current = loadWeights(pixel, size);\n\n // SMAA stores right/bottom weights in adjacent texels and left/top weights\n // in the current texel. Preserve that exact channel convention.\n let right = loadWeights(pixel + vec2<i32>(1, 0), size).a;\n let bottom = loadWeights(pixel + vec2<i32>(0, 1), size).g;\n let left = current.b;\n let top = current.r;\n let edgeAmount = max(max(right, bottom), max(left, top));\n\n var color = center;\n if (edgeAmount > 1e-5) {\n let texel = 1.0 / vec2<f32>(size);\n if (max(right, left) > max(bottom, top)) {\n let total = max(right + left, 1e-5);\n let rightColor = textureSampleLevel(\n sourceTexture,\n fullscreenSampler,\n input.uv + vec2<f32>(right * texel.x, 0.0),\n 0.0\n );\n let leftColor = textureSampleLevel(\n sourceTexture,\n fullscreenSampler,\n input.uv - vec2<f32>(left * texel.x, 0.0),\n 0.0\n );\n color = (rightColor * right + leftColor * left) / total;\n } else {\n let total = max(bottom + top, 1e-5);\n let bottomColor = textureSampleLevel(\n sourceTexture,\n fullscreenSampler,\n input.uv + vec2<f32>(0.0, bottom * texel.y),\n 0.0\n );\n let topColor = textureSampleLevel(\n sourceTexture,\n fullscreenSampler,\n input.uv - vec2<f32>(0.0, top * texel.y),\n 0.0\n );\n color = (bottomColor * bottom + topColor * top) / total;\n }\n }\n\n color = vec4<f32>(sharpen(color.rgb, pixel, size, edgeAmount), color.a);\n return color;\n}\n"};var ho=null;function po(e,t,r,i){const n=2*(160*r+t);e[n]=Math.floor(255*bo(i[0],0,1)),e[n+1]=Math.floor(255*bo(i[1],0,1))}function fo(e,t,r){const i=t+r+1,n=.5,a=-.5,s=()=>mo([0,a],[i/2,0],t),o=()=>mo([i/2,0],[i,a],t);switch(e){case 0:case 5:case 10:case 15:default:return[0,0];case 1:return t<=r?s():[0,0];case 2:return t>=r?o():[0,0];case 3:return go(i,s(),o());case 4:return t<=r?mo([0,n],[i/2,0],t):[0,0];case 6:case 14:case 7:return mo([0,n],[i,a],t);case 8:return t>=r?mo([i/2,0],[i,n],t):[0,0];case 9:case 11:case 13:return mo([0,a],[i,n],t);case 12:return go(i,mo([0,n],[i/2,0],t),mo([i/2,0],[i,n],t))}}function mo(e,t,r){const i=t[0]-e[0],n=t[1]-e[1];if(Math.abs(i)<1e-6)return[0,0];const a=r,s=r+1,o=e[1]+n*(a-e[0])/i,l=e[1]+n*(s-e[0])/i;if(!(a>=e[0]&&a<t[0]||s>e[0]&&s<=t[0]))return[0,0];if(Math.sign(o)===Math.sign(l)||Math.abs(o)<1e-4||Math.abs(l)<1e-4){const e=.5*(o+l);return e<0?[-e,0]:[0,e]}const c=-e[1]*i/n+e[0],u=c-Math.floor(c),d=c>e[0]?o*u*.5:0,h=c<t[0]?l*(1-u)*.5:0;return(Math.abs(d)>Math.abs(h)?d:-h)<0?[Math.abs(d),Math.abs(h)]:[Math.abs(h),Math.abs(d)]}function go(e,t,r){const i=e=>[.5*Math.sqrt(2*e[0]),.5*Math.sqrt(2*e[1])],n=bo(e/32,0,1),a=i(t),s=i(r);return[wo(a[0],t[0],n)+wo(s[0],r[0],n),wo(a[1],t[1],n)+wo(s[1],r[1],n)]}function vo(e,t,r){const i=t+r+1,[n,a]=[[0,0],[1,0],[0,2],[1,2],[2,0],[3,0],[2,2],[3,2],[0,1],[1,1],[0,3],[1,3],[2,1],[3,1],[2,3],[3,3]][e],s=(e,r)=>function(e,t,r){const i=30;let n=0,a=0;if(e[0]===t[0]&&e[1]===t[1])return[0,1];const s=.5*(e[0]+t[0]),o=.5*(e[1]+t[1]),l=t[1]-e[1],c=e[0]-t[0],u=(e,t)=>l*(e-s)+c*(t-o)>0;for(let e=0;e<i;e+=1)for(let t=0;t<i;t+=1){const s=t/(i-1),o=e/(i-1);u(1+r+s,r+o)&&(n+=1),u(1+r+s,1+r+o)&&(a+=1)}const d=i*i;return[1-n/d,a/d]}(n>0?[e[0],e[1]]:e,a>0?[r[0],r[1]]:r,t),o=(e,t)=>s([1,e],[1+i,t+i]);switch(e){case 0:return xo(o(1,1),o(0,0));case 1:return xo(s([1,0],[i,i]),o(0,0));case 2:return xo(s([0,0],[1+i,i]),o(0,0));case 3:return o(0,0);case 4:return xo(s([1,1],[i,i]),s([1,1],[1+i,i]));case 5:return xo(s([1,1],[i,i]),o(0,0));case 6:return s([1,1],[1+i,i]);case 7:return xo(s([1,1],[1+i,i]),o(0,0));case 8:return xo(s([0,0],[1+i,1+i]),s([1,0],[1+i,1+i]));case 9:return s([1,0],[1+i,1+i]);case 10:return xo(s([0,0],[1+i,1+i]),o(0,0));case 11:return xo(s([1,0],[1+i,1+i]),o(0,0));case 12:return s([1,1],[1+i,1+i]);case 13:return xo(s([1,1],[1+i,1+i]),s([1,0],[1+i,1+i]));case 14:return xo(s([1,1],[1+i,1+i]),s([1,1],[1+i,i]));case 15:return xo(s([1,1],[1+i,1+i]),o(0,0));default:return[0,0]}}function xo(e,t){return[.5*(e[0]+t[0]),.5*(e[1]+t[1])]}function wo(e,t,r){return e+(t-e)*r}function bo(e,t,r){return Math.min(r,Math.max(t,e))}var yo=class{strength;threshold;knee;radius;levels;targetPrefix;passes=new Map;constructor(e={}){var t,r,i;this.strength=Math.max(0,e.strength??.9),this.threshold=Math.max(0,e.threshold??1),this.knee=Math.max(1e-4,e.knee??.1),this.radius=Mo(e.radius??.2,0,1),this.levels=(t=e.levels??5,r=1,i=5,Math.floor(Mo(t,r,i))),this.targetPrefix=e.targetPrefix??"bloom"}addPass(e,t,r={}){const i=[];let n=t;for(let t=0;t<this.levels;t+=1){const r=1/2**(t+1),a=e.createColorTarget(`${this.targetPrefix}Horizontal${t}`,{format:"rgba16float",scale:r}),s=e.createColorTarget(`${this.targetPrefix}Vertical${t}`,{format:"rgba16float",scale:r}),o=n,l=`h:${t}:${o}:${a}`;let c=this.passes.get(l);c||(c=0===t?new So(o,a,this):new Co(`BloomDownsampleHorizontal${t}`,o,a,!0,t),this.passes.set(l,c)),e.addFullscreenPass(c);const u=`v:${t}:${a}:${s}`;let d=this.passes.get(u);d||(d=new Co(`BloomVertical${t}`,a,s,!1,t),this.passes.set(u,d)),e.addFullscreenPass(d),i.push(s),n=s}const a=r.output??e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"}),s=Object.fromEntries(i.map((e,t)=>[`blur${t}`,e])),o=`composite:${t}:${i.join(":")}:${a}`;let l=this.passes.get(o);return l||(l=new Po(t,s,a,this,this.levels),this.passes.set(o,l)),e.addFullscreenPass(l),a}},So=class{constructor(e,t,r){this.state=r,this.inputs={source:e},this.outputs=t}state;name="BloomThresholdHorizontal";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([this.state.threshold,this.state.knee,0,0]),this.uniforms);fragmentShader="\nfn bright(color: vec3<f32>) -> vec3<f32> {\n let brightness = dot(color, vec3<f32>(0.2126, 0.7152, 0.0722));\n let threshold = fullscreenUniforms[0].x;\n let knee = fullscreenUniforms[0].y;\n let soft = clamp(brightness - threshold + knee, 0.0, 2.0 * knee);\n let contribution = max(brightness - threshold, soft * soft / (4.0 * knee));\n return color * contribution / max(brightness, 0.0001);\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let texel = 1.0 / vec2<f32>(textureDimensions(sourceTexture));\n let center = bright(textureSample(sourceTexture, fullscreenSampler, input.uv).rgb) * 0.227027;\n let a = bright(textureSample(sourceTexture, fullscreenSampler, input.uv + vec2<f32>(1.384615 * texel.x, 0.0)).rgb);\n let b = bright(textureSample(sourceTexture, fullscreenSampler, input.uv - vec2<f32>(1.384615 * texel.x, 0.0)).rgb);\n let c = bright(textureSample(sourceTexture, fullscreenSampler, input.uv + vec2<f32>(3.230769 * texel.x, 0.0)).rgb);\n let d = bright(textureSample(sourceTexture, fullscreenSampler, input.uv - vec2<f32>(3.230769 * texel.x, 0.0)).rgb);\n return vec4<f32>(center + (a + b) * 0.316216 + (c + d) * 0.070270, 1.0);\n}"},Co=class{constructor(e,t,r,i,n){this.name=e,this.inputs={source:t},this.outputs=r;const a=i?"vec2<f32>(texel.x, 0.0)":"vec2<f32>(0.0, texel.y)",s=(1+.35*n).toFixed(2);this.fragmentShader=`\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let texel = 1.0 / vec2<f32>(textureDimensions(sourceTexture));\n let axis = ${a} * ${s};\n var color = textureSample(sourceTexture, fullscreenSampler, input.uv).rgb * 0.227027;\n color += textureSample(sourceTexture, fullscreenSampler, input.uv + axis * 1.384615).rgb * 0.316216;\n color += textureSample(sourceTexture, fullscreenSampler, input.uv - axis * 1.384615).rgb * 0.316216;\n color += textureSample(sourceTexture, fullscreenSampler, input.uv + axis * 3.230769).rgb * 0.070270;\n color += textureSample(sourceTexture, fullscreenSampler, input.uv - axis * 3.230769).rgb * 0.070270;\n return vec4<f32>(color, 1.0);\n}`}name;sampler="linear";inputs;outputs;fragmentShader},Po=class{constructor(e,t,r,i,n){this.state=i,this.inputs={source:e,...t},this.outputs=r;const a=[1,.8,.6,.4,.2],s=Array.from({length:n},(e,t)=>`bloom += textureSample(blur${t}Texture, fullscreenSampler, input.uv).rgb * mix(${a[t].toFixed(1)}, ${(1.2-a[t]).toFixed(1)}, radius);`).join("\n ");this.fragmentShader=`\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let scene = textureSample(sourceTexture, fullscreenSampler, input.uv);\n let radius = fullscreenUniforms[0].y;\n var bloom = vec3<f32>(0.0);\n ${s}\n return vec4<f32>(scene.rgb + bloom * fullscreenUniforms[0].x, scene.a);\n}`}state;name="BloomComposite";sampler="linear";uniformBufferSize=32;inputs;outputs;uniforms=new Float32Array(8);updateUniforms=()=>(this.uniforms.set([this.state.strength,Mo(this.state.radius,0,1),0,0]),this.uniforms);fragmentShader};function Mo(e,t,r){return Math.min(r,Math.max(t,e))}var Bo=[1,1,1],Do=[0,0,0],To=class{options;passes=new Map;targetPrefix;constructor(e={}){this.options=e,this.targetPrefix=e.targetPrefix??"colorGrading"}addPass(e,t){if(!1===this.options.enabled)return t;const r=e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"}),i=`${t}:${r}`;let n=this.passes.get(i);return n||(n=new Io(t,r,this.options),this.passes.set(i,n)),e.addFullscreenPass(n),r}},Io=class{constructor(e,t,r){this.state=r,this.inputs={source:e},this.outputs=t}state;name="ColorGrading";sampler="linear";uniformBufferSize=384;inputs;outputs;uniforms=new Float32Array(this.uniformBufferSize/4);updateUniforms=()=>{const e=[],t=(t,r)=>e.push(...t??r,0),r=e=>{t(e?.saturation,Bo),t(e?.contrast,Bo),t(e?.gamma,Bo),t(e?.gain,Bo),t(e?.offset,Do)};return t(this.state.whiteBalance,Bo),t(this.state.tint,Bo),r(this.state),r(this.state.shadows),r(this.state.midtones),r(this.state.highlights),e.push(this.state.exposure??1,{none:0,linear:1,reinhard:2,cineon:3,aces:4,agx:5,neutral:6}[this.state.toneMapping??"none"],Math.max(0,this.state.vignetteIntensity??0),Math.min(1,Math.max(0,this.state.tintIntensity??0)),this.state.shadowsMax??.09,this.state.highlightsMin??.5,!1===this.state.enabled?0:1,0),this.uniforms.fill(0),this.uniforms.set(e),this.uniforms};fragmentShader="\nfn grade(color: vec3<f32>, s: vec3<f32>, c: vec3<f32>, g: vec3<f32>, gain: vec3<f32>, offset: vec3<f32>) -> vec3<f32> {\n let luma = dot(color, vec3<f32>(0.2126, 0.7152, 0.0722));\n var result = mix(vec3<f32>(luma), color, s);\n result = (result - vec3<f32>(0.18)) * c + vec3<f32>(0.18);\n result = pow(max(result, vec3<f32>(0.0)), vec3<f32>(1.0) / max(g, vec3<f32>(0.0001)));\n return max(result * gain + offset, vec3<f32>(0.0));\n}\nfn aces(x: vec3<f32>) -> vec3<f32> { return clamp((x * (2.51*x + vec3<f32>(0.03))) / (x * (2.43*x + vec3<f32>(0.59)) + vec3<f32>(0.14)), vec3<f32>(0.0), vec3<f32>(1.0)); }\nfn tonemap(x: vec3<f32>, mode: i32) -> vec3<f32> {\n if (mode == 1) { return clamp(x, vec3<f32>(0.0), vec3<f32>(1.0)); }\n if (mode == 2) { return x / (vec3<f32>(1.0) + x); }\n if (mode == 3) { let y=max(vec3<f32>(0.0),x-vec3<f32>(0.004)); return pow((y*(6.2*y+vec3<f32>(0.5)))/(y*(6.2*y+vec3<f32>(1.7))+vec3<f32>(0.06)),vec3<f32>(2.2)); }\n if (mode == 4) { return aces(x); }\n if (mode == 5) { return clamp((x * (x + vec3<f32>(0.0245786)) - vec3<f32>(0.000090537)) / (x * (0.983729*x + vec3<f32>(0.432951)) + vec3<f32>(0.238081)), vec3<f32>(0.0), vec3<f32>(1.0)); }\n if (mode == 6) { return clamp(x / (max(max(x.r,x.g),x.b) + 1.0), vec3<f32>(0.0), vec3<f32>(1.0)); }\n return x;\n}\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let source = textureSample(sourceTexture, fullscreenSampler, input.uv);\n if (fullscreenUniforms[23].z < 0.5) { return source; }\n var color = source.rgb * fullscreenUniforms[0].xyz;\n color = mix(color, color * fullscreenUniforms[1].xyz, fullscreenUniforms[22].w);\n let lum = clamp(dot(color, vec3<f32>(0.2126,0.7152,0.0722)), 0.0, 1.0);\n let shadowLimit = clamp(fullscreenUniforms[23].x, 0.0, 0.98);\n let highlightLimit = clamp(max(fullscreenUniforms[23].y, shadowLimit + 0.02), 0.02, 1.0);\n let sw = 1.0 - smoothstep(shadowLimit, min(1.0, shadowLimit + 0.05), lum);\n let hw = smoothstep(max(0.0, highlightLimit - 0.05), highlightLimit, lum);\n let mw = clamp(1.0-sw-hw, 0.0, 1.0);\n var s=fullscreenUniforms[2].xyz; var c=fullscreenUniforms[3].xyz; var g=fullscreenUniforms[4].xyz; var gn=fullscreenUniforms[5].xyz; var o=fullscreenUniforms[6].xyz;\n s*=mix(vec3<f32>(1),fullscreenUniforms[7].xyz,sw)*mix(vec3<f32>(1),fullscreenUniforms[12].xyz,mw)*mix(vec3<f32>(1),fullscreenUniforms[17].xyz,hw);\n c*=mix(vec3<f32>(1),fullscreenUniforms[8].xyz,sw)*mix(vec3<f32>(1),fullscreenUniforms[13].xyz,mw)*mix(vec3<f32>(1),fullscreenUniforms[18].xyz,hw);\n g*=mix(vec3<f32>(1),fullscreenUniforms[9].xyz,sw)*mix(vec3<f32>(1),fullscreenUniforms[14].xyz,mw)*mix(vec3<f32>(1),fullscreenUniforms[19].xyz,hw);\n gn*=mix(vec3<f32>(1),fullscreenUniforms[10].xyz,sw)*mix(vec3<f32>(1),fullscreenUniforms[15].xyz,mw)*mix(vec3<f32>(1),fullscreenUniforms[20].xyz,hw);\n o+=fullscreenUniforms[11].xyz*sw+fullscreenUniforms[16].xyz*mw+fullscreenUniforms[21].xyz*hw;\n color=grade(color,s,c,g,gn,o);\n color=tonemap(color*fullscreenUniforms[22].x,i32(fullscreenUniforms[22].y));\n let d=distance(input.uv,vec2<f32>(0.5));\n color*=smoothstep(0.8,0.1598,d*(fullscreenUniforms[22].z+0.2));\n return vec4<f32>(color,source.a);\n}"};import{Matrix4 as Vo}from"three";var Ro=class{options;passes=new Map;targetPrefix;constructor(e={}){this.options=e,this.targetPrefix=e.targetPrefix??"depthOfField"}addPass(e,t,r){if(!1===this.options.enabled)return t;const i=e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"}),n=`${t}:${r}:${i}`;let a=this.passes.get(n);return a||(a=new Go(t,r,i,this.options),this.passes.set(n,a)),e.addFullscreenPass(a),i}},Go=class{constructor(e,t,r,i){this.state=i,this.inputs={source:e,sceneDepth:t},this.outputs=r}state;name="DepthOfField";sampler="linear";uniformBufferSize=80;inputs;outputs;uniforms=new Float32Array(20);inverseProjection=new Vo;updateUniforms=e=>(this.inverseProjection.copy(zo).multiply(e.camera.projectionMatrix).invert(),this.uniforms.set(this.inverseProjection.elements,0),this.uniforms.set([this.state.focus??10,this.state.aperture??2e-4,this.state.maxBlur??.01,!1===this.state.enabled?0:1],16),this.uniforms);fragmentShader="\nfn viewDistance(uv:vec2<f32>,depth:f32)->f32 { let clip=vec4<f32>(uv*vec2<f32>(2,-2)+vec2<f32>(-1,1),depth,1); let view=mat4x4<f32>(fullscreenUniforms[0],fullscreenUniforms[1],fullscreenUniforms[2],fullscreenUniforms[3])*clip; return abs(view.z/view.w); }\n@fragment fn fsMain(input:FullscreenVertexOutput)->@location(0) vec4<f32>{\n let center=textureSample(sourceTexture,fullscreenSampler,input.uv); if(fullscreenUniforms[4].w<0.5){return center;}\n let px=vec2<f32>(1)/vec2<f32>(textureDimensions(sourceTexture)); let depth=textureLoad(sceneDepthTexture,vec2<i32>(input.position.xy),0);\n let blur=clamp(abs(viewDistance(input.uv,depth)-fullscreenUniforms[4].x)*fullscreenUniforms[4].y,0,fullscreenUniforms[4].z);\n var color=center.rgb*0.2; color+=textureSample(sourceTexture,fullscreenSampler,input.uv+vec2<f32>( blur,0)*px*400).rgb*0.1; color+=textureSample(sourceTexture,fullscreenSampler,input.uv-vec2<f32>( blur,0)*px*400).rgb*0.1;\n color+=textureSample(sourceTexture,fullscreenSampler,input.uv+vec2<f32>(0, blur)*px*400).rgb*0.1; color+=textureSample(sourceTexture,fullscreenSampler,input.uv-vec2<f32>(0, blur)*px*400).rgb*0.1;\n color+=textureSample(sourceTexture,fullscreenSampler,input.uv+vec2<f32>( blur, blur)*px*280).rgb*0.1; color+=textureSample(sourceTexture,fullscreenSampler,input.uv+vec2<f32>(-blur, blur)*px*280).rgb*0.1; color+=textureSample(sourceTexture,fullscreenSampler,input.uv+vec2<f32>( blur,-blur)*px*280).rgb*0.1; color+=textureSample(sourceTexture,fullscreenSampler,input.uv-vec2<f32>( blur, blur)*px*280).rgb*0.1;\n return vec4<f32>(color,center.a); }"},zo=(new Vo).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);import{Matrix4 as Lo,Vector2 as Uo,Vector3 as Ao}from"three";var Fo=(new Lo).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),ko=(e=>(e[e.Disabled=0]="Disabled",e[e.CameraOnly=1]="CameraOnly",e[e.ObjectAndCamera=2]="ObjectAndCamera",e[e.ForceObjectBlur=3]="ForceObjectBlur",e))(ko||{}),Eo={off:{enabled:!1,sampleCount:0},low:{enabled:!0,sampleCount:4,shutterScale:.65,maxBlurPixels:10,cameraBlurScale:.08,objectBlurScale:.8,depthRejectionStrength:28,velocityThresholdPixels:.75,dilation:!1},medium:{enabled:!0,sampleCount:8,shutterScale:.75,maxBlurPixels:18,cameraBlurScale:.1,objectBlurScale:1,depthRejectionStrength:24,velocityThresholdPixels:.6,dilation:!0},high:{enabled:!0,sampleCount:12,shutterScale:.85,maxBlurPixels:24,cameraBlurScale:.12,objectBlurScale:1.1,depthRejectionStrength:20,velocityThresholdPixels:.45,dilation:!0}},Oo=class{options;targetPrefix;currentViewProjection=new Lo;currentInverseViewProjection=new Lo;currentInverseProjection=new Lo;previousViewProjection=new Lo;pendingViewProjection=new Lo;previousProjection=new Lo;previousCameraWorld=new Lo;previousCameraPosition=new Ao;currentCameraPosition=new Ao;currentJitterUv=new Uo;historyValid=!1;pendingCamera=!1;width=1;height=1;timeSeconds=0;frameDuration=1/60;previousTimeSeconds=Number.NaN;nextOverrideId=1;overrides=[];passes=new Map;constructor(e={}){this.options={enabled:e.enabled??!0,sampleCount:$o(e.sampleCount??8),shutterScale:Wo(e.shutterScale??.75,0,4),maxBlurPixels:Wo(e.maxBlurPixels??18,0,128),cameraBlurScale:Wo(e.cameraBlurScale??.1,0,4),objectBlurScale:Wo(e.objectBlurScale??1,0,8),depthRejectionStrength:Wo(e.depthRejectionStrength??24,0,200),velocityThresholdPixels:Wo(e.velocityThresholdPixels??.6,0,16),dilation:e.dilation??!0,debugVelocity:e.debugVelocity??!1,targetFrameRate:Wo(e.targetFrameRate??60,15,240),maxFrameTime:Wo(e.maxFrameTime??.1,1/240,1),cameraCutDistance:Wo(e.cameraCutDistance??8,0,1e3),cameraCutRotationThreshold:Wo(e.cameraCutRotationThreshold??.75,0,2),projectionCutThreshold:Wo(e.projectionCutThreshold??.25,0,4)},this.targetPrefix=e.targetPrefix??"motionBlur"}applyPreset(e){Object.assign(this.options,Eo[e]),this.options.sampleCount=$o(this.options.sampleCount)}prepareCamera(e,t,r,i){t===this.width&&r===this.height||(this.width=Math.max(1,t),this.height=Math.max(1,r),this.reset());const n=i-this.previousTimeSeconds;Number.isFinite(n)&&n>0&&(this.frameDuration=Math.min(n,this.options.maxFrameTime),n>this.options.maxFrameTime&&this.reset()),this.previousTimeSeconds=i,this.timeSeconds=i,this.pruneOverrides(),e.getWorldPosition(this.currentCameraPosition),this.historyValid&&(this.currentCameraPosition.distanceTo(this.previousCameraPosition)>this.options.cameraCutDistance||function(e,t){let r=0;const i=[0,1,2,4,5,6,8,9,10];for(const n of i)r=Math.max(r,Math.abs(e.elements[n]-t.elements[n]));return r}(e.matrixWorld,this.previousCameraWorld)>this.options.cameraCutRotationThreshold||function(e,t){let r=0;for(let i=0;i<16;i+=1)r=Math.max(r,Math.abs(e.elements[i]-t.elements[i]));return r}(e.projectionMatrix,this.previousProjection)>this.options.projectionCutThreshold)&&this.reset(),this.pendingViewProjection.copy(Fo).multiply(e.projectionMatrix).multiply(e.matrixWorldInverse),this.currentViewProjection.copy(this.pendingViewProjection),this.currentInverseViewProjection.copy(this.currentViewProjection).invert(),this.currentInverseProjection.copy(Fo).multiply(e.projectionMatrix).invert(),this.historyValid||this.previousViewProjection.copy(this.currentViewProjection),this.pendingCamera=!0,this.previousProjection.copy(e.projectionMatrix),this.previousCameraWorld.copy(e.matrixWorld),this.previousCameraPosition.copy(this.currentCameraPosition)}commitCamera(){this.pendingCamera&&(this.previousViewProjection.copy(this.pendingViewProjection),this.historyValid=!0,this.pendingCamera=!1)}setJitterUv(e,t){this.currentJitterUv.set(Number.isFinite(e)?e:0,Number.isFinite(t)?t:0)}reset(){this.historyValid=!1,this.pendingCamera=!1}requiresRendererHistoryReset(){return!this.historyValid}pushOverride(e){const t=this.nextOverrideId++,r=Math.max(0,e.duration);return this.overrides.push({id:t,startTime:this.timeSeconds,endTime:this.timeSeconds+r,options:e}),{id:t,cancel:()=>{const e=this.overrides.findIndex(e=>e.id===t);e>=0&&this.overrides.splice(e,1)}}}addPass(e,t,r,i=e.mainDepth){const n=this.getResolvedSettings();if(!n.enabled||0===n.sampleCount)return t;const a=e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"}),s=$o(n.sampleCount),o=`${t}:${r}:${i}:${a}:${s}`;let l=this.passes.get(o);return l||(l=new jo(t,r,i,a,s,this),this.passes.set(o,l)),l.settings=n,e.addFullscreenPass(l),a}dispose(){this.passes.clear(),this.overrides.length=0}getTemporalMatrices(){return{currentInverseViewProjection:this.currentInverseViewProjection,currentInverseProjection:this.currentInverseProjection,previousViewProjection:this.previousViewProjection}}getFrameDuration(){return this.frameDuration}getJitterUv(){return this.currentJitterUv}pruneOverrides(){for(let e=this.overrides.length-1;e>=0;e-=1)this.overrides[e].endTime<=this.timeSeconds&&this.overrides.splice(e,1)}getResolvedSettings(){const e={...this.options};for(const t of this.overrides){const r=t.options;null!=r.enabled&&(e.enabled||=r.enabled),null!=r.sampleCount&&(e.sampleCount=Math.max(e.sampleCount,$o(r.sampleCount))),null!=r.shutterScale&&(e.shutterScale=Math.max(e.shutterScale,r.shutterScale)),null!=r.maxBlurPixels&&(e.maxBlurPixels=Math.max(e.maxBlurPixels,r.maxBlurPixels)),null!=r.cameraBlurScale&&(e.cameraBlurScale=Math.max(e.cameraBlurScale,r.cameraBlurScale)),null!=r.objectBlurScale&&(e.objectBlurScale=Math.max(e.objectBlurScale,r.objectBlurScale)),null!=r.dilation&&(e.dilation||=r.dilation),null!=r.debugVelocity&&(e.debugVelocity||=r.debugVelocity)}return e}},jo=class{constructor(e,t,r,i,n,a){this.state=a,this.name=`MotionBlurResolve${n}`,this.inputs={source:e,velocity:t,depth:r},this.outputs=i,this.settings=a.options,this.fragmentShader=function(e){return`\nfn currentInverseViewProjection() -> mat4x4<f32> {\n return mat4x4<f32>(\n fullscreenUniforms[0], fullscreenUniforms[1],\n fullscreenUniforms[2], fullscreenUniforms[3]\n );\n}\n\nfn previousViewProjection() -> mat4x4<f32> {\n return mat4x4<f32>(\n fullscreenUniforms[4], fullscreenUniforms[5],\n fullscreenUniforms[6], fullscreenUniforms[7]\n );\n}\n\nfn currentInverseProjection() -> mat4x4<f32> {\n return mat4x4<f32>(\n fullscreenUniforms[8], fullscreenUniforms[9],\n fullscreenUniforms[10], fullscreenUniforms[11]\n );\n}\n\nfn uvToNdc(uv: vec2<f32>, depth: f32) -> vec4<f32> {\n let unjitteredUv = uv - fullscreenUniforms[14].xy;\n return vec4<f32>(\n unjitteredUv.x * 2.0 - 1.0,\n (0.5 - unjitteredUv.y) * 2.0,\n depth,\n 1.0\n );\n}\n\nfn viewDepth(uv: vec2<f32>, depth: f32) -> f32 {\n let view = currentInverseProjection() * uvToNdc(uv, depth);\n return abs(view.z / max(abs(view.w), 1e-6));\n}\n\nfn depthAt(uv: vec2<f32>) -> f32 {\n let dimensions = vec2<i32>(textureDimensions(depthTexture));\n let pixel = clamp(\n vec2<i32>(uv * vec2<f32>(dimensions)),\n vec2<i32>(0),\n dimensions - vec2<i32>(1)\n );\n return textureLoad(depthTexture, pixel, 0);\n}\n\nfn cameraVelocity(uv: vec2<f32>, depth: f32) -> vec2<f32> {\n let worldH = currentInverseViewProjection() * uvToNdc(uv, depth);\n let world = worldH / max(abs(worldH.w), 1e-6);\n let previousClip = previousViewProjection() * world;\n let previousNdc = previousClip.xy / max(abs(previousClip.w), 1e-6);\n let previousUv = previousNdc * vec2<f32>(0.5, -0.5) + vec2<f32>(0.5);\n return (uv - fullscreenUniforms[14].xy) - previousUv;\n}\n\nfn scaledVelocity(uv: vec2<f32>, packed: vec4<f32>, depth: f32) -> vec2<f32> {\n let camera = cameraVelocity(uv, depth);\n let objectRelative = packed.xy - camera;\n let mode = i32(round(packed.z));\n if (mode == 0) { return vec2<f32>(0.0); }\n if (mode == 1) {\n return camera * fullscreenUniforms[12].z;\n }\n let forceScale = select(1.0, 1.35, mode == 3);\n return camera * fullscreenUniforms[12].z +\n objectRelative * fullscreenUniforms[12].w * packed.w * forceScale;\n}\n\nfn chooseDilatedVelocity(\n uv: vec2<f32>,\n centerDepthRaw: f32,\n texel: vec2<f32>\n) -> vec2<f32> {\n let centerPacked = textureSampleLevel(velocityTexture, fullscreenSampler, uv, 0.0);\n var best = scaledVelocity(uv, centerPacked, centerDepthRaw);\n if (fullscreenUniforms[13].z < 0.5) { return best; }\n let centerDepth = viewDepth(uv, centerDepthRaw);\n for (var y = -1; y <= 1; y += 1) {\n for (var x = -1; x <= 1; x += 1) {\n let sampleUv = clamp(uv + vec2<f32>(f32(x), f32(y)) * texel, vec2<f32>(0.0), vec2<f32>(1.0));\n let sampleDepthRaw = depthAt(sampleUv);\n let sampleDepth = viewDepth(sampleUv, sampleDepthRaw);\n let depthSimilarity = abs(sampleDepth - centerDepth) / max(centerDepth, 1e-3);\n if (depthSimilarity < 0.025 || sampleDepth <= centerDepth) {\n let candidatePacked = textureSampleLevel(velocityTexture, fullscreenSampler, sampleUv, 0.0);\n let candidate = scaledVelocity(sampleUv, candidatePacked, sampleDepthRaw);\n if (dot(candidate, candidate) > dot(best, best)) { best = candidate; }\n }\n }\n }\n return best;\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let centerColor = textureSampleLevel(sourceTexture, fullscreenSampler, input.uv, 0.0);\n let dimensions = vec2<f32>(textureDimensions(sourceTexture));\n let texel = 1.0 / dimensions;\n let centerDepthRaw = depthAt(input.uv);\n let centerDepth = viewDepth(input.uv, centerDepthRaw);\n var blurUv = chooseDilatedVelocity(input.uv, centerDepthRaw, texel) * fullscreenUniforms[12].x;\n let velocityPixels = length(blurUv * dimensions);\n\n if (fullscreenUniforms[13].w > 0.5) {\n let debugMagnitude = clamp(\n velocityPixels / max(fullscreenUniforms[12].y, 1.0),\n 0.0,\n 1.0\n );\n // Black means stationary. Moving pixels become brighter; R/G retain the\n // signed horizontal/vertical mapping around 0.5 and B shows magnitude.\n let directionColor = vec3<f32>(\n 0.5 + 0.5 * clamp(blurUv.x * 32.0, -1.0, 1.0),\n 0.5 + 0.5 * clamp(blurUv.y * 32.0, -1.0, 1.0),\n 1.0\n ) * debugMagnitude;\n return vec4<f32>(directionColor, 1.0);\n }\n\n let threshold = fullscreenUniforms[13].y;\n if (velocityPixels <= threshold) { return centerColor; }\n let maxBlurUv = fullscreenUniforms[12].y / max(dimensions.x, dimensions.y);\n let blurLength = length(blurUv);\n if (blurLength > maxBlurUv) { blurUv *= maxBlurUv / blurLength; }\n\n let activeSamples = clamp(\n i32(ceil(velocityPixels / max(threshold, 0.25))),\n 2,\n ${e}\n );\n var accumulated = centerColor;\n var totalWeight = 1.0;\n for (var sampleIndex = 0; sampleIndex < ${e}; sampleIndex += 1) {\n if (sampleIndex >= activeSamples) { continue; }\n let t = (f32(sampleIndex) + 0.5) / f32(activeSamples);\n let sampleUv = clamp(\n input.uv + mix(-0.5, 0.5, t) * blurUv,\n vec2<f32>(0.0),\n vec2<f32>(1.0)\n );\n let sampleDepthRaw = depthAt(sampleUv);\n let sampleDepth = viewDepth(sampleUv, sampleDepthRaw);\n let relativeDifference = abs(sampleDepth - centerDepth) / max(centerDepth, 1e-3);\n let depthWeight = exp(-relativeDifference * fullscreenUniforms[13].x);\n let sampleColor = textureSampleLevel(sourceTexture, fullscreenSampler, sampleUv, 0.0);\n accumulated += sampleColor * depthWeight;\n totalWeight += depthWeight;\n }\n return accumulated / max(totalWeight, 1e-4);\n}\n`}(n)}state;name;sampler="linear";uniformBufferSize=256;inputs;outputs;fragmentShader;settings;uniforms=new Float32Array(64);updateUniforms=()=>{const e=this.state.getTemporalMatrices();this.uniforms.set(e.currentInverseViewProjection.elements,0),this.uniforms.set(e.previousViewProjection.elements,16),this.uniforms.set(e.currentInverseProjection.elements,32);const t=1/this.settings.targetFrameRate/Math.max(this.state.getFrameDuration(),.001);this.uniforms.set([this.settings.shutterScale*t,this.settings.maxBlurPixels,this.settings.cameraBlurScale,this.settings.objectBlurScale,this.settings.depthRejectionStrength,this.settings.velocityThresholdPixels,this.settings.dilation?1:0,this.settings.debugVelocity?1:0],48);const r=this.state.getJitterUv();return this.uniforms[56]=r.x,this.uniforms[57]=r.y,this.uniforms}};function $o(e){return e<=0?0:e<=4?4:e<=8?8:e<=12?12:16}function Wo(e,t,r){return Math.min(r,Math.max(t,e))}var No=class{enabled;visibleEdgeColor;edgeStrength;edgeThickness;edgeSoftness;selectedObjects=new Set;selectedInstances=[];targetPrefix;maskMaterial;skinnedMaskMaterial;instanceMaskMaterials=new Map;passes=new Map;constructor(e={}){this.enabled=e.enabled??!0,this.visibleEdgeColor=[...e.visibleEdgeColor??[1,1,1]],this.edgeStrength=Math.max(0,e.edgeStrength??5),this.edgeThickness=Math.max(0,e.edgeThickness??.6),this.edgeSoftness=Math.max(0,e.edgeSoftness??.6),this.targetPrefix=e.targetPrefix??"outline",this.maskMaterial=_o(!1),this.skinnedMaskMaterial=_o(!0)}setSelectedObjects(e){this.selectedObjects.clear();for(const t of e)this.selectedObjects.add(t)}setSelectedInstances(e){this.selectedInstances.length=0;for(const t of e)Number.isInteger(t.instanceIndex)&&t.instanceIndex>=0&&this.selectedInstances.push(t)}addPass(e,t){if(!this.enabled||0===this.selectedObjects.size&&0===this.selectedInstances.length)return t;const r=e.createColorTarget(`${this.targetPrefix}Mask`,{format:"rgba8unorm"}),i=this.selectedObjects;e.addMaterialPass({name:"OutlineMask",outputs:r,clearColor:[0,0,0,0],loadDepth:!0,objectFilter:e=>null!==e&&function(e,t){for(let r=e;null!==r;r=r.parent)if(t.has(r))return!0;return!1}(e,i),overrideMaterial:(e,t)=>t?this.skinnedMaskMaterial:this.maskMaterial});for(let t=0;t<this.selectedInstances.length;t+=1){const i=this.selectedInstances[t];let n=this.instanceMaskMaterials.get(i.instanceIndex);n||(n=[_o(!1,i.instanceIndex),_o(!0,i.instanceIndex)],this.instanceMaskMaterials.set(i.instanceIndex,n)),e.addMaterialPass({name:`OutlineInstanceMask${t}-${i.instanceIndex}`,outputs:r,loadColor:!0,loadDepth:!0,objectFilter:e=>e===i.object,overrideMaterial:(e,t)=>t?n[1]:n[0]})}const n=e.createColorTarget(`${this.targetPrefix}Edge`,{format:"rgba16float"}),a=e.createColorTarget(`${this.targetPrefix}BlurHorizontal`,{format:"rgba16float"}),s=e.createColorTarget(`${this.targetPrefix}Blurred`,{format:"rgba16float"}),o=e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"});return this.addCachedPass(e,`edge:${r}:${n}`,()=>new Ho(r,n,this)),this.addCachedPass(e,`blur-h:${n}:${a}`,()=>new qo("OutlineBlurHorizontal",n,a,!0,this)),this.addCachedPass(e,`blur-v:${a}:${s}`,()=>new qo("OutlineBlurVertical",a,s,!1,this)),this.addCachedPass(e,`composite:${t}:${s}:${o}`,()=>new Ko(t,s,o,this)),o}addCachedPass(e,t,r){let i=this.passes.get(t);i||(i=r(),this.passes.set(t,i)),e.addFullscreenPass(i)}dispose(){this.maskMaterial.dispose(),this.skinnedMaskMaterial.dispose();for(const e of this.instanceMaskMaterials.values())e[0].dispose(),e[1].dispose();this.instanceMaskMaterials.clear(),this.passes.clear()}};function _o(e,t=-1){return new Sr({vertexShader:`\nstruct VertexInput {\n @location(0) position: vec3<f32>,${e?"\n @location(4) skinIndex: vec4<u32>,\n @location(5) skinWeight: vec4<f32>,":""}\n @builtin(instance_index) instanceIndex: u32,\n};\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @interpolate(flat) @location(0) batchingId: u32,\n};\n@vertex fn vsMain(input: VertexInput) -> VertexOutput {\n return VertexOutput(\n rendererClipPosition(${e?"rendererSkinPosition(input.position, input.skinIndex, input.skinWeight)":"input.position"}, input.instanceIndex),\n rendererBatchingId(input.instanceIndex)\n );\n}`,fragmentShader:"\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @interpolate(flat) @location(0) batchingId: u32,\n};\n@fragment fn fsMain(input: VertexOutput) -> @location(0) vec4<f32> {\n if (materialUniforms.selectedInstance >= 0.0 &&\n input.batchingId != u32(materialUniforms.selectedInstance)) { discard; }\n return vec4(1.0);\n}",uniforms:{selectedInstance:t},depthWrite:!1,depthTest:!1})}var Ho=class{constructor(e,t,r){this.state=r,this.inputs={mask:e},this.outputs=t}state;name="OutlineEdge";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([this.state.edgeThickness,0,0,0]),this.uniforms);fragmentShader="\n@fragment fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let texel = 1.0 / vec2<f32>(textureDimensions(maskTexture));\n let radius = max(fullscreenUniforms[0].x, 0.5);\n let center = textureSample(maskTexture, fullscreenSampler, input.uv).r;\n let diagonalRadius = radius * 0.70710678;\n var around = 0.0;\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv + vec2(texel.x * radius, 0.0)).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv - vec2(texel.x * radius, 0.0)).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv + vec2(0.0, texel.y * radius)).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv - vec2(0.0, texel.y * radius)).r);\n let diagonalOffset = texel * diagonalRadius;\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv + diagonalOffset).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv - diagonalOffset).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv + vec2(diagonalOffset.x, -diagonalOffset.y)).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv + vec2(-diagonalOffset.x, diagonalOffset.y)).r);\n let edge = clamp(around - center, 0.0, 1.0);\n return vec4(edge, edge, edge, 1.0);\n}"},qo=class{constructor(e,t,r,i,n){this.name=e,this.horizontal=i,this.state=n,this.inputs={source:t},this.outputs=r}name;horizontal;state;sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([this.state.edgeSoftness,this.horizontal?1:0,0,0]),this.uniforms);fragmentShader="\n@fragment fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let texel = 1.0 / vec2<f32>(textureDimensions(sourceTexture));\n let spread = max(fullscreenUniforms[0].x, 0.01);\n let axis = mix(vec2<f32>(0.0, texel.y), vec2<f32>(texel.x, 0.0), fullscreenUniforms[0].y) * spread;\n var value = textureSample(sourceTexture, fullscreenSampler, input.uv).r * 0.227027;\n value += textureSample(sourceTexture, fullscreenSampler, input.uv + axis * 1.384615).r * 0.316216;\n value += textureSample(sourceTexture, fullscreenSampler, input.uv - axis * 1.384615).r * 0.316216;\n value += textureSample(sourceTexture, fullscreenSampler, input.uv + axis * 3.230769).r * 0.070270;\n value += textureSample(sourceTexture, fullscreenSampler, input.uv - axis * 3.230769).r * 0.070270;\n return vec4(value, value, value, 1.0);\n}"},Ko=class{constructor(e,t,r,i){this.state=i,this.inputs={source:e,edge:t},this.outputs=r}state;name="OutlineComposite";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([this.state.visibleEdgeColor[0],this.state.visibleEdgeColor[1],this.state.visibleEdgeColor[2],this.state.edgeStrength]),this.uniforms);fragmentShader="\n@fragment fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let scene = textureSample(sourceTexture, fullscreenSampler, input.uv);\n let edge = textureSample(edgeTexture, fullscreenSampler, input.uv).r;\n let color = fullscreenUniforms[0].rgb * fullscreenUniforms[0].a;\n return vec4(scene.rgb + color * edge, scene.a);\n}"};import{AmbientLight as Zo,BackSide as Yo,Bone as Xo,BatchedMesh as Jo,BoxGeometry as Qo,BufferAttribute as el,BufferGeometry as tl,CanvasTexture as rl,Color as il,CompressedArrayTexture as nl,CompressedArrayTexture as al,CompressedCubeTexture as sl,CompressedTexture as ol,CubeTexture as ll,Data3DTexture as cl,DataArrayTexture as ul,DataTexture as dl,DepthTexture as hl,DirectionalLight as pl,DoubleSide as fl,FrontSide as ml,Group as gl,HemisphereLight as vl,InstancedMesh as xl,MathUtils as wl,Matrix4 as bl,Mesh as yl,Object3D as Sl,OrthographicCamera as Cl,PerspectiveCamera as Pl,PlaneGeometry as Ml,PointLight as Bl,RepeatWrapping as Dl,Scene as Tl,Skeleton as Il,SkinnedMesh as Vl,SphereGeometry as Rl,SpotLight as Gl,Texture as zl,Vector2 as Ll,Vector3 as Ul,Vector4 as Al}from"three";export{Zo as AmbientLight,Yo as BackSide,Jo as BatchedMesh,yo as BloomEffect,Xo as Bone,Qo as BoxGeometry,el as BufferAttribute,tl as BufferGeometry,rl as CanvasTexture,il as Color,To as ColorGradingEffect,nl as CompressedArrayTexture,sl as CompressedCubeTexture,ol as CompressedTexture,al as CompressedTextureArray,j as ComputeKernel,ll as CubeTexture,yr as DEFAULT_WGSL_VERTEX_ATTRIBUTES,cl as Data3DTexture,ul as DataArrayTexture,dl as DataTexture,Ro as DepthOfFieldEffect,hl as DepthTexture,pl as DirectionalLight,fl as DoubleSide,Xs as FXAAEffect,rr as FrameGraphBuilder,ml as FrontSide,Bs as GTAOEffect,Ms as GTAO_PRESETS,gl as Group,vl as HemisphereLight,xl as InstancedMesh,Eo as MOTION_BLUR_PRESETS,wl as MathUtils,bl as Matrix4,yl as Mesh,Oo as MotionBlurEffect,ko as MotionBlurMode,Sl as Object3D,Cl as OrthographicCamera,No as OutlineEffect,Pl as PerspectiveCamera,Ml as PlaneGeometry,Bl as PointLight,wn as RenderGraph,Dl as RepeatWrapping,C as SCENE_COLOR_FORMAT,oo as SMAAEffect,ks as SSREffect,Tl as Scene,Il as Skeleton,Vl as SkinnedMesh,Rl as SphereGeometry,Gl as SpotLight,qs as TemporalAAEffect,zl as Texture,fe as VOLUMETRIC_FOG_MATERIAL_WGSL,J as VOLUMETRIC_FOG_PRESETS,Ll as Vector2,Ul as Vector3,Al as Vector4,oe as VolumetricFogEffect,X as VolumetricFogVolumeObject,Sr as WGSLShaderMaterial,In as WebGpuPMREMGenerator,vs as WebGpuRenderer,On as buildParticleLightingShaderHeader,me as configureVolumetricFogMaterial,O as createComputePipelineAsync,E as createRenderPipelineAsync,r as registerPipelineDiagnosticOrigin,h as resolveDetailCulling,c as setObjectDetailCulling,t as setPipelineDiagnosticLoading};
1
+ var e=new WeakMap;function t(t,r,i){const n=e.get(t);n&&(r?(n.loadingStartedAt=performance.now(),n.loadingRequests=[]):n.loading&&(!function(e,t){const r=e.loadingRequests,i=new Map;for(const e of r){const t=e.kind+":"+(e.origin?.key??e.label??"unlabelled"),r=i.get(t);r?r.push(e):i.set(t,[e])}console.groupCollapsed("[Hology shaders] Loading compilation summary: "+t),console.info("New creation requests during this load (previously cached pipelines are excluded)",{elapsedMs:Math.round(performance.now()-e.loadingStartedAt),...l(r),render:l(r.filter(e=>"render"===e.kind)),compute:l(r.filter(e=>"compute"===e.kind)),gpuVfx:l(r.filter(e=>e.origin?.key.startsWith("gpu-vfx:")))}),console.table([...i].map(([e,t])=>({origin:e,...l(t)})).sort((e,t)=>t.uniquePipelineVariants-e.uniquePipelineVariants)),console.info("Slowest creation requests",[...r].sort((e,t)=>t.durationMs-e.durationMs).slice(0,20).map(({signature:e,shaders:t,state:r,...i})=>i));const n=u(r);console.table(n.map(({variants:e,...t})=>t)),console.info("GPU VFX variant report (copy this array)",n);const a=u(r,!1);console.table(a.map(({variants:e,...t})=>t)),console.info("Material variant report (copy this array)",a),console.info("VFX groups attribute each created pipeline to its first requester; cache-hit users are not enumerated. Difference fields compare against the first variant in each group and do not prove why shader source changed."),console.info("Counts use descriptor signatures and shader source fingerprints, not material counts. Async totals overlap; sync timings measure handle creation, not full GPU compilation. GPU VFX attribution excludes CPU-simulated VFX drawn through ordinary mesh pipelines."),console.groupEnd()}(n,i),n.loadingRequests=[]),n.loading=r,n.phase=i)}function r(t,r,i){const n=e.get(t);n&&(n.origins.size>=4096&&!n.origins.has(r)&&n.origins.delete(n.origins.keys().next().value),n.origins.set(r,i))}function i(t,r){const i=e.get(t),n=i?.origins.get(r.label??"");n&&i.descriptorOrigins.set(r,n)}function n(e){let t=2166136261;for(let r=0;r<e.length;r++)t=Math.imul(t^e.charCodeAt(r),16777619);return(t>>>0).toString(16)}function a(e,t){if(null==e||"object"!=typeof e)return e;const r=t.objects.get(e);if(null!=r)return r;if(Array.isArray(e))return e.map(e=>a(e,t));const i={};for(const r of Object.keys(e).sort())"label"!==r&&(i[r]=a(e[r],t));return i}function s(e,t,r=""){if(JSON.stringify(e)===JSON.stringify(t))return[];if(e&&t&&"object"==typeof e&&"object"==typeof t){const i=e,n=t;return[...new Set([...Object.keys(i),...Object.keys(n)])].flatMap(e=>s(i[e],n[e],r?r+"."+e:e))}return[{field:r,previous:e,current:t}]}function o(e){const t=[];for(const r of["vertex","fragment","compute"]){const i=e[r]?.module;i?.shaderHash&&t.push(i.shaderHash+":"+i.codeLength)}return t}function l(e){const t=new Set(e.map(e=>e.kind+":"+e.signature));return{requests:e.length,uniquePipelineVariants:t.size,uniqueShaderSources:new Set(e.flatMap(e=>e.shaders)).size,duplicateRequests:e.length-t.size,failed:e.filter(e=>"failed"===e.status).length,pending:e.filter(e=>"pending"===e.status).length,asyncReadyTotalMs:Math.round(e.reduce((e,t)=>e+(t.async?t.durationMs:0),0)),syncCreationTotalMs:Math.round(e.reduce((e,t)=>e+(t.async?0:t.durationMs),0))}}function c(e){const t={...e};for(const r of["vertex","fragment","compute"])if(null!=e[r]){const{module:i,...n}=e[r];t[r]=n}return t}function u(e,t=!0){const r=new Map;for(const i of e){if("render"!==i.kind||Boolean(i.origin?.key.startsWith("gpu-vfx:"))!==t)continue;const e=i.origin?.shader,n=i.origin?.material,a=t?e?.key??"unattributed":String(n?.assetId??n?.sourceUuid??i.origin?.key.replace(/:(forward|depth:.*)$/,"")??i.label??"unattributed"),s=r.get(a);s?s.push(i):r.set(a,[i])}return[...r].map(([e,r])=>{const i=[...new Map(r.map(e=>[e.signature,e])).values()],a=c(i[0].state),o=i[0].origin?.shader,u=i.map(e=>{const t=c(e.state);return{pipelineId:n(e.signature),origin:e.origin?.key,material:e.origin?.material,shaderSources:[...new Set(e.shaders)],stageSources:Object.fromEntries(["vertex","fragment"].filter(t=>null!=e.state[t]).map(t=>[t,e.state[t].module])),stateId:n(JSON.stringify(t)),layoutId:n(JSON.stringify(t.layout??null)),stateDifferenceFields:s(a,t).map(e=>e.field),shaderProfileDifferences:s(o,e.origin?.shader),shader:e.origin?.shader,features:e.origin?.variant,featureDifferences:s(i[0].origin?.variant,e.origin?.variant),defines:e.origin?.defines,bindings:e.origin?.bindings,assets:e.origin?.vfxAssets,pipelineState:t,readyAfterMs:Math.round(e.durationMs),status:e.status}});return{graph:e,name:t?r[0].origin?.shader?.name??e:r[0].origin?.material?.assetName||r[0].origin?.material?.name||e,...l(r),shaderCombinations:new Set(i.map(e=>JSON.stringify(e.shaders))).size,pipelineStates:new Set(u.map(e=>e.stateId)).size,layouts:new Set(u.map(e=>e.layoutId)).size,variants:u}}).sort((e,t)=>t.uniquePipelineVariants-e.uniquePipelineVariants)}var d=2,h={minScreenSize:2};function p(e,t){e.userData.detailCulling=t}var f=Object.freeze({minScreenSize:2,maxDistance:0,shadowMinScreenSize:2,shadowMaxDistance:0}),m=[];function g(e,t){let r=!!t;for(let t=e;t&&!r;t=t.parent)r=!!t.userData.detailCulling;if(!r)return f;let i=!0,n=d,a=0,s=!0,o=h.minScreenSize,l=0;const c=e=>{e&&(i=e.enabled??i,n=e.minScreenSize??n,a=e.maxDistance??a,s=e.shadow?.enabled??s,o=e.shadow?.minScreenSize??o,l=e.shadow?.maxDistance??l)};c(t),m.length=0;for(let t=e;t;t=t.parent)m.push(t);for(let e=m.length-1;e>=0;e--)c(m[e].userData.detailCulling);const u=e=>Number.isFinite(e)&&e>0?e:0;return{minScreenSize:i?u(n):0,maxDistance:u(a),shadowMinScreenSize:s?u(o):0,shadowMaxDistance:u(l)}}function v(e,t,r,i,n,a,s,o){if(o>0&&e.distanceTo(a)-t>o)return!1;if(s<=0)return!0;const l=r.elements,c=e.x,u=e.y,d=e.z,h=l[3]*c+l[7]*u+l[11]*d+l[15],p=Math.hypot(l[3],l[7],l[11]),f=h-t*p;if(f<=1e-4)return!0;const m=(l[0]*c+l[4]*u+l[8]*d+l[12])/h,g=(l[1]*c+l[5]*u+l[9]*d+l[13])/h;return t*Math.max((Math.hypot(l[0],l[4],l[8])+Math.abs(m)*p)*i,(Math.hypot(l[1],l[5],l[9])+Math.abs(g)*p)*n)/f>=s}import{Matrix4 as x,Sphere as w,Vector3 as b}from"three";var y=64,S=64,C=40,M=12,P=new Float32Array(C),B=new Float32Array([1,1,1,1]),D="rgba16float",T="rgba8unorm",I=(new x).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),V=[new b(0,-1,0),new b(0,-1,0),new b(0,0,1),new b(0,0,-1),new b(0,-1,0),new b(0,-1,0)],G=[new b(1,0,0),new b(-1,0,0),new b(0,1,0),new b(0,-1,0),new b(0,0,1),new b(0,0,-1)],L=4004,z=[{name:"position",shaderLocation:0,format:"float32x3"}],R=[{name:"position",shaderLocation:0,format:"float32x3"},{name:"skinIndex",shaderLocation:1,format:"uint32x4"},{name:"skinWeight",shaderLocation:2,format:"float32x4"}],U=new x,A=new x,k=(new x,new x,new w),F=new b,$=new b,E=new b,O=(new b,new b,new b,new b,new WeakMap);async function _(e,t){const r=O.get(e)??Promise.resolve();let i;const n=new Promise(e=>{i=e});O.set(e,r.catch(()=>{}).then(()=>n)),await r.catch(()=>{});try{return await new Promise(e=>requestAnimationFrame(()=>e())),t()}finally{i()}}function j(e,t){return i(e,t),"function"==typeof e.createRenderPipelineAsync?e.createRenderPipelineAsync(t):_(e,()=>e.createRenderPipeline(t))}function N(e,t){return i(e,t),"function"==typeof e.createComputePipelineAsync?e.createComputePipelineAsync(t):_(e,()=>e.createComputePipeline(t))}var W=class e{layout;pipeline;static async createAsync(t,r){const{pipelineDescriptor:i}=H(t,r),n=await N(t,i);return new e(t,r,n)}constructor(e,t,r){if(r)return this.layout=r.getBindGroupLayout(0),void(this.pipeline=r);const{layout:i,pipelineDescriptor:n}=H(e,t);this.layout=i,this.pipeline=e.createComputePipeline(n)}createBindGroup(e,t,r){return e.createBindGroup({label:r,layout:this.layout,entries:t})}};function H(e,t){const r=e.createBindGroupLayout({label:t.label?`${t.label}-layout`:void 0,entries:t.bindGroupLayoutEntries});return{layout:r,pipelineDescriptor:{label:t.label,layout:e.createPipelineLayout({label:t.label?`${t.label}-pipeline-layout`:void 0,bindGroupLayouts:[r]}),compute:{module:e.createShaderModule({label:t.label?`${t.label}-module`:void 0,code:t.code}),entryPoint:t.entryPoint??"main"}}}}import{Color as q,DirectionalLight as K,Matrix4 as Z,Object3D as Y,PointLight as X,Scene as J,SpotLight as Q,Vector3 as ee}from"three";var te=class extends Y{constructor(e){super(),this.volume=e}volume;isFogVolumeObject=!0},re={low:{froxelPixelSize:16,depthSlices:32,integrationSubsteps:1,shadowFilterTaps:1,temporalJitter:!0,temporal:{historyWeight:.88,depthRejection:.055,neighborhoodClamp:!0},blur:{scale:.25,radius:2,depthSigma:.06,spatialSigma:1.5,depthAwareUpsample:!1}},medium:{froxelPixelSize:12,depthSlices:40,integrationSubsteps:1,shadowFilterTaps:1,temporalJitter:!0,temporal:{historyWeight:.92,depthRejection:.045,neighborhoodClamp:!0},blur:{scale:.375,radius:2,depthSigma:.055,spatialSigma:1.75,depthAwareUpsample:!0}},high:{froxelPixelSize:8,depthSlices:64,integrationSubsteps:1,shadowFilterTaps:1,temporalJitter:!0,temporal:{historyWeight:.94,depthRejection:.04,neighborhoodClamp:!0},blur:{scale:.5,radius:3,depthSigma:.05,spatialSigma:2,depthAwareUpsample:!0}}},ie=20,ne=16,ae=(new Z).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),se=new ee,oe=new ee,le=new ee,ce={label:"VolumetricFogFroxelPass"};function ue(e,t,r,i,n,a){e[t]=r,e[t+1]=i,e[t+2]=n,e[t+3]=a}var de=class{constructor(e=new J,t={}){this.scene=e,this.options=he(t),this.integratedVolume=`${this.options.targetPrefix}Integrated`,this.columnDepthBounds=`${this.options.targetPrefix}DepthBounds`,this.scatteringHistoryA=`${this.options.targetPrefix}ScatteringHistoryA`,this.scatteringHistoryB=`${this.options.targetPrefix}ScatteringHistoryB`,this.activeHistoryRead=this.scatteringHistoryB,this.activeHistoryWrite=this.scatteringHistoryA,this.volumeData=new Float32Array(this.options.maxVolumes*ie);const r=this.options.maxDirectionalLights+this.options.maxPointLights+this.options.maxSpotLights;this.lightData=new Float32Array(r*ne),this.selectedPointIndices=new Int32Array(this.options.maxPointLights),this.selectedPointScores=new Float32Array(this.options.maxPointLights),this.selectedSpotIndices=new Int32Array(this.options.maxSpotLights),this.selectedSpotScores=new Float32Array(this.options.maxSpotLights)}scene;integratedVolume;columnDepthBounds;scatteringHistoryA;scatteringHistoryB;options;resources=new WeakMap;uniformStorage=new ArrayBuffer(256);uniforms=new Float32Array(this.uniformStorage);uniformIntegers=new Uint32Array(this.uniformStorage);volumeData;lightData;selectedPointIndices;selectedPointScores;selectedSpotIndices;selectedSpotScores;collectedVolumes=[];collectedDirectionals=[];collectedPoints=[];collectedSpots=[];volumeCount=0;directionalCount=0;pointCount=0;spotCount=0;collectionCamera=null;collectVolumeObject=e=>{const t=e;t.isFogVolumeObject&&t.volume&&!this.collectedVolumes.includes(t.volume)&&this.collectedVolumes.push(t.volume)};collectLightObject=e=>{const t=this.collectionCamera;e instanceof K&&e.layers.test(t.layers)&&!this.collectedDirectionals.includes(e)?this.collectedDirectionals.push(e):e instanceof X&&e.layers.test(t.layers)?this.collectedPoints.push(e):e instanceof Q&&e.layers.test(t.layers)&&this.collectedSpots.push(e)};executeFroxelPass=e=>{this.executeFroxels(e)};projectionInverse=new Z;viewProjectionInverse=new Z;previousTemporalViewProjection=new Z;previousFroxelViewProjection=new Z;previousFroxelCameraPosition=new ee;previousFroxelNear=.1;previousFroxelFar=1;previousFroxelWidth=0;previousFroxelHeight=0;froxelHistoryValid=!1;froxelHistoryWriteIndex=0;activeHistoryRead;activeHistoryWrite;explicitVolumes=[];volumeObjects;extractedLights;cascadeDirectionalLights=[];compositePass=null;blurPassCache=new Map;temporalPassCache=new Map;temporalWriteIndex=0;temporalHistoryValid=!1;activeLastFrame=!1;frameIndex=0;setScene(e){this.scene=e}get enabled(){return this.options.enabled}setOptions(e){const t=he({...this.options,...e,ambientColor:e.ambientColor??this.options.ambientColor,blur:void 0===e.blur?this.options.blur:e.blur,temporal:void 0===e.temporal?this.options.temporal:e.temporal,targetPrefix:this.options.targetPrefix,maxVolumes:this.options.maxVolumes,maxDirectionalLights:this.options.maxDirectionalLights,maxPointLights:this.options.maxPointLights,maxSpotLights:this.options.maxSpotLights});Object.assign(this.options,t),this.compositePass=null,this.blurPassCache.clear(),this.temporalPassCache.clear(),this.reset()}applyPreset(e){this.setOptions(re[e])}reset(){this.frameIndex=0,this.temporalWriteIndex=0,this.temporalHistoryValid=!1,this.froxelHistoryValid=!1,this.froxelHistoryWriteIndex=0,this.previousFroxelWidth=0,this.previousFroxelHeight=0,this.activeLastFrame=!1,this.previousTemporalViewProjection.identity()}setCascadedDirectionalLights(e){this.cascadeDirectionalLights=e}addPasses(e,t){if(this.explicitVolumes=t.volumes??[],this.volumeObjects=t.volumeObjects,this.extractedLights=t.lights,!this.options.enabled||0===this.explicitVolumes.length&&0===this.volumeObjects?.length)return this.activeLastFrame&&this.reset(),t.sceneColor;this.activeLastFrame=!0,e.createTextureTarget(this.integratedVolume,{dimension:"3d",depthOrArrayLayers:this.options.depthSlices,scale:1/this.options.froxelPixelSize,format:"rgba16float",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING}),e.createTextureTarget(this.columnDepthBounds,{scale:1/this.options.froxelPixelSize,format:"rg32float",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING});for(const t of[this.scatteringHistoryA,this.scatteringHistoryB])e.createTextureTarget(t,{dimension:"3d",depthOrArrayLayers:this.options.depthSlices,scale:1/this.options.froxelPixelSize,format:"rgba16float",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING});this.activeHistoryRead=0===this.froxelHistoryWriteIndex?this.scatteringHistoryB:this.scatteringHistoryA,this.activeHistoryWrite=0===this.froxelHistoryWriteIndex?this.scatteringHistoryA:this.scatteringHistoryB,e.addPass({name:"VolumetricFogFroxelPass",inputs:{sceneDepth:t.depth,scatteringHistory:this.activeHistoryRead},outputs:[this.integratedVolume,this.columnDepthBounds,this.activeHistoryWrite],execute:this.executeFroxelPass}),this.froxelHistoryWriteIndex=1-this.froxelHistoryWriteIndex;const r=e.createColorTarget(`${this.options.targetPrefix}Composite`,{format:"rgba16float"});return!1!==this.options.blur?this.addBlurredComposite(e,t,r):(this.compositePass&&this.compositePass.matches(t.sceneColor,t.depth,r)||(this.compositePass=new pe(t.sceneColor,t.depth,this.integratedVolume,this.columnDepthBounds,r,this.options.maxDistance,this.options.fogDitherStrength)),this.compositePass.setFrameIndex(this.frameIndex),e.addFullscreenPass(this.compositePass),r)}addBlurredComposite(e,t,r){const i=this.options.blur;if(!1===i)return r;const n=e.createColorTarget(`${this.options.targetPrefix}Resolved`,{format:"rgba16float",scale:i.scale}),a=e.createColorTarget(`${this.options.targetPrefix}BlurTemporary`,{format:"rgba16float",scale:i.scale}),s=e.createColorTarget(`${this.options.targetPrefix}Blurred`,{format:"rgba16float",scale:i.scale}),o=`resolve:${t.depth}:${n}`;let l=this.blurPassCache.get(o);l||(l=new fe(t.depth,this.integratedVolume,this.columnDepthBounds,n,this.options.maxDistance,this.options.fogDitherStrength),this.blurPassCache.set(o,l)),l.setFrameIndex(this.frameIndex),e.addFullscreenPass(l);const c=n;for(const[r,n,o]of[[c,a,[1,0]],[a,s,[0,1]]]){const a=`blur:${r}:${n}:${o[0]}:${i.radius}:${i.depthSigma}:${i.spatialSigma}`;let s=this.blurPassCache.get(a);s||(s=new ge(r,t.depth,n,o,i),this.blurPassCache.set(a,s)),e.addFullscreenPass(s)}const u=`blurComposite:${t.sceneColor}:${t.depth}:${s}:${r}:${i.depthAwareUpsample}`;let d=this.blurPassCache.get(u);return d||(d=new ve(t.sceneColor,t.depth,s,this.integratedVolume,this.columnDepthBounds,r,i.depthAwareUpsample),this.blurPassCache.set(u,d)),e.addFullscreenPass(d),r}addTemporalPass(e,t,r,i){const n=this.options.temporal;if(!1===n)return r;const a=e.createColorTarget(`${this.options.targetPrefix}TemporalA`,{format:"rgba16float",scale:i}),s=e.createColorTarget(`${this.options.targetPrefix}TemporalB`,{format:"rgba16float",scale:i}),o=e.createColorTarget(`${this.options.targetPrefix}TemporalDepthA`,{format:"r16float",scale:i}),l=e.createColorTarget(`${this.options.targetPrefix}TemporalDepthB`,{format:"r16float",scale:i}),c=0===this.temporalWriteIndex?s:a,u=0===this.temporalWriteIndex?a:s,d=0===this.temporalWriteIndex?l:o,h=0===this.temporalWriteIndex?o:l,p=[r,t.depth,t.velocity??"camera",c,d,u,h].join(":");let f=this.temporalPassCache.get(p);return f||(f=new me(r,t.depth,t.velocity,c,d,u,h,n,this),this.temporalPassCache.set(p,f)),e.addFullscreenPass(f),this.temporalWriteIndex=1-this.temporalWriteIndex,u}consumeTemporalHistoryValid(){const e=this.temporalHistoryValid;return this.temporalHistoryValid=!0,e}updateTemporalUniforms(e,t,r,i,n){t.copy(ae).multiply(n.camera.projectionMatrix).multiply(n.camera.matrixWorldInverse),r.copy(t).invert();const a=this.consumeTemporalHistoryValid();e.set(r.elements,0),e.set((a?this.previousTemporalViewProjection:t).elements,16),ue(e,32,i.historyWeight,i.depthRejection,i.neighborhoodClamp?1:0,a?1:0),this.previousTemporalViewProjection.copy(t)}dispose(){this.compositePass=null,this.blurPassCache.clear(),this.temporalPassCache.clear()}executeFroxels(e){const t=this.getResources(e.device);this.collectSceneData(e.camera);const r=Math.max(.01,e.camera.near),i=Math.min(e.camera.far,this.options.maxDistance);e.camera.getWorldPosition(oe);let n=r+.01;for(let e=0;e<this.volumeCount;e++){const t=e*ie,r=this.volumeData[t]-oe.x,i=this.volumeData[t+1]-oe.y,a=this.volumeData[t+2]-oe.z;n=Math.max(n,Math.sqrt(r*r+i*i+a*a)+this.volumeData[t+3])}const a=Math.max(r+.01,Math.min(i,n));let s=a;for(let e=0;e<this.volumeCount;e++)s=Math.min(s,Math.max(this.volumeData[e*ie+10],r));s=Math.min(s,a);const o=Math.max(1,Math.floor(e.width/this.options.froxelPixelSize)),l=Math.max(1,Math.floor(e.height/this.options.froxelPixelSize));o===this.previousFroxelWidth&&l===this.previousFroxelHeight||(this.froxelHistoryValid=!1),this.projectionInverse.copy(ae).multiply(e.camera.projectionMatrix).multiply(e.camera.matrixWorldInverse),this.viewProjectionInverse.copy(this.projectionInverse).invert(),this.uniforms.set(this.viewProjectionInverse.elements,0),this.uniforms[16]=e.camera.position.x,this.uniforms[17]=e.camera.position.y,this.uniforms[18]=e.camera.position.z,this.uniforms[19]=r,ue(this.uniforms,20,o,l,this.options.depthSlices,a),this.uniformIntegers[24]=this.volumeCount,this.uniformIntegers[25]=this.directionalCount,this.uniformIntegers[26]=this.pointCount,this.uniformIntegers[27]=this.spotCount,ue(this.uniforms,28,this.options.ambientColor.r,this.options.ambientColor.g,this.options.ambientColor.b,this.options.temporalJitter?this.frameIndex++%1024+1:0),e.camera.getWorldDirection(oe),ue(this.uniforms,32,oe.x,oe.y,oe.z,Math.max(e.camera.far-r,1e-4)),ue(this.uniforms,36,this.options.scatteringIntensity,this.options.spatialJitter?1:0,0,0),this.uniforms.set((this.froxelHistoryValid?this.previousFroxelViewProjection:this.projectionInverse).elements,40),ue(this.uniforms,56,this.previousFroxelCameraPosition.x,this.previousFroxelCameraPosition.y,this.previousFroxelCameraPosition.z,this.froxelHistoryValid&&!1!==this.options.temporal?1:0),ue(this.uniforms,60,this.previousFroxelNear,this.previousFroxelFar,!1===this.options.temporal?0:this.options.temporal.historyWeight,0),e.device.queue.writeBuffer(t.uniformBuffer,0,this.uniforms),this.volumeCount>0&&e.device.queue.writeBuffer(t.volumeBuffer,0,this.volumeData.buffer,this.volumeData.byteOffset,this.volumeCount*ie*4);const c=this.directionalCount+this.pointCount+this.spotCount;c>0&&e.device.queue.writeBuffer(t.lightBuffer,0,this.lightData.buffer,this.lightData.byteOffset,c*ne*4);const u=e.getSceneLightingResources(),d=e.getTextureView(this.integratedVolume),h=e.getTextureView(this.columnDepthBounds),p=e.getTextureView(this.activeHistoryRead),f=e.getTextureView(this.activeHistoryWrite),m=e.depthView,g=t.bindGroupResources;t.bindGroup&&g&&g.integratedVolumeView===d&&g.historyReadView===p&&g.historyWriteView===f&&g.lightBuffer===u.lightBuffer&&g.comparisonSampler===e.comparisonSampler&&g.directionalShadowView===u.directionalShadowView&&g.pointShadowView===u.pointShadowView&&g.spotShadowView===u.spotShadowView&&g.spotLightMapView===u.spotLightMapView&&g.depthView===m&&g.columnDepthBoundsView===h||(t.bindGroup=e.device.createBindGroup({label:"volumetric-fog-bind-group",layout:t.layout,entries:[{binding:0,resource:{buffer:t.uniformBuffer}},{binding:1,resource:{buffer:t.volumeBuffer}},{binding:2,resource:{buffer:t.lightBuffer}},{binding:3,resource:d},{binding:4,resource:{buffer:u.lightBuffer}},{binding:5,resource:e.comparisonSampler},{binding:6,resource:u.directionalShadowView},{binding:7,resource:u.pointShadowView},{binding:8,resource:u.spotShadowView},{binding:9,resource:m},{binding:10,resource:h},{binding:11,resource:e.linearClampSampler},{binding:12,resource:p},{binding:13,resource:f},{binding:14,resource:u.spotLightMapView}]}),t.bindGroupResources={integratedVolumeView:d,historyReadView:p,historyWriteView:f,lightBuffer:u.lightBuffer,comparisonSampler:e.comparisonSampler,directionalShadowView:u.directionalShadowView,pointShadowView:u.pointShadowView,spotShadowView:u.spotShadowView,spotLightMapView:u.spotLightMapView,depthView:m,columnDepthBoundsView:h});const v=e.encoder.beginComputePass(ce);v.setPipeline(t.pipeline),v.setBindGroup(0,t.bindGroup),v.dispatchWorkgroups(Math.ceil(o/8),Math.ceil(l/8)),v.end(),this.previousFroxelViewProjection.copy(this.projectionInverse),this.previousFroxelCameraPosition.set(this.uniforms[16],this.uniforms[17],this.uniforms[18]),this.previousFroxelNear=s,this.previousFroxelFar=a,this.previousFroxelWidth=o,this.previousFroxelHeight=l,this.froxelHistoryValid=!0}collectSceneData(e){const t=this.collectedVolumes,r=this.collectedDirectionals,i=this.collectedPoints,n=this.collectedSpots;t.length=0,r.length=0,i.length=0,n.length=0;for(const e of this.explicitVolumes)t.push(e);for(const t of this.cascadeDirectionalLights)t.visible&&t.layers.test(e.layers)&&!r.includes(t)&&r.push(t);if(void 0===this.volumeObjects)this.scene.traverseVisible(this.collectVolumeObject);else for(const e of this.volumeObjects)this.collectVolumeObject(e);void 0===this.extractedLights&&(this.collectionCamera=e,this.scene.traverseVisible(this.collectLightObject),this.collectionCamera=null);const a=Math.min(t.length,this.options.maxVolumes);this.volumeData.fill(0,0,a*ie);for(let e=0;e<a;e++)this.writeVolume(e,t[e]);const s=Math.min(this.extractedLights?.directionals.length??r.length,this.options.maxDirectionalLights),o=this.extractedLights?.points,l=this.extractedLights?.spots,c=this.selectClosestLights(o??i,e,this.selectedPointIndices,this.selectedPointScores),u=this.selectClosestLights(l??n,e,this.selectedSpotIndices,this.selectedSpotScores);this.lightData.fill(0,0,(s+c+u)*ne);let d=0;for(let e=0;e<s;e++){const t=this.extractedLights?.directionals[e];t?this.writeExtractedDirectional(d++,t):this.writeDirectional(d++,r[e])}for(let e=0;e<c;e++){const t=this.selectedPointIndices[e];o?this.writeExtractedPoint(d++,o[t],t):this.writePoint(d++,i[t])}for(let e=0;e<u;e++){const t=this.selectedSpotIndices[e];l?this.writeExtractedSpot(d++,l[t],t):this.writeSpot(d++,n[t])}this.volumeCount=a,this.directionalCount=s,this.pointCount=c,this.spotCount=u}selectClosestLights(e,t,r,i){const n=r.length;if(0===n)return 0;t.getWorldPosition(oe);let a=0;for(let t=0;t<e.length;t+=1){const s=e[t],o=Number(s instanceof Y?s.userData?.volumetricIntensity??0:s.volumetricIntensity);if(!Number.isFinite(o)||o<=0)continue;const l=s instanceof Y?s.getWorldPosition(se):s.position,c=oe.distanceToSquared(l);if(a===n&&c>=i[n-1])continue;let u=Math.min(a,n-1);for(;u>0&&c<i[u-1];)u<n&&(i[u]=i[u-1],r[u]=r[u-1]),u-=1;i[u]=c,r[u]=t,a<n&&(a+=1)}return a}writeVolume(e,t){const r=e*ie;t.object.getWorldPosition(se),t.object.getWorldScale(le),ue(this.volumeData,r,se.x,se.y,se.z,5*Math.max(le.x,le.y,le.z)),ue(this.volumeData,r+4,t.albedo.r,t.albedo.g,t.albedo.b,Math.max(0,t.baseDensity)),ue(this.volumeData,r+8,t.heightFalloff,t.heightOffset,t.startDistance??3,-Math.max(-.99,Math.min(.99,t.scatteringDistribution))),ue(this.volumeData,r+12,t.emissive.r,t.emissive.g,t.emissive.b,t.ambientIntensity??1),this.volumeData[r+16]="lightShaft"===t.scatteringMode?1:0}writeDirectional(e,t){const r=e*ne;t.getWorldPosition(se),t.target.getWorldPosition(oe),oe.sub(se).normalize(),ue(this.lightData,r,oe.x,oe.y,oe.z,0);const i=t.intensity*(t.userData?.volumetricIntensity??1);ue(this.lightData,r+4,t.color.r*i,t.color.g*i,t.color.b*i,0)}writeExtractedDirectional(e,t){const r=e*ne;ue(this.lightData,r,t.direction.x,t.direction.y,t.direction.z,0);const i=t.intensity*t.volumetricIntensity;ue(this.lightData,r+4,t.color.x*i,t.color.y*i,t.color.z*i,0)}writePoint(e,t,r=e){const i=e*ne;t.getWorldPosition(se),ue(this.lightData,i,se.x,se.y,se.z,Math.max(.001,t.distance||this.options.maxDistance));const n=t.intensity*(t.userData?.volumetricIntensity??1);ue(this.lightData,i+4,t.color.r*n,t.color.g*n,t.color.b*n,Math.max(0,t.decay)),this.lightData[i+13]=r}writeExtractedPoint(e,t,r){const i=e*ne;ue(this.lightData,i,t.position.x,t.position.y,t.position.z,Math.max(.001,t.range||this.options.maxDistance));const n=t.intensity*t.volumetricIntensity;ue(this.lightData,i+4,t.color.x*n,t.color.y*n,t.color.z*n,Math.max(0,t.decay)),this.lightData[i+13]=r,this.lightData[i+14]=1}writeSpot(e,t,r=e){const i=e*ne;t.getWorldPosition(se),t.target.getWorldPosition(oe),oe.sub(se).normalize(),ue(this.lightData,i,se.x,se.y,se.z,Math.max(.001,t.distance||this.options.maxDistance));const n=t.intensity*(t.userData?.volumetricIntensity??1);ue(this.lightData,i+4,t.color.r*n,t.color.g*n,t.color.b*n,Math.max(0,t.decay)),ue(this.lightData,i+8,oe.x,oe.y,oe.z,Math.cos(t.angle)),this.lightData[i+12]=Math.cos(t.angle*(1-t.penumbra)),this.lightData[i+13]=r}writeExtractedSpot(e,t,r){const i=e*ne;ue(this.lightData,i,t.position.x,t.position.y,t.position.z,Math.max(.001,t.range||this.options.maxDistance));const n=t.intensity*t.volumetricIntensity;ue(this.lightData,i+4,t.color.x*n,t.color.y*n,t.color.z*n,Math.max(0,t.decay)),ue(this.lightData,i+8,t.direction.x,t.direction.y,t.direction.z,Math.cos(t.angle)),this.lightData[i+12]=Math.cos(t.angle*(1-t.penumbra)),this.lightData[i+13]=r,this.lightData[i+14]=1}getResources(e){let t=this.resources.get(e);t||(t=new Map,this.resources.set(e,t));const r=[this.options.shadowFilterTaps,this.options.integrationSubsteps,this.options.maxVolumes,this.options.maxDirectionalLights,this.options.maxPointLights,this.options.maxSpotLights].join(":"),i=t.get(r);if(i)return i;const n=e.createBuffer({size:256,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),a=e.createBuffer({size:this.volumeData.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),s=e.createBuffer({size:this.lightData.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),o=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"rgba16float",viewDimension:"3d"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:5,visibility:GPUShaderStage.COMPUTE,sampler:{type:"comparison"}},{binding:6,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:7,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"float",viewDimension:"2d-array"}},{binding:8,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:9,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"depth",viewDimension:"2d"}},{binding:10,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"rg32float",viewDimension:"2d"}},{binding:11,visibility:GPUShaderStage.COMPUTE,sampler:{type:"filtering"}},{binding:12,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"float",viewDimension:"3d"}},{binding:13,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"rgba16float",viewDimension:"3d"}},{binding:14,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"float",viewDimension:"2d"}}]}),l=e.createShaderModule({label:"volumetric-fog-compute",code:be.replace("__SHADOW_TAPS__",String(this.options.shadowFilterTaps)).replace("__INTEGRATION_SUBSTEPS__",String(this.options.integrationSubsteps))}),c={uniformBuffer:n,volumeBuffer:a,lightBuffer:s,layout:o,pipeline:e.createComputePipeline({layout:e.createPipelineLayout({bindGroupLayouts:[o]}),compute:{module:l,entryPoint:"main"}})};return t.set(r,c),c}};function he(e){return{enabled:e.enabled??!0,froxelPixelSize:Math.max(2,Math.floor(e.froxelPixelSize??8)),depthSlices:Math.max(8,Math.floor(e.depthSlices??64)),integrationSubsteps:e.integrationSubsteps??1,maxDistance:Math.max(1,e.maxDistance??256),targetPrefix:e.targetPrefix??"volumetricFog",maxVolumes:Math.max(1,Math.floor(e.maxVolumes??32)),maxDirectionalLights:Math.min(4,Math.max(1,Math.floor(e.maxDirectionalLights??4))),maxPointLights:Math.min(4,Math.max(0,Math.floor(e.maxPointLights??4))),maxSpotLights:Math.min(4,Math.max(0,Math.floor(e.maxSpotLights??4))),ambientColor:e.ambientColor?.clone()??new q(.03,.035,.045),shadowFilterTaps:e.shadowFilterTaps??1,temporalJitter:e.temporalJitter??!0,temporal:!1!==e.temporal&&{historyWeight:Math.min(.98,Math.max(0,e.temporal?.historyWeight??.92)),depthRejection:Math.max(1e-4,e.temporal?.depthRejection??.04),neighborhoodClamp:e.temporal?.neighborhoodClamp??!0},spatialJitter:e.spatialJitter??!0,fogDitherStrength:Math.max(0,e.fogDitherStrength??.75),scatteringIntensity:Math.max(0,e.scatteringIntensity??1),blur:!1!==e.blur&&{scale:Math.max(.125,Math.min(1,e.blur?.scale??.5)),radius:Math.max(1,Math.min(12,Math.floor(e.blur?.radius??3))),depthSigma:Math.max(1e-4,e.blur?.depthSigma??.05),spatialSigma:Math.max(.1,e.blur?.spatialSigma??2),depthAwareUpsample:e.blur?.depthAwareUpsample??!0}}}var pe=class{constructor(e,t,r,i,n,a,s){this.maxDistance=a,this.ditherStrength=s,this.inputs={sceneColor:e,sceneDepth:t,fogVolume:r,fogBounds:i},this.outputs=n}maxDistance;ditherStrength;name="VolumetricFogCompositePass";sampler="linear";uniformBufferSize=80;inputs;inputDimensions={fogVolume:"3d"};outputs;fragmentShader=ye;data=new Float32Array(20);inverseProjection=new Z;frameIndex=0;setFrameIndex(e){this.frameIndex=e}matches(e,t,r){return this.inputs.sceneColor===e&&this.inputs.sceneDepth===t&&this.outputs===r}updateUniforms=e=>(this.inverseProjection.copy(ae).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),ue(this.data,16,Math.max(.01,e.camera.near),Math.min(e.camera.far,this.maxDistance),this.frameIndex>0?this.frameIndex%1024:-1,this.ditherStrength),this.data)},fe=class{constructor(e,t,r,i,n,a){this.maxDistance=n,this.ditherStrength=a,this.inputs={sceneDepth:e,fogVolume:t,fogBounds:r},this.outputs=i}maxDistance;ditherStrength;name="VolumetricFogResolvePass";sampler="linear";uniformBufferSize=80;inputDimensions={fogVolume:"3d"};inputs;outputs;fragmentShader=Se;data=new Float32Array(20);inverseProjection=new Z;frameIndex=0;setFrameIndex(e){this.frameIndex=e}updateUniforms=e=>(this.inverseProjection.copy(ae).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),ue(this.data,16,Math.max(.01,e.camera.near),Math.min(e.camera.far,this.maxDistance),this.frameIndex>0?this.frameIndex%1024:-1,this.ditherStrength),this.data)},me=class{constructor(e,t,r,i,n,a,s,o,l){var c;this.temporal=o,this.state=l,this.inputs=null==r?{currentFog:e,sceneDepth:t,historyFog:i,historyDepth:n}:{currentFog:e,sceneDepth:t,historyFog:i,historyDepth:n,velocity:r},this.outputs=[a,s],this.fragmentShader=`\nstruct FogTemporalOutput{\n @location(0) fog:vec4<f32>,\n @location(1) depth:vec4<f32>,\n};\nfn currentViewProjectionInverse()->mat4x4<f32>{\n return mat4x4<f32>(fullscreenUniforms[0],fullscreenUniforms[1],fullscreenUniforms[2],fullscreenUniforms[3]);\n}\nfn previousViewProjection()->mat4x4<f32>{\n return mat4x4<f32>(fullscreenUniforms[4],fullscreenUniforms[5],fullscreenUniforms[6],fullscreenUniforms[7]);\n}\nfn loadCurrentFog(pixel:vec2<i32>,size:vec2<i32>)->vec4<f32>{\n return textureLoad(currentFogTexture,clamp(pixel,vec2<i32>(0),size-vec2<i32>(1)),0);\n}\nfn loadHistoryFog(pixel:vec2<i32>,size:vec2<i32>)->vec4<f32>{\n return textureLoad(historyFogTexture,clamp(pixel,vec2<i32>(0),size-vec2<i32>(1)),0);\n}\nfn sampleHistoryBilinear(uv:vec2<f32>)->vec4<f32>{\n let size=vec2<i32>(textureDimensions(historyFogTexture));\n let position=uv*vec2<f32>(size)-0.5;\n let base=vec2<i32>(floor(position));\n let f=fract(position);\n let a=mix(loadHistoryFog(base,size),loadHistoryFog(base+vec2<i32>(1,0),size),f.x);\n let b=mix(loadHistoryFog(base+vec2<i32>(0,1),size),loadHistoryFog(base+vec2<i32>(1,1),size),f.x);\n return mix(a,b,f.y);\n}\nfn loadSceneDepth(uv:vec2<f32>)->f32{\n let size=vec2<i32>(textureDimensions(sceneDepthTexture));\n let pixel=clamp(vec2<i32>(uv*vec2<f32>(size)),vec2<i32>(0),size-vec2<i32>(1));\n return textureLoad(sceneDepthTexture,pixel,0);\n}\nfn loadHistoryDepth(uv:vec2<f32>)->f32{\n let size=vec2<i32>(textureDimensions(historyDepthTexture));\n let pixel=clamp(vec2<i32>(uv*vec2<f32>(size)),vec2<i32>(0),size-vec2<i32>(1));\n return textureLoad(historyDepthTexture,pixel,0).r;\n}\n${(c=null!=r)?"\nfn loadVelocity(uv:vec2<f32>)->vec2<f32>{\n let size=vec2<i32>(textureDimensions(velocityTexture));\n let pixel=clamp(vec2<i32>(uv*vec2<f32>(size)),vec2<i32>(0),size-vec2<i32>(1));\n return textureLoad(velocityTexture,pixel,0).xy;\n}\n":""}\n@fragment fn fsMain(input:FullscreenVertexOutput)->FogTemporalOutput{\n let size=vec2<i32>(textureDimensions(currentFogTexture));\n let pixel=clamp(vec2<i32>(input.position.xy),vec2<i32>(0),size-vec2<i32>(1));\n let uv=(vec2<f32>(pixel)+0.5)/vec2<f32>(size);\n let current=textureLoad(currentFogTexture,pixel,0);\n var neighborhoodMin=current;\n var neighborhoodMax=current;\n for(var y=-1;y<=1;y+=1){\n for(var x=-1;x<=1;x+=1){\n let value=loadCurrentFog(pixel+vec2<i32>(x,y),size);\n neighborhoodMin=min(neighborhoodMin,value);\n neighborhoodMax=max(neighborhoodMax,value);\n }\n }\n let rawDepth=loadSceneDepth(uv);\n let clip=vec4<f32>(uv.x*2.0-1.0,1.0-uv.y*2.0,rawDepth,1.0);\n let worldH=currentViewProjectionInverse()*clip;\n let world=worldH/worldH.w;\n let previousClip=previousViewProjection()*world;\n let previousNdc=previousClip.xy/previousClip.w;\n let cameraHistoryUv=vec2<f32>(previousNdc.x*0.5+0.5,0.5-previousNdc.y*0.5);\n${c?"\n let velocity=loadVelocity(uv);\n let finiteVelocity=all(velocity==velocity)&&all(abs(velocity)<vec2<f32>(2.0));\n let hasUsefulVelocity=finiteVelocity&&dot(velocity,velocity)>1e-12;\n let historyUv=select(cameraHistoryUv,uv-velocity,hasUsefulVelocity);\n":"\n let historyUv=cameraHistoryUv;\n"}\n let validUv=all(historyUv>=vec2<f32>(0.0))&&all(historyUv<=vec2<f32>(1.0));\n let historyValid=fullscreenUniforms[8].w>0.5&&validUv;\n let history=sampleHistoryBilinear(clamp(historyUv,vec2<f32>(0.0),vec2<f32>(1.0)));\n let previousDistance=loadHistoryDepth(clamp(historyUv,vec2<f32>(0.0),vec2<f32>(1.0)));\n let currentDistance=length(world.xyz-fullscreenUniforms[9].xyz);\n let relativeDepthDelta=abs(log(max(previousDistance,0.001)/max(currentDistance,0.001)));\n let rejection=max(fullscreenUniforms[8].y,0.0001);\n let depthWeight=exp(-relativeDepthDelta*relativeDepthDelta/(rejection*rejection));\n let clampedHistory=select(history,clamp(history,neighborhoodMin,neighborhoodMax),fullscreenUniforms[8].z>0.5);\n let historyWeight=select(0.0,fullscreenUniforms[8].x*depthWeight,historyValid);\n var output:FogTemporalOutput;\n output.fog=mix(current,clampedHistory,clamp(historyWeight,0.0,0.98));\n output.depth=vec4<f32>(min(currentDistance,65504.0),0.0,0.0,1.0);\n return output;\n}`}temporal;state;name="VolumetricFogTemporalPass";sampler="nearest";uniformBufferSize=160;inputs;outputs;fragmentShader;uniforms=new Float32Array(this.uniformBufferSize/4);currentViewProjection=new Z;currentViewProjectionInverse=new Z;updateUniforms=e=>(this.state.updateTemporalUniforms(this.uniforms,this.currentViewProjection,this.currentViewProjectionInverse,this.temporal,e),ue(this.uniforms,36,e.camera.position.x,e.camera.position.y,e.camera.position.z,e.camera.far),this.uniforms)},ge=class{name;sampler="linear";uniformBufferSize=80;inputs;outputs;fragmentShader;data=new Float32Array(20);inverseProjection=new Z;constructor(e,t,r,i,n){this.name=i[0]?"VolumetricFogBlurHorizontalPass":"VolumetricFogBlurVerticalPass",this.inputs={fogInput:e,sceneDepth:t},this.outputs=r,this.data.set([i[0],i[1],n.depthSigma,n.spatialSigma],16),this.fragmentShader=`\nconst BLUR_RADIUS:i32=${n.radius};\nfn inverseProjection() -> mat4x4<f32> { return mat4x4<f32>(fullscreenUniforms[0],fullscreenUniforms[1],fullscreenUniforms[2],fullscreenUniforms[3]); }\nfn viewDistance(uv:vec2<f32>)->f32 { let size=vec2<i32>(textureDimensions(sceneDepthTexture));let pixel=clamp(vec2<i32>(uv*vec2<f32>(size)),vec2<i32>(0),size-vec2<i32>(1));let depth=textureLoad(sceneDepthTexture,pixel,0);let clip=vec4<f32>(uv.x*2.0-1.0,1.0-uv.y*2.0,depth,1.0);let view=inverseProjection()*clip;return length(view.xyz/view.w); }\n@fragment fn fsMain(input:FullscreenVertexOutput)->@location(0) vec4<f32>{\n let size=vec2<f32>(textureDimensions(fogInputTexture));let texel=1.0/size;let direction=fullscreenUniforms[4].xy;let depthSigma=fullscreenUniforms[4].z;let spatialSigma=fullscreenUniforms[4].w;\n let centerDepth=viewDistance(input.uv);var sum=vec4<f32>(0.0);var weightSum=0.0;\n for(var i=-BLUR_RADIUS;i<=BLUR_RADIUS;i+=1){let uv=clamp(input.uv+direction*f32(i)*texel,vec2<f32>(0.0),vec2<f32>(1.0));let sampleDepth=viewDistance(uv);let fi=f32(i);let spatial=exp(-0.5*fi*fi/(spatialSigma*spatialSigma));let delta=log(max(sampleDepth,0.0001)/max(centerDepth,0.0001));let depthWeight=exp(-0.5*delta*delta/(depthSigma*depthSigma));let weight=spatial*depthWeight;sum+=textureSampleLevel(fogInputTexture,fullscreenSampler,uv,0.0)*weight;weightSum+=weight;}\n return sum/max(weightSum,0.0001);\n}`}updateUniforms=e=>(this.inverseProjection.copy(ae).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),this.data)},ve=class{name="VolumetricFogBlurCompositePass";sampler="linear";uniformBufferSize=64;inputs;inputDimensions={};outputs;fragmentShader;data=new Float32Array(16);inverseProjection=new Z;constructor(e,t,r,i,n,a,s){this.inputs=s?{sceneColor:e,sceneDepth:t,fogInput:r}:{sceneColor:e,fogInput:r},this.outputs=a,this.fragmentShader=s?Ce:Me}updateUniforms=e=>(this.inverseProjection.copy(ae).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements),this.data)},xe="\nfn rendererSampleIntegratedFogRaw(uv: vec2<f32>, normalizedDepth: f32) -> vec4<f32> {\n let sliceCount = f32(textureDimensions(volumetricFogTexture).z);\n let slicePosition = clamp(normalizedDepth, 0.0, 1.0) * sliceCount;\n let textureZ = clamp((slicePosition - 0.5) / sliceCount, 0.0, 1.0);\n let integrated = textureSampleLevel(volumetricFogTexture, volumetricFogSampler, vec3<f32>(uv, textureZ), 0.0);\n // The volume stores slice endpoints but has no texel for the near-plane\n // identity value. Reconstruct that missing endpoint for the first slice.\n return mix(vec4<f32>(0.0, 0.0, 0.0, 1.0), integrated, min(slicePosition, 1.0));\n}\nfn rendererSampleIntegratedFog(uv: vec2<f32>, normalizedDepth: f32) -> vec4<f32> {\n return rendererSampleIntegratedFogRaw(uv, normalizedDepth);\n}\nfn rendererApplyVolumetricFog(color: vec4<f32>, worldPosition: vec3<f32>) -> vec4<f32> {\n let clip = rendererCamera.viewProj * vec4<f32>(worldPosition, 1.0);\n let uv = clip.xy / clip.w * vec2<f32>(0.5, -0.5) + vec2<f32>(0.5);\n let distance = length(worldPosition - rendererCamera.cameraPosition.xyz);\n let bounds = textureSampleLevel(volumetricFogBoundsTexture, volumetricFogBoundsSampler, uv, 0.0).rg;\n let z = clamp(log(max(distance, bounds.x) / bounds.x) / max(log(bounds.y / bounds.x), 0.0001), 0.0, 1.0);\n let fog = rendererSampleIntegratedFog(uv, z);\n return vec4<f32>(fog.rgb + color.rgb * fog.a, color.a);\n}";function we(e,t="volumetricFogIntegrated",r=(t.endsWith("Integrated")?`${t.slice(0,-10)}DepthBounds`:"volumetricFogDepthBounds")){return e.graphTextures.volumetricFog={resource:t,dimension:"3d",sampleType:"float",sampler:"filtering",requiresLatePass:!0},e.graphTextures.volumetricFogBounds={resource:r,dimension:"2d",sampleType:"float",sampler:"filtering",requiresLatePass:!0},e.needsUpdate=!0,e}var be="\nstruct FogUniforms { inverseViewProjection: mat4x4<f32>, cameraNear: vec4<f32>, dimensionsFar: vec4<f32>, counts: vec4<u32>, ambient: vec4<f32>, cameraForwardDepthRange: vec4<f32>, scattering: vec4<f32>, previousViewProjection: mat4x4<f32>, historyCameraValid: vec4<f32>, historyNearFarWeight: vec4<f32> };\nstruct FogVolume { centerRadius: vec4<f32>, albedoDensity: vec4<f32>, heightStartPhase: vec4<f32>, emissiveAmbient: vec4<f32>, mode: vec4<f32> };\nstruct FogLight { positionRange: vec4<f32>, colorDecay: vec4<f32>, directionCone: vec4<f32>, penumbra: vec4<f32> };\nstruct RendererLightUniforms {\n ambientColor: vec4<f32>, lightCounts: vec4<f32>,\n directionalDirections: array<vec4<f32>,4>, directionalColorIntensities: array<vec4<f32>,4>,\n directionalShadowParams: array<vec4<f32>,4>, directionalShadowParams2: array<vec4<f32>,4>, directionalShadowMatrices: array<mat4x4<f32>,4>,\n pointPositionRanges: array<vec4<f32>,64>, pointColorIntensities: array<vec4<f32>,64>, pointParams: array<vec4<f32>,64>, pointShadowParams: array<vec4<f32>,64>, pointShadowParams2: array<vec4<f32>,64>,\n spotPositionRanges: array<vec4<f32>,64>, spotDirectionCones: array<vec4<f32>,64>, spotColorIntensities: array<vec4<f32>,64>,\n spotShadowParams: array<vec4<f32>,64>, spotShadowParams2: array<vec4<f32>,64>, spotParams: array<vec4<f32>,64>, spotShadowMatrices: array<mat4x4<f32>,64>,\n csmCascadeRanges: array<vec4<f32>,4>, hemisphereSkyColorIntensity: vec4<f32>, hemisphereGroundColorIntensity: vec4<f32>, hemisphereDirection: vec4<f32>\n};\n@group(0) @binding(0) var<uniform> uniforms: FogUniforms;\n@group(0) @binding(1) var<storage, read> volumes: array<FogVolume>;\n@group(0) @binding(2) var<storage, read> lights: array<FogLight>;\n@group(0) @binding(3) var outputFog: texture_storage_3d<rgba16float, write>;\n@group(0) @binding(4) var<uniform> rendererLights: RendererLightUniforms;\n@group(0) @binding(5) var shadowSampler: sampler_comparison;\n@group(0) @binding(6) var directionalShadows: texture_depth_2d_array;\n@group(0) @binding(7) var pointShadows: texture_2d_array<f32>;\n@group(0) @binding(8) var spotShadows: texture_depth_2d_array;\n@group(0) @binding(9) var sceneDepth: texture_depth_2d;\n@group(0) @binding(10) var outputDepthBounds: texture_storage_2d<rg32float, write>;\n@group(0) @binding(11) var historySampler: sampler;\n@group(0) @binding(12) var scatteringHistory: texture_3d<f32>;\n@group(0) @binding(13) var outputScatteringHistory: texture_storage_3d<rgba16float, write>;\n@group(0) @binding(14) var spotLightMapAtlas: texture_2d<f32>;\nconst PI = 3.14159265359;\nconst SHADOW_TAPS = __SHADOW_TAPS__;\nconst INTEGRATION_SUBSTEPS = __INTEGRATION_SUBSTEPS__;\nfn phaseHG(cosTheta: f32, g: f32) -> f32 { let gg = g*g; return (1.0-gg)/(4.0*PI*pow(max(0.001,1.0+gg-2.0*g*cosTheta),1.5)); }\nfn attenuation(distance: f32, range: f32, decay: f32) -> f32 { let window = max(0.0, 1.0-pow(distance/range,4.0)); return window*window / max(1.0, pow(distance, decay)); }\nfn spotConeAttenuation(angleCos: f32, coneCos: f32, penumbraCos: f32) -> f32 {\n // Three.js spotlights default to a zero-width penumbra. smoothstep() is\n // undefined when both edges are equal, so use a hard cutoff in that case.\n let width = penumbraCos - coneCos;\n if (width <= 0.000001) { return select(0.0, 1.0, angleCos >= coneCos); }\n return smoothstep(coneCos, penumbraCos, angleCos);\n}\nfn hash12(p:vec2<f32>)->f32 { let p3=fract(vec3<f32>(p.xyx)*0.1031); let q=p3+dot(p3,p3.yzx+33.33); return fract((q.x+q.y)*q.z); }\nfn halton(index:u32,base:u32)->f32{var i=index;var fraction=1.0;var result=0.0;loop{if(i==0u){break;}fraction/=f32(base);result+=fraction*f32(i%base);i/=base;}return result;}\nfn rotatedOffset(tap:i32, angle:f32)->vec2<f32> {\n let disk=array<vec2<f32>,4>(vec2<f32>(-0.326,-0.406),vec2<f32>(-0.840,0.074),vec2<f32>(-0.696,0.457),vec2<f32>(0.203,0.621));\n let v=disk[tap]; let c=cos(angle); let s=sin(angle); return vec2<f32>(c*v.x-s*v.y,s*v.x+c*v.y);\n}\nfn projectedShadow(matrix: mat4x4<f32>, p: vec3<f32>, layer: i32, bias: f32, intensity: f32, textureKind: u32) -> f32 {\n let clip=matrix*vec4<f32>(p,1.0); if (clip.w<=0.0) { return 1.0; } let ndc=clip.xyz/clip.w;\n if (ndc.x < -1.0 || ndc.x > 1.0 || ndc.y < -1.0 || ndc.y > 1.0 || ndc.z < 0.0 || ndc.z > 1.0) { return 1.0; }\n let uv=ndc.xy*vec2<f32>(0.5,-0.5)+vec2<f32>(0.5); var visibility=0.0;\n // Avoid a world-space random pattern swimming through the camera-relative grid.\n let angle=select(0.0,hash12(p.xz+vec2<f32>(uniforms.ambient.w, f32(layer)))*6.2831853,uniforms.ambient.w>0.0);\n if (textureKind==0u) {\n let dims=vec2<f32>(textureDimensions(directionalShadows)); let radius=max(rendererLights.directionalShadowParams2[u32(layer)].x,0.0);let offset=radius/dims;let depth=ndc.z+bias;\n // Match the surface-lighting path: a weighted hardware-PCF center and\n // four cardinal taps. The former sparse rotated disk made partially\n // shadowed froxels jump between a few discrete visibility values.\n let center=textureSampleCompareLevel(directionalShadows,shadowSampler,uv,layer,depth);\n if(SHADOW_TAPS==1){\n visibility=center;\n }else{\n let left=textureSampleCompareLevel(directionalShadows,shadowSampler,clamp(uv-vec2<f32>(offset.x,0.0),vec2<f32>(0.0),vec2<f32>(1.0)),layer,depth);\n let right=textureSampleCompareLevel(directionalShadows,shadowSampler,clamp(uv+vec2<f32>(offset.x,0.0),vec2<f32>(0.0),vec2<f32>(1.0)),layer,depth);\n let up=textureSampleCompareLevel(directionalShadows,shadowSampler,clamp(uv-vec2<f32>(0.0,offset.y),vec2<f32>(0.0),vec2<f32>(1.0)),layer,depth);\n let down=textureSampleCompareLevel(directionalShadows,shadowSampler,clamp(uv+vec2<f32>(0.0,offset.y),vec2<f32>(0.0),vec2<f32>(1.0)),layer,depth);\n visibility=(center*4.0+left+right+up+down)*0.5;\n }\n } else {\n let dims=vec2<f32>(textureDimensions(spotShadows)); let radius=max(rendererLights.spotShadowParams2[u32(layer)].x,1.0);\n for(var tap=0;tap<SHADOW_TAPS;tap+=1){let suv=clamp(uv+rotatedOffset(tap,angle)*radius/dims,vec2<f32>(0.0),vec2<f32>(1.0));let pixel=vec2<i32>(clamp(suv*dims,vec2<f32>(0.0),dims-1.0));visibility+=select(0.0,1.0,ndc.z-bias<=textureLoad(spotShadows,pixel,layer,0));}\n }\n visibility/=f32(SHADOW_TAPS);\n return mix(1.0,visibility,intensity);\n}\nfn pointShadowUvLayer(direction: vec3<f32>, index: u32) -> vec3<f32> {\n let a=abs(direction); var face=0u; var uv=vec2<f32>(0.0);\n if (a.x>=a.y && a.x>=a.z) { if(direction.x>=0.0){face=0u;uv=vec2<f32>(-direction.z,-direction.y)/a.x;}else{face=1u;uv=vec2<f32>(direction.z,-direction.y)/a.x;} }\n else if(a.y>=a.x && a.y>=a.z){if(direction.y>=0.0){face=2u;uv=vec2<f32>(direction.x,direction.z)/a.y;}else{face=3u;uv=vec2<f32>(direction.x,-direction.z)/a.y;}}\n else{if(direction.z>=0.0){face=4u;uv=vec2<f32>(direction.x,-direction.y)/a.z;}else{face=5u;uv=vec2<f32>(-direction.x,-direction.y)/a.z;}}\n return vec3<f32>(uv*0.5+0.5,f32(index*6u+face));\n}\nfn directionalVisibility(index:u32,p:vec3<f32>)->f32 { let sp=rendererLights.directionalShadowParams[index]; if(sp.y<0.5){return 1.0;} return projectedShadow(rendererLights.directionalShadowMatrices[index],p,i32(index),sp.x,rendererLights.directionalShadowParams2[index].y,0u); }\nfn pointVisibility(index:u32,p:vec3<f32>)->f32 { let sp=rendererLights.pointShadowParams[index]; if(sp.y<0.5){return 1.0;} let delta=p-rendererLights.pointPositionRanges[index].xyz; let range=rendererLights.pointPositionRanges[index].w; let uv=pointShadowUvLayer(delta,index); let dims=vec2<f32>(textureDimensions(pointShadows)); let angle=select(0.0,hash12(p.xy+vec2<f32>(uniforms.ambient.w,f32(index)))*6.2831853,uniforms.ambient.w>0.0); var visible=0.0; for(var tap=0;tap<SHADOW_TAPS;tap+=1){let suv=clamp(uv.xy+rotatedOffset(tap,angle)/dims,vec2<f32>(0.0),vec2<f32>(1.0));let pixel=vec2<i32>(clamp(suv*dims,vec2<f32>(0.0),dims-1.0));let stored=textureLoad(pointShadows,pixel,i32(round(uv.z)),0).r;visible+=select(0.0,1.0,length(delta)/max(range,0.0001)-sp.x<=stored);} visible/=f32(SHADOW_TAPS); return mix(1.0,visible,rendererLights.pointShadowParams2[index].y); }\nfn spotVisibility(index:u32,p:vec3<f32>)->f32 { let sp=rendererLights.spotShadowParams[index]; if(sp.y<0.5){return 1.0;} return projectedShadow(rendererLights.spotShadowMatrices[index],p,i32(index),sp.x,rendererLights.spotShadowParams2[index].y,1u); }\nfn fogPointVisibility(light:FogLight,p:vec3<f32>)->f32 { if(light.penumbra.z<0.5){return 1.0;} return pointVisibility(u32(round(light.penumbra.y)),p); }\nfn fogSpotVisibility(light:FogLight,p:vec3<f32>)->f32 { if(light.penumbra.z<0.5){return 1.0;} return spotVisibility(u32(round(light.penumbra.y)),p); }\nfn fogSpotMap(light:FogLight,p:vec3<f32>)->vec3<f32> { let index=u32(round(light.penumbra.y)); if(rendererLights.spotParams[index].w<0.5){return vec3<f32>(1.0);} let clip=rendererLights.spotShadowMatrices[index]*vec4<f32>(p,1.0); if(clip.w<=0.0){return vec3<f32>(1.0);} let ndc=clip.xyz/clip.w; if(any(ndc<vec3<f32>(-1.0,-1.0,0.0))||any(ndc>vec3<f32>(1.0))){return vec3<f32>(1.0);} let uv=ndc.xy*vec2<f32>(0.5,-0.5)+vec2<f32>(0.5);let cell=vec2<f32>(f32(index%8u),f32(index/8u));let cellUv=clamp(uv,vec2<f32>(0.0),vec2<f32>(1.0))*(255.0/256.0)+vec2<f32>(0.5/256.0);return textureSampleLevel(spotLightMapAtlas,historySampler,(cell+cellUv)/8.0,0.0).rgb; }\nfn sceneDistanceAt(pixel:vec2<u32>)->f32{\n let size=textureDimensions(sceneDepth);let clamped=min(pixel,size-vec2<u32>(1u));let depth=textureLoad(sceneDepth,vec2<i32>(clamped),0);\n let uv=(vec2<f32>(clamped)+vec2<f32>(0.5))/vec2<f32>(size);let world4=uniforms.inverseViewProjection*vec4<f32>(uv.x*2.0-1.0,1.0-uv.y*2.0,depth,1.0);\n return length(world4.xyz/world4.w-uniforms.cameraNear.xyz);\n}\n@compute @workgroup_size(8,8,1)\nfn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let dims = vec3<u32>(uniforms.dimensionsFar.xyz); if (id.x >= dims.x || id.y >= dims.y) { return; }\n // Keep the froxel lattice fixed. Moving the complete XY grid with a Halton\n // offset makes high-contrast shaft boundaries alternate between adjacent\n // froxels, which reads as the entire shadow edge blinking. We still use a\n // temporal Z offset to integrate within-slice variation over time without\n // moving the grid or the shadow-classification position sideways.\n let frameIndex=u32(max(uniforms.ambient.w,1.0));\n let temporal=vec2<f32>(0.5);\n let rayJitter=select(hash12(vec2<f32>(id.xy)+vec2<f32>(17.17,43.43)),halton(frameIndex,5u),uniforms.ambient.w>0.0);\n let uv = (vec2<f32>(id.xy)+temporal)/vec2<f32>(dims.xy);\n let farPoint4 = uniforms.inverseViewProjection * vec4<f32>(uv.x*2.0-1.0, 1.0-uv.y*2.0, 1.0, 1.0);\n let camera = uniforms.cameraNear.xyz; let ray = normalize(farPoint4.xyz/farPoint4.w-camera);\n let centerUv=(vec2<f32>(id.xy)+vec2<f32>(0.5))/vec2<f32>(dims.xy);\n let centerFarPoint4=uniforms.inverseViewProjection*vec4<f32>(centerUv.x*2.0-1.0,1.0-centerUv.y*2.0,1.0,1.0);\n let centerRay=normalize(centerFarPoint4.xyz/centerFarPoint4.w-camera);\n let nearPlane = uniforms.cameraNear.w; let farPlane = uniforms.dimensionsFar.w;\n var columnNear=farPlane;\n for(var volumeIndex=0u;volumeIndex<uniforms.counts.x;volumeIndex+=1u){columnNear=min(columnNear,max(volumes[volumeIndex].heightStartPhase.z,nearPlane));}\n columnNear=min(columnNear,farPlane);let columnFar=max(farPlane,columnNear+0.001);textureStore(outputDepthBounds,vec2<i32>(id.xy),vec4<f32>(columnNear,columnFar,0.0,0.0));\n let sliceRatio=pow(columnFar/columnNear,1.0/f32(dims.z));\n var transmittance = 1.0; var scattering = vec3<f32>(0.0); var previousDistance = columnNear; var sliceEnd=columnNear;\n for (var z=0u; z<dims.z; z+=1u) {\n // Every column uses the same logarithmic Z coordinate, so XY filtering\n // blends cumulative fog evaluated at the same physical distance.\n sliceEnd*=sliceRatio; let stepSize = sliceEnd-previousDistance;\n var localScattering=vec3<f32>(0.0);var localExtinction=0.0;\n if(stepSize>0.0){\n // Resizing recreates the 3D history. Use a few stratified samples only on\n // that first frame so the raw one-sample slice pattern is never exposed.\n let integrationSubsteps=max(INTEGRATION_SUBSTEPS,select(4u,INTEGRATION_SUBSTEPS,uniforms.historyCameraValid.w>0.5));\n let substepSize=stepSize/f32(integrationSubsteps);\n for(var substep=0u;substep<integrationSubsteps;substep+=1u){\n let sampleOffset=select(0.5,fract(rayJitter+f32(substep)/f32(integrationSubsteps)),uniforms.scattering.y>0.5);\n let sampleDistance=previousDistance+(f32(substep)+sampleOffset)*substepSize;\n let p = camera + ray*sampleDistance; var sigma = 0.0; var source = vec3<f32>(0.0);\n // Follow the temporally stratified Z sample so history integrates shadow\n // transitions within a slice. XY remains fixed, preventing the complete\n // edge from oscillating sideways between neighboring froxels.\n let shadowP=p;\n let csmCount=u32(round(rendererLights.lightCounts.w));let viewDepth=max(dot(shadowP-camera,uniforms.cameraForwardDepthRange.xyz),0.0);let normalizedViewDepth=viewDepth/uniforms.cameraForwardDepthRange.w;\n var filteredDirectionalVisibility=array<f32,4>(1.0,1.0,1.0,1.0);\n for(var d=0u;d<uniforms.counts.y;d+=1u){var cascadeWeight=1.0;if(d<csmCount){let range=rendererLights.csmCascadeRanges[d].xy;let isLast=d+1u==csmCount;cascadeWeight=select(0.0,1.0,normalizedViewDepth>=range.x&&(normalizedViewDepth<range.y||isLast));}filteredDirectionalVisibility[d]=directionalVisibility(d,shadowP)*cascadeWeight;}\n for (var v=0u; v<uniforms.counts.x; v+=1u) { let volume=volumes[v]; let localDistance=distance(p,volume.centerRadius.xyz);\n if (localDistance < volume.centerRadius.w && sampleDistance >= volume.heightStartPhase.z) {\n var density=volume.albedoDensity.w*exp(-volume.heightStartPhase.x*(p.y-volume.heightStartPhase.y)); density*=1.0-smoothstep(volume.centerRadius.w*0.8,volume.centerRadius.w,localDistance);\n let rendererAmbient=rendererLights.ambientColor.rgb*rendererLights.ambientColor.w;\n let hemisphereAmbient=(rendererLights.hemisphereSkyColorIntensity.rgb*rendererLights.hemisphereSkyColorIntensity.w+rendererLights.hemisphereGroundColorIntensity.rgb*rendererLights.hemisphereGroundColorIntensity.w)*0.5;\n let sceneAmbient=rendererAmbient+hemisphereAmbient;\n let ambient=select(uniforms.ambient.rgb,sceneAmbient,dot(sceneAmbient,sceneAmbient)>0.000001);\n var lighting=ambient*volume.emissiveAmbient.w+volume.emissiveAmbient.rgb; var direct=vec3<f32>(0.0); var shaftVisibility=0.0; var li=0u;\n for (var d=0u; d<uniforms.counts.y; d+=1u) {\n let l=lights[li]; li+=1u;\n shaftVisibility=max(shaftVisibility,filteredDirectionalVisibility[d]);\n direct += l.colorDecay.rgb*phaseHG(dot(ray,l.positionRange.xyz),volume.heightStartPhase.w)*filteredDirectionalVisibility[d];\n }\n for (var q=0u; q<uniforms.counts.z; q+=1u) { let l=lights[li]; li+=1u; let delta=l.positionRange.xyz-p; let dist=length(delta); direct += l.colorDecay.rgb*attenuation(dist,l.positionRange.w,l.colorDecay.w)*phaseHG(dot(ray,normalize(delta)),volume.heightStartPhase.w)*fogPointVisibility(l,p); }\n for (var s=0u; s<uniforms.counts.w; s+=1u) { let l=lights[li]; li+=1u; let delta=l.positionRange.xyz-p; let dist=length(delta); let cd=dot(normalize(-delta),l.directionCone.xyz); let cone=spotConeAttenuation(cd,l.directionCone.w,l.penumbra.x); direct += l.colorDecay.rgb*fogSpotMap(l,p)*attenuation(dist,l.positionRange.w,l.colorDecay.w)*cone*phaseHG(dot(ray,normalize(delta)),volume.heightStartPhase.w)*fogSpotVisibility(l,p); }\n direct*=uniforms.scattering.x;\n if (volume.mode.x < 0.5) { lighting += direct; } else { lighting = direct; }\n // Preserve fractional filtered visibility at shaft boundaries. A hard\n // threshold produces a temporally moving saw-tooth edge as jittered\n // froxels alternate between lit and shadowed. Direct lighting already\n // contains this visibility, while extinction must be scaled explicitly.\n if (volume.mode.x < 0.5) {\n sigma += density; source += lighting*volume.albedoDensity.rgb*density;\n } else {\n let visibleDensity=density*clamp(shaftVisibility,0.0,1.0);\n sigma += visibleDensity; source += lighting*volume.albedoDensity.rgb*density;\n }\n }\n }\n localScattering+=source/f32(integrationSubsteps);localExtinction+=sigma/f32(integrationSubsteps);\n }\n let historyPosition=camera+ray*(previousDistance+0.5*stepSize);\n let previousClip=uniforms.previousViewProjection*vec4<f32>(historyPosition,1.0);\n let previousUv=previousClip.xy/previousClip.w*vec2<f32>(0.5,-0.5)+vec2<f32>(0.5);\n let previousDistanceToCamera=length(historyPosition-uniforms.historyCameraValid.xyz);\n let previousNear=uniforms.historyNearFarWeight.x;let previousFar=uniforms.historyNearFarWeight.y;\n let previousZ=log(max(previousDistanceToCamera,previousNear)/previousNear)/max(log(previousFar/previousNear),0.0001);\n let validHistory=uniforms.historyCameraValid.w>0.5&&previousClip.w>0.0&&all(previousUv>=vec2<f32>(0.0))&&all(previousUv<=vec2<f32>(1.0))&&previousZ>=0.0&&previousZ<=1.0;\n if(validHistory){let history=textureSampleLevel(scatteringHistory,historySampler,vec3<f32>(previousUv,previousZ),0.0);let weight=uniforms.historyNearFarWeight.z;localScattering=mix(localScattering,history.rgb,weight);localExtinction=mix(localExtinction,history.a,weight);}\n }\n textureStore(outputScatteringHistory,vec3<i32>(i32(id.x),i32(id.y),i32(z)),vec4<f32>(localScattering,localExtinction));\n if(localExtinction>0.000001){let extinction=exp(-localExtinction*stepSize);scattering+=transmittance*localScattering*((1.0-extinction)/localExtinction);transmittance*=extinction;}\n textureStore(outputFog, vec3<i32>(i32(id.x),i32(id.y),i32(z)), vec4<f32>(scattering,transmittance)); previousDistance=sliceEnd;\n }\n}",ye="\nfn inverseProjection() -> mat4x4<f32> { return mat4x4<f32>(fullscreenUniforms[0],fullscreenUniforms[1],fullscreenUniforms[2],fullscreenUniforms[3]); }\nfn fogDither(pixel:vec2<f32>,frame:f32)->f32 { let p3=fract(vec3<f32>(pixel.xyx+frame*vec3<f32>(0.754877,0.569841,0.438289))*0.1031); let q=p3+dot(p3,p3.yzx+33.33); return fract((q.x+q.y)*q.z)-0.5; }\nfn sampleIntegratedFogRaw(uv:vec2<f32>,normalizedDepth:f32)->vec4<f32>{\n let slices=f32(textureDimensions(fogVolumeTexture).z);let slicePosition=clamp(normalizedDepth,0.0,1.0)*slices;\n let textureZ=clamp((slicePosition-0.5)/slices,0.0,1.0);let integrated=textureSampleLevel(fogVolumeTexture,fullscreenSampler,vec3<f32>(uv,textureZ),0.0);\n return mix(vec4<f32>(0.0,0.0,0.0,1.0),integrated,min(slicePosition,1.0));\n}\nfn sampleIntegratedFog(uv:vec2<f32>,normalizedDepth:f32)->vec4<f32>{return sampleIntegratedFogRaw(uv,normalizedDepth);}\n@fragment fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let pixel=vec2<i32>(input.position.xy); let color=textureLoad(sceneColorTexture,pixel,0); let depth=textureLoad(sceneDepthTexture,pixel,0);\n let clip=vec4<f32>(input.uv.x*2.0-1.0,1.0-input.uv.y*2.0,depth,1.0); let view=inverseProjection()*clip; let distance=length(view.xyz/view.w);\n let bounds=textureSampleLevel(fogBoundsTexture,fullscreenSampler,input.uv,0.0).rg;let z=clamp(log(max(distance,bounds.x)/bounds.x)/max(log(bounds.y/bounds.x),0.0001),0.0,1.0);\n let frame=fullscreenUniforms[4].z; let ditherStrength=fullscreenUniforms[4].w;\n let noise=fogDither(input.position.xy,max(frame,0.0));\n let fog=sampleIntegratedFog(input.uv,z);\n let fogAmount=clamp(1.0-fog.a,0.0,1.0); let dither=vec3<f32>(noise*(ditherStrength/255.0)*fogAmount);\n return vec4<f32>(max(vec3<f32>(0.0),fog.rgb+color.rgb*fog.a+dither),color.a);\n}",Se="\nfn inverseProjection() -> mat4x4<f32> { return mat4x4<f32>(fullscreenUniforms[0],fullscreenUniforms[1],fullscreenUniforms[2],fullscreenUniforms[3]); }\nfn fogDither(pixel:vec2<f32>,frame:f32)->f32 { let p3=fract(vec3<f32>(pixel.xyx+frame*vec3<f32>(0.754877,0.569841,0.438289))*0.1031); let q=p3+dot(p3,p3.yzx+33.33); return fract((q.x+q.y)*q.z)-0.5; }\nfn sampleIntegratedFogRaw(uv:vec2<f32>,normalizedDepth:f32)->vec4<f32>{\n let slices=f32(textureDimensions(fogVolumeTexture).z);let slicePosition=clamp(normalizedDepth,0.0,1.0)*slices;\n let textureZ=clamp((slicePosition-0.5)/slices,0.0,1.0);let integrated=textureSampleLevel(fogVolumeTexture,fullscreenSampler,vec3<f32>(uv,textureZ),0.0);\n return mix(vec4<f32>(0.0,0.0,0.0,1.0),integrated,min(slicePosition,1.0));\n}\nfn sampleIntegratedFog(uv:vec2<f32>,normalizedDepth:f32)->vec4<f32>{return sampleIntegratedFogRaw(uv,normalizedDepth);}\n@fragment fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let depthSize=vec2<i32>(textureDimensions(sceneDepthTexture)); let depthPixel=clamp(vec2<i32>(input.uv*vec2<f32>(depthSize)),vec2<i32>(0),depthSize-vec2<i32>(1));\n let depth=textureLoad(sceneDepthTexture,depthPixel,0); let clip=vec4<f32>(input.uv.x*2.0-1.0,1.0-input.uv.y*2.0,depth,1.0);\n let view=inverseProjection()*clip; let distance=length(view.xyz/view.w); let nearPlane=fullscreenUniforms[4].x; let farPlane=fullscreenUniforms[4].y;\n let bounds=textureSampleLevel(fogBoundsTexture,fullscreenSampler,input.uv,0.0).rg;let z=clamp(log(max(distance,bounds.x)/bounds.x)/max(log(bounds.y/bounds.x),0.0001),0.0,1.0);var fog=sampleIntegratedFog(input.uv,z);let frame=fullscreenUniforms[4].z; let noise=fogDither(input.position.xy,max(frame,0.0));\n fog=vec4<f32>(max(vec3<f32>(0.0),fog.rgb+vec3<f32>(noise*(fullscreenUniforms[4].w/255.0)*clamp(1.0-fog.a,0.0,1.0))),fog.a); return fog;\n}";var Ce="\nfn loadDepth(uv:vec2<f32>)->f32{let size=vec2<i32>(textureDimensions(sceneDepthTexture));let pixel=clamp(vec2<i32>(uv*vec2<f32>(size)),vec2<i32>(0),size-vec2<i32>(1));return textureLoad(sceneDepthTexture,pixel,0);}\n@fragment fn fsMain(input:FullscreenVertexOutput)->@location(0) vec4<f32>{\n let color=textureLoad(sceneColorTexture,vec2<i32>(input.position.xy),0);let fogSize=vec2<f32>(textureDimensions(fogInputTexture));let texel=1.0/fogSize;let grid=input.uv*fogSize-0.5;let base=(floor(grid)+0.5)*texel;\n let candidates=array<vec2<f32>,4>(base,base+vec2<f32>(texel.x,0.0),base+vec2<f32>(0.0,texel.y),base+texel);let centerDepth=loadDepth(input.uv);var bestUv=clamp(candidates[0],vec2<f32>(0.0),vec2<f32>(1.0));var bestDifference=abs(centerDepth-loadDepth(bestUv));var maxDifference=bestDifference;\n for(var i=1;i<4;i+=1){let uv=clamp(candidates[i],vec2<f32>(0.0),vec2<f32>(1.0));let difference=abs(centerDepth-loadDepth(uv));maxDifference=max(maxDifference,difference);if(difference<bestDifference){bestDifference=difference;bestUv=uv;}}\n let sampleUv=select(input.uv,bestUv,maxDifference>0.001);let fog=textureSampleLevel(fogInputTexture,fullscreenSampler,sampleUv,0.0);return vec4<f32>(fog.rgb+color.rgb*fog.a,color.a);\n}",Me="\n@fragment fn fsMain(input:FullscreenVertexOutput)->@location(0) vec4<f32>{\n let color=textureLoad(sceneColorTexture,vec2<i32>(input.position.xy),0);\n let fog=textureSampleLevel(fogInputTexture,fullscreenSampler,input.uv,0.0);\n return vec4<f32>(fog.rgb+color.rgb*fog.a,color.a);\n}";import{ByteType as Pe,DepthFormat as Be,DepthStencilFormat as De,FloatType as Te,HalfFloatType as Ie,IntType as Ve,RED_GREEN_RGTC2_Format as Ge,RED_RGTC1_Format as Le,RGBA_ASTC_10x10_Format as ze,RGBA_ASTC_10x5_Format as Re,RGBA_ASTC_10x6_Format as Ue,RGBA_ASTC_10x8_Format as Ae,RGBA_ASTC_12x10_Format as ke,RGBA_ASTC_12x12_Format as Fe,RGBA_ASTC_4x4_Format as $e,RGBA_ASTC_5x4_Format as Ee,RGBA_ASTC_5x5_Format as Oe,RGBA_ASTC_6x5_Format as _e,RGBA_ASTC_6x6_Format as je,RGBA_ASTC_8x5_Format as Ne,RGBA_ASTC_8x6_Format as We,RGBA_ASTC_8x8_Format as He,RGBA_BPTC_Format as qe,RGBA_ETC2_EAC_Format as Ke,RGBA_S3TC_DXT1_Format as Ze,RGBA_S3TC_DXT3_Format as Ye,RGBA_S3TC_DXT5_Format as Xe,RGBAFormat as Je,RGBAIntegerFormat as Qe,RGFormat as et,RGIntegerFormat as tt,RGB_ETC1_Format as rt,RGB_ETC2_Format as it,RGB_S3TC_DXT1_Format as nt,RGBFormat as at,RedFormat as st,RedIntegerFormat as ot,ShortType as lt,SIGNED_RED_GREEN_RGTC2_Format as ct,SIGNED_RED_RGTC1_Format as ut,SRGBColorSpace as dt,UnsignedByteType as ht,UnsignedInt248Type as pt,UnsignedInt5999Type as ft,UnsignedIntType as mt,UnsignedShortType as gt}from"three";function vt(e,t){const r=function(e){if(!0===e.isCubeTexture){const t=e.image,r=t?.[0],i=r?.image??r;return{width:i?.width??1,height:i?.height??1,depthOrArrayLayers:6}}const t=e.image;return{width:t?.width??1,height:t?.height??1,depthOrArrayLayers:t?.depth??1}}(e),i=bt(e,t),n=Pt(e),a=function(e){return"3d"===Mt(e)?"3d":"2d"}(e),s=yt(e,i,t),o=St(e,s),l=function(e){if(!0===e.isCompressedCubeTexture){const t=e.image;return Math.max(1,t?.[0]?.mipmaps?.length??1)}const t=e.mipmaps;return Math.max(1,t?.length??1)}(e);return{format:i,textureDimension:a,viewDimension:n,sampleType:s,samplerBindingType:o,wgslTextureType:Ct(n,s),wgslSamplerType:"comparison"===o?"sampler_comparison":"sampler",width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers,mipLevelCount:l,compressed:Bt(e)}}function xt(e,t){const r=vt(e,t);return[r.format,r.textureDimension,r.viewDimension,r.sampleType,r.samplerBindingType,r.width,r.height,r.depthOrArrayLayers,r.mipLevelCount].join(":")}function wt(e){const t=yt(e,bt(e,void 0,!1));return[Ct(Pt(e),t),"comparison"===St(e,t)?"sampler_comparison":"sampler"].join(":")}function bt(e,t,r=!0){const i=e.format,n=e.type,a=e.colorSpace===dt;let s=null;if(Bt(e))switch(i){case nt:case Ze:s=a?"bc1-rgba-unorm-srgb":"bc1-rgba-unorm";break;case Ye:s=a?"bc2-rgba-unorm-srgb":"bc2-rgba-unorm";break;case Xe:s=a?"bc3-rgba-unorm-srgb":"bc3-rgba-unorm";break;case Le:s="bc4-r-unorm";break;case ut:s="bc4-r-snorm";break;case Ge:s="bc5-rg-unorm";break;case ct:s="bc5-rg-snorm";break;case qe:s=a?"bc7-rgba-unorm-srgb":"bc7-rgba-unorm";break;case it:case rt:s=a?"etc2-rgb8unorm-srgb":"etc2-rgb8unorm";break;case Ke:s=a?"etc2-rgba8unorm-srgb":"etc2-rgba8unorm";break;case $e:s=a?"astc-4x4-unorm-srgb":"astc-4x4-unorm";break;case Ee:s=a?"astc-5x4-unorm-srgb":"astc-5x4-unorm";break;case Oe:s=a?"astc-5x5-unorm-srgb":"astc-5x5-unorm";break;case _e:s=a?"astc-6x5-unorm-srgb":"astc-6x5-unorm";break;case je:s=a?"astc-6x6-unorm-srgb":"astc-6x6-unorm";break;case Ne:s=a?"astc-8x5-unorm-srgb":"astc-8x5-unorm";break;case We:s=a?"astc-8x6-unorm-srgb":"astc-8x6-unorm";break;case He:s=a?"astc-8x8-unorm-srgb":"astc-8x8-unorm";break;case Re:s=a?"astc-10x5-unorm-srgb":"astc-10x5-unorm";break;case Ue:s=a?"astc-10x6-unorm-srgb":"astc-10x6-unorm";break;case Ae:s=a?"astc-10x8-unorm-srgb":"astc-10x8-unorm";break;case ze:s=a?"astc-10x10-unorm-srgb":"astc-10x10-unorm";break;case ke:s=a?"astc-12x10-unorm-srgb":"astc-12x10-unorm";break;case Fe:s=a?"astc-12x12-unorm-srgb":"astc-12x12-unorm";break;case Je:s=a?"rgba8unorm-srgb":"rgba8unorm"}else switch(i){case Je:switch(n){case Pe:s="rgba8snorm";break;case lt:s="rgba16sint";break;case gt:s="rgba16uint";break;case mt:s="rgba32uint";break;case Ve:s="rgba32sint";break;case ht:s=a?"rgba8unorm-srgb":"rgba8unorm";break;case Ie:s="rgba16float";break;case Te:s="rgba32float"}break;case at:switch(n){case ft:s="rgb9e5ufloat";break;case 35899:s="rg11b10ufloat"}break;case st:switch(n){case Pe:s="r8snorm";break;case lt:s="r16sint";break;case gt:s="r16uint";break;case mt:s="r32uint";break;case Ve:s="r32sint";break;case ht:s="r8unorm";break;case Ie:s="r16float";break;case Te:s="r32float"}break;case et:switch(n){case Pe:s="rg8snorm";break;case lt:s="rg16sint";break;case gt:s="rg16uint";break;case mt:s="rg32uint";break;case Ve:s="rg32sint";break;case ht:s="rg8unorm";break;case Ie:s="rg16float";break;case Te:s="rg32float"}break;case Be:switch(n){case gt:s="depth16unorm";break;case mt:s="depth24plus";break;case Te:s="depth32float"}break;case De:switch(n){case pt:s="depth24plus-stencil8";break;case Te:Dt("depth32float-stencil8",t,e,"DepthTexture with DepthStencilFormat + FloatType"),s="depth32float-stencil8"}break;case ot:switch(n){case Ve:s="r32sint";break;case mt:s="r32uint"}break;case tt:switch(n){case Ve:s="rg32sint";break;case mt:s="rg32uint"}break;case Qe:switch(n){case Ve:s="rgba32sint";break;case mt:s="rgba32uint"}}if(!s)throw new Error(`Texture format "${i}" with type "${n}" from "${e.constructor.name}" is not supported by this renderer yet.`);const o=function(e){if(e.startsWith("bc"))return"texture-compression-bc";if(e.startsWith("etc2")||e.startsWith("eac"))return"texture-compression-etc2";if(e.startsWith("astc"))return"texture-compression-astc";return null}(s);return o&&r&&Dt(o,t,e,`Texture format "${s}"`),s}function yt(e,t,r){if(!0===e.isDepthTexture)return"depth";if(t.endsWith("uint"))return"uint";if(t.endsWith("sint"))return"sint";if(!0===e.isDataTexture||!0===e.isDataArrayTexture||!0===e.isData3DTexture){if(e.type===Ve)return"sint";if(e.type===mt)return"uint";if(e.type===Te&&!Tt(r,"float32-filterable")&&("r32float"===t||"rg32float"===t||"rgba32float"===t))return"unfilterable-float"}return"float"}function St(e,t){const r=e.compareFunction;return"depth"===t&&null!=r?"comparison":"float"===t?"filtering":"non-filtering"}function Ct(e,t){if("depth"===t)switch(e){case"2d-array":return"texture_depth_2d_array";case"cube":return"texture_depth_cube";default:return"texture_depth_2d"}const r="uint"===t?"u32":"sint"===t?"i32":"f32";switch(e){case"2d-array":return`texture_2d_array<${r}>`;case"cube":return`texture_cube<${r}>`;case"3d":return`texture_3d<${r}>`;default:return`texture_2d<${r}>`}}function Mt(e){return!0===e.isCubeTexture?"cube":!0===e.isArrayTexture||!0===e.isDataArrayTexture||!0===e.isCompressedArrayTexture?"2d-array":!0===e.is3DTexture||!0===e.isData3DTexture?"3d":"2d"}function Pt(e){const t=Mt(e);return"cube"===t?"cube":"2d-array"===t?"2d-array":"3d"===t?"3d":"2d"}function Bt(e){return!0===e.isCompressedTexture||!0===e.isCompressedArrayTexture}function Dt(e,t,r,i){if(!Tt(t,e))throw new Error(`${i} for "${r.name||r.uuid}" requires the WebGPU feature "${e}", which is not enabled on this device.`)}function Tt(e,t){return!!e&&(e instanceof Set?e.has(t):"features"in e?e.features.has(t):e.has(t))}import{Color as It,Matrix3 as Vt,Matrix4 as Gt,Vector2 as Lt,Vector3 as zt,Vector4 as Rt}from"three";var Ut=new ArrayBuffer(8),At=new Float64Array(Ut),kt=new Uint32Array(Ut),Ft={f32:{alignment:4,size:4},i32:{alignment:4,size:4},u32:{alignment:4,size:4},"vec2<f32>":{alignment:8,size:8},"vec3<f32>":{alignment:16,size:12},"vec4<f32>":{alignment:16,size:16},"mat3x3<f32>":{alignment:16,size:48},"mat4x4<f32>":{alignment:16,size:64}};function $t(e,t){return Math.ceil(e/t)*t}function Et(e,t,r,i){const n="boolean"==typeof i?i?1:0:Number(i);"i32"!==r?"u32"!==r?e.setFloat32(t,n,!0):e.setUint32(t,n,!0):e.setInt32(t,n,!0)}function Ot(e,t,r,i){for(let n=0;n<i;n+=1)e[t+n]=_t(r,n,i)}function _t(e,t,r){if("number"==typeof e||"boolean"==typeof e)return 0===t?Number(e):0;if(Array.isArray(e))return e[t]??0;if(e instanceof Vt||e instanceof Gt)return e.elements[t]??0;if(e instanceof It)return 0===t?e.r:1===t?e.g:2===t?e.b:3===t&&r>=4?1:0;if(e instanceof Lt||e instanceof zt||e instanceof Rt){if(0===t)return e.x;if(1===t)return e.y;if(2===t&&(e instanceof zt||e instanceof Rt))return e.z;if(3===t&&e instanceof Rt)return e.w}return 0}function jt(e,t,r){for(let i=0;i<3;i+=1){const n=3*i,a=t+4*i;e[a+0]=_t(r,n+0,9),e[a+1]=_t(r,n+1,9),e[a+2]=_t(r,n+2,9),e[a+3]=0}}function Nt(e){let t=0;const r=[];for(const[i,n]of Object.entries(e)){const e=Ft[n.type];t=$t(t,e.alignment),r.push({name:i,offset:t,type:n.type}),t+=e.size}return{byteLength:$t(t,16),entries:r}}function Wt(e,t){const r=new ArrayBuffer(t.byteLength);return qt(e,t,new DataView(r),new Float32Array(r)),r}var Ht=class{constructor(e){this.layout=e,this.buffer=new ArrayBuffer(e.byteLength),this.view=new DataView(this.buffer),this.floats=new Float32Array(this.buffer)}layout;buffer;view;floats;update(e){return qt(e,this.layout,this.view,this.floats),this.buffer}};function qt(e,t,r,i){i.fill(0);for(const n of t.entries){const t=e[n.name],a=n.offset/4;switch(n.type){case"f32":case"i32":case"u32":Et(r,n.offset,n.type,t.value);break;case"vec2<f32>":Ot(i,a,t.value,2);break;case"vec3<f32>":Ot(i,a,t.value,3);break;case"vec4<f32>":Ot(i,a,t.value,4);break;case"mat3x3<f32>":jt(i,a,t.value);break;case"mat4x4<f32>":t.value instanceof Gt?i.set(t.value.elements,a):Ot(i,a,t.value,16)}}}function Kt(e,t){let r=Math.imul(e^t,16777619);return r^=r>>>13,r>>>0}function Zt(e,t){return At[0]=t,e=Kt(e,kt[0]??0),e=Kt(e,kt[1]??0)}function Yt(e,t,r){const i=function(e,t){return"number"==typeof e||"boolean"==typeof e?[Number(e)]:Array.isArray(e)?Array.from(e.slice(0,t)):e instanceof It?t>=4?[e.r,e.g,e.b,1]:[e.r,e.g,e.b]:e instanceof Lt?[e.x,e.y]:e instanceof zt?[e.x,e.y,e.z]:e instanceof Rt?[e.x,e.y,e.z,e.w]:e instanceof Vt||e instanceof Gt?Array.from(e.elements):[]}(t,r);e=Kt(e,i.length);for(let t=0;t<i.length;t+=1)e=Zt(e,i[t]??0);return e}var Xt="\nstruct FullscreenVertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) uv: vec2<f32>,\n};\n\n@vertex\nfn vsMain(@builtin(vertex_index) vertexIndex: u32) -> FullscreenVertexOutput {\n var output: FullscreenVertexOutput;\n let position = array<vec2<f32>, 3>(\n vec2(-1.0, -3.0),\n vec2(-1.0, 1.0),\n vec2(3.0, 1.0),\n );\n let clip = position[vertexIndex];\n output.position = vec4(clip, 0.0, 1.0);\n output.uv = clip * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n return output;\n}\n";function Jt(e,t,r,i){let n=e.execution;if(!n){const a=[];for(let e=0;e<t;e++)a.push({binding:e,resource:null});e.uniformBuffer&&a.push({binding:t,resource:{buffer:e.uniformBuffer}});const s=[];for(let e=0;e<r;e++)s.push({view:null,clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"});n={resources:[],entries:a,attachments:s,bindGroupDescriptor:{label:`${i}-bind-group`,layout:e.bindGroupLayout,entries:a},passDescriptor:{label:i,colorAttachments:s}},e.execution=n}return n.passDescriptor.label=i,n}var Qt=new WeakMap;function er(e){let t=Qt.get(e);return t||(t={outputFormats:[],inputDimensions:[]},Qt.set(e,t)),t}var tr=new WeakMap;function rr(e,t,r,i,n){let a=tr.get(e);a||tr.set(e,a=new Map);let s=a.get(t);s||(s={module:e.createShaderModule({label:r,code:t}),variants:new Map},a.set(t,s));let o=s.variants.get(i);return o||s.variants.set(i,o=n(s.module)),o}function ir(){return{children:new WeakMap}}function nr(e,t,r,i){let n=e;for(const e of t){let t=n.children.get(e);t||(t=ir(),n.children.set(e,t)),n=t}return n.bindGroup??=r.createBindGroup(i),n.bindGroup}var ar=new WeakMap,sr=new WeakMap;function or(e){return e?"string"==typeof e?[e]:Array.from(e):[]}function lr(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}var cr=class{constructor(e){this.context=e}context;sceneColor="sceneColor";mainDepth="mainDepth";postProcessColor="postProcessColor";createColorTarget(e,t={}){return this.context.defineColorTarget(e,t),e}createTextureTarget(e,t={}){return this.context.defineTextureTarget(e,t),e}addStandardScenePasses(e=this.sceneColor){this.context.addDirectionalShadowPass(),this.context.addPointShadowPass(),this.context.addSpotShadowPass(),this.context.addDepthPrepass(),this.context.addHiZPasses(),this.context.addVisibilityPass(),this.context.addOpaquePass(e),this.context.addHiZHistoryPass("OpaquePass"),this.context.addSceneTextureCopyPass(e),this.context.addLatePass(e)}addDirectionalShadowPass(){this.context.addDirectionalShadowPass()}addPointShadowPass(){this.context.addPointShadowPass()}addSpotShadowPass(){this.context.addSpotShadowPass()}addDepthPrepass(){this.context.addDepthPrepass()}addHiZPasses(){this.context.addHiZPasses()}addVisibilityPass(){this.context.addVisibilityPass()}addForwardPass(e=this.sceneColor){this.context.addForwardPass(e)}addOpaquePass(e=this.sceneColor){this.context.addOpaquePass(e)}addSceneTextureCopyPass(e=this.sceneColor,t){this.context.addSceneTextureCopyPass(e,t)}addLatePass(e=this.sceneColor){this.context.addLatePass(e)}addHiZHistoryPass(e="ForwardPass"){this.context.addHiZHistoryPass(e)}addMaterialPass(e={}){const t={name:e.name,outputs:e.outputs??this.sceneColor,drawStage:e.drawStage,loadColor:e.loadColor,clearColor:e.clearColor,loadDepth:e.loadDepth,objectFilter:e.objectFilter,overrideMaterial:e.overrideMaterial};this.context.addMaterialPass(t)}addPass(e){const t=e.inputs?Object.values(e.inputs):void 0,r=or(e.outputs),i={name:e.name,reads:t,writes:r.length>0?r:void 0,dependsOn:e.dependsOn,execute:e.execute};this.context.addCustomPass(i)}addFullscreenPass(e){const t=or(e.outputs),r=Object.entries(e.inputs),i=Object.entries(e.textures??{});for(const[t]of i)if(t in e.inputs)throw new Error(`Fullscreen pass "${e.name}" cannot use "${t}" as both an input and an external texture.`);const n=r.map(([,e])=>e===this.mainDepth?"depth":"color");this.addPass({name:e.name,inputs:e.inputs,outputs:t,execute:a=>{const{outputFormats:s,inputDimensions:o}=er(e);s.length=t.length;for(let e=0;e<t.length;e++)s[e]=a.getColorFormat(t[e]);const l=i.map(([,e])=>xt(e,a.device)).join("|");o.length=r.length;for(let t=0;t<r.length;t++)o[t]=e.inputDimensions?.[r[t][0]]??"2d";const c=`${s.join("|")}:${n.map((e,t)=>`${e}-${o[t]}`).join("|")}:${l}:${e.uniformBufferSize??0}`,u=c,d=function(e,t){let r=ar.get(e);r||(r=new WeakMap,ar.set(e,r));let i=r.get(t);return i||(i=new Map,r.set(t,i)),i}(e,a.device);let h=d.get(u);if(!h){const t=i.map(([,e])=>vt(e,a.device)),l=[Xt,"@group(0) @binding(0) var fullscreenSampler: sampler;",r.map(([e],t)=>`@group(0) @binding(${t+1}) var ${e}Texture: ${"depth"===n[t]?"texture_depth_2d":"3d"===o[t]?"texture_3d<f32>":"texture_2d<f32>"};`).join("\n"),i.map(([e],i)=>{const n=r.length+1+2*i,a=t[i];return`@group(0) @binding(${n}) var ${e}Sampler: ${a.wgslSamplerType};\n@group(0) @binding(${n+1}) var ${e}Texture: ${a.wgslTextureType};`}).join("\n"),e.uniformBufferSize?`@group(0) @binding(${r.length+1+2*i.length}) var<uniform> fullscreenUniforms: array<vec4<f32>, ${Math.max(1,Math.ceil(e.uniformBufferSize/16))}>;`:"",e.fragmentShader].filter(Boolean).join("\n\n"),p=`${c}:sampler=${"nearest"===e.sampler?"non-filtering":"filtering"}`,{bindGroupLayout:f,pipeline:m}=rr(a.device,l,`${e.name}-shader-module`,p,l=>{const c=a.device.createBindGroupLayout({label:`${e.name}-layout`,entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"nearest"===e.sampler?"non-filtering":"filtering"}},...r.map((e,t)=>({binding:t+1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth"===n[t]?"depth":"float",viewDimension:"3d"===o[t]?"3d":"2d"}})),...t.flatMap((e,t)=>{const i=r.length+1+2*t;return[{binding:i,visibility:GPUShaderStage.FRAGMENT,sampler:{type:e.samplerBindingType}},{binding:i+1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:e.sampleType,viewDimension:e.viewDimension}}]}),...e.uniformBufferSize?[{binding:r.length+1+2*i.length,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]:[]]}),u=a.device.createPipelineLayout({label:`${e.name}-pipeline-layout`,bindGroupLayouts:[c]});return{bindGroupLayout:c,pipeline:a.device.createRenderPipeline({label:`${e.name}-pipeline`,layout:u,vertex:{module:l,entryPoint:"vsMain"},fragment:{module:l,entryPoint:"fsMain",targets:s.map(e=>({format:e}))},primitive:{topology:"triangle-list"}})}});h={bindGroupLayout:f,pipeline:m,uniformBuffer:e.uniformBufferSize?a.device.createBuffer({label:`${e.name}-uniform-buffer`,size:16*Math.ceil(Math.max(16,e.uniformBufferSize)/16),usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}):null,bindGroupCache:ir()},d.set(u,h)}const{pipeline:p,uniformBuffer:f}=h,m=e.updateUniforms?.(a)??null;f&&m&&a.device.queue.writeBuffer(f,0,m.buffer,m.byteOffset,m.byteLength);const g=Jt(h,r.length+1+2*i.length,t.length,e.name),v=g.resources;v[0]="nearest"===e.sampler||"linear"!==e.sampler&&n.includes("depth")?a.nearestClampSampler:a.linearClampSampler;for(let e=0;e<r.length;e++)v[e+1]="depth"===n[e]?a.depthView:a.getColorView(r[e][1]);for(let e=0;e<i.length;e++){const t=a.getExternalTexture(i[e][1]),n=r.length+1+2*e;v[n]=t.sampler,v[n+1]=t.view}const x=r.length+1+2*i.length;for(let e=0;e<x;e++)g.entries[e].resource=v[e];f&&(v[x]=f);const w=nr(h.bindGroupCache,v,a.device,g.bindGroupDescriptor);for(let e=0;e<t.length;e++)g.attachments[e].view=a.getColorView(t[e]);const b=a.encoder.beginRenderPass(g.passDescriptor);b.setPipeline(p),b.setBindGroup(0,w),b.draw(3),b.end()}})}addNodeFullscreenPass(e){const t=or(e.outputs),i=Object.entries(function(e){const t={};for(const[r,i]of Object.entries(e.sceneTextures??{}))t[r]="sceneDepth"===i?{resource:"mainDepth",dimension:"depth-2d",sampleType:"depth",sampler:"non-filtering"}:{resource:"sceneColor",dimension:"2d",sampleType:"float",sampler:"filtering"};return{...t,...e.graphTextures}}(e.shader)).map(([t,r])=>[t,null!=e.inputOverrides?.[t]?{...r,resource:e.inputOverrides[t]}:r]),n=Object.entries(e.shader.textures??{}),a=Object.fromEntries(i.map(([e,t])=>[e,t.resource])),s=Nt(e.shader.uniforms);this.addPass({name:e.name,inputs:a,outputs:t,execute:a=>{const{outputFormats:o}=er(e);o.length=t.length;for(let e=0;e<t.length;e++)o[e]=a.getColorFormat(t[e]);const l=i.map(([e,t])=>`${e}:${t.dimension}:${t.sampleType}:${t.sampler??"filtering"}`).join("|"),c=n.map(([,e])=>xt(e,a.device)).join("|"),u=s.entries.map(e=>`${e.name}:${e.type}:${e.offset}`).join("|"),d=`${o.join("|")}:${l}:${c}:${u}`,h=function(e,t){let r=sr.get(e);r||(r=new WeakMap,sr.set(e,r));let i=r.get(t);return i||(i=new Map,r.set(t,i)),i}(e.shader,a.device);let p=h.get(d);if(!p){const t=n.map(([,e])=>vt(e,a.device)),l=[];for(const[,e]of i){const t=l.length;l.push({binding:t,visibility:GPUShaderStage.FRAGMENT,sampler:{type:e.sampler??("depth-2d"===e.dimension?"non-filtering":"filtering")}},{binding:t+1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:e.sampleType??("depth-2d"===e.dimension?"depth":"float"),viewDimension:"3d"===e.dimension?"3d":"2d"}})}for(const[e,r]of t.entries()){const e=l.length;l.push({binding:e,visibility:GPUShaderStage.FRAGMENT,sampler:{type:r.samplerBindingType}},{binding:e+1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:r.sampleType,viewDimension:r.viewDimension}})}const c=2*(i.length+n.length);s.byteLength>0&&l.push({binding:c,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}});const u=i.map(([e,t],r)=>{const i=lr(e);return`@group(0) @binding(${2*r}) var ${i}Sampler: ${"comparison"===t.sampler?"sampler_comparison":"sampler"};\n@group(0) @binding(${2*r+1}) var ${i}Texture: ${"depth-2d"===t.dimension?"texture_depth_2d":"3d"===t.dimension?"texture_3d<f32>":"texture_2d<f32>"};`}).join("\n"),f=n.map(([e],r)=>{const n=2*(i.length+r),a=t[r],s=lr(e);return`@group(0) @binding(${n}) var ${s}Sampler: ${a.wgslSamplerType};\n@group(0) @binding(${n+1}) var ${s}Texture: ${a.wgslTextureType};`}).join("\n"),m=s.entries.map(e=>` ${lr(e.name)}: ${e.type},`).join("\n"),g=s.byteLength>0?`struct MaterialUniforms {\n${m}\n};\n@group(0) @binding(${c}) var<uniform> materialUniforms: MaterialUniforms;`:"",v=[Xt,u,f,g,e.shader.fragmentShader].filter(Boolean).join("\n\n"),x=JSON.stringify([o,l]),{bindGroupLayout:w,pipeline:b}=rr(a.device,v,`${e.name}-node-shader-module`,x,t=>{const i=a.device.createBindGroupLayout({label:`${e.name}-node-layout`,entries:l}),n=a.device.createPipelineLayout({label:`${e.name}-node-pipeline-layout`,bindGroupLayouts:[i]});e.diagnosticOrigin&&r(a.device,`${e.name}-node-pipeline`,e.diagnosticOrigin);return{bindGroupLayout:i,pipeline:a.device.createRenderPipeline({label:`${e.name}-node-pipeline`,layout:n,vertex:{module:t,entryPoint:"vsMain"},fragment:{module:t,entryPoint:"fsMain",targets:o.map(e=>({format:e}))},primitive:{topology:"triangle-list"}})}});p={bindGroupLayout:w,pipeline:b,uniformBuffer:s.byteLength>0?a.device.createBuffer({label:`${e.name}-node-uniforms`,size:s.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}):null,bindGroupCache:ir()},h.set(d,p)}const{pipeline:f,uniformBuffer:m}=p;e.shader.syncLiveUniforms(e.shader.uniforms),m&&a.device.queue.writeBuffer(m,0,(p.uniformData??=new Ht(s)).update(e.shader.uniforms));const g=2*(i.length+n.length),v=Jt(p,g,t.length,e.name),x=v.resources;for(let e=0;e<i.length;e++){const t=i[e][1];x[2*e]="comparison"===t.sampler?a.comparisonSampler:"non-filtering"===t.sampler||"depth-2d"===t.dimension?a.nearestClampSampler:a.linearClampSampler,x[2*e+1]=a.getTextureView(t.resource)}for(let e=0;e<n.length;e++){const t=a.getExternalTexture(n[e][1]),r=2*(i.length+e);x[r]=t.sampler,x[r+1]=t.view}for(let e=0;e<g;e++)v.entries[e].resource=x[e];m&&(x[g]=m);const w=nr(p.bindGroupCache,x,a.device,v.bindGroupDescriptor);for(let e=0;e<t.length;e++)v.attachments[e].view=a.getColorView(t[e]);const b=a.encoder.beginRenderPass(v.passDescriptor);b.setPipeline(f),b.setBindGroup(0,w),b.draw(3),b.end()}})}present(e=this.sceneColor){this.context.addPresentPass(e)}};import{AlwaysCompare as ur,BufferAttribute as dr,EqualCompare as hr,GreaterCompare as pr,GreaterEqualCompare as fr,InterleavedBufferAttribute as mr,LessCompare as gr,LessEqualCompare as vr,MirroredRepeatWrapping as xr,NearestFilter as wr,NearestMipmapLinearFilter as br,NearestMipmapNearestFilter as yr,NeverCompare as Sr,NotEqualCompare as Cr,Object3D as Mr,RepeatWrapping as Pr,Vector3 as Br}from"three";import{Material as Dr}from"three";var Tr=[{name:"position",shaderLocation:0,format:"float32x3"},{name:"normal",shaderLocation:1,format:"float32x3",defaultValue:[0,0,1]},{name:"uv",shaderLocation:2,format:"float32x2",defaultValue:[0,0]},{name:"color",shaderLocation:3,format:"float32x4",defaultValue:[1,1,1,1]}],Ir=class e extends Dr{isWGSLShaderMaterial=!0;vertexShader;fragmentShader;depthVertexShader;depthFragmentShader;pointShadowVertexShader;pointShadowFragmentShader;defines;uniforms;textures;sceneTextures;graphTextures;storageBuffers;vertexAttributes;primitiveTopology;wireframe;uniformLayoutCache=null;programCacheKeyCache=null;depthProgramCacheKeyCache=null;pointShadowProgramCacheKeyCache=null;textureListCache=null;textureVersionsCache=[];textureVersionHashCache=0;storageBufferBindingListCache=null;storageBufferListCache=null;textureLayoutKeyDeviceCache=null;textureLayoutKeyCache=null;uniformValuesAutoUpdate=!0;uniformValuesAutoVersion=0;set uniformValuesNeedsUpdate(e){e&&this.uniformValuesAutoVersion++}constructor(e){super();const{vertexShader:t,fragmentShader:r,depthVertexShader:i,depthFragmentShader:n,pointShadowVertexShader:a,pointShadowFragmentShader:s,defines:o,uniforms:l,textures:c,sceneTextures:u,graphTextures:d,storageBuffers:h,vertexAttributes:p,primitiveTopology:f,uniformValuesAutoUpdate:m,wireframe:g,...v}=e,x=function(e,t){const r={},i={...t};for(const[t,n]of Object.entries(e)){const e=zr(t,n);"texture"!==e.kind?r[t]=e.uniform:i[t]=e.texture}return{uniforms:r,textures:i}}(l??{},c??{});this.type="WGSLShaderMaterial",this.vertexShader=t,this.fragmentShader=r,this.depthVertexShader=i??null,this.depthFragmentShader=n??null,this.pointShadowVertexShader=a??null,this.pointShadowFragmentShader=s??null,this.defines={...o??{}},this.uniforms=x.uniforms,this.textures=x.textures,this.sceneTextures={...u??{}},this.graphTextures={...d??{}},this.storageBuffers={...h??{}},this.vertexAttributes=Gr(p??Tr),this.primitiveTopology=f??"triangle-list",this.uniformValuesAutoUpdate=m??!0,this.wireframe=g??!1,this.transparent=v.transparent??!1,this.depthTest=v.depthTest??!0,this.depthWrite=v.depthWrite??!0,this.setValues(v)}getUniformLayout(){return null===this.uniformLayoutCache&&(this.uniformLayoutCache=Nt(this.uniforms)),this.uniformLayoutCache}setUniform(e,t){const r=zr(e,t);return"texture"===r.kind?(delete this.uniforms[e],this.textures[e]=r.texture,this.uniformLayoutCache=null,this.invalidateBindingCache(),this.invalidateProgramStructureCache(),this.needsUpdate=!0,this):(delete this.textures[e],this.uniforms[e]=r.uniform,this.uniformLayoutCache=null,this.invalidateBindingCache(),this.invalidateProgramStructureCache(),this.needsUpdate=!0,this)}setDefine(e,t=!0){return this.defines[e]=t,this.invalidateProgramStructureCache(),this.needsUpdate=!0,this}deleteDefine(e){return delete this.defines[e],this.invalidateProgramStructureCache(),this.needsUpdate=!0,this}setTexture(e,t){return delete this.uniforms[e],this.textures[e]=t,this.uniformLayoutCache=null,this.invalidateBindingCache(),this.invalidateProgramStructureCache(),this.needsUpdate=!0,this}setStorageBuffer(e,t){return this.storageBuffers[e]=t,this.invalidateBindingCache(),this.invalidateProgramStructureCache(),this.needsUpdate=!0,this}setVertexAttributes(e){return this.vertexAttributes=Gr(e),this.invalidateProgramStructureCache(),this.needsUpdate=!0,this}copy(e){return super.copy(e),this.vertexShader=e.vertexShader,this.fragmentShader=e.fragmentShader,this.depthVertexShader=e.depthVertexShader,this.depthFragmentShader=e.depthFragmentShader,this.pointShadowVertexShader=e.pointShadowVertexShader,this.pointShadowFragmentShader=e.pointShadowFragmentShader,this.defines={...e.defines},this.uniforms=Object.fromEntries(Object.entries(e.uniforms).map(([e,t])=>[e,{type:t.type,value:Lr(t.value)}])),this.textures={...e.textures},this.sceneTextures={...e.sceneTextures},this.graphTextures={...e.graphTextures},this.storageBuffers={...e.storageBuffers},this.vertexAttributes=Gr(e.vertexAttributes),this.primitiveTopology=e.primitiveTopology,this.wireframe=e.wireframe,this.uniformValuesAutoUpdate=e.uniformValuesAutoUpdate,this.uniformValuesAutoVersion=e.uniformValuesAutoVersion,this.uniformLayoutCache=null,this.invalidateBindingCache(),this.invalidateProgramStructureCache(),this}clone(){return new e({vertexShader:this.vertexShader,fragmentShader:this.fragmentShader}).copy(this)}customProgramCacheKey(){return null!==this.programCacheKeyCache||(this.programCacheKeyCache=this.createProgramCacheKey(`vertex:${this.vertexShader};fragment:${this.fragmentShader};depthVertex:${this.depthVertexShader??""};depthFragment:${this.depthFragmentShader??""};pointShadowVertex:${this.pointShadowVertexShader??""};pointShadowFragment:${this.pointShadowFragmentShader??""};`)),this.programCacheKeyCache}getDepthProgramCacheKey(e=!1){const t=e?this.pointShadowProgramCacheKeyCache:this.depthProgramCacheKeyCache;if(null!==t)return t;const r=(e?this.pointShadowVertexShader:this.depthVertexShader)??this.vertexShader,i=e?this.pointShadowFragmentShader:this.depthFragmentShader,n=this.createProgramCacheKey(`vertex:${r};fragment:${i??""};`);return e?this.pointShadowProgramCacheKeyCache=n:this.depthProgramCacheKeyCache=n,n}createProgramCacheKey(e){const t=Object.keys(this.defines).sort((e,t)=>e.localeCompare(t));let r=e;for(const e of t)r+=`${e}:${String(this.defines[e])};`;for(const e in this.uniforms)r+=`uniform:${e}:${this.uniforms[e].type};`;for(const[e,t]of Object.entries(this.textures))r+=`texture:${e}:${wt(t)};`;for(const[e,t]of Object.entries(this.sceneTextures))r+=`sceneTexture:${e}:${t};`;for(const[e,t]of Object.entries(this.getGraphTextureInputs()))r+=`graphTexture:${e}:${t.resource}:${t.dimension}:${t.sampleType??"float"}:${t.sampler??"filtering"}:${Number(t.requiresLatePass??!1)};`;for(const[e,t]of Object.entries(this.storageBuffers))r+=`storage:${e}:${t.type}:${t.visibility??"fragment"};`;for(const e of this.vertexAttributes){const t=e.defaultValue?e.defaultValue.join(","):"";r+=`attribute:${e.name}:${e.shaderLocation}:${e.format}:${e.stepMode??"vertex"}:${t};`}return r+=`topology:${this.primitiveTopology};wireframe:${Number(this.wireframe)};transparent:${Number(this.transparent)};blending:${this.blending};premultipliedAlpha:${Number(this.premultipliedAlpha)};blendSrc:${this.blendSrc};blendDst:${this.blendDst};blendEquation:${this.blendEquation};blendSrcAlpha:${this.blendSrcAlpha};blendDstAlpha:${this.blendDstAlpha};blendEquationAlpha:${this.blendEquationAlpha};depthWrite:${Number(this.depthWrite)};depthTest:${Number(this.depthTest)};side:${String(this.side)};shadowSide:${String(this.shadowSide)};`,r}getTexturesList(){return null===this.textureListCache&&(this.textureListCache=Object.values(this.textures)),this.textureListCache}usesSceneTextures(){return this.usesSceneColor()||this.usesSceneDepth()}usesSceneColor(){return Object.values(this.sceneTextures).includes("sceneColor")||Object.values(this.graphTextures).some(e=>"sceneColorSnapshot"===e.resource)}usesSceneDepth(){return Object.values(this.sceneTextures).includes("sceneDepth")||Object.values(this.graphTextures).some(e=>"sceneDepthSnapshot"===e.resource)}getGraphTextureInputs(){const e={...this.graphTextures};for(const[t,r]of Object.entries(this.sceneTextures))e[t]="sceneDepth"===r?{resource:"sceneDepthSnapshot",dimension:"2d",sampleType:"unfilterable-float",sampler:"non-filtering",requiresLatePass:!0}:{resource:"sceneColorSnapshot",dimension:"2d",sampleType:"float",sampler:"filtering",requiresLatePass:!0};return e}requiresLatePass(){return Object.values(this.getGraphTextureInputs()).some(e=>!0===e.requiresLatePass)}getUniformValueHash(){return function(e,t){let r=2166136261;for(let i=0;i<t.entries.length;i+=1){const n=t.entries[i],a=e[n.name];if(a)switch(r=Kt(r,n.offset),n.type){case"f32":case"i32":case"u32":r=Zt(r,"boolean"==typeof a.value?a.value?1:0:Number(a.value));break;case"vec2<f32>":r=Yt(r,a.value,2);break;case"vec3<f32>":r=Yt(r,a.value,3);break;case"vec4<f32>":r=Yt(r,a.value,4);break;case"mat3x3<f32>":r=Yt(r,a.value,9);break;case"mat4x4<f32>":r=Yt(r,a.value,16);break;default:r=Kt(r,i+17)}else r=Kt(r,i+1)}return r>>>0}(this.uniforms,this.getUniformLayout())}getTextureVersionsList(){const e=this.getTexturesList(),t=this.textureVersionsCache;t.length=e.length;let r=2166136261;for(let i=0;i<e.length;i+=1){const n=e[i].version;t[i]=n,r=Math.imul((r^n)>>>0,16777619)>>>0}return this.textureVersionHashCache=r,t}getTextureVersionHash(){return this.getTextureVersionsList(),this.textureVersionHashCache}getStorageBufferBindingList(){return null===this.storageBufferBindingListCache&&(this.storageBufferBindingListCache=Object.values(this.storageBuffers)),this.storageBufferBindingListCache}getStorageBufferList(){if(null===this.storageBufferListCache){const e=this.getStorageBufferBindingList();this.storageBufferListCache=e.map(e=>e.buffer)}return this.storageBufferListCache}getTextureLayoutKey(e){return null!==this.textureLayoutKeyCache&&this.textureLayoutKeyDeviceCache===e||(this.textureLayoutKeyDeviceCache=e,this.textureLayoutKeyCache=this.getTexturesList().map(t=>function(e,t){const r=vt(e,t);return[r.viewDimension,r.sampleType,r.samplerBindingType].join(":")}(t,e)).join("|")),this.textureLayoutKeyCache}invalidateProgramStructureCache(){this.programCacheKeyCache=null,this.depthProgramCacheKeyCache=null,this.pointShadowProgramCacheKeyCache=null}invalidateBindingCache(){this.textureListCache=null,this.textureVersionsCache.length=0,this.textureVersionHashCache=0,this.storageBufferBindingListCache=null,this.storageBufferListCache=null,this.textureLayoutKeyDeviceCache=null,this.textureLayoutKeyCache=null}};function Vr(e){return!0===e.isWGSLShaderMaterial}function Gr(e){return e.map(e=>({name:e.name,shaderLocation:e.shaderLocation,format:e.format,stepMode:e.stepMode,defaultValue:e.defaultValue?Array.from(e.defaultValue):void 0}))}function Lr(e){return Array.isArray(e)?Array.from(e):"number"==typeof e||"boolean"==typeof e?e:e.clone()}function zr(e,t){const r=Ur(t)?t:null,i=null!==r&&"value"in r?r.value:t;if(function(e){return Rr(e,"isTexture")}(i))return{kind:"texture",texture:i};if(!function(e){return"number"==typeof e||"boolean"==typeof e||Array.isArray(e)||Rr(e,"isColor")||Rr(e,"isVector2")||Rr(e,"isVector3")||Rr(e,"isVector4")||Rr(e,"isMatrix3")||Rr(e,"isMatrix4")}(i))throw new Error(`Unsupported WGSLShaderMaterial uniform "${e}". Use a number, boolean, vector, color, matrix, numeric array, or Texture.`);const n=r?.type,a=function(e){return"f32"===e||"i32"===e||"u32"===e||"vec2<f32>"===e||"vec3<f32>"===e||"vec4<f32>"===e||"mat3x3<f32>"===e||"mat4x4<f32>"===e}(n)?n:function(e,t){if("number"==typeof t)return"f32";if("boolean"==typeof t)return"u32";if(Array.isArray(t)){if(t.length<=1)return"f32";if(2===t.length)return"vec2<f32>";if(3===t.length)return"vec3<f32>";if(4===t.length)return"vec4<f32>";if(9===t.length)return"mat3x3<f32>";if(16===t.length)return"mat4x4<f32>";throw new Error(`Cannot infer WGSL type for uniform "${e}" from an array of length ${t.length}. Provide an explicit type.`)}if(Rr(t,"isColor"))return"vec3<f32>";if(Rr(t,"isVector2"))return"vec2<f32>";if(Rr(t,"isVector3"))return"vec3<f32>";if(Rr(t,"isVector4"))return"vec4<f32>";if(Rr(t,"isMatrix3"))return"mat3x3<f32>";if(Rr(t,"isMatrix4"))return"mat4x4<f32>";throw new Error(`Cannot infer WGSL type for uniform "${e}". Provide an explicit type.`)}(e,i);return{kind:"uniform",uniform:{type:a,value:i}}}function Rr(e,t){return Ur(e)&&!0===e[t]}function Ur(e){return"object"==typeof e&&null!==e}var Ar=new WeakMap,kr=1;function Fr(e){return e?"version"in e?e.version:e.data.version:0}function $r(e){const t=Object.keys(e.attributes).sort().map(t=>{const r=e.getAttribute(t);return[t,Fr(r),r?.itemSize??0,r?.count??0].join(":")}).join("|"),r=e.index?.version??0,i=e.groups.map(e=>`${e.start}:${e.count}:${e.materialIndex??0}`).join("|");return[t,r,e.drawRange.start,e.drawRange.count,i].join(";")}function Er(e){switch(e){case"float32":case"uint32":case"sint32":return 1;case"float32x2":case"uint32x2":case"sint32x2":return 2;case"float32x3":case"uint32x3":case"sint32x3":return 3;default:return 4}}function Or(e){return e.startsWith("uint32")?"uint32":e.startsWith("sint32")?"sint32":"float32"}function _r(e,t){switch(t){case"uint32":return new Uint32Array(e);case"sint32":return new Int32Array(e);default:return new Float32Array(e)}}function jr(e,t,r,i){switch(r){case"uint32":e[t]=Math.max(0,Math.round(i));break;case"sint32":e[t]=Math.trunc(i);break;default:e[t]=i}}function Nr(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r+=1)if(e[r]!==t[r])return!1;return!0}function Wr(e,t,r,i){const n=Math.max(4,t.byteLength),a=e.createBuffer({label:i,size:4*Math.ceil(n/4),usage:r,mappedAtCreation:!0});return new Uint8Array(a.getMappedRange()).set(new Uint8Array(t.buffer,t.byteOffset,t.byteLength)),a.unmap(),a}function Hr(e){switch(e){case"vertex":return GPUShaderStage.VERTEX;case"vertex-fragment":return GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT;default:return GPUShaderStage.FRAGMENT}}function qr(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r+=1)if(e[r]!==t[r])return!1;return!0}function Kr(e,t){if(!e)return!1;if(e.length!==t.length)return!1;for(let r=0;r<e.length;r+=1)if(e[r]!==t[r])return!1;return!0}function Zr(e,t,r){try{return e.beginComputePass({timestampWrites:{querySet:t,...r}}).end(),!0}catch{return!1}}function Yr(e,t,r,i){if(e instanceof dr&&!e.normalized&&e.itemSize===r&&e.count===t&&e.array instanceof Float32Array)return e.array;const n=new Float32Array(t*r);if(!e){for(let e=0;e<t;e+=1)n.set(i,e*r);return n}for(let a=0;a<t;a+=1){for(let t=0;t<r;t+=1)t<e.itemSize?n[a*r+t]=e.getComponent(a,t):n[a*r+t]=i[t]??0;3===e.itemSize&&4===r&&(n[a*r+3]=i[3]??1)}return n}function Xr(e,t,r,i,n=0,a){const s=Er(r),o=Or(r);if(!e)return function(e,t,r,i,n,a){const s=_r(r*i,a);for(let o=0;o<r;o+=1){const r=o*t,l=o*i;for(let o=0;o<i;o+=1)jr(s,l+o,a,e&&o<t?e[r+o]??n[o]??0:n[o]??0)}return s}(void 0,0,t,s,i,o);if(0===n&&e instanceof dr&&!e.normalized&&e.itemSize===s&&e.count===t){const t=e.array;if("float32"===o&&t instanceof Float32Array||"uint32"===o&&t instanceof Uint32Array||"sint32"===o&&t instanceof Int32Array)return t}const l=t*s,c=a?.length===l&&("float32"===o?a instanceof Float32Array:"uint32"===o?a instanceof Uint32Array:a instanceof Int32Array)?a:_r(l,o);if("float32"===o&&!e.normalized&&(e instanceof dr?e.getComponent===dr.prototype.getComponent:e.getComponent===mr.prototype.getComponent)){const r=e instanceof mr,a=r?e.data.array:e.array,o=r?e.data.stride:e.itemSize,l=r?e.offset:0,u=Math.min(s,e.itemSize);for(let r=0;r<t;r++){const t=r*s,d=r-n,h=d>=0&&d<e.count,p=d*o+l;for(let e=0;e<s;e++)c[t+e]=h&&e<u?a[p+e]:i[e]??0}return c}for(let r=0;r<t;r+=1){const t=r*s,a=r-n,l=a>=0&&a<e.count;for(let r=0;r<s;r+=1){jr(c,t+r,o,l&&r<e.itemSize?e.getComponent(a,r):i[r]??0)}}return c}function Jr(e,t,r,i){return Number.isFinite(i)&&i>0?i:t?Math.max(0,(e.index?.count??0)-r):Math.max(0,e.getAttribute("position").count-r)}function Qr(e,t){return{start:e.drawRange.start,count:Jr(e,t,e.drawRange.start,e.drawRange.count)}}function ei(e){return e===Pr?"repeat":e===xr?"mirror-repeat":"clamp-to-edge"}function ti(e){return e===wr||e===yr||e===br?"nearest":"linear"}function ri(e){return"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement||"undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement||"undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap||"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas||"undefined"!=typeof HTMLVideoElement&&e instanceof HTMLVideoElement?e:null}function ii(e){return e}function ni(e,t,r,i,n,a,s,o,l,c,u){return e.appendMatrixAndColorValues(t,r,i,n,a,s,o,l,c,u)}function ai(e,t,r,i,n,a,s,o,l,c,u){return e.appendMatrixAndColorValues(t.elements,r,i,n,a,s,o,l,c,u)}function si(e,t,r){const i=e.elements;for(let e=0;e<16;e+=1)i[e]=t[r+e]??0;return e}function oi(e){const t=Ar.get(e);if(void 0!==t)return t;const r=kr+=1;return Ar.set(e,r),r}function li(e,t,r,i,n,a){return[oi(e),oi(t),r?1:0,i,n,a?oi(a):0].join(":")}function ci(e,t,r,i,n,a){let s=2166136261;return s=pi(s,e),s=pi(s,t),s=pi(s,r?1:0),s=pi(s,i),s=pi(s,n),s=pi(s,a),s}function ui(e,t){return e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:(r=e.sortMaterialId,i=e.sortGeometryId,n=e.indexed,a=e.start,s=e.count,o=e.sortCustomDepthMaterialId,l=t.sortMaterialId,c=t.sortGeometryId,u=t.indexed,d=t.start,h=t.count,p=t.sortCustomDepthMaterialId,r!==l?r-l:i!==c?i-c:n!==u?n?-1:1:a!==d?a-d:s!==h?s-h:o-p);var r,i,n,a,s,o,l,c,u,d,h,p}function di(e,t){return e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:0!==e.transparentSortGroup&&e.transparentSortGroup===t.transparentSortGroup&&e.transparentSortOrder!==t.transparentSortOrder?e.transparentSortOrder-t.transparentSortOrder:e.sortDepth!==t.sortDepth?t.sortDepth-e.sortDepth:ui(e,t)}function hi(e){for(let t=0;t<e.length;t+=1)if(e[t].hasRenderCallbacks)return!0;return!1}function pi(e,t){let r=Math.imul((e^t)>>>0,16777619);return r^=r>>>13,r>>>0}function fi(e,t){return e.cameraDetailRejected===t.cameraDetailRejected&&e.detailCulling?.minScreenSize===t.detailCulling?.minScreenSize&&e.detailCulling?.maxDistance===t.detailCulling?.maxDistance&&e.detailCulling?.shadowMinScreenSize===t.detailCulling?.shadowMinScreenSize&&e.detailCulling?.shadowMaxDistance===t.detailCulling?.shadowMaxDistance&&e.renderOrder===t.renderOrder&&!e.hasRenderCallbacks&&!t.hasRenderCallbacks&&e.castShadow===t.castShadow&&e.receiveShadow===t.receiveShadow&&gi(e)===gi(t)&&e.usesBatching===t.usesBatching&&e.sortMaterialId===t.sortMaterialId&&e.sortGeometryId===t.sortGeometryId&&e.indexed===t.indexed&&e.start===t.start&&e.count===t.count&&e.sortCustomDepthMaterialId===t.sortCustomDepthMaterialId}function mi(e,t){return e.cameraDetailRejected===t.cameraDetailRejected&&e.detailCulling?.minScreenSize===t.detailCulling?.minScreenSize&&e.detailCulling?.maxDistance===t.detailCulling?.maxDistance&&e.detailCulling?.shadowMinScreenSize===t.detailCulling?.shadowMinScreenSize&&e.detailCulling?.shadowMaxDistance===t.detailCulling?.shadowMaxDistance&&e.renderOrder===t.renderOrder&&!e.hasRenderCallbacks&&!t.hasRenderCallbacks&&e.castShadow===t.castShadow&&e.receiveShadow===t.receiveShadow&&gi(e)===gi(t)&&e.usesBatching===t.usesBatching&&e.sortMaterialId===t.sortMaterialId&&e.sortGeometryId===t.sortGeometryId&&e.indexed===t.indexed&&e.start===t.start&&e.count===t.count&&e.sortCustomDepthMaterialId===t.sortCustomDepthMaterialId}function gi(e){return e.frontFaceCW}function vi(e,t){for(let r=0;r<16;r+=1)t[r]=e[r]??0}function xi(e,t){for(let r=0;r<16;r+=1)if((e[r]??0)!==(t[r]??0))return!1;return!0}function wi(e){return 1===(e[0]??0)&&0===(e[1]??0)&&0===(e[2]??0)&&0===(e[3]??0)&&0===(e[4]??0)&&1===(e[5]??0)&&0===(e[6]??0)&&0===(e[7]??0)&&0===(e[8]??0)&&0===(e[9]??0)&&1===(e[10]??0)&&0===(e[11]??0)&&0===(e[12]??0)&&0===(e[13]??0)&&0===(e[14]??0)&&1===(e[15]??0)}function bi(e,t,r,i){r.x<e.x&&(e.x=r.x),r.y<e.y&&(e.y=r.y),r.z<e.z&&(e.z=r.z),i.x>t.x&&(t.x=i.x),i.y>t.y&&(t.y=i.y),i.z>t.z&&(t.z=i.z)}function yi(e,t){return t.multiplyMatrices(A.multiplyMatrices(I,e.projectionMatrix),e.matrixWorldInverse)}function Si(e,t,r,i,n,a){const s=Math.hypot(r,i,n)||1;e[t+0]=r/s,e[t+1]=i/s,e[t+2]=n/s,e[t+3]=a/s}function Ci(e,t,r,i,n){const a=-n;for(let n=0;n<24;n+=4){if(e[n+0]*t+e[n+1]*r+e[n+2]*i+e[n+3]<a)return!1}return!0}function Mi(e){return null===e.boundingSphere&&e.computeBoundingSphere(),e.boundingSphere?{center:e.boundingSphere.center.clone(),radius:e.boundingSphere.radius}:{center:new Br,radius:1}}function Pi(e){const t=e.elements,r=Math.hypot(t[0],t[1],t[2]),i=Math.hypot(t[4],t[5],t[6]),n=Math.hypot(t[8],t[9],t[10]);return Math.max(r,i,n,1e-5)}function Bi(e,t,r,i,n,a,s){const o=r.elements,l=a.elements,c=e.x,u=e.y,d=e.z,h=o[0]*c+o[4]*u+o[8]*d+o[12],p=o[1]*c+o[5]*u+o[9]*d+o[13],f=o[2]*c+o[6]*u+o[10]*d+o[14],m=i[n]*h+i[n+4]*p+i[n+8]*f+i[n+12],g=i[n+1]*h+i[n+5]*p+i[n+9]*f+i[n+13],v=i[n+2]*h+i[n+6]*p+i[n+10]*f+i[n+14];s.set(l[0]*m+l[4]*g+l[8]*v+l[12],l[1]*m+l[5]*g+l[9]*v+l[13],l[2]*m+l[6]*g+l[10]*v+l[14]);const x=i[n],w=i[n+4],b=i[n+8],y=i[n+1],S=i[n+5],C=i[n+9],M=i[n+2],P=i[n+6],B=i[n+10],D=x*o[0]+w*o[1]+b*o[2],T=x*o[4]+w*o[5]+b*o[6],I=x*o[8]+w*o[9]+b*o[10],V=y*o[0]+S*o[1]+C*o[2],G=y*o[4]+S*o[5]+C*o[6],L=y*o[8]+S*o[9]+C*o[10],z=M*o[0]+P*o[1]+B*o[2],R=M*o[4]+P*o[5]+B*o[6],U=M*o[8]+P*o[9]+B*o[10],A=l[0]*D+l[4]*V+l[8]*z,k=l[0]*T+l[4]*G+l[8]*R,F=l[0]*I+l[4]*L+l[8]*U,$=l[1]*D+l[5]*V+l[9]*z,E=l[1]*T+l[5]*G+l[9]*R,O=l[1]*I+l[5]*L+l[9]*U,_=l[2]*D+l[6]*V+l[10]*z,j=l[2]*T+l[6]*G+l[10]*R,N=l[2]*I+l[6]*L+l[10]*U,W=Math.hypot(A,$,_),H=Math.hypot(k,E,j),q=Math.hypot(F,O,N);return t*Math.max(W,H,q,1e-5)}function Di(e,t,r,i){const n=r.x-i,a=r.y-i,s=r.z-i,o=r.x+i,l=r.y+i,c=r.z+i;n<e.x&&(e.x=n),a<e.y&&(e.y=a),s<e.z&&(e.z=s),o>t.x&&(t.x=o),l>t.y&&(t.y=l),c>t.z&&(t.z=c)}function Ti(e){return Math.floor(Math.max(0,e.count)/3)*Math.max(0,e.instanceCount)}function Ii(e){const t=e??1;if(!Number.isInteger(t)||t<1)throw new Error(`Renderer sampleCount must be a positive integer. Received: ${e}`);return t}function Vi(e){const t=e.customDepthMaterial;return t&&Vr(t)?t:null}var Gi=class{palettes=new WeakMap;dispose(){this.palettes=new WeakMap}update(e){const t=16*e.bones.length;if(e.boneInverses.length!==e.bones.length)throw new Error("Skeleton inverse-bind count does not match bones");let r=this.palettes.get(e);r&&r.values.length===t||(r={values:new Float32Array(t),published:null},this.palettes.set(e,r)),e.boneMatrices.length<t&&(e.boneMatrices=new Float32Array(t)),function(e,t=!0){const r=e.bones,i=e.boneInverses,n=e.boneMatrices;for(let e=0;e<r.length;e+=1){const t=r[e],a=t?.matrixWorld.elements,s=i[e].elements,o=16*e;if(!a){n.set(s,o);continue}const l=a[0],c=a[4],u=a[8],d=a[12],h=a[1],p=a[5],f=a[9],m=a[13],g=a[2],v=a[6],x=a[10],w=a[14],b=a[3],y=a[7],S=a[11],C=a[15],M=s[0],P=s[4],B=s[8],D=s[12],T=s[1],I=s[5],V=s[9],G=s[13],L=s[2],z=s[6],R=s[10],U=s[14],A=s[3],k=s[7],F=s[11],$=s[15];n[o]=l*M+c*T+u*L+d*A,n[o+4]=l*P+c*I+u*z+d*k,n[o+8]=l*B+c*V+u*R+d*F,n[o+12]=l*D+c*G+u*U+d*$,n[o+1]=h*M+p*T+f*L+m*A,n[o+5]=h*P+p*I+f*z+m*k,n[o+9]=h*B+p*V+f*R+m*F,n[o+13]=h*D+p*G+f*U+m*$,n[o+2]=g*M+v*T+x*L+w*A,n[o+6]=g*P+v*I+x*z+w*k,n[o+10]=g*B+v*V+x*R+w*F,n[o+14]=g*D+v*G+x*U+w*$,n[o+3]=b*M+y*T+S*L+C*A,n[o+7]=b*P+y*I+S*z+C*k,n[o+11]=b*B+y*V+S*R+C*F,n[o+15]=b*D+y*G+S*U+C*$}t&&null!==e.boneTexture&&(e.boneTexture.needsUpdate=!0)}(e,!1);let i=!1;for(let n=0;n<t;n++){const t=e.boneMatrices[n];r.values[n]!==t&&(i=!0),r.values[n]=t}return!i&&r.published===e.boneMatrices||null===e.boneTexture||(e.boneTexture.needsUpdate=!0),r.published=e.boneMatrices,i}},Li=class{data;lengthFloats=0;constructor(e=1024){this.data=new Float32Array(e)}get floatLength(){return this.lengthFloats}get rawData(){return this.data}get byteLength(){return this.lengthFloats*Float32Array.BYTES_PER_ELEMENT}get instanceCount(){return this.lengthFloats/C}reset(){this.lengthFloats=0}appendMatrixAndColor(e,t,r=e,i=2,n=1,a=0){return this.appendMatrixAndColorValues(e,t[0]??1,t[1]??1,t[2]??1,t[3]??1,void 0,r,i,n,a)}appendMatrixAndColorValues(e,t,r,i,n,a=this.instanceCount,s=e,o=2,l=1,c=0){const u=this.instanceCount;this.ensureCapacity(this.lengthFloats+C);const d=this.lengthFloats;for(let t=0;t<16;t+=1)this.data[d+t]=e[t]??0;this.data[d+16]=t,this.data[d+17]=r,this.data[d+18]=i,this.data[d+19]=n,this.data[d+20]=a,this.data[d+21]=o,this.data[d+22]=l,this.data[d+23]=c;for(let t=0;t<16;t+=1)this.data[d+24+t]=s[t]??e[t]??0;return this.lengthFloats+=C,u}appendRange(e,t,r){if(r<=0)return;const i=t*C,n=i+r*C;this.ensureCapacity(this.lengthFloats+(n-i)),this.data.set(e.data.subarray(i,n),this.lengthFloats),this.lengthFloats+=n-i}appendBuilder(e){this.appendRange(e,0,e.instanceCount)}beginWriteInstances(e){const t=e*C;return this.ensureCapacity(t),this.lengthFloats=t,this.data}toFloat32Array(){return this.data.slice(0,this.lengthFloats)}ensureCapacity(e){if(e<=this.data.length)return;let t=this.data.length;for(;t<e;)t*=2;const r=new Float32Array(t);r.set(this.data.subarray(0,this.lengthFloats),0),this.data=r}},zi=class{disposed=!1;cachedInstanceData=new Li;residentInstanceBinding={mode:"packed",buffer:null,colorBuffer:null,sceneBindGroup:null,shadowBindGroup:null,shadowBindGroups:new Map,sceneBindGroupVersion:0,shadowBindGroupVersion:0};residentBufferSize=0;residentColorBufferSize=0;residentBufferDirty=!1;residentColorBufferDirty=!1;count=-1;update(e,t,r,i,n,a){const s=this.cachedInstanceData.rawData;let o=e!==this.count||s[21]!==Math.fround(i)||s[22]!==Math.fround(n)||s[23]!==a;for(let e=0;!o&&e<16;e++)o=s[e]!==Math.fround(t[e])||s[24+e]!==Math.fround(r[e]);if(o){this.cachedInstanceData.reset();for(let s=0;s<e;s++)this.cachedInstanceData.appendMatrixAndColorValues(t,1,1,1,1,s,r,i,n,a);this.count=e,this.residentBufferDirty=!0}}dispose(){this.disposed=!0;const e=this.residentInstanceBinding;e.buffer?.destroy(),e.buffer=null,e.sceneBindGroup=null,e.shadowBindGroup=null,e.shadowBindGroups.clear(),this.residentBufferSize=0,this.count=-1}};import{BufferAttribute as Ri,InterleavedBufferAttribute as Ui}from"three";var Ai=class{constructor(e){this.attributes=e;let t=0;for(const r of e){this.offsets.push(t);const e=Er(r.format);this.components.push(e),this.kinds.push(Or(r.format)),t+=e}this.stride=t}attributes;sources=[];versions=[];counts=[];itemSizes=[];components=[];offsets=[];kinds=[];stride;count=-1;floats=new Float32Array(0);unsigned=new Uint32Array(0);signed=new Int32Array(0);data=new Uint8Array(0);update(e,t,r,i){const n="instance"===this.attributes[0].stepMode;let a=n?Math.max(1,i):t,s=this.count<0;for(let t=0;t<this.attributes.length;t++){const r=e.getAttribute(this.attributes[t].name),i=Fr(r);n&&(a=Math.max(a,r?.count??1)),s||=this.sources[t]!==r||this.versions[t]!==i||this.counts[t]!==(r?.count??0)||this.itemSizes[t]!==(r?.itemSize??0),this.sources[t]=r,this.versions[t]=i,this.counts[t]=r?.count??0,this.itemSizes[t]=r?.itemSize??0}if(n&&(a+=r),s||=this.count!==a,!s)return!1;this.count=a;const o=a*this.stride;if(this.floats.length<o){const e=new ArrayBuffer(4*o);this.floats=new Float32Array(e),this.unsigned=new Uint32Array(e),this.signed=new Int32Array(e)}this.data.buffer===this.floats.buffer&&this.data.byteLength===4*o||(this.data=new Uint8Array(this.floats.buffer,0,4*o));for(let e=0;e<this.attributes.length;e++){const t=this.sources[e],i=this.attributes[e],s=this.components[e],o=this.kinds[e],l="uint32"===o?this.unsigned:"sint32"===o?this.signed:this.floats,c=t instanceof Ui,u=t&&!t.normalized&&(c?t.getComponent===Ui.prototype.getComponent:t.getComponent===Ri.prototype.getComponent),d=t?c?t.data.array:t.array:void 0,h=t?c?t.data.stride:t.itemSize:0,p=c?t.offset:0;for(let c=0;c<a;c++){const a=c-(n?r:0),f=t&&a>=0&&a<t.count,m=c*this.stride+this.offsets[e];for(let e=0;e<s;e++){const r=f&&e<t.itemSize?u?d[a*h+p+e]:t.getComponent(a,e):i.defaultValue?.[e]??0;l[m+e]="uint32"===o?Math.max(0,Math.round(r)):"sint32"===o?Math.trunc(r):r}}}return!0}};import{Frustum as ki,Matrix4 as Fi,Vector3 as $i}from"three";import{Color as Ei,CompressedArrayTexture as Oi,Matrix3 as _i,Matrix4 as ji,Vector2 as Ni,Vector3 as Wi,Vector4 as Hi}from"three";import{Color as qi,Matrix3 as Ki,Matrix4 as Zi}from"three";function Yi(e){return!0===e.isWgslCompiler}function Xi(e){return!0===e.isWgslFragmentCompiler}function Ji(e){return e instanceof ln?e:new cn(e)}function Qi(e){return e instanceof pn||e instanceof Mn?new Rn(e):e instanceof zn?e:new Un(e)}function en(e){return e instanceof zn?new mn(e):e instanceof pn?e:new fn(e)}function tn(e){return e instanceof zn||e instanceof pn?new Bn(e):e instanceof Mn?e:new Pn(e)}var rn={level:0};function nn(e){return Number.isInteger(e)?e+".":e.toString()}var an=class{scopeLevel=rn.level};function sn(e,t,r,i,n){if(Yi(n)){const a=`${i}_op_${n.variable()}`;return{chunk:n.local(i,a,`${n.get(e)} ${r} ${n.get(t)}`),out:a}}if("-"===r&&e instanceof Un&&t instanceof Un&&void 0!==e.number&&void 0!==t.number){return{out:`${nn(e.number-t.number)}`}}const a=`${i}_op_${n.variable()}`;return{chunk:`${i} ${a} = ${n.get(e)} ${r} ${n.get(t)};`,out:a}}function on(e,t,r,i){const n=`${r}_op_${i.variable()}`,a=`${t}${i.get(e)}`;return{chunk:Yi(i)?i.local(r,n,a):`${r} ${n} = ${a};`,out:n}}var ln=class extends an{static typeName="bool";isBoolean(){return!0}and(e){return new dn(this,Ji(e))}or(e){return new hn(this,Ji(e))}},cn=class extends ln{bool;constructor(e){super(),this.bool=e}isBoolean(){return!0}compile(e){return{out:`${this.bool}`}}},un=class extends ln{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return sn(this.a,this.b,this.op,"bool",e)}},dn=class extends un{constructor(e,t){super(e,t,"&&")}},hn=class extends un{constructor(e,t){super(e,t,"||")}},pn=class extends an{static typeName="int";isInt(){return!0}add(e){return new wn(this,en(e))}subtract(e){return new bn(this,en(e))}multiply(e){return new Sn(this,en(e))}divide(e){return new yn(this,en(e))}gt(e){return new Os(this,en(e))}lt(e){return new _s(this,en(e))}gte(e){return new js(this,en(e))}lte(e){return new Ns(this,en(e))}equals(e){return Zs(this,en(e))}notEquals(e){return Ys(this,en(e))}mod(e){return new Cn(this,en(e))}bitAnd(e){return new gn(this,en(e),"&")}bitOr(e){return new gn(this,en(e),"|")}bitXor(e){return new gn(this,en(e),"^")}bitNot(){return new xn(this,"~")}shiftLeft(e){return new vn(this,tn(e),"<<")}shiftRight(e){return new vn(this,tn(e),">>")}},fn=class extends pn{number;constructor(e){super(),this.number=e}compile(e){return{out:`${Math.floor(this.number)}`}}},mn=class extends pn{number;constructor(e){super(),this.number=e}compile(e){return Yi(e)?{out:`i32(${e.get(this.number)})`}:{out:`int(${e.get(this.number)})`}}},gn=class extends pn{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return sn(this.a,this.b,this.op,"int",e)}},vn=class extends pn{value;amount;op;constructor(e,t,r){super(),this.value=e,this.amount=t,this.op=r}compile(e){return sn(this.value,this.amount,this.op,"int",e)}},xn=class extends pn{value;op;constructor(e,t){super(),this.value=e,this.op=t}compile(e){return on(this.value,this.op,"int",e)}},wn=class extends gn{constructor(e,t){super(e,t,"+")}},bn=class extends gn{constructor(e,t){super(e,t,"-")}},yn=class extends gn{constructor(e,t){super(e,t,"/")}},Sn=class extends gn{constructor(e,t){super(e,t,"*")}},Cn=class extends gn{constructor(e,t){super(e,t,"%")}},Mn=class extends an{static typeName="int";isuInt(){return!0}add(e){return new In(this,tn(e))}subtract(e){return new Vn(this,tn(e))}multiply(e){return new Ln(this,tn(e))}divide(e){return new Gn(this,tn(e))}gt(e){return new Ws(this,tn(e))}lt(e){return new Hs(this,tn(e))}gte(e){return new qs(this,tn(e))}lte(e){return new Ks(this,tn(e))}equals(e){return Zs(this,tn(e))}notEquals(e){return Ys(this,tn(e))}bitAnd(e){return new Dn(this,tn(e),"&")}bitOr(e){return new Dn(this,tn(e),"|")}bitXor(e){return new Dn(this,tn(e),"^")}bitNot(){return new Tn(this,"~")}shiftLeft(e){return new Dn(this,tn(e),"<<")}shiftRight(e){return new Dn(this,tn(e),">>")}},Pn=class extends Mn{number;constructor(e){super(),this.number=e}compile(e){return Yi(e)?{out:`${Math.floor(this.number)}u`}:{out:`${Math.floor(this.number)}`}}},Bn=class extends Mn{number;constructor(e){super(),this.number=e}compile(e){return Yi(e)?{out:`u32(${e.get(this.number)})`}:{out:`uint(${e.get(this.number)})`}}},Dn=class extends Mn{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return sn(this.a,this.b,this.op,"uint",e)}},Tn=class extends Mn{value;op;constructor(e,t){super(),this.value=e,this.op=t}compile(e){return on(this.value,this.op,"uint",e)}},In=class extends Dn{constructor(e,t){super(e,t,"+")}},Vn=class extends Dn{constructor(e,t){super(e,t,"-")}},Gn=class extends Dn{constructor(e,t){super(e,t,"/")}},Ln=class extends Dn{constructor(e,t){super(e,t,"*")}},zn=class extends an{static typeName="float";isFloat(){return!0}add(e){return new kn(this,Qi(e))}subtract(e){return new Fn(this,Qi(e))}divide(e){return new $n(this,Qi(e))}multiply(e){return new En(this,Qi(e))}multiplyVec2(e){return new Qn(this,e)}multiplyVec3(e){return new Ba(this,e)}multiplyVec4(e){return new Oa(this,e)}gt(e){return new ks(this,Qi(e))}lt(e){return new Fs(this,Qi(e))}gte(e){if(this instanceof Un&&e instanceof Un&&void 0!==this.number&&void 0!==e.number){const t=this.number>=e.number;return new cn(t)}return new $s(this,Qi(e))}lte(e){return new Es(this,Qi(e))}equals(e){return Zs(this,Qi(e))}notEquals(e){return Ys(this,Qi(e))}},Rn=class extends zn{number;constructor(e){super(),this.number=e}compile(e){return Yi(e)?{out:`f32(${e.get(this.number)})`}:{out:`float(${e.get(this.number)})`}}},Un=class extends zn{number;constructor(e){super(),this.number=e}compile(e){if(Yi(e))return{out:e.floatLiteral(this.number)};return{out:`${nn(this.number)}`}}},An=class extends zn{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return sn(this.a,this.b,this.op,"float",e)}},kn=class extends An{constructor(e,t){super(e,t,"+")}},Fn=class extends An{constructor(e,t){super(e,t,"-")}},$n=class extends An{constructor(e,t){super(e,t,"/")}},En=class extends An{constructor(e,t){super(e,t,"*")}},On=class extends an{static typeName="vec2";isVec2(){return!0}get x(){return Rs(this)}get y(){return Us(this)}get yx(){return new jn(Us(this),Rs(this))}subtractScalar(e){return new Kn(this,Qi(e))}subtract(e){return new Hn(this,e)}addScalar(e){return new qn(this,Qi(e))}add(e){return new Wn(this,e)}divideScalar(e){return new Yn(this,Qi(e))}divide(e){return new Xn(this,e)}multiplyScalar(e){return new Zn(this,Qi(e))}multiply(e){return new Jn(this,e)}multiplyMat(e){return new Qa(this,e)}equals(e){return Zs(this,e)}notEquals(e){return Ys(this,e)}},_n=class extends On{vec;constructor(e){super(),this.vec=e}compile(e){const t=e.variable();if(Yi(e)){const r=`vec2_${t}`;return{chunk:e.local("vec2",r,e.construct("vec2",[e.floatLiteral(this.vec.x),e.floatLiteral(this.vec.y)])),out:r}}return{chunk:`vec2 vec2_${t} = vec2(${nn(this.vec.x)},${nn(this.vec.y)});`,out:`vec2_${t}`}}},jn=class extends On{_x;_y;constructor(e,t){super(),this._x=e,this._y=t}compile(e){const t=e.variable();if(Yi(e)){const r=`vec2_${t}`;return{chunk:e.local("vec2",r,e.construct("vec2",[e.get(this._x),e.get(this._y)])),out:r}}return{chunk:`vec2 vec2_${t} = vec2(${e.get(this._x)},${e.get(this._y)});`,out:`vec2_${t}`}}},Nn=class extends On{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return sn(this.a,this.b,this.op,"vec2",e)}},Wn=class extends Nn{constructor(e,t){super(e,t,"+")}},Hn=class extends Nn{constructor(e,t){super(e,t,"-")}},qn=class extends Nn{constructor(e,t){super(e,t,"+")}},Kn=class extends Nn{constructor(e,t){super(e,t,"-")}},Zn=class extends Nn{constructor(e,t){super(e,t,"*")}},Yn=class extends Nn{constructor(e,t){super(e,t,"/")}},Xn=class extends Nn{constructor(e,t){super(e,t,"/")}},Jn=class extends Nn{constructor(e,t){super(e,t,"*")}},Qn=class extends Nn{constructor(e,t){super(e,t,"*")}},ea=class extends an{static typeName="ivec2";isiVec2(){return!0}get x(){return new Ls(this,"x")}get y(){return new Ls(this,"y")}subtractScalar(e){return new oa(this,en(e))}subtract(e){return new aa(this,e)}addScalar(e){return new sa(this,en(e))}add(e){return new na(this,e)}divideScalar(e){return new ca(this,en(e))}divide(e){return new ua(this,e)}multiplyScalar(e){return new la(this,en(e))}multiply(e){return new da(this,e)}multiplyMat(e){return new _a(this,e)}equals(e){return Zs(this,e)}notEquals(e){return Ys(this,e)}},ta=class extends ea{vec;constructor(e){super(),this.vec=e}compile(e){const t=e.variable();if(Yi(e)){const r=`ivec2_${t}`;return{chunk:e.local("ivec2",r,e.construct("ivec2",[`${Math.trunc(this.vec.x)}`,`${Math.trunc(this.vec.y)}`])),out:r}}return{chunk:`vec2 vec2_${t} = vec2(${nn(this.vec.x)},${nn(this.vec.y)});`,out:`vec2_${t}`}}},ra=class extends ea{_x;_y;constructor(e,t){super(),this._x=e,this._y=t}compile(e){return Yi(e)?{out:e.construct("ivec2",[e.get(this._x),e.get(this._y)])}:{out:`ivec2(${e.get(this._x)},${e.get(this._y)})`}}},ia=class extends ea{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return sn(this.a,this.b,this.op,"ivec2",e)}},na=class extends ia{constructor(e,t){super(e,t,"+")}},aa=class extends ia{constructor(e,t){super(e,t,"-")}},sa=class extends ia{constructor(e,t){super(e,t,"+")}},oa=class extends ia{constructor(e,t){super(e,t,"-")}},la=class extends ia{constructor(e,t){super(e,t,"*")}},ca=class extends ia{constructor(e,t){super(e,t,"/")}},ua=class extends ia{constructor(e,t){super(e,t,"/")}},da=class extends ia{constructor(e,t){super(e,t,"*")}},ha=class extends an{static typeName="vec3";isVec3(){return!0}get x(){return Rs(this)}get y(){return Us(this)}get z(){return As(this)}get xy(){return new ga(this,"xy")}get xz(){return new ga(this,"xz")}get yz(){return new ga(this,"yz")}get zx(){return new ga(this,"zx")}get rgb(){return new Ds(this)}rgba(e){return this.rgb.rgba(e)}subtractScalar(e){return new ya(this,Qi(e))}subtract(e){return new wa(this,e)}addScalar(e){return new ba(this,Qi(e))}add(e){return new xa(this,e)}divideScalar(e){return new Ca(this,Qi(e))}divide(e){return new Ma(this,e)}multiplyScalar(e){return new Sa(this,Qi(e))}multiply(e){return new Pa(this,e)}multiplyMat(e){return new us(this,e)}equals(e){return Zs(this,e)}notEquals(e){return Ys(this,e)}},pa=class extends ha{vec;constructor(e){super(),this.vec=e}compile(e){const t=e.variable();if(Yi(e)){const r=`vec3_${t}`;return{chunk:e.local("vec3",r,e.construct("vec3",[e.floatLiteral(this.vec.x),e.floatLiteral(this.vec.y),e.floatLiteral(this.vec.z)])),out:r}}return{chunk:`vec3 vec3_${t} = vec3(${nn(this.vec.x)},${nn(this.vec.y)},${nn(this.vec.z)});`,out:`vec3_${t}`}}},fa=class extends ha{_x;_y;_z;constructor(e,t,r){super(),this._x=e,this._y=t,this._z=r}compile(e){const t=e.variable();if(Yi(e)){const r=`vec3_${t}`;return{chunk:e.local("vec3",r,e.construct("vec3",[e.get(this._x),e.get(this._y),e.get(this._z)])),out:r}}return{chunk:`vec3 vec3_${t} = vec3(${e.get(this._x)},${e.get(this._y)},${e.get(this._z)});`,out:`vec3_${t}`}}},ma=class extends ha{source;swizzle;constructor(e,t="xyz"){super(),this.source=e,this.swizzle=t}compile(e){return{out:`${e.get(this.source)}.${this.swizzle}`}}},ga=class extends On{source;swizzle;constructor(e,t="xy"){super(),this.source=e,this.swizzle=t}compile(e){return{out:`${e.get(this.source)}.${this.swizzle}`}}},va=class extends ha{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return sn(this.a,this.b,this.op,"vec3",e)}},xa=class extends va{constructor(e,t){super(e,t,"+")}},wa=class extends va{constructor(e,t){super(e,t,"-")}},ba=class extends va{constructor(e,t){super(e,t,"+")}},ya=class extends va{constructor(e,t){super(e,t,"-")}},Sa=class extends va{constructor(e,t){super(e,t,"*")}},Ca=class extends va{constructor(e,t){super(e,t,"/")}},Ma=class extends va{constructor(e,t){super(e,t,"/")}},Pa=class extends va{constructor(e,t){super(e,t,"*")}},Ba=class extends va{constructor(e,t){super(e,t,"*")}},Da=class extends an{static typeName="vec4";isVec4(){return!0}get x(){return Rs(this)}get y(){return Us(this)}get z(){return As(this)}get w(){return new Gs(this,"w")}get xy(){return new ga(this,"xy")}get xz(){return new ga(this,"xz")}get yz(){return new ga(this,"yz")}get zx(){return new ga(this,"zx")}get zw(){return new ga(this,"zw")}get xyz(){return new ma(this,"xyz")}get rgb(){return new Bs(this.x,this.y,this.z)}get rgba(){return new Ts(this)}subtractScalar(e){return new Aa(this,Qi(e))}subtract(e){return new Ra(this,e)}addScalar(e){return new Ua(this,Qi(e))}add(e){return new za(this,e)}divideScalar(e){return new Fa(this,Qi(e))}divide(e){return new $a(this,e)}multiplyScalar(e){return new ka(this,Qi(e))}multiply(e){return new Ea(this,e)}multiplyMat(e){return new ys(this,e)}equals(e){return Zs(this,e)}notEquals(e){return Ys(this,e)}},Ta=class extends Da{vec;constructor(e){super(),this.vec=e}compile(e){const t=e.variable();if(Yi(e)){const r=`vec4_${t}`;return{chunk:e.local("vec4",r,e.construct("vec4",[e.floatLiteral(this.vec.x),e.floatLiteral(this.vec.y),e.floatLiteral(this.vec.z),e.floatLiteral(this.vec.w)])),out:r}}return{chunk:`vec4 vec4_${t} = vec4(${nn(this.vec.x)},${nn(this.vec.y)},${nn(this.vec.z)},${nn(this.vec.w)});`,out:`vec4_${t}`}}},Ia=class extends Da{_x;_y;_z;_w;constructor(e,t,r,i){super(),this._x=e,this._y=t,this._z=r,this._w=i}compile(e){const t=e.variable();if(Yi(e)){const r=`comps_${t}`;return{chunk:e.local("vec4",r,e.construct("vec4",[e.get(this._x),e.get(this._y),e.get(this._z),e.get(this._w)])),out:r}}return{chunk:`vec4 comps_${t} = vec4(${e.get(this._x)},${e.get(this._y)},${e.get(this._z)},${e.get(this._w)});`,out:`comps_${t}`}}},Va=class extends Da{_xyz;_w;constructor(e,t){super(),this._xyz=e,this._w=t}compile(e){const t=e.variable();if(Yi(e)){const r=`comps_${t}`;return{chunk:e.local("vec4",r,e.construct("vec4",[e.get(this._xyz),e.get(this._w)])),out:r}}return{chunk:`vec4 comps_${t} = vec4(${e.get(this._xyz)},${e.get(this._w)});`,out:`comps_${t}`}}},Ga=class extends Da{_xy;_zw;constructor(e,t){super(),this._xy=e,this._zw=t}compile(e){const t=e.variable();if(Yi(e)){const r=`comps_${t}`;return{chunk:e.local("vec4",r,e.construct("vec4",[e.get(this._xy),e.get(this._zw)])),out:r}}return{chunk:`vec4 comps_${t} = vec4(${e.get(this._xy)},${e.get(this._zw)});`,out:`comps_${t}`}}},La=class extends Da{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return sn(this.a,this.b,this.op,"vec4",e)}},za=class extends La{constructor(e,t){super(e,t,"+")}},Ra=class extends La{constructor(e,t){super(e,t,"-")}},Ua=class extends La{constructor(e,t){super(e,t,"+")}},Aa=class extends La{constructor(e,t){super(e,t,"-")}},ka=class extends La{constructor(e,t){super(e,t,"*")}},Fa=class extends La{constructor(e,t){super(e,t,"/")}},$a=class extends La{constructor(e,t){super(e,t,"/")}},Ea=class extends La{constructor(e,t){super(e,t,"*")}},Oa=class extends La{constructor(e,t){super(e,t,"*")}},_a=class extends ia{constructor(e,t){super(e,t,"*")}},ja=class extends an{static typeName="uvec4";isuVec4(){return!0}get x(){return new zs(this,"x")}get y(){return new zs(this,"y")}get z(){return new zs(this,"z")}get w(){return new zs(this,"w")}subtractScalar(e){return new Ka(this,tn(e))}subtract(e){return new Ha(this,e)}addScalar(e){return new qa(this,tn(e))}add(e){return new Wa(this,e)}divideScalar(e){return new Ya(this,tn(e))}divide(e){return new Xa(this,e)}multiplyScalar(e){return new Za(this,tn(e))}multiply(e){return new Ja(this,e)}equals(e){return Zs(this,e)}notEquals(e){return Ys(this,e)}},Na=class extends ja{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return sn(this.a,this.b,this.op,"ivec2",e)}},Wa=class extends Na{constructor(e,t){super(e,t,"+")}},Ha=class extends Na{constructor(e,t){super(e,t,"-")}},qa=class extends Na{constructor(e,t){super(e,t,"+")}},Ka=class extends Na{constructor(e,t){super(e,t,"-")}},Za=class extends Na{constructor(e,t){super(e,t,"*")}},Ya=class extends Na{constructor(e,t){super(e,t,"/")}},Xa=class extends Na{constructor(e,t){super(e,t,"/")}},Ja=class extends Na{constructor(e,t){super(e,t,"*")}},Qa=class extends Nn{constructor(e,t){super(e,t,"*")}},es=class extends an{static typeName="mat3";isMat3(){return!0}col(e){return new ro(this,e)}add(e){return new as(this,e)}subtract(e){return new ss(this,e)}divideScalar(e){return new ls(this,Qi(e))}multiplyScalar(e){return new cs(this,e)}multiplyVec(e){return new ds(this,e)}multiply(e){return new os(this,e)}equals(e){return Zs(this,e)}notEquals(e){return Ys(this,e)}},ts=class extends es{mat;constructor(e){super(),this.mat=e}compile(e){return{out:`mat3(${e.get(this.mat)})`}}},rs=class extends es{a;b;c;d;e;f;g;h;i;constructor(e,t,r,i,n,a,s,o,l){super(),this.a=e,this.b=t,this.c=r,this.d=i,this.e=n,this.f=a,this.g=s,this.h=o,this.i=l}compile(e){const t=`mat3_${e.variable()}`;let r;if("number"==typeof this.a&&[this.b,this.c,this.d,this.e,this.f,this.g,this.h,this.i].every(e=>"number"==typeof e))r=[this.a,this.b,this.c,this.d,this.e,this.f,this.g,this.h,this.i];else{if(!((i=this.a)instanceof Ki||"object"==typeof i&&null!=i&&!0===i.isMatrix3&&"function"==typeof i.toArray))throw new Error("Invalid parameters to Matrix3");r=this.a.toArray()}var i;return{chunk:Yi(e)?e.local("mat3",t,e.construct("mat3",r.map(t=>e.floatLiteral(t)))):`mat3 ${t} = mat3(${r.map(nn).join(",")});`,out:t}}},is=class extends es{a;b;c;d;e;f;g;h;i;constructor(e,t,r,i,n,a,s,o,l){super(),this.a=e,this.b=t,this.c=r,this.d=i,this.e=n,this.f=a,this.g=s,this.h=o,this.i=l}compile(e){return Yi(e)?{out:e.construct("mat3",[this.a,this.b,this.c,this.d,this.e,this.f,this.g,this.h,this.i].map(t=>e.get(t)))}:{out:`mat3(\n ${e.get(this.a)},${e.get(this.b)},${e.get(this.c)},\n ${e.get(this.d)},${e.get(this.e)},${e.get(this.f)},\n ${e.get(this.g)},${e.get(this.h)},${e.get(this.i)}\n )`}}},ns=class extends es{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return sn(this.a,this.b,this.op,"mat3",e)}},as=class extends ns{constructor(e,t){super(e,t,"+")}},ss=class extends ns{constructor(e,t){super(e,t,"-")}},os=class extends ns{constructor(e,t){super(e,t,"*")}},ls=class extends ns{constructor(e,t){super(e,t,"*")}},cs=class extends ns{constructor(e,t){super(e,t,"*")}},us=class extends va{constructor(e,t){super(e,t,"*")}},ds=class extends va{constructor(e,t){super(e,t,"*")}},hs=class extends an{static typeName="mat4";isMat4(){return!0}col(e){return new io(this,e)}add(e){return new gs(this,e)}subtract(e){return new vs(this,e)}divideScalar(e){return new ws(this,Qi(e))}multiplyScalar(e){return new bs(this,Qi(e))}multiplyVec(e){return new Ss(this,e)}multiply(e){return new xs(this,e)}equals(e){return Zs(this,e)}notEquals(e){return Ys(this,e)}},ps=class extends hs{a1;b1;c1;d1;a2;b2;c2;d2;a3;b3;c3;d3;a4;b4;c4;d4;constructor(e,t,r,i,n,a,s,o,l,c,u,d,h,p,f,m){super(),this.a1=e,this.b1=t,this.c1=r,this.d1=i,this.a2=n,this.b2=a,this.c2=s,this.d2=o,this.a3=l,this.b3=c,this.c3=u,this.d3=d,this.a4=h,this.b4=p,this.c4=f,this.d4=m}compile(e){const t=e.variable(),r=`mat4_${t}`;if("number"==typeof this.a1&&"number"==typeof this.a2&&"number"==typeof this.a3&&"number"==typeof this.a4&&"number"==typeof this.b1&&"number"==typeof this.b2&&"number"==typeof this.b3&&"number"==typeof this.b4&&"number"==typeof this.c1&&"number"==typeof this.c2&&"number"==typeof this.c3&&"number"==typeof this.c4&&"number"==typeof this.d1&&"number"==typeof this.d2&&"number"==typeof this.d3&&"number"==typeof this.d4)return Yi(e)?{chunk:e.local("mat4",r,e.construct("mat4",[e.floatLiteral(this.a1),e.floatLiteral(this.b1),e.floatLiteral(this.c1),e.floatLiteral(this.d1),e.floatLiteral(this.a2),e.floatLiteral(this.b2),e.floatLiteral(this.c2),e.floatLiteral(this.d2),e.floatLiteral(this.a3),e.floatLiteral(this.b3),e.floatLiteral(this.c3),e.floatLiteral(this.d3),e.floatLiteral(this.a4),e.floatLiteral(this.b4),e.floatLiteral(this.c4),e.floatLiteral(this.d4)])),out:r}:{chunk:`mat4 mat4_${t} = mat4(\n ${nn(this.a1)},${nn(this.b1)},${nn(this.c1)},${nn(this.d1)},\n ${nn(this.a2)},${nn(this.b2)},${nn(this.c2)},${nn(this.d2)},\n ${nn(this.a3)},${nn(this.b3)},${nn(this.c3)},${nn(this.d3)},\n ${nn(this.a4)},${nn(this.b4)},${nn(this.c4)},${nn(this.d4)}\n );`,out:r};if((i=this.a1)instanceof Zi||"object"==typeof i&&null!=i&&!0===i.isMatrix4&&"function"==typeof i.toArray){if(Yi(e))return{chunk:e.local("mat4",r,e.construct("mat4",this.a1.toArray().map(t=>e.floatLiteral(t)))),out:r};return{chunk:`mat4 mat4_${t} = mat4(${this.a1.toArray().map(e=>nn(e)).join(",")});`,out:r}}throw new Error("Invalid parameters to Matrix4");var i}},fs=class extends hs{col0;col1;col2;col3;constructor(e,t,r,i){super(),this.col0=e,this.col1=t,this.col2=r,this.col3=i}compile(e){const t=e.variable();if(Yi(e)){const r=`mat4_${t}`;return{chunk:e.local("mat4",r,e.construct("mat4",[e.get(this.col0),e.get(this.col1),e.get(this.col2),e.get(this.col3)])),out:r}}return{chunk:`mat4 mat4_${t} = mat4(${e.get(this.col0)},${e.get(this.col1)},${e.get(this.col2)},${e.get(this.col3)});`,out:`mat4_${t}`}}},ms=class extends hs{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return sn(this.a,this.b,this.op,"mat4",e)}},gs=class extends ms{constructor(e,t){super(e,t,"+")}},vs=class extends ms{constructor(e,t){super(e,t,"-")}},xs=class extends ms{constructor(e,t){super(e,t,"*")}},ws=class extends ms{constructor(e,t){super(e,t,"/")}},bs=class extends ms{constructor(e,t){super(e,t,"*")}},ys=class extends La{constructor(e,t){super(e,t,"*")}},Ss=class extends La{constructor(e,t){super(e,t,"*")}},Cs=class extends Da{isRgba(){return!0}get r(){return this.x}get g(){return this.y}get b(){return this.z}get a(){return this.w}subtractScalar(e){return super.subtractScalar(e).rgba}subtract(e){return super.subtract(e).rgba}addScalar(e){return super.addScalar(e).rgba}add(e){return super.add(e).rgba}divideScalar(e){return super.divideScalar(e).rgba}divide(e){return super.divide(e).rgba}multiplyScalar(e){return super.multiplyScalar(e).rgba}multiply(e){return super.multiply(e).rgba}},Ms=class extends ha{isRgb(){return!0}get r(){return this.x}get g(){return this.y}get b(){return this.z}rgba(e){return new Vs(this,Qi(e))}add(e){return super.add(e).rgb}subtract(e){return super.subtract(e).rgb}multiply(e){return super.multiply(e).rgb}divide(e){return super.divide(e).rgb}multiplyScalar(e){return super.multiplyScalar(e).rgb}addScalar(e){return super.addScalar(e).rgb}},Ps=class extends Cs{_r;_g;_b;_a;constructor(e,t,r,i){super(),this._r=e,this._g=t,this._b=r,this._a=i}get w(){return this._a}compile(e){const t=e.variable();if(Yi(e)){const r=`comps_${t}`;return{chunk:e.local("vec4",r,e.construct("vec4",[e.get(this._r),e.get(this._g),e.get(this._b),e.get(this._a)])),out:r}}return{chunk:`vec4 comps_${t} = vec4(${e.get(this._r)},${e.get(this._g)},${e.get(this._b)},${e.get(this._a)});`,out:`comps_${t}`}}},Bs=class extends Ms{_r;_g;_b;constructor(e,t,r){super(),this._r=e,this._g=t,this._b=r}compile(e){const t=e.variable();if(Yi(e)){const r=`vec3_${t}`;return{chunk:e.local("vec3",r,e.construct("vec3",[e.get(this._r),e.get(this._g),e.get(this._b)])),out:r}}return{chunk:`vec3 vec3_${t} = vec3(${e.get(this._r)},${e.get(this._g)},${e.get(this._b)});`,out:`vec3_${t}`}}},Ds=class extends Ms{vec;constructor(e){super(),this.vec=e}compile(e){return{out:`${e.get(this.vec)}`}}},Ts=class extends Cs{vec;constructor(e){super(),this.vec=e}compile(e){return{out:`${e.get(this.vec)}`}}},Is=class extends Ms{color;constructor(e){super(),this.color=e}compile(e){const t=new qi(this.color),r=e.variable();if(Yi(e)){const i=`vec3_${r}`;return{chunk:e.local("vec3",i,e.construct("vec3",[e.floatLiteral(t.r),e.floatLiteral(t.g),e.floatLiteral(t.b)])),out:i}}return{chunk:`vec3 vec3_${r} = vec3(${nn(t.r)},${nn(t.g)},${nn(t.b)});`,out:`vec3_${r}`}}},Vs=class extends Cs{_rgb;alpha;constructor(e,t){super(),this._rgb=e,this.alpha=t}compile(e){const t=e.get(this._rgb),r=e.get(this.alpha),i=e.variable();if(Yi(e)){const n=`vec4_${i}`;return{chunk:e.local("vec4",n,e.construct("vec4",[`${t}.x`,`${t}.y`,`${t}.z`,r])),out:n}}return{chunk:`vec4 vec4_${i} = vec4(${t}.x,${t}.y,${t}.z, ${r});`,out:`vec4_${i}`}}},Gs=class extends zn{vec;component;constructor(e,t){super(),this.vec=e,this.component=t}compile(e){return{out:`${e.get(this.vec)}.${this.component}`}}},Ls=class extends pn{vec;component;constructor(e,t){super(),this.vec=e,this.component=t}compile(e){return{out:`${e.get(this.vec)}.${this.component}`}}},zs=class extends Mn{vec;component;constructor(e,t){super(),this.vec=e,this.component=t}compile(e){return{out:`${e.get(this.vec)}.${this.component}`}}};function Rs(e){return new Gs(e,"x")}function Us(e){return new Gs(e,"y")}function As(e){return new Gs(e,"z")}var ks=class extends ln{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} > ${e.get(this.b)}`}}},Fs=class extends ln{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} < ${e.get(this.b)}`}}},$s=class extends ln{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} >= ${e.get(this.b)}`}}},Es=class extends ln{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} <= ${e.get(this.b)}`}}},Os=class extends ln{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} > ${e.get(this.b)}`}}},_s=class extends ln{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} < ${e.get(this.b)}`}}},js=class extends ln{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} >= ${e.get(this.b)}`}}},Ns=class extends ln{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} <= ${e.get(this.b)}`}}},Ws=class extends ln{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} > ${e.get(this.b)}`}}},Hs=class extends ln{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} < ${e.get(this.b)}`}}},qs=class extends ln{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} >= ${e.get(this.b)}`}}},Ks=class extends ln{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} <= ${e.get(this.b)}`}}};function Zs(e,t){return new class extends ln{compile(r){return{out:`${r.get(e)} == ${r.get(t)}`}}}}function Ys(e,t){return new class extends ln{compile(r){return{out:`${r.get(e)} != ${r.get(t)}`}}}}var Xs=class extends an{static get typeName(){return"sampler2D"}sample(e,t){return new eo(this,e,t)}sampleGrad(e,t,r){return new to(this,e,t,r)}},Js=class extends an{static typeName="usampler2D";sample(e,t){return new Qs(this,e,t)}},Qs=class extends ja{sampler;cord;bias;constructor(e,t,r){super(),this.sampler=e,this.cord=t,this.bias=r}compile(e){const t=e.variable(),r=e.get(this.sampler);return{chunk:null!=this.bias?`ivec4 texture_sample_${t} = texture2D(${r}, ${e.get(this.cord)}, ${e.get(this.bias)});`:`ivec4 texture_sample_${t} = texture2D(${r}, ${e.get(this.cord)});`,out:`texture_sample_${t}`}}},eo=class extends Cs{sampler;cord;bias;constructor(e,t,r){super(),this.sampler=e,this.cord=t,this.bias=r}compile(e){const t=e.variable(),r=e.get(this.sampler);if(Yi(e)){const i=`texture_sample_${t}`,n=e.get(this.cord),a=e.getTextureSampleType(r),s=null!=this.bias?"depth"===a?`i32(${e.get(this.bias)})`:e.get(this.bias):"depth"===a?"0":"0.0",o=Xi(e)?null!=this.bias?`textureSampleBias(${r}Texture, ${r}Sampler, ${n}, ${e.get(this.bias)})`:`textureSample(${r}Texture, ${r}Sampler, ${n})`:`textureSampleLevel(${r}Texture, ${r}Sampler, ${n}, ${s})`,l="depth"===a?`vec4<f32>(${o})`:o;return{chunk:e.local("vec4",i,l),out:i}}return{chunk:null!=this.bias?`vec4 texture_sample_${t} = texture2D(${r}, ${e.get(this.cord)}, ${e.get(this.bias)});`:`vec4 texture_sample_${t} = texture2D(${r}, ${e.get(this.cord)});`,out:`texture_sample_${t}`}}},to=class extends Cs{sampler;cord;ddx;ddy;constructor(e,t,r,i){super(),this.sampler=e,this.cord=t,this.ddx=r,this.ddy=i}compile(e){const t=e.variable(),r=e.get(this.sampler);if(Yi(e)){const i=`texture_sample_grad_${t}`;return{chunk:e.local("vec4",i,`textureSampleGrad(${r}Texture, ${r}Sampler, ${e.get(this.cord)}, ${e.get(this.ddx)}, ${e.get(this.ddy)})`),out:i}}return{chunk:`vec4 texture_sample_grad_${t} = textureGrad(\n ${r}, \n ${e.get(this.cord)}, \n ${e.get(this.ddx)}, \n ${e.get(this.ddy)});`,out:`texture_sample_grad_${t}`}}},ro=class extends ha{mat;i;constructor(e,t){super(),this.mat=e,this.i=t}compile(e){return{out:`${e.get(this.mat)}[${this.i}]`}}},io=class extends Da{mat;i;constructor(e,t){super(),this.mat=e,this.i=t}compile(e){return{out:`${e.get(this.mat)}[${this.i}]`}}};var no=class extends Da{name;constructor(e){super(),this.name=e}compile(e){return e instanceof Co||Xi(e)?e.defineVarying("vec4",this):function(e,t,r){return Xi(e)?e.defineBuiltinVarying(r,t):Yi(e)?"position"===t||"normal"===t||"uv"===t||"color"===t?{out:`input.${t}`}:e.getVertexAttribute(t,r):"color"===t?{pars:`\n #ifndef USE_COLOR\n attribute ${r} color;\n #endif\n `,chunk:"\n #if defined( USE_COLOR_ALPHA )\n vec4 vertexColor = color;\n #elif defined( USE_COLOR )\n vec4 vertexColor = vec4(color, 1.0);\n #else \n vec4 vertexColor = color;\n #endif\n ",out:"vertexColor"}:{pars:`\n attribute ${r} ${t};\n `,out:t}}(e,this.name,"vec4")}},ao=class{currentValue;uniforms=new Set;constructor(e){this.currentValue=e}get value(){return this.currentValue}set value(e){this.currentValue=e;for(const t of this.uniforms)t.value=e}bindUniform(e){this.uniforms.add(e)}unbindUniform(e){this.uniforms.delete(e)}},so=class extends ln{name;ifdef;binding;currentValue;constructor(e,t=!1,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new ao(t):void 0}get value(){return this.currentValue}set value(e){this.currentValue=e,null!=this.binding&&(this.binding.value=e)}compile(e){return e.defineUniform("bool",this.name,this.value,this.ifdef,this.binding)}},oo=class extends zn{name;ifdef;binding;currentValue;constructor(e,t=0,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new ao(t):void 0}get value(){return this.currentValue}set value(e){this.currentValue=e,null!=this.binding&&(this.binding.value=e)}compile(e){return e.defineUniform("float",this.name,this.value,this.ifdef,this.binding)}},lo=class extends hs{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new ao(t):void 0}get value(){return this.currentValue}set value(e){this.currentValue=e,null!=this.binding&&(this.binding.value=e)}compile(e){return e.defineUniform("mat4",this.name,this.value,this.ifdef,this.binding)}},co=class extends Xs{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new ao(t):void 0}get value(){return this.currentValue}set value(e){this.currentValue=e,null!=this.binding&&(this.binding.value=e)}compile(e){return Yi(e)?e.defineTexture(this.name,this.value):e.defineUniform("sampler2D",this.name,this.value,this.ifdef,this.binding)}},uo=class extends ha{a;isVarying=!0;constructor(e){super(),this.a=e}compile(e){if(e instanceof Co||Xi(e))return e.defineVarying("vec3",this.a);throw new Error("A varying can not be defined as input to another varying.")}},ho=class extends Da{a;isVarying=!0;constructor(e){super(),this.a=e}compile(e){if(e instanceof Co||Xi(e))return e.defineVarying("vec4",this.a);throw new Error("A varying can not be defined as input to another varying.")}};function po(e){return new Io(e)}function fo(e,t,r){if((e instanceof zn||"number"==typeof e)&&(t instanceof zn||"number"==typeof t))return new Bs(Qi(e),Qi(t),Qi(r??0)).divideScalar(255);if((i=e)instanceof Ei||!0===i?.isColor||"number"==typeof e||"string"==typeof e)return new Is(e);var i;throw"Unsupported arguments to construct RGB"}function mo(e,t){return e instanceof Ni?new ta(e):new ra(en(e),en(null!=t?t:e))}function go(e,t){if(e instanceof ha||e instanceof Da)return e.xy;if(("number"==typeof e||e instanceof zn)&&("number"==typeof t||t instanceof zn||null==t))return new jn(Qi(e),Qi(t??e));if("number"==typeof e){if(t instanceof zn)return new jn(Qi(e),Qi(t));if("number"==typeof t||null==t)return new _n(new Ni(e,null!=t?t:e))}else if(e instanceof Ni)return new _n(e);if(e instanceof Wi||e instanceof Hi)return new _n(new Ni(e.x,e.y));if(e instanceof zn)return new jn(Qi(e),Qi(null!=t?t:e));throw new Error("Invalid arguments for vec2")}function vo(e,t,r){if((e instanceof zn||"number"==typeof e)&&void 0===t)return new fa(Qi(e),Qi(e),Qi(e));if(e instanceof ha)return e;if(e instanceof Da)return e.xyz;if(("number"==typeof e||e instanceof zn)&&("number"==typeof t||t instanceof zn)&&("number"==typeof r||r instanceof zn))return new fa(Qi(e),Qi(t),Qi(r));if(e instanceof Wi||e instanceof Hi)return new pa(e);throw new Error("Invalid arguments for vec3")}function xo(e,t,r,i){if((e instanceof zn||"number"==typeof e)&&void 0===t)return new Ia(Qi(e),Qi(e),Qi(e),Qi(e));if(e instanceof ha)return new Va(e,Qi(t));if(yo(e)&&yo(t)&&yo(r)&&yo(i))return new Ia(Qi(e),Qi(t),Qi(r),Qi(i));if(e instanceof On){if(t instanceof On)return new Ga(e,t)}else if(e instanceof Hi)return new Ta(e);throw"Unsupported combination of inputs"}function wo(e,t,r){if(e instanceof _i)return new rs(e);if("number"==typeof e&&void 0===t)return new rs(e,e,e,e,e,e,e,e,e);if(e instanceof ha&&t instanceof ha&&r instanceof ha)return new is(e.x,e.y,e.z,t.x,t.y,t.z,r.x,r.y,r.z);if(e instanceof hs)return new ts(e);throw"Unsupported combination of inputs"}function bo(e,t,r,i){if(e instanceof ji)return new ps(e);if("number"==typeof e&&void 0===t)return new ps(e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e);if(e instanceof Da&&t instanceof Da&&r instanceof Da&&i instanceof Da)return new fs(e,t,r,i);throw"Unsupported combination of inputs"}function yo(e){return"number"==typeof e||e instanceof zn}var So=class{cachedOuts=new Map;pars=[];uniquePars=new Set;registeredStructNames=new Set;uniformNodes={};outputs={};addDefinition(e){this.uniquePars.has(e)||(this.uniquePars.add(e),this.pars.push(e))}chunks=[];uniforms={};uniformTypes={};liveUniforms=[];variableNumber=0;variable(){return++this.variableNumber}scopeLevelChunkIndex=[];chunkBuffers=[];forceAppend=!1;startScope(e,t=[]){rn.level,this.scopeLevelChunkIndex[rn.level]=this.chunks.length-1,rn.level++,rn.level;const r=this.getCachedOuts(rn.level);for(const e of t){const t=this.cachedOuts.get(e);null!=t&&r.set(e,t)}null==this.chunkBuffers[rn.level]&&(this.chunkBuffers[rn.level]=[]),this.chunkBuffers[rn.level].push([e])}getScopeChunks(e){if(0===e)return this.chunks;const t=this.chunkBuffers[e];return null==t||t.length,t[t.length-1]}stopScope(e=""){if(this.getCachedOuts(rn.level).clear(),0===rn.level)throw"stop scope only after entering";const t=this.getScopeChunks(rn.level);this.chunkBuffers[rn.level].pop(),rn.level--;const r=this.getScopeChunks(rn.level);r.push(...t),r.push(e),rn.level}caches=[];getCachedOuts(e){return null==this.caches[e]&&(this.caches[e]=new Map),this.caches[e]}get(e,t){const r=e.scopeLevel||0;let i;i=0===r||e.isVarying?this.cachedOuts:this.caches[r]||(this.caches[r]=new Map);const n=i.get(e);return void 0!==n?n.out:this.compileNode(e,i,r)}compileNode(e,t,r){if(e.isStruct)this.registerStructDefinition(e);else if(e.isArray&&e.type&&e.type.prototype.isStruct){const t=e.type.typeName;this.registeredStructNames.has(t)||this.registerStructDefinition(new e.type)}const i=e.compile(this);if(null!=i.chunk){const e=this.getScopeChunks(this.forceAppend?rn.level:r);if(null==e)throw new Error("No chunks exist for scope level "+r);e.push(i.chunk)}return null!=i.pars&&this.addDefinition(i.pars),t.set(e,i),i.out}injectScoped(e,t){if(rn.level>e){const r=this.scopeLevelChunkIndex[e]-1;r<0?(this.chunks.unshift(t),this.scopeLevelChunkIndex[e]++):this.chunks[r]+=t}else this.chunks.push(t)}cachedUniforms=new Map;defineUniform(e,t,r,i,n){if(null!=t&&t in this.uniformNodes)return{out:this.get(this.uniformNodes[t])};const a=t??r??n;if(!this.cachedUniforms.has(a)){const n=t??`u_${e}_${this.variable()}`;null!=i&&this.pars.push(`#ifdef ${i}`),this.addDefinition(`\n uniform ${e} ${n};\n `),null!=i&&this.pars.push("#endif"),null!=r&&(this.uniforms[n]={value:r}),this.uniformTypes[n]=e,this.cachedUniforms.set(a,n)}const s=this.cachedUniforms.get(a);return n instanceof ao&&this.liveUniforms.push({name:s,binding:n}),{out:s}}registerStructDefinition(e){const t=e.constructor.typeName;if(this.registeredStructNames.has(t))return;this.registeredStructNames.add(t);const r=e.definition();this.addDefinition(r)}getPars(){const e=[];for(const t of this.pars){const r=t.split("\n");for(const t of r){const r=t.trim();r.length>0&&e.push(r)}}return e.join("\n")}getMain(){const e=[];for(const t of this.chunks){const r=t.split("\n");for(const t of r){const r=t.trim();r.length>0&&e.push(r)}}return e.join("\n")}render(){return`\n ${this.getPars()}\n\n void main() {\n ${this.getMain()}\n }\n `}},Co=class extends So{vertexCompiler;constructor(e){super(),this.vertexCompiler=e}varyingCache=new Map;defineVarying(e,t,r=null){const i=this.varyingCache.get(t);if(null!=i)return{out:i};const n=rn.level;rn.level=0;const a=this.vertexCompiler.get(t);rn.level=n;const s=`v_${e}_${this.vertexCompiler.variable()}`;let o=`\n varying ${e} ${s};\n `,l=`\n ${s} = ${a};\n `;if(null!=r){const t=rn.level;rn.level=0;const i=this.vertexCompiler.get(en(r));rn.level=t,o=`\n #if ${i} > 0\n varying ${e} ${s}[ ${i} ];\n #endif`,l=`\n #if ${i} > 0\n ${l};\n #endif`}return this.vertexCompiler.addDefinition(o.replace("varying","out")),this.vertexCompiler.chunks.push(l),this.addDefinition(o.replace("varying","in")),this.varyingCache.set(t,s),{out:s}}getVarying(e,t){return this.defineVarying(e,t).out}},Mo=/^\s*(?:(\w+)) (?=\w+)/g,Po=/^\s*(?:(\w+)) (?=(\w+))/g,Bo=class extends pn{compile(e){return Yi(e)?{out:e.currentLoopIndex()}:{out:"UNROLLED_LOOP_INDEX"}}},Do=class e{type;isArray=!0;constructor(e){this.type=e}startIndex=0;wgslArrayBounds(e){if("number"!=typeof this.limit)throw new Error("WGSL array loops require a static capacity. Provide a renderer array binding with an explicit capacity.");return{count:e.get(en(this.limit)),capacity:this.limit}}compileElement(e,t){return`${e.get(this)}[${e.get(t)}]`}get(e){const t=this,r=en(e);return new class extends this.type{compile(e){return{out:t.compileElement(e,r)}}}}slice(e,t){const r=this.clone();return r.limit=r.startIndex+t,r.startIndex+=e,r}first(e){const t=this.clone();return t.limit=e,t}sum(e){const t=this;rn.level++;const r=new Bo,i=e(t.get(r),r);rn.level--;const n=i.constructor;return new class extends n{compile(e){if(Yi(e))return function(e,t,r,i){const n=e.variable(),a=`loop_sum_${n}`,s=`loop_index_${n}`,{count:o,capacity:l,fragmentMask:c}=t.wgslArrayBounds(e);if(null!=c&&Xi(e)){if(l>64)throw new Error("WGSL masked reductions support at most 64 elements.");e.startScope(`\n var ${a}: ${e.type(r.typeName)} = ${e.zero(r.typeName)};\n {\n let masks_${n} = ${c};\n for (var word_${n} = 0u; word_${n} < 2u; word_${n}++) {\n var bits_${n} = masks_${n}[word_${n}];\n while (bits_${n} != 0u) {\n let ${s} = i32(word_${n} * 32u + firstTrailingBit(bits_${n}));\n bits_${n} &= bits_${n} - 1u;\n if (${s} >= ${o}) { continue; }`,[t]),e.pushLoopIndex(s);const u=e.get(i);return e.popLoopIndex(),e.stopScope(`\n ${a} = ${a} + ${u};\n }\n }\n }`),{out:a}}e.startScope(`\n var ${a}: ${e.type(r.typeName)} = ${e.zero(r.typeName)};\n for (var ${s}: i32 = 0; ${s} < ${o}; ${s} = ${s} + 1) {`,[t]),e.pushLoopIndex(s);const u=e.get(i);return e.popLoopIndex(),e.stopScope(`\n ${a} = ${a} + ${u};\n }`),{out:a}}(e,t,n,i);const r=e.variable(),a=e.get(en(t.limit)),s=`\n ${n.typeName} loop_sum_${r} = ${n.typeName}(0.0);\n\n #if ${a} > 0\n // Ensure the array is evaluated before the loop\n ${e.get(t)};\n //VARIABLES\n #pragma unroll_loop_start\n for ( int i = 0; i < ${e.get(en(t.limit))}; i ++ ) {\n //VARSTART(${r})\n `;e.startScope(s,[t]);const o=e.get(i);e.stopScope(`\n loop_sum_${r} += ${o};\n }\n #pragma unroll_loop_end\n #endif\n `);const l=e.chunks.findIndex(e=>e.includes(`//VARSTART(${r})`))+1,c=[];for(let t=l;t<e.chunks.length;t++){const r=e.chunks[t];for(const e of r.matchAll(Po))c.push(`${e[1]} ${e[2]};`)}const u=c.join("\n");return e.chunks.slice(l).forEach((t,r)=>{e.chunks[l+r]=t.replace(Mo,"")}),e.chunks[l-1]=e.chunks[l-1].replace("//VARIABLES",u),{out:`loop_sum_${r}`}}}}map(t){const r=this;rn.level++;const i=new Bo,n=t(r.get(i),i),a=n.constructor;return rn.level--,new class extends e{type=a;limit=r.limit;compile(e){if(Yi(e))return function(e,t,r,i){const n=e.variable(),a=`loop_map_${n}`,s=`loop_index_${n}`,{count:o,capacity:l}=t.wgslArrayBounds(e);e.startScope(`\n var ${a}: array<${e.type(r.typeName)}, ${l}>;\n for (var ${s}: i32 = 0; ${s} < ${o}; ${s} = ${s} + 1) {`),e.pushLoopIndex(s);const c=e.get(i);return e.popLoopIndex(),e.stopScope(`\n ${a}[${s}] = ${c};\n }`),{out:a}}(e,r,a,n);const t=e.variable(),i=e.get(en(r.limit)),s=`\n\n #if ${i} > 0\n ${a.typeName} loop_map_${t}[${i}];\n //VARIABLES\n #pragma unroll_loop_start\n for ( int i = 0; i < ${i}; i ++ ) {\n //VARSTART(${t})\n `;e.startScope(s);const o=e.get(n);e.stopScope(`\n loop_map_${t}[i] = ${o};\n }\n #pragma unroll_loop_end\n #else\n // Not sure what this even is\n ${a.typeName} loop_map_${t}[1];\n #endif\n `);const l=e.chunks.findIndex(e=>e.includes(`//VARSTART(${t})`))+1,c=[];for(let t=l;t<e.chunks.length;t++){const r=e.chunks[t];for(const e of r.matchAll(Po))c.push(`${e[1]} ${e[2]};`)}const u=c.join("\n");return e.chunks.slice(l).forEach((t,r)=>{e.chunks[l+r]=t.replace(Mo,"")}),e.chunks[l-1]=e.chunks[l-1].replace("//VARIABLES",u),{out:`loop_map_${t}`}}}}};var To=class e extends Do{name;type;limit;value;constructor(e,t,r,i){super(t),this.name=e,this.type=t,this.limit=r,this.value=i}compile(e){if(Yi(e)){if(null==e.getArrayBinding(this.name))throw new Error(`WGSL emitter has no renderer binding for array "${this.name}".`);return{out:`external_array_${this.name}`}}const t=e.get(en(this.limit));return null!=this.value&&(e.uniforms[this.name]={value:this.value}),{pars:`\n #if ${t} > 0\n uniform ${this.type.typeName} ${this.name}[ ${t} ];\n #endif\n `,out:`${this.name}`}}wgslArrayBounds(e){const t=e.getArrayBinding(this.name);if(null==t)throw new Error(`WGSL emitter has no renderer binding for array "${this.name}".`);return{count:t.activeCount,capacity:t.capacity,fragmentMask:t.fragmentMask}}compileElement(e,t){if(Yi(e)){const r=e.getArrayBinding(this.name);if(null==r)throw new Error(`WGSL emitter has no renderer binding for array "${this.name}".`);return r.element(e.get(t))}return super.compileElement(e,t)}clone(){return new e(this.name,this.type,this.limit,this.value)}},Io=class e extends Do{node;limit;type;constructor(e,t=e.limit,r=e.type){super(e.type),this.node=e,this.limit=t,this.type=r}compile(e){return e.defineVarying(this.type.typeName,this.node,this.node.limit)}clone(){return new e(this.node,this.limit,this.type)}},Vo=class extends pn{expr;constructor(e){super(),this.expr=e}compile(e){if(Yi(e))throw new Error(`WGSL emitter does not support the raw int expression "${this.expr}". Use a node expression or add a dedicated WGSL emitter for it.`);return{out:this.expr}}},Go=class extends ha{expr;constructor(e){super(),this.expr=e}compile(e){return Yi(e)?Ro(e,"vec3",this.expr):{out:this.expr}}},Lo=class extends Da{expr;constructor(e){super(),this.expr=e}compile(e){return Yi(e)?Ro(e,"vec4",this.expr):{out:this.expr}}},zo=class extends hs{expr;constructor(e){super(),this.expr=e}compile(e){if(Yi(e))switch(this.expr){case"modelMatrix":return Uo(e,"rendererModelMatrix");case"modelViewMatrix":return Uo(e,"rendererModelViewMatrix");case"projectionMatrix":return{out:"rendererProjectionMatrix()"};case"viewMatrix":return{out:"rendererViewMatrix()"};case"instanceMatrix":case"vertexTransform":return{out:ko};default:throw Ao("mat4",this.expr)}return{out:this.expr}}};function Ro(e,t,r){if("instanceColor"===r&&("vec3"===t||"vec4"===t)){if(Xi(e))return e.defineVarying(t,"vec3"===t?new Go(r):new Lo(r));const i="rendererObjectColor(input.instanceIndex)";return{out:"vec3"===t?`${i}.xyz`:i}}if("uv"===r||"position"===r||"normal"===r||"color"===r)return Xi(e)?e.defineBuiltinVarying(t,r):{out:`input.${r}`};if("cameraPosition"===r&&"vec3"===t)return{out:"rendererCameraPosition()"};if(Xi(e)){if("gl_FragCoord.xy"===r&&"vec2"===t)return{out:"input.position.xy"};if("gl_FragCoord"===r&&"vec3"===t)return{out:"input.position.xyz"};if("gl_FragCoord.z"===r&&"float"===t)return{out:"input.position.z"}}throw Ao(t,r)}function Uo(e,t){if(Xi(e))throw new Error(`WGSL renderer matrix "${t}" must be evaluated in the vertex stage. Pass a derived value through varying(...) before reading it in the fragment stage.`);return{out:`${t}(input.instanceIndex)`}}function Ao(e,t){throw new Error(`WGSL emitter does not support the raw ${e} expression "${t}". Use a node expression or add a dedicated WGSL emitter for it.`)}var ko="mat4x4<f32>(\n vec4<f32>(1.0, 0.0, 0.0, 0.0),\n vec4<f32>(0.0, 1.0, 0.0, 0.0),\n vec4<f32>(0.0, 0.0, 1.0, 0.0),\n vec4<f32>(0.0, 0.0, 0.0, 1.0)\n)";import{Matrix4 as Fo,Vector3 as $o}from"three";var Eo=new ps((new Fo).identity()),Oo={tangent:new no("tangent"),position:new Go("position"),normal:new Go("normal"),uv:new class extends On{expr;constructor(e){super(),this.expr=e}compile(e){return Yi(e)?Ro(e,"vec2",this.expr):{out:this.expr}}}("uv"),color:new no("color").rgba},_o=(new uo(Oo.position),new uo(Oo.normal),new class extends On{a;isVarying=!0;constructor(e){super(),this.a=e}compile(e){if(e instanceof Co||Xi(e))return e.defineVarying("vec2",this.a);throw new Error("A varying can not be defined as input to another varying.")}}(Oo.uv),{instanceMatrix:new class extends hs{compile(e){if(Yi(e))return{out:e.get(Eo)};const t=e.variable();return{chunk:`\n mat4 instanceMatrixOpt_${t} = ${e.get(Eo)};\n #ifdef USE_INSTANCING\n instanceMatrixOpt_${t} = instanceMatrix;\n #endif\n `,out:`instanceMatrixOpt_${t}`}}},modelMatrix:new zo("modelMatrix"),modelViewMatrix:new zo("modelViewMatrix"),projectionMatrix:new zo("projectionMatrix"),viewMatrix:new zo("viewMatrix"),normalMatrix:new class extends es{expr;constructor(e){super(),this.expr=e}compile(e){if(Yi(e)){if("normalMatrix"===this.expr)return Uo(e,"rendererNormalMatrix");throw Ao("mat3",this.expr)}return{out:this.expr}}}("normalMatrix"),cameraPosition:new Go("cameraPosition")});new Lo("projectionMatrix * modelViewMatrix * vec4( position , 1.0 )");function jo(e,t){const r=Object.getPrototypeOf(t).constructor;return new class extends r{compile(i){const n=i.variable(),a=`out_${e}_${n}`;if(Yi(i)){const n=qo(e,1,r.typeName),s=function(e,t){if("inverse"!==e)return;switch(t){case"mat2":return Ko;case"mat3":return Zo;case"mat4":return Yo;default:return}}(e,r.typeName);null!=s&&i.addWgslDefinition(s);const o=`${n}(${i.get(t)})`,l=function(e){return"dFdy"===e||"dFdyCoarse"===e||"dFdyFine"===e}(e)?`-${o}`:o;return{chunk:i.local(r.typeName,a,l),out:a}}return{chunk:`${r.typeName} ${a} = ${e}(${i.get(t)});`,out:a}}}}function No(e){return Ho(zn,"length",e)}function Wo(e){return jo("normalize",e)}function Ho(e,t,...r){return new class extends e{compile(i){const n=r.map(e=>i.get("number"==typeof e?Qi(e):e)),a=i.variable(),s=`out_${t}_${a}`;if(Yi(i)){const a="mod"===t?`(${n[0]} - ${n[1]} * floor(${n[0]} / ${n[1]}))`:`${qo(t,r.length)}(${n.join(", ")})`;return{chunk:i.local(e.typeName,s,a),out:s}}return{chunk:`${e.typeName} ${s} = ${t}(${n.join(", ")});`,out:s}}}}function qo(e,t,r){switch(e){case"inverse":switch(r){case"mat2":return"nodeInverseMat2";case"mat3":return"nodeInverseMat3";case"mat4":return"nodeInverseMat4";default:throw new Error(`WGSL inverse() expects a matrix return type, received ${r??"unknown"}.`)}case"inversesqrt":return"inverseSqrt";case"dFdx":return"dpdx";case"dFdy":return"dpdy";case"dFdxCoarse":return"dpdxCoarse";case"dFdyCoarse":return"dpdyCoarse";case"dFdxFine":return"dpdxFine";case"dFdyFine":return"dpdyFine";case"atan":return 2===t?"atan2":"atan";default:return e}}var Ko="\nfn nodeInverseMat2(m: mat2x2<f32>) -> mat2x2<f32> {\n let det = m[0].x * m[1].y - m[1].x * m[0].y;\n let safeDet = select(det, select(-1e-8, 1e-8, det >= 0.0), abs(det) < 1e-8);\n let invDet = 1.0 / safeDet;\n return mat2x2<f32>(\n vec2<f32>(m[1].y, -m[0].y),\n vec2<f32>(-m[1].x, m[0].x)\n ) * invDet;\n}\n",Zo="\nfn nodeInverseMat3(m: mat3x3<f32>) -> mat3x3<f32> {\n let a = m[0];\n let b = m[1];\n let c = m[2];\n let r0 = cross(b, c);\n let r1 = cross(c, a);\n let r2 = cross(a, b);\n let det = dot(r2, c);\n let safeDet = select(det, select(-1e-8, 1e-8, det >= 0.0), abs(det) < 1e-8);\n let invDet = 1.0 / safeDet;\n return transpose(mat3x3<f32>(r0 * invDet, r1 * invDet, r2 * invDet));\n}\n",Yo="\nfn nodeInverseMat4(m: mat4x4<f32>) -> mat4x4<f32> {\n let m00 = m[0][0]; let m01 = m[0][1]; let m02 = m[0][2]; let m03 = m[0][3];\n let m10 = m[1][0]; let m11 = m[1][1]; let m12 = m[1][2]; let m13 = m[1][3];\n let m20 = m[2][0]; let m21 = m[2][1]; let m22 = m[2][2]; let m23 = m[2][3];\n let m30 = m[3][0]; let m31 = m[3][1]; let m32 = m[3][2]; let m33 = m[3][3];\n let b00 = m00 * m11 - m01 * m10;\n let b01 = m00 * m12 - m02 * m10;\n let b02 = m00 * m13 - m03 * m10;\n let b03 = m01 * m12 - m02 * m11;\n let b04 = m01 * m13 - m03 * m11;\n let b05 = m02 * m13 - m03 * m12;\n let b06 = m20 * m31 - m21 * m30;\n let b07 = m20 * m32 - m22 * m30;\n let b08 = m20 * m33 - m23 * m30;\n let b09 = m21 * m32 - m22 * m31;\n let b10 = m21 * m33 - m23 * m31;\n let b11 = m22 * m33 - m23 * m32;\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n let safeDet = select(det, select(-1e-8, 1e-8, det >= 0.0), abs(det) < 1e-8);\n let invDet = 1.0 / safeDet;\n return mat4x4<f32>(\n vec4<f32>(\n m11 * b11 - m12 * b10 + m13 * b09,\n m02 * b10 - m01 * b11 - m03 * b09,\n m31 * b05 - m32 * b04 + m33 * b03,\n m22 * b04 - m21 * b05 - m23 * b03\n ) * invDet,\n vec4<f32>(\n m12 * b08 - m10 * b11 - m13 * b07,\n m00 * b11 - m02 * b08 + m03 * b07,\n m32 * b02 - m30 * b05 - m33 * b01,\n m20 * b05 - m22 * b02 + m23 * b01\n ) * invDet,\n vec4<f32>(\n m10 * b10 - m11 * b08 + m13 * b06,\n m01 * b08 - m00 * b10 - m03 * b06,\n m30 * b04 - m31 * b02 + m33 * b00,\n m21 * b02 - m20 * b04 - m23 * b00\n ) * invDet,\n vec4<f32>(\n m11 * b07 - m10 * b09 - m12 * b06,\n m00 * b09 - m01 * b07 + m02 * b06,\n m31 * b01 - m30 * b03 - m32 * b00,\n m20 * b03 - m21 * b01 + m22 * b00\n ) * invDet\n );\n}\n";function Xo(e,t){return Ho(zn,"dot",e,t)}function Jo(e,t){return new el(e,en(t))}function Qo(e,t,r){return e instanceof Xs?new tl(e,t,en(r)):new rl(e,t,en(r))}var el=class extends ea{sampler;lod;constructor(e,t){super(),this.sampler=e,this.lod=t}compile(e){const t=`textureSize_${e.variable()}`,r=e.get(this.sampler),i=e.get(this.lod);return Yi(e)?{chunk:e.local("ivec2",t,`vec2<i32>(textureDimensions(${r}Texture, ${i}))`),out:t}:{chunk:`ivec2 ${t} = textureSize(${r}, ${i});`,out:t}}},tl=class extends Cs{sampler;coordinates;lod;constructor(e,t,r){super(),this.sampler=e,this.coordinates=t,this.lod=r}compile(e){const t=`texelFetch_${e.variable()}`,r=e.get(this.sampler),i=e.get(this.coordinates),n=e.get(this.lod);return Yi(e)?{chunk:e.local("vec4",t,`textureLoad(${r}Texture, ${i}, ${n})`),out:t}:{chunk:`vec4 ${t} = texelFetch(${r}, ${i}, ${n});`,out:t}}},rl=class extends ja{sampler;coordinates;lod;constructor(e,t,r){super(),this.sampler=e,this.coordinates=t,this.lod=r}compile(e){const t=`texelFetch_${e.variable()}`,r=e.get(this.sampler),i=e.get(this.coordinates),n=e.get(this.lod);return Yi(e)?{chunk:e.local("uvec4",t,`textureLoad(${r}Texture, ${i}, ${n})`),out:t}:{chunk:`uvec4 ${t} = texelFetch(${r}, ${i}, ${n});`,out:t}}},il=class extends zn{vec;component;constructor(e,t){super(),this.vec=e,this.component=t}compile(e){return{out:`${e.get(this.vec)}.${this.component}`}}};var nl=class{get isStruct(){return!0}static typeName;properties=new Map;get(e,t){this.properties.set(t,e);const r=this;return new class extends e{propertyName=t;compile(e){return{out:`${e.get(r)}.${t}`}}}}definition(){const e=Array.from(this.properties.entries()).map(([e,t])=>`${t.typeName} ${e};`).join("\n");return`\n struct ${this.constructor.typeName} {\n ${e}\n };\n `}},al=new class extends pn{compile(e){return Yi(e)?{out:"i32(rendererCsmCascadeCount())"}:{out:"CSM_CASCADES"}}},sl=(new To("lightProbe",ha,9),new To("pointLights",class extends nl{static typeName="PointLight";position=this.get(ha,"position");color=this.get(Ms,"color");distance=this.get(zn,"distance");decay=this.get(zn,"decay")},new Vo("NUM_POINT_LIGHTS")),new To("spotLights",class extends nl{static typeName="SpotLight";position=this.get(ha,"position");direction=this.get(ha,"direction");color=this.get(Ms,"color");distance=this.get(zn,"distance");decay=this.get(zn,"decay");coneCos=this.get(zn,"coneCos");penumbraCos=this.get(zn,"penumbraCos")},new Vo("NUM_SPOT_LIGHTS")),new To("hemisphereLights",class extends nl{static typeName="HemisphereLight";direction=this.get(ha,"direction");skyColor=this.get(Ms,"skyColor");groundColor=this.get(Ms,"groundColor")},new Vo("NUM_HEMI_LIGHTS")),new To("directionalLights",class extends nl{static typeName="DirectionalLight";direction=this.get(ha,"direction");color=this.get(Ms,"color")},new Vo("NUM_DIR_LIGHTS")),new To("rectAreaLights",class extends nl{static typeName="RectAreaLight";color=this.get(Ms,"color");position=this.get(ha,"position");halfWidth=this.get(ha,"halfWidth");halfHeight=this.get(ha,"halfHeight")},new Vo("NUM_RECT_AREA_LIGHTS")),new co("ltc_1"),new co("ltc_2"),new class extends ha{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new ao(t):void 0}get value(){return this.currentValue}set value(e){this.currentValue=e,null!=this.binding&&(this.binding.value=e)}compile(e){return e.defineUniform("vec3",this.name,this.value,this.ifdef,this.binding)}}("ambientLightColor"),new so("receiveShadow"),new To("pointLightShadows",class extends nl{static typeName="PointLightShadow";shadowBias=this.get(zn,"shadowBias");shadowNormalBias=this.get(zn,"shadowNormalBias");shadowRadius=this.get(zn,"shadowRadius");shadowMapSize=this.get(On,"shadowMapSize");shadowCameraNear=this.get(zn,"shadowCameraNear");shadowCameraFar=this.get(zn,"shadowCameraFar")},new Vo("NUM_POINT_LIGHT_SHADOWS"))),ol=(new To("pointShadowMap",Xs,new Vo("NUM_POINT_LIGHT_SHADOWS")),new To("pointShadowMatrix",hs,new Vo("NUM_POINT_LIGHT_SHADOWS"))),ll=new To("directionalLightShadows",class extends nl{static typeName="DirectionalLightShadow";shadowBias=this.get(zn,"shadowBias");shadowNormalBias=this.get(zn,"shadowNormalBias");shadowRadius=this.get(zn,"shadowRadius");shadowMapSize=this.get(On,"shadowMapSize")},new Vo("NUM_DIR_LIGHT_SHADOWS")),cl=(new To("directionalShadowMap",Xs,new Vo("NUM_DIR_LIGHT_SHADOWS")),new To("directionalShadowMatrix",hs,new Vo("NUM_DIR_LIGHT_SHADOWS"))),ul=new To("spotLightShadows",class extends nl{static typeName="SpotLightShadow";shadowBias=this.get(zn,"shadowBias");shadowNormalBias=this.get(zn,"shadowNormalBias");shadowRadius=this.get(zn,"shadowRadius");shadowMapSize=this.get(On,"shadowMapSize")},new Vo("NUM_SPOT_LIGHT_SHADOWS")),dl=(new To("spotShadowMap",Xs,new Vo("NUM_SPOT_LIGHT_SHADOWS")),new To("spotShadowMatrix",hs,new Vo("NUM_SPOT_LIGHT_SHADOWS")));new To("CSM_cascades",On,al);import*as hl from"three";import{ShaderMaterial as pl,UniformsUtils as fl}from"three";function ml(e,t,r){return new class extends Object.getPrototypeOf(t).constructor{compile(i){if(Yi(i))return{out:i.get(t)};const n=`select_out_${i.variable()}`,a=t.constructor.typeName,s=i.forceAppend;i.forceAppend=!0;const o=rn.level;rn.level=this.scopeLevel,i.startScope(`\n ${a} ${n} = ${i.get(t)};\n #ifdef ${e}`);const l=r(t);return i.stopScope(`\n ${n} = ${i.get(l)};\n #endif\n `),rn.level=o,i.forceAppend=s,{out:n}}}}var gl=new co("batchingTexture",void 0,"USE_BATCHING"),vl=new class extends Js{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new ao(t):void 0}get value(){return this.currentValue}set value(e){this.currentValue=e,null!=this.binding&&(this.binding.value=e)}compile(e){return Yi(e)?e.defineTexture(this.name,this.value):e.defineUniform("usampler2D",this.name,this.value,this.ifdef,this.binding)}}("batchingIdTexture",void 0,"USE_BATCHING"),xl=(new co("batchingColorTexture",void 0,"USE_BATCHING"),class extends zn{drawId;constructor(e){super(),this.drawId=e}compile(e){if(Yi(e))return{out:`f32(${e.get(this.drawId)})`};const t=Jo(vl,0).x,r=this.drawId.mod(t),i=this.drawId.divide(t);return{out:e.get(Qi(Qo(vl,mo(r,i),0).x))}}}),wl=new class extends pn{compile(e){return Yi(e)?{out:"i32(rendererBatchingId(input.instanceIndex))"}:{pars:"\n #if ! defined( GL_ANGLE_multi_draw )\n #define gl_DrawID _gl_DrawID\n uniform int _gl_DrawID;\n #endif\n ",out:"gl_DrawID"}}};var bl=function(e){const t=Jo(gl,0).x,r=en(e).multiply(4),i=r.mod(t),n=r.divide(t);return bo(Qo(gl,mo(i,n),0),Qo(gl,mo(i.add(1),n),0),Qo(gl,mo(i.add(2),n),0),Qo(gl,mo(i.add(3),n),0))}(new xl(wl)),yl=new lo("bindMatrix",void 0,"USE_SKINNING"),Sl=new lo("bindMatrixInverse",void 0,"USE_SKINNING"),Cl=new co("boneTexture",void 0,"USE_SKINNING");function Ml(e){const t=Jo(Cl,0).x,r=en(e).multiply(4),i=r.mod(t),n=r.divide(t);return bo(Qo(Cl,mo(i,n),0),Qo(Cl,mo(i.add(1),n),0),Qo(Cl,mo(i.add(2),n),0),Qo(Cl,mo(i.add(3),n),0))}var Pl=new Lo("skinIndex"),Bl=new Lo("skinWeight"),Dl=Ml(Pl.x),Tl=Ml(Pl.y),Il=Ml(Pl.z),Vl=Ml(Pl.w),Gl=xo(0,0,0,0),Ll=bo(Gl,Gl,Gl,Gl);Ll=(Ll=(Ll=(Ll=Ll.add(Dl.multiplyScalar(Bl.x))).add(Tl.multiplyScalar(Bl.y))).add(Il.multiplyScalar(Bl.z))).add(Vl.multiplyScalar(Bl.w)),Ll=Sl.multiply(Ll).multiply(yl);var zl=new zo("vertexTransform"),Rl=_o.instanceMatrix.multiplyVec(zl.multiplyVec(El(Oo.position)));Rl=ml("USE_SKINNING",Rl,e=>function(e){const t=yl.multiplyVec(e),r=Gl.add(Dl.multiplyVec(t).multiplyScalar(Bl.x)).add(Tl.multiplyVec(t).multiplyScalar(Bl.y)).add(Il.multiplyVec(t).multiplyScalar(Bl.z)).add(Vl.multiplyVec(t).multiplyScalar(Bl.w));return Sl.multiplyVec(r)}(e)),Rl=ml("USE_BATCHING",Rl,e=>bl.multiplyVec(e));var Ul,Al,kl=_o.modelViewMatrix.multiplyVec(Rl),Fl={position:Rl,mvPosition:kl,worldPosition:_o.modelMatrix.multiplyVec(Rl).xyz,normal:Wo(_o.normalMatrix.multiplyVec(function(e){return jo("transpose",e)}((Al=zl,jo("inverse",Al))).multiplyVec(El(ml("USE_INSTANCING",ml("USE_BATCHING",ml("USE_SKINNING",Oo.normal,e=>{return t=Oo.normal,Ll.multiplyVec(xo(t,0)).xyz;var t}),e=>{const t=wo(bl);return t.multiplyVec(e.divide(vo(Xo(t.col(0),t.col(0)),Xo(t.col(1),t.col(1)),Xo(t.col(2),t.col(2)))))}),e=>{const t=wo(new zo("instanceMatrix"));return t.multiplyVec(e.divide(vo(Xo(t.col(0),t.col(0)),Xo(t.col(1),t.col(1)),Xo(t.col(2),t.col(2)))))}),1)).xyz)),viewDir:Wo((Ul=kl.xyz,Ul.multiplyScalar(Qi(-1))))},$l={position:new ho(Fl.position),mvPosition:new ho(Fl.mvPosition),normal:Wo(new uo(Fl.normal)),worldPosition:new uo(Fl.worldPosition),viewDir:new uo(Fl.viewDir)};function El(e,t=1){return new Ia(new il(e,"x"),function(e){return new il(e,"y")}(e),function(e){return new il(e,"z")}(e),new Un(t))}new ps(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),function(e,t=1){if(e instanceof ha)return new Ps(e.x,e.y,e.z,Qi(t));if(e instanceof Da)return new Ps(e.x,e.y,e.z,null!=t?Qi(t):e.w);const r=new Ei(e);new Ps(Qi(r.r),Qi(r.g),Qi(r.b),Qi(t))}(0);var Ol=new oo("cameraNear"),_l=new oo("shadowFar"),jl=(new so("receiveShadow",!1),Qi(1e-6),Qi(.3183098861837907),$l.mvPosition.z.multiply(Qi(-1)).divide(_l.subtract(Ol))),Nl=Fl.mvPosition.z.multiply(Qi(-1)).divide(_l.subtract(Ol)),Wl=class extends zn{glslDepth;fragment;constructor(e,t){super(),this.glslDepth=e,this.fragment=t}compile(e){if(Yi(e)){return{out:`-(rendererCamera.view * vec4<f32>(${this.fragment&&Xi(e)?"input.worldPosition":`rendererWorldPosition(${e.getRendererVertexPosition()}, input.instanceIndex).xyz`}, 1.0)).z / max(rendererCameraFar() - rendererCameraNear(), 0.0001)`}}return{out:e.get(this.glslDepth)}}};new Wl(jl,!0),new Wl(Nl,!1),Qi(1);import{Matrix3 as Hl}from"three";Qi(1),Qi(-2),Qi(.8),Qi(-1),Qi(.4),Qi(2),Qi(.305),Qi(3),Qi(.21),Qi(4);import{Color as ql,ColorManagement as Kl,HalfFloatType as Zl,LinearMipmapLinearFilter as Yl,NoToneMapping as Xl,UnsignedByteType as Jl,Vector2 as Ql,WebGLRenderTarget as ec}from"three";tc=vo(No(_o.modelMatrix.col(0).xyz),No(_o.modelMatrix.col(1).xyz),No(_o.modelMatrix.col(2).xyz)),new class extends Object.getPrototypeOf(tc).constructor{compile(e){if(e instanceof Co||Xi(e))return e.defineVarying(tc.constructor.typeName,tc);throw new Error("A varying can not be defined as input to another varying.")}},vo(0,0,0),vo(1,1,1),Qi(1),Qi(0);var tc,rc=Qi(1e-6);new oo("envMapIntensity",1),new class extends es{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new ao(t):void 0}get value(){return this.currentValue}set value(e){this.currentValue=e,null!=this.binding&&(this.binding.value=e)}compile(e){return e.defineUniform("mat3",this.name,this.value,this.ifdef,this.binding)}}("envMapRotation",new Hl),new co("envMap");var ic,nc=_o.modelMatrix.multiplyVec(Fl.position),ac=(ic=xo(Fl.normal,0).multiplyMat(_o.viewMatrix).xyz).multiplyScalar(function(e){return jo("inversesqrt",e)}(function(e,t){return Ho(Object.getPrototypeOf(e).constructor,"max",e,t)}(Xo(ic,ic),rc))),sc=sl.map((e,t)=>{const r=nc.add(xo(ac.multiplyScalar(e.shadowNormalBias),0));return ol.get(t).multiplyVec(r)}),oc=(po(sc),ul.map((e,t)=>{const r=nc.add(xo(ac.multiplyScalar(e.shadowNormalBias),0));return dl.get(t).multiplyVec(r)})),lc=(po(oc),ll.map((e,t)=>{const r=nc.add(xo(ac.multiplyScalar(e.shadowNormalBias),0));return cl.get(t).multiplyVec(r)}));po(lc),vo(1),vo(1),fo(0),fo(0),$l.normal,go(1,0),xo(-1,-.0275,-.572,.022),xo(1,.0425,1.04,-.04),new class extends ha{glslValue;constructor(e){super(),this.glslValue=e}compile(e){return Yi(e)?Xi(e)?(e.markRendererWorldNormal(),{out:"(input.worldNormal * inverseSqrt(max(dot(input.worldNormal, input.worldNormal), 1e-6)))"}):{out:`rendererWorldNormal(${e.getRendererVertexNormal()}, input.instanceIndex)`}:{out:e.get(this.glslValue)}}}($l.normal);import{Matrix3 as cc}from"three";Qi(1),Qi(0),Qi(1e-6),_o.modelMatrix.multiplyVec(Fl.position),Wo(xo(Fl.normal,0).multiplyMat(_o.viewMatrix).xyz),fo(0),fo(0),Qi(1),$l.normal,fo(8950960),fo(16740429),fo(9424895),fo(16777215),fo(12179967);var uc=class{nextBinding=0;bindings=new WeakMap;usedNames=new Set;reserve(e){return this.usedNames.add(e),e}allocate(e){const t=this.bindings.get(e);if(null!=t)return t;let r;do{r="nodeTexture"+ ++this.nextBinding}while(this.usedNames.has(r));return this.usedNames.add(r),this.bindings.set(e,r),r}},dc=class{externalBindings;bindings=new Map;usedLocations=new Set([0,1,2,3,4,5]);constructor(e){this.externalBindings=e}resolve(e,t){const r=this.bindings.get(e);if(null!=r)return r;const i=this.externalBindings.attributes?.[e];if(null!=i){if(this.usedLocations.has(i.shaderLocation))throw new Error(`WGSL vertex attribute "${e}" uses an already allocated location ${i.shaderLocation}.`);const t={name:e,...i};return this.usedLocations.add(t.shaderLocation),this.bindings.set(e,t),t}let n=6;for(;this.usedLocations.has(n);)n+=1;const a={name:e,shaderLocation:n,format:t};return this.usedLocations.add(n),this.bindings.set(e,a),a}},hc=class extends So{externalBindings;textureBindings;vertexAttributeBindings;isWgslCompiler=!0;wgslDefinitions=[];uniqueWgslDefinitions=new Set;loopIndices=[];vertexAttributes=new Map;rendererVertexPosition="input.position";rendererVertexNormal="input.normal";constructor(e={},t=new uc,r=new dc(e)){super(),this.externalBindings=e,this.textureBindings=t,this.vertexAttributeBindings=r}local(e,t,r){return`let ${t}: ${this.type(e)} = ${r};`}type(e){switch(e){case"bool":return"bool";case"int":return"i32";case"uint":return"u32";case"float":return"f32";case"vec2":return"vec2<f32>";case"vec3":return"vec3<f32>";case"vec4":return"vec4<f32>";case"ivec2":return"vec2<i32>";case"ivec3":return"vec3<i32>";case"ivec4":return"vec4<i32>";case"uvec2":return"vec2<u32>";case"uvec3":return"vec3<u32>";case"uvec4":return"vec4<u32>";case"mat2":return"mat2x2<f32>";case"mat3":return"mat3x3<f32>";case"mat4":return"mat4x4<f32>";default:throw new Error(`WGSL emitter does not support the GLSL type "${e}".`)}}construct(e,t){return`${this.type(e)}(${t.join(", ")})`}floatLiteral(e){if(!Number.isFinite(e))throw new Error("WGSL emitter cannot represent a non-finite float literal.");return Number.isInteger(e)?`${e}.0`:`${e}`}zero(e){switch(e){case"bool":return"false";case"int":return"0";case"uint":return"0u";case"float":return"0.0";default:return this.construct(e,["0.0"])}}pushLoopIndex(e){this.loopIndices.push(e)}popLoopIndex(){if(null==this.loopIndices.pop())throw new Error("WGSL emitter attempted to leave a loop that was not open.")}currentLoopIndex(){const e=this.loopIndices[this.loopIndices.length-1];if(null==e)throw new Error("A graph loop index was read outside of a WGSL loop.");return e}getArrayBinding(e){return this.externalBindings.arrays?.[e]}getVertexAttribute(e,t){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))throw new Error(`WGSL emitter cannot use "${e}" as a vertex attribute name.`);const r=function(e){switch(e){case"float":return"float32";case"vec2":return"float32x2";case"vec3":return"float32x3";case"vec4":return"float32x4";default:throw new Error(`WGSL custom vertex attributes currently support scalar and vector float nodes, not ${e}.`)}}(t),i=this.vertexAttributeBindings.resolve(e,r);if(i.shaderLocation<6)throw new Error(`WGSL custom vertex attribute "${e}" must use location 6 or greater; locations 0 through 5 are reserved by the renderer mesh ABI.`);if(i.format!==r)throw new Error(`WGSL vertex attribute "${e}" is ${i.format}, but ${t} nodes require ${r}.`);const n=this.vertexAttributes.get(e),a=i;if(null!=n&&(n.shaderLocation!==a.shaderLocation||n.format!==a.format))throw new Error(`WGSL vertex attribute "${e}" was declared with incompatible bindings.`);return this.vertexAttributes.set(e,a),{out:`input.${e}`}}getVertexAttributes(){return[...this.vertexAttributes.values()]}setRendererVertexGeometry(e,t){this.rendererVertexPosition=e,this.rendererVertexNormal=t}getRendererVertexPosition(){return this.rendererVertexPosition}getRendererVertexNormal(){return this.rendererVertexNormal}getExternalBindings(){return this.externalBindings}getTextureBindingAllocator(){return this.textureBindings}addWgslDefinition(e){this.uniqueWgslDefinitions.has(e)||(this.uniqueWgslDefinitions.add(e),this.wgslDefinitions.push(e))}getWgslDefinitions(){return this.wgslDefinitions}defineUniform(e,t,r,i,n){if(e.startsWith("sampler"))throw new Error("WGSL texture nodes must use defineTexture().");if(null!=t&&t in this.uniformNodes)return{out:this.get(this.uniformNodes[t])};const a=null==t?void 0:this.externalBindings.uniformExpressions?.[t];if(null!=a){if(a.type!==e)throw new Error(`WGSL renderer uniform expression "${t}" expects ${a.type}, but the graph requested ${e}.`);return{out:a.expression}}const s=`materialUniforms.${super.defineUniform("bool"===e?"int":e,t,"bool"===e&&"boolean"==typeof r?Number(r):r,i,n).out}`;return{out:"bool"===e?`(${s} != 0)`:s}}textures={};sceneTextures={};graphTextures={};textureSampleTypes=new Map;defineTexture(e,t){if(null!=e){const t=this.externalBindings.graphTextures?.[e];if(null!=t){const r=this.textureBindings.reserve(e),i=pc(r);return this.graphTextures[r]=t,this.textureSampleTypes.set(i,t.sampleType),{out:i}}const r=this.externalBindings.sceneTextures?.[e];if(null!=r){const t=this.textureBindings.reserve(e),i=pc(t);return this.sceneTextures[t]=r.semantic,this.textureSampleTypes.set(i,r.sampleType),{out:i}}}const r=(null==e?void 0:this.externalBindings.textures?.[e])??t;if(null==r)throw new Error(`The WGSL emitter requires an initial Texture value${null==e?"":` for "${e}"`}.`);const i=null==e?this.textureBindings.allocate(r):this.textureBindings.reserve(e);this.textures[i]=r;const n=pc(i);return this.textureSampleTypes.set(n,!0===r.isDepthTexture?"depth":"float"),{out:n}}getTextureSampleType(e){return this.textureSampleTypes.get(e)??"float"}};function pc(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}var fc={uniformExpressions:{fogColor:{type:"vec3",expression:"rendererFogColor()"},fogNear:{type:"float",expression:"rendererFogNear()"},fogFar:{type:"float",expression:"rendererFogFar()"},fogDensity:{type:"float",expression:"rendererFogDensity()"},fogMode:{type:"float",expression:"rendererFogMode()"}},arrays:{directionalLights:{capacity:4,activeCount:"i32(rendererDirectionalLightCount())",element:e=>`rendererDirectionalLightForLight(u32(${e}))`},directionalLightShadows:{capacity:4,activeCount:"i32(rendererDirectionalLightCount())",element:e=>`rendererDirectionalLightShadowForLight(u32(${e}))`},pointLights:{capacity:64,activeCount:"i32(rendererPointLightCount())",element:e=>`rendererPointLightForLight(u32(${e}))`},pointLightShadows:{capacity:64,activeCount:"i32(rendererPointLightCount())",element:e=>`rendererPointLightShadowForLight(u32(${e}))`},spotLights:{capacity:64,activeCount:"i32(rendererSpotLightCount())",element:e=>`rendererSpotLightForLight(u32(${e}))`},spotLightShadows:{capacity:64,activeCount:"i32(rendererSpotLightCount())",element:e=>`rendererSpotLightShadowForLight(u32(${e}))`},CSM_cascades:{capacity:4,activeCount:"i32(rendererCsmCascadeCount())",element:e=>`rendererCsmCascadeRangeForLight(u32(${e}))`}}};fc.arrays.pointLights;function mc(e){if(/\b(?:attribute|varying|uniform|texture2D|gl_Position|#if|#ifdef|#endif|float\s*\(|vec[234]\s*\(|mat[234]\s*\()\b/.test(e)||/\b(?:float|vec[234])\s+[A-Za-z_]\w*\s*=/.test(e))throw new Error("The WebGPU material graph contains a node without a native WGSL emitter. Port that node before compiling this material for WebGPU.")}var gc=255/256,vc=[1,256,65536,16777216],xc=[gc,1/vc[1]],wc=(go(xc[0],xc[1]),[gc/vc[0],gc/vc[1],1/vc[2]]),bc=(vo(wc[0],wc[1],wc[2]),[gc/vc[0],gc/vc[1],gc/vc[2],1/vc[3]]),yc=(xo(bc[0],bc[1],bc[2],bc[3]),class extends zn{constructor(e){super(),this.name=e}name;compile(){return{out:this.name}}}),Sc=new yc("radius"),Cc=new yc("scale"),Mc=new yc("threshold"),Pc=new yc("boundary"),Bc=new yc("maxDistance"),Dc=new yc("distanceSquared"),Tc=Bc.add(Sc),Ic=function(e){const t=new hc,r=t.get(e);if(Object.keys(t.uniformTypes).length||Object.keys(t.textures).length||Object.keys(t.graphTextures).length||Object.keys(t.sceneTextures).length||t.getVertexAttributes().length)throw new Error("WGSL expressions require explicit parameters, not resource bindings.");const i=t.chunks.join("\n"),n=t.getWgslDefinitions().join("\n");return mc(i),mc(n),{expression:r,statements:i,definitions:n}}(Mc.lte(0).or(Sc.multiply(Cc).gte(Mc.multiply(Pc))).and(Bc.lte(0).or(Dc.lte(Tc.multiply(Tc))))),Vc=`\nstruct ShadowCullParams {\n planes: array<vec4<f32>, 6>,\n viewer: vec4<f32>,\n diameterPerRadius: f32,\n instanceCount: u32,\n drawCount: u32,\n padding: u32,\n};\nstruct ShadowInstance { centerRadius: vec4<f32>, drawAndSource: vec4<u32> };\n@group(0) @binding(0) var<uniform> params: ShadowCullParams;\n@group(0) @binding(1) var<storage, read> metadata: array<ShadowInstance>;\n@group(0) @binding(2) var<storage, read> policies: array<vec4<f32>>;\n@group(0) @binding(3) var<storage, read_write> indirect: array<atomic<u32>>;\n@group(0) @binding(4) var<storage, read_write> indices: array<u32>;\n@group(0) @binding(5) var<storage, read_write> history: array<u32>;\n${`${Ic.definitions}\nfn shadowDetailVisible(radius: f32, scale: f32, threshold: f32, boundary: f32,\n maxDistance: f32, distanceSquared: f32) -> bool {\n ${Ic.statements}\n return ${Ic.expression};\n}`}\n\n@compute @workgroup_size(64)\nfn clear(@builtin(global_invocation_id) id: vec3<u32>) {\n if (id.x < params.drawCount) { atomicStore(&indirect[id.x * 5u + 1u], 0u); }\n}\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) id: vec3<u32>) {\n if (id.x >= params.instanceCount) { return; }\n let instance = metadata[id.x];\n let draw = instance.drawAndSource.x;\n if (draw >= params.drawCount) { return; }\n let policy = policies[draw];\n if (policy.z < 0.5 || policy.w < 0.5) { history[id.x] = 0u; return; }\n let sphere = instance.centerRadius;\n let delta = sphere.xyz - params.viewer.xyz;\n let boundary = select(1.15, 0.85, history[id.x] != 0u);\n var visible = shadowDetailVisible(sphere.w, params.diameterPerRadius, policy.x,\n boundary, policy.y, dot(delta, delta));\n for (var plane = 0u; plane < 6u && visible; plane++) {\n visible = dot(params.planes[plane].xyz, sphere.xyz) + params.planes[plane].w >= -sphere.w;\n }\n history[id.x] = select(0u, 1u, visible);\n if (!visible) { return; }\n let destination = atomicLoad(&indirect[draw * 5u + 4u]);\n let slot = atomicAdd(&indirect[draw * 5u + 1u], 1u);\n indices[destination + slot] = instance.drawAndSource.y;\n}\n`,Gc="\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> @builtin(position) @invariant vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n return shadowCamera.viewProj * world;\n}\n",Lc="\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\nstruct PointShadowVertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> PointShadowVertexOutput {\n var output: PointShadowVertexOutput;\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n output.position = shadowCamera.viewProj * world;\n output.worldPosition = world.xyz;\n return output;\n}\n\n@fragment\nfn fsMain(input: PointShadowVertexOutput) -> @location(0) vec4<f32> {\n let distanceToLight = length(input.worldPosition - shadowCamera.lightPositionRange.xyz);\n let normalizedDepth = clamp(distanceToLight / shadowCamera.lightPositionRange.w, 0.0, 1.0);\n return vec4(normalizedDepth, normalizedDepth, normalizedDepth, 1.0);\n}\n",zc="\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\nstruct PointShadowVertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstanceMatrices: array<vec4<f32>>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let base = instanceIndex * 4u;\n return mat4x4<f32>(\n rendererInstanceMatrices[base + 0u],\n rendererInstanceMatrices[base + 1u],\n rendererInstanceMatrices[base + 2u],\n rendererInstanceMatrices[base + 3u]\n );\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> PointShadowVertexOutput {\n var output: PointShadowVertexOutput;\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n output.position = shadowCamera.viewProj * world;\n output.worldPosition = world.xyz;\n return output;\n}\n\n@fragment\nfn fsMain(input: PointShadowVertexOutput) -> @location(0) vec4<f32> {\n let distanceToLight = length(input.worldPosition - shadowCamera.lightPositionRange.xyz);\n let normalizedDepth = clamp(distanceToLight / shadowCamera.lightPositionRange.w, 0.0, 1.0);\n return vec4(normalizedDepth, normalizedDepth, normalizedDepth, 1.0);\n}\n",Rc="\nstruct RendererSkinningUniforms {\n bindMatrix: mat4x4<f32>,\n bindMatrixInverse: mat4x4<f32>,\n};\n\n@group(2) @binding(0) var<storage, read> rendererBoneMatrixColumns: array<vec4<f32>>;\n@group(2) @binding(1) var<uniform> rendererSkinning: RendererSkinningUniforms;\n\nfn rendererBoneMatrix(index: u32) -> mat4x4<f32> {\n let base = index * 4u;\n return mat4x4<f32>(\n rendererBoneMatrixColumns[base + 0u],\n rendererBoneMatrixColumns[base + 1u],\n rendererBoneMatrixColumns[base + 2u],\n rendererBoneMatrixColumns[base + 3u],\n );\n}\n\nfn rendererSkinPosition(position: vec3<f32>, skinIndex: vec4<u32>, skinWeight: vec4<f32>) -> vec3<f32> {\n let boundPosition = rendererSkinning.bindMatrix * vec4(position, 1.0);\n let weightSum = skinWeight.x + skinWeight.y + skinWeight.z + skinWeight.w;\n if (weightSum <= 0.0) {\n return position;\n }\n let skinnedPosition =\n (rendererBoneMatrix(skinIndex.x) * boundPosition) * skinWeight.x +\n (rendererBoneMatrix(skinIndex.y) * boundPosition) * skinWeight.y +\n (rendererBoneMatrix(skinIndex.z) * boundPosition) * skinWeight.z +\n (rendererBoneMatrix(skinIndex.w) * boundPosition) * skinWeight.w;\n let fallbackWeight = max(0.0, 1.0 - weightSum);\n return (rendererSkinning.bindMatrixInverse * (skinnedPosition + boundPosition * fallbackWeight)).xyz;\n}\n",Uc=`\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> rendererLights: array<vec4<f32>, 11>;\n@group(0) @binding(2) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\n${Rc}\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @location(1) skinIndex: vec4<u32>,\n @location(2) skinWeight: vec4<f32>,\n @builtin(instance_index) instanceIndex: u32,\n) -> @builtin(position) @invariant vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(rendererSkinPosition(position, skinIndex, skinWeight), 1.0);\n return rendererCamera.viewProj * world;\n}\n`,Ac=`\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\n${Rc}\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @location(1) skinIndex: vec4<u32>,\n @location(2) skinWeight: vec4<f32>,\n @builtin(instance_index) instanceIndex: u32,\n) -> @builtin(position) vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(rendererSkinPosition(position, skinIndex, skinWeight), 1.0);\n return shadowCamera.viewProj * world;\n}\n`,kc=`\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\nstruct PointShadowVertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\n${Rc}\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @location(1) skinIndex: vec4<u32>,\n @location(2) skinWeight: vec4<f32>,\n @builtin(instance_index) instanceIndex: u32,\n) -> PointShadowVertexOutput {\n var output: PointShadowVertexOutput;\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(rendererSkinPosition(position, skinIndex, skinWeight), 1.0);\n output.position = shadowCamera.viewProj * world;\n output.worldPosition = world.xyz;\n return output;\n}\n\n@fragment\nfn fsMain(input: PointShadowVertexOutput) -> @location(0) vec4<f32> {\n let distanceToLight = length(input.worldPosition - shadowCamera.lightPositionRange.xyz);\n let normalizedDepth = clamp(distanceToLight / shadowCamera.lightPositionRange.w, 0.0, 1.0);\n return vec4(normalizedDepth, normalizedDepth, normalizedDepth, 1.0);\n}\n`,Fc="\nstruct FullscreenVertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) uv: vec2<f32>,\n};\n\n@group(0) @binding(0) var sourceSampler: sampler;\n@group(0) @binding(1) var sourceTexture: texture_2d<f32>;\n\n@vertex\nfn vsMain(@builtin(vertex_index) vertexIndex: u32) -> FullscreenVertexOutput {\n var output: FullscreenVertexOutput;\n let position = array<vec2<f32>, 3>(\n vec2(-1.0, -3.0),\n vec2(-1.0, 1.0),\n vec2(3.0, 1.0),\n );\n let clip = position[vertexIndex];\n output.position = vec4(clip, 0.0, 1.0);\n output.uv = clip * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n return output;\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let linearColor = textureSample(sourceTexture, sourceSampler, input.uv);\n let low = linearColor.rgb * 12.92;\n let high = 1.055 * pow(max(linearColor.rgb, vec3<f32>(0.0)), vec3<f32>(1.0 / 2.4)) - 0.055;\n let srgb = select(high, low, linearColor.rgb <= vec3<f32>(0.0031308));\n return vec4<f32>(srgb, linearColor.a);\n}\n";function $c(e){return`\nstruct FullscreenVertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) uv: vec2<f32>,\n};\n\n@group(0) @binding(0) var sourceSampler: sampler;\n@group(0) @binding(1) var sourceTexture: texture_2d<f32>;\n\n@vertex\nfn vsMain(@builtin(vertex_index) vertexIndex: u32) -> FullscreenVertexOutput {\n var output: FullscreenVertexOutput;\n let position = array<vec2<f32>, 3>(\n vec2(-1.0, -3.0),\n vec2(-1.0, 1.0),\n vec2(3.0, 1.0),\n );\n let clip = position[vertexIndex];\n output.position = vec4(clip, 0.0, 1.0);\n output.uv = clip * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n return output;\n}\n\n @fragment\n fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let source = textureSample(sourceTexture, sourceSampler, input.uv);\n ${e?"return vec4(source.rgb, 1.0);":"return vec4(clamp(source.rgb, vec3(0.0), vec3(1.0)), clamp(source.a / 3.0, 0.0, 1.0));"}\n }\n`}var Ec=$c(!1),Oc=$c(!0),_c=class{enabled=!0;available=!1;sets=new Map;device=null;layout=null;clear=null;cull=null;pipeline=null;matrix=new Fi;frustum=new ki;viewer=new $i;paramData=new Float32Array(32);paramInts=new Uint32Array(this.paramData.buffer);async initialize(e,t){if(!e.features.has("indirect-first-instance"))return;this.device=e,this.layout=t;const r=Array.from({length:6},(e,t)=>({binding:t,visibility:GPUShaderStage.COMPUTE,buffer:{type:0===t?"uniform":t<3?"read-only-storage":"storage"}})),i=Vc,n=Gc.replace("let instance = rendererInstances[instanceIndex];","let instance = rendererInstances[rendererVisibleInstanceIndices[instanceIndex]];").replace("@vertex","@group(0) @binding(2) var<storage, read> rendererVisibleInstanceIndices: array<u32>;\n@vertex");[this.clear,this.cull,this.pipeline]=await Promise.all([W.createAsync(e,{label:"directional-shadow-clear",code:i,entryPoint:"clear",bindGroupLayoutEntries:r}),W.createAsync(e,{label:"directional-shadow-cull",code:i,bindGroupLayoutEntries:r}),j(e,{label:"directional-shadow-visible-depth",layout:e.createPipelineLayout({bindGroupLayouts:[t]}),vertex:{module:e.createShaderModule({code:n}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"front",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}})]),this.available=!0}buffer(e,t,r){return this.device.createBuffer({label:e,size:256*Math.ceil(Math.max(4,t)/256),usage:r})}getSet(e){let t=this.sets.get(e);if(!t){const r=new Uint32Array(5*e.draws.length);for(let t=0;t<e.draws.length;t++){const i=e.draws[t];r.set([i.count,0,i.start,0,i.instanceStart],5*t)}t={eligibleDrawCount:0,triangleCount:0,commands:r,policies:this.buffer(`${e.label}-shadow-policies`,16*e.draws.length,GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST),policyData:new Float32Array(4*e.draws.length),eligibility:new Uint8Array(e.draws.length),eligibilityVersion:0,layers:new Map},t.policyData.fill(NaN),this.sets.set(e,t),e.disposeDirectionalGpuShadows=()=>this.disposeSet(e)}return t}eligible(e){if(!e.indexed||e.wireframe||e.skinning||e.hasRenderCallbacks||"triangle-list"!==e.material.primitiveTopology||"packed"!==e.residentInstanceBinding?.mode)return!1;const t=e.customDepthMaterial??(null!==e.material.depthVertexShader?e.material:null);return!t||"triangle-list"===t.primitiveTopology&&!t.vertexAttributes.some(e=>"instance"===e.stepMode)}prepare(e,t,r,i,n,a,s,o,l){if(!this.enabled||!this.available||r.instanceCount>64*this.device.limits.maxComputeWorkgroupsPerDimension)return null;const c=this.getSet(r);c.eligibleDrawCount=0,c.triangleCount=0;let u=!1,d=!1;for(let e=0;e<r.draws.length;e++){const t=r.draws[e],i=t.detailCulling,n=this.eligible(t)?1:0,a=4*e;d||=c.eligibility[e]!==n,c.eligibility[e]=n,n&&(c.eligibleDrawCount++,t.castShadow&&(c.triangleCount+=Ti(t)));const s=Math.fround(i.shadowMinScreenSize),o=Math.fround(i.shadowMaxDistance),l=t.castShadow?1:0;c.policyData[a]===s&&c.policyData[a+1]===o&&c.policyData[a+2]===l&&c.policyData[a+3]===n||(u=!0),c.policyData[a]=s,c.policyData[a+1]=o,c.policyData[a+2]=l,c.policyData[a+3]=n}u&&this.device.queue.writeBuffer(c.policies,0,c.policyData),d&&c.eligibilityVersion++;let h=c.layers.get(n);if(!h){const e=GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,t=this.buffer(`${r.label}-shadow-cull-params`,128,GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST),i=this.buffer(`${r.label}-shadow-indirect`,c.commands.byteLength,e|GPUBufferUsage.INDIRECT),a=this.buffer(`${r.label}-shadow-indices`,4*r.instanceCount,e),s=this.buffer(`${r.label}-shadow-history`,4*r.instanceCount,e);this.device.queue.writeBuffer(i,0,c.commands);const o=[t,r.instanceVisibilityResource.instanceMetadataBuffer,c.policies,i,a,s].map((e,t)=>({binding:t,resource:{buffer:e}}));h={params:t,indirect:i,indices:a,history:s,clearGroup:this.clear.createBindGroup(this.device,o),cullGroup:this.cull.createBindGroup(this.device,o),shadowGroup:this.device.createBindGroup({layout:this.layout,entries:[{binding:0,resource:{buffer:n}},{binding:1,resource:{buffer:r.instanceBuffer}},{binding:2,resource:{buffer:a}}]}),bundle:null,materials:[],eligibilityVersion:-1,bundles:[],materialCacheKey:`directional-shadow-gpu-${c.layers.size}`},c.layers.set(n,h),r.depthMaterialResources.set(h.materialCacheKey,h.materials)}this.frustum.setFromProjectionMatrix(this.matrix.multiplyMatrices(i.projectionMatrix,i.matrixWorldInverse));for(let e=0;e<6;e++){const t=this.frustum.planes[e],r=4*e;this.paramData[r]=t.normal.x,this.paramData[r+1]=t.normal.y,this.paramData[r+2]=t.normal.z,this.paramData[r+3]=t.constant}const p=l??a.getWorldPosition(this.viewer);this.paramData[24]=p.x,this.paramData[25]=p.y,this.paramData[26]=p.z,this.paramData[28]=Math.max(Math.abs(i.projectionMatrix.elements[0]),Math.abs(i.projectionMatrix.elements[5]))*s,this.paramInts[29]=r.instanceCount,this.paramInts[30]=r.draws.length,this.device.queue.writeBuffer(h.params,0,this.paramData);let f=!h.bundle||h.eligibilityVersion!==c.eligibilityVersion;for(let t=0;t<r.draws.length;t++){const i=r.draws[t],n=i.customDepthMaterial??(null!==i.material.depthVertexShader?i.material:null),a=c.eligibility[t]&&n?e.getDepthPassMaterialResourceForDraw(n,"directionalShadow",i,"packed-visible"):null;h.materials[t]!==a&&(f=!0),h.materials[t]=a}f&&this.buildBundle(e,r,c,h);const m=o??t.beginComputePass({label:`${r.label}-directional-shadow-selection`});return m.setPipeline(this.clear.pipeline),m.setBindGroup(0,h.clearGroup),m.dispatchWorkgroups(Math.ceil(r.draws.length/64)),m.setPipeline(this.cull.pipeline),m.setBindGroup(0,h.cullGroup),m.dispatchWorkgroups(Math.ceil(r.instanceCount/64)),o||m.end(),c.eligibility}buildBundle(e,t,r,i){const n=this.device.createRenderBundleEncoder({colorFormats:[],depthStencilFormat:"depth32float",sampleCount:1});let a=null,s=null,o=null;for(let l=0;l<t.draws.length;l++){if(!r.eligibility[l])continue;const c=t.draws[l],u=i.materials[l],d=u?.pipeline??this.pipeline;d!==a&&(n.setPipeline(d),n.setBindGroup(0,i.shadowGroup),a=d,s=null,o=null),u&&s!==u.bindGroup&&(n.setBindGroup(1,u.bindGroup),s=u.bindGroup),o!==c.geometryKey&&(e.bindGeometryVertexBuffers(n,c.geometry,c.geometryResource,u?.vertexAttributes??z,c.instanceStart,c.instanceCount,!1),o=c.geometryKey),n.drawIndexedIndirect(i.indirect,20*l)}i.bundle=n.finish(),i.bundles[0]=i.bundle,i.eligibilityVersion=r.eligibilityVersion}submit(e,t,r,i){const n=this.sets.get(t),a=n?.layers.get(r);return!!(this.enabled&&this.available&&n&&a)&&(e.executeBundles(a.bundles),i.drawCallCount+=n.eligibleDrawCount,i.directionalShadowGpuDraws=(i.directionalShadowGpuDraws??0)+n.eligibleDrawCount,i.triangleCount+=n.triangleCount,!0)}disposeSet(e){const t=this.sets.get(e);if(t){t.policies.destroy();for(const e of t.layers.values())e.params.destroy(),e.indirect.destroy(),e.indices.destroy(),e.history.destroy();t.layers.clear(),this.sets.delete(e),e.disposeDirectionalGpuShadows=void 0}}dispose(){for(const e of this.sets.keys())this.disposeSet(e);this.available=!1}},jc=class{records=new WeakMap;get(e,t,r,i,n,a,s){let o=this.records.get(e);o||(o=[],this.records.set(e,o));let l=o[t];if(!l||l.material!==r||l.customDepthMaterial!==s||l.indexed!==i||l.start!==n||l.count!==a){const c=oi(r),u=oi(e),d=s?oi(s):0;l={material:r,customDepthMaterial:s,indexed:i,start:n,count:a,materialId:c,geometryId:u,depthMaterialId:d,batchKey:li(r,e,i,n,a,s),batchHash:ci(c,u,i,n,a,d)},o[t]=l}return l}},Nc=class e{constructor(e,t,r,i){this.device=e,this.camera=t,this.lights=r,this.pipeline=i}device;camera;lights;pipeline;texture=null;textureView=null;bindGroup=null;columns=0;rows=0;static async createAsync(t,r,i){const n=await N(t,{label:"tiled-point-lights",layout:"auto",compute:{module:t.createShaderModule({label:"tiled-point-lights",code:"\nstruct Camera {\n viewProj: mat4x4<f32>,\n position: vec4<f32>,\n viewport: vec4<f32>,\n};\n@group(0) @binding(0) var<uniform> camera: Camera;\n@group(0) @binding(1) var<uniform> lights: array<vec4<f32>, 1001>;\n@group(0) @binding(2) var masks: texture_storage_2d<rg32uint, write>;\n\nfn normalizePlane(plane: vec4<f32>) -> vec4<f32> {\n return plane / max(length(plane.xyz), 1e-20);\n}\n\n@compute @workgroup_size(8, 8)\nfn main(@builtin(global_invocation_id) id: vec3<u32>) {\n if (any(id.xy >= textureDimensions(masks))) { return; }\n let lo = vec2<f32>(id.xy * 16u) / camera.viewport.xy;\n let hi = min(vec2<f32>((id.xy + 1u) * 16u), camera.viewport.xy) / camera.viewport.xy;\n let rows = transpose(camera.viewProj);\n let left = normalizePlane(rows[0] - (lo.x * 2.0 - 1.0) * rows[3]);\n let right = normalizePlane((hi.x * 2.0 - 1.0) * rows[3] - rows[0]);\n let top = normalizePlane((1.0 - lo.y * 2.0) * rows[3] - rows[1]);\n let bottom = normalizePlane(rows[1] - (1.0 - hi.y * 2.0) * rows[3]);\n var mask = vec2<u32>(0u);\n let count = min(u32(lights[1].y), 64u);\n for (var i = 0u; i < count; i++) {\n let center = vec4<f32>(lights[34u + i].xyz, 1.0);\n // Use the authored attenuation cutoff, NOT the finite shadow-camera range.\n let radius = lights[162u + i].x;\n let distance = min(min(dot(left, center), dot(right, center)), min(dot(top, center), dot(bottom, center)));\n // A small conservative tolerance avoids precision cracks on tile boundaries.\n if (radius <= 0.0 || distance >= -radius - max(0.001, radius * 1e-5)) {\n mask[i >> 5u] |= 1u << (i & 31u);\n }\n }\n textureStore(masks, vec2<i32>(id.xy), vec4<u32>(mask, 0u, 0u));\n}\n"}),entryPoint:"main"}});return new e(t,r,i,n)}get view(){if(!this.textureView)throw new Error("Tiled lighting has not been sized.");return this.textureView}resize(e,t){const r=Math.max(1,Math.ceil(e/16)),i=Math.max(1,Math.ceil(t/16));return(r!==this.columns||i!==this.rows)&&(this.texture?.destroy(),this.columns=r,this.rows=i,this.texture=this.device.createTexture({label:"tiled-point-light-masks",size:[r,i],format:"rg32uint",usage:GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.TEXTURE_BINDING}),this.textureView=this.texture.createView(),this.bindGroup=this.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:this.camera}},{binding:1,resource:{buffer:this.lights}},{binding:2,resource:this.textureView}]}),!0)}execute(e){const t=e.beginComputePass({label:"TiledPointLightsPass"});t.setPipeline(this.pipeline),t.setBindGroup(0,this.bindGroup),t.dispatchWorkgroups(Math.ceil(this.columns/8),Math.ceil(this.rows/8)),t.end()}destroy(){this.texture?.destroy()}};import{AdditiveBlending as Wc,BackSide as Hc,BufferAttribute as qc,BufferGeometry as Kc,Color as Zc,DoubleSide as Yc,FrontSide as Xc,InstancedBufferAttribute as Jc,InstancedBufferGeometry as Qc,InstancedMesh as eu,MultiplyBlending as tu,Matrix4 as ru,Mesh as iu,OrthographicCamera as nu,PerspectiveCamera as au,SkinnedMesh as su,Sphere as ou,SubtractiveBlending as lu,Vector2 as cu,Vector3 as uu,Vector4 as du,ShaderMaterial as hu}from"three";var pu=/^[A-Za-z_][A-Za-z0-9_]*$/;function fu(e,t={},r={}){const i=function(e){const t=new Map;for(const[r,i]of Object.entries(e))pu.test(r)&&!1!==i&&null!=i&&t.set(r,{name:r,parameters:null,body:mu(i)});return t}(t),n=new Map,a=[],s=[],o=e.split(/\r?\n/),l=r.sourceName??"shader";for(let e=0;e<o.length;e+=1){const t=o[e],r=gu(t),c=xu(a);if(!r){s.push(c?bu(t,i,n):"");continue}const{name:u,rest:d}=r;switch(u){case"define":if(c){const t=vu(d,i,l,e+1),r=i.get(t);null===r.parameters?n.delete(t):n.set(t,r)}s.push("");break;case"undef":c&&(i.delete(d.trim()),n.delete(d.trim())),s.push("");break;case"ifdef":{const e=c,t=e&&i.has(d.trim());a.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),s.push("");break}case"ifndef":{const e=c,t=e&&!i.has(d.trim());a.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),s.push("");break}case"if":{const e=c,t=e&&Tu(d,i);a.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),s.push("");break}case"elif":{const t=wu(a,l,e+1,u);if(t.elseSeen)throw new Error(`${l}:${e+1}: #elif after #else`);const r=t.parentActive&&!t.branchTaken&&Tu(d,i);t.active=r,t.branchTaken=t.branchTaken||r,s.push("");break}case"else":{const t=wu(a,l,e+1,u);if(t.elseSeen)throw new Error(`${l}:${e+1}: duplicate #else`);t.active=t.parentActive&&!t.branchTaken,t.branchTaken=!0,t.elseSeen=!0,s.push("");break}case"endif":wu(a,l,e+1,u),a.pop(),s.push("");break;case"error":if(c)throw new Error(`${l}:${e+1}: ${d.trim()||"#error"}`);s.push("");break;case"warning":case"line":case"version":case"pragma":s.push("");break;default:if(c)throw new Error(`${l}:${e+1}: unsupported preprocessor directive #${u}`);s.push("")}}if(a.length>0)throw new Error(`${l}: unterminated preprocessor conditional`);return s.join("\n")}function mu(e){return"boolean"==typeof e?e?"1":"0":String(e)}function gu(e){const t=/^\s*#\s*([A-Za-z_][A-Za-z0-9_]*)(.*)$/.exec(e);return t?{name:t[1],rest:t[2]??""}:null}function vu(e,t,r,i){const n=/^\s*([A-Za-z_][A-Za-z0-9_]*)(.*)$/.exec(e);if(!n)throw new Error(`${r}:${i}: invalid #define`);const a=n[1],s=n[2]??"";if(s.startsWith("(")){const e=Du(s,0);if(e<0)throw new Error(`${r}:${i}: invalid function-like #define ${a}`);const n=s.slice(1,e).trim(),o=0===n.length?[]:n.split(",").map(e=>e.trim());for(const e of o)if(!pu.test(e))throw new Error(`${r}:${i}: invalid macro parameter "${e}"`);return t.set(a,{name:a,parameters:o,body:Vu(s.slice(e+1)).trim()||"1"}),a}return t.set(a,{name:a,parameters:null,body:Vu(s).trim()||"1"}),a}function xu(e){for(const t of e)if(!t.active)return!1;return!0}function wu(e,t,r,i){const n=e[e.length-1];if(!n)throw new Error(`${t}:${r}: #${i} without matching #if`);return n}function bu(e,t,r){let i=e;for(let e=0;e<8;e+=1){const e=i;if(i=Su(i,r),i=yu(i,t),i===e)return i}return i}function yu(e,t){let r=null,i=0;for(let n=0;n<e.length;){let a=e.charCodeAt(n);if(a>=65&&a<=90||a>=97&&a<=122||95===a){const s=n++;let o=a>=65&&a<=90;for(;n<e.length;)if(a=e.charCodeAt(n),a>=65&&a<=90)n++;else if(a>=97&&a<=122)o=!1,n++;else{if(!(a>=48&&a<=57||95===a))break;n++}if(!o)continue;const l=e.slice(s,n),c=t.get(l);null===c?.parameters&&(r??=[],r.push(e.slice(i,s),c.body),i=n)}else n++}return null===r?e:(r.push(e.slice(i)),r.join(""))}function Su(e,t){if(0===t.size||!e.includes("("))return e;let r=e;for(const e of t.values())null!==e.parameters&&(r=Cu(r,e));return r}function Cu(e,t){let r="",i=0;for(;i<e.length;){const n=Mu(e,t.name,i);if(n<0){r+=e.slice(i);break}let a=n+t.name.length;for(;/\s/.test(e[a]??"");)a+=1;if("("!==e[a]){r+=e.slice(i,n+t.name.length),i=n+t.name.length;continue}const s=Du(e,a);if(s<0){r+=e.slice(i);break}const o=Bu(e.slice(a+1,s));r+=e.slice(i,n),r+=Pu(t,o),i=s+1}return r}function Mu(e,t,r){let i=e.indexOf(t,r);for(;i>=0;){const r=i>0?e[i-1]:"",n=e[i+t.length]??"";if(!/[A-Za-z0-9_]/.test(r)&&!/[A-Za-z0-9_]/.test(n))return i;i=e.indexOf(t,i+t.length)}return-1}function Pu(e,t){let r=e.body;const i=e.parameters??[];for(let e=0;e<i.length;e+=1){const n=i[e],a=t[e]?.trim()??"";r=r.replace(new RegExp(`\\b${Gu(n)}\\b`,"g"),a)}return r}function Bu(e){const t=[];let r=0,i=0;for(let n=0;n<e.length;n+=1){const a=e[n];"("===a?r+=1:")"===a?r-=1:","===a&&0===r&&(t.push(e.slice(i,n)),i=n+1)}return(e.length>0||i>0)&&t.push(e.slice(i)),t}function Du(e,t){let r=0;for(let i=t;i<e.length;i+=1){const t=e[i];if("("===t)r+=1;else if(")"===t&&(r-=1,0===r))return i}return-1}function Tu(e,t){const r=function(e){const t=[];let r=0;for(;r<e.length;){const i=e[r];if(/\s/.test(i)){r+=1;continue}const n=e.slice(r,r+2);if(["&&","||","==","!=","<=",">="].includes(n)){t.push({type:"operator",value:n}),r+=2;continue}if("!<>+-*/%".includes(i)){t.push({type:"operator",value:i}),r+=1;continue}if("("===i||")"===i){t.push({type:"paren",value:i}),r+=1;continue}const a=/^(?:0x[0-9A-Fa-f]+|\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)/.exec(e.slice(r));if(a){t.push({type:"number",value:a[0]}),r+=a[0].length;continue}const s=/^[A-Za-z_][A-Za-z0-9_]*/.exec(e.slice(r));s?(t.push({type:"identifier",value:s[0]}),r+=s[0].length):r+=1}return t}(Vu(e));return 0!==new Iu(r,t).parseExpression()}var Iu=class{constructor(e,t){this.tokens=e,this.macros=t}tokens;macros;cursor=0;parseExpression(){return this.parseLogicalOr()}parseLogicalOr(){let e=this.parseLogicalAnd();for(;this.consumeOperator("||");){const t=this.parseLogicalAnd();e=0!==e||0!==t?1:0}return e}parseLogicalAnd(){let e=this.parseEquality();for(;this.consumeOperator("&&");){const t=this.parseEquality();e=0!==e&&0!==t?1:0}return e}parseEquality(){let e=this.parseComparison();for(;;)if(this.consumeOperator("=="))e=e===this.parseComparison()?1:0;else{if(!this.consumeOperator("!="))return e;e=e!==this.parseComparison()?1:0}}parseComparison(){let e=this.parseAdditive();for(;;)if(this.consumeOperator("<"))e=e<this.parseAdditive()?1:0;else if(this.consumeOperator(">"))e=e>this.parseAdditive()?1:0;else if(this.consumeOperator("<="))e=e<=this.parseAdditive()?1:0;else{if(!this.consumeOperator(">="))return e;e=e>=this.parseAdditive()?1:0}}parseAdditive(){let e=this.parseMultiplicative();for(;;)if(this.consumeOperator("+"))e+=this.parseMultiplicative();else{if(!this.consumeOperator("-"))return e;e-=this.parseMultiplicative()}}parseMultiplicative(){let e=this.parseUnary();for(;;)if(this.consumeOperator("*"))e*=this.parseUnary();else if(this.consumeOperator("/"))e/=this.parseUnary();else{if(!this.consumeOperator("%"))return e;e%=this.parseUnary()}}parseUnary(){return this.consumeOperator("!")?0===this.parseUnary()?1:0:this.consumeOperator("-")?-this.parseUnary():this.consumeOperator("+")?this.parseUnary():this.parsePrimary()}parsePrimary(){const e=this.peek();if(!e)return 0;if("number"===e.type)return this.cursor+=1,e.value.startsWith("0x")?Number.parseInt(e.value,16):Number.parseFloat(e.value);if("identifier"===e.type&&"defined"===e.value){if(this.cursor+=1,this.consumeParen("(")){const e=this.consumeIdentifier();return this.consumeParen(")"),e&&this.macros.has(e)?1:0}const e=this.consumeIdentifier();return e&&this.macros.has(e)?1:0}if("identifier"===e.type)return this.cursor+=1,function(e){if(!e)return 0;const t=e.body.trim();if("true"===t)return 1;if("false"===t)return 0;const r=t.startsWith("0x")?Number.parseInt(t,16):Number.parseFloat(t);return Number.isFinite(r)?r:1}(this.macros.get(e.value));if(this.consumeParen("(")){const e=this.parseExpression();return this.consumeParen(")"),e}return this.cursor+=1,0}consumeIdentifier(){const e=this.peek();return"identifier"!==e?.type?null:(this.cursor+=1,e.value)}consumeOperator(e){const t=this.peek();return"operator"===t?.type&&t.value===e&&(this.cursor+=1,!0)}consumeParen(e){const t=this.peek();return"paren"===t?.type&&t.value===e&&(this.cursor+=1,!0)}peek(){return this.tokens[this.cursor]}};function Vu(e){const t=e.indexOf("//");return t>=0?e.slice(0,t):e}function Gu(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Lu=/(?!\s*@invariant)\s+(?=(?:[A-Za-z_]\w*\s*:|vec4(?:\s*<\s*f32\s*>|f)\b))/y;function zu(e){return 32===e||9===e||10===e||13===e}var Ru=class{passes=[];addPass(e){this.passes.push(e)}async executeAsync(e,t){const r=this.resolveExecutionOrder(),i=performance.now();t?.begin?.(r,e);for(let i=0;i<r.length;i+=1){const n=r[i];t?.beforePass?.(n,i,e);const a=performance.now();await(n.prepare?.(e)),n.execute(e),t?.afterPass?.(n,i,performance.now()-a,e)}t?.end?.(r,performance.now()-i,e)}execute(e,t){const r=this.resolveExecutionOrder(),i=performance.now();t?.begin?.(r,e);for(let i=0;i<r.length;i+=1){const n=r[i];t?.beforePass?.(n,i,e);const a=performance.now();n.execute(e),t?.afterPass?.(n,i,performance.now()-a,e)}t?.end?.(r,performance.now()-i,e)}reset(){this.passes.length=0}resolveExecutionOrder(){const e=new Map,t=new Map,r=new Map,i=new Map;for(const i of this.passes)e.set(i.name,i),t.set(i.name,new Set(i.dependsOn??[])),r.set(i.name,new Set);for(const e of this.passes){const r=t.get(e.name);for(const t of e.reads??[]){const n=i.get(t);n&&n!==e.name&&r.add(n)}for(const t of e.writes??[]){const n=i.get(t);n&&n!==e.name&&r.add(n),i.set(t,e.name)}}for(const[e,i]of t)for(const t of i){const i=r.get(t);if(!i)throw new Error(`RenderGraph dependency "${t}" for pass "${e}" is missing.`);i.add(e)}const n=Array.from(t.entries()).filter(([,e])=>0===e.size).map(([e])=>e),a=[];for(;n.length>0;){const i=n.shift();a.push(e.get(i));for(const e of r.get(i)??[]){const r=t.get(e);r.delete(i),0===r.size&&n.push(e)}}if(a.length!==this.passes.length)throw new Error("RenderGraph contains a dependency cycle.");return a}};import{CubeUVReflectionMapping as Uu,HalfFloatType as Au,LinearFilter as ku,LinearSRGBColorSpace as Fu,RGBAFormat as $u,Texture as Eu}from"three";var Ou=[.125,.215,.35,.446,.526,.582],_u=20,ju=function(){const e=(1+Math.sqrt(5))/2,t=1/e;return[[-e,t,0],[e,t,0],[-t,0,e],[t,0,e],[0,e,-t],[0,e,t],[-1,1,-1],[1,1,-1],[-1,1,1],[1,1,1]]}(),Nu=class{constructor(e,t=20){this.context=e;const{device:r}=e,i=Math.max(1,Math.min(20,Math.floor(t)));this.maxBlurSamples=i,this.equirectBindGroupLayout=r.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"unfilterable-float",viewDimension:"2d"}}]}),this.blurBindGroupLayout=r.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}}]}),this.equirectPipeline=Wu(r,this.equirectBindGroupLayout,Ku,"pmrem-equirectangular"),this.blurPipeline=Wu(r,this.blurBindGroupLayout,Zu.replaceAll("PMREM_MAX_SAMPLES",String(i)),"pmrem-blur")}context;equirectPipeline;blurPipeline;equirectBindGroupLayout;blurBindGroupLayout;maxBlurSamples;fromEquirectangular(e){const t=this.context.getTextureResource(e);if("2d"!==t.viewDimension)throw new Error("WebGpuPMREMGenerator.fromEquirectangular() requires a 2D equirectangular texture.");const r=2**Math.floor(Math.log2(Math.max(16,Math.floor(t.width/4)))),i=Math.floor(Math.log2(r)),n=function(e){const t=[];for(let r=e;r>=4;r-=1){const i=2**r;t.push({mip:r,size:i,sigma:r===e?0:1/i})}for(let e=0;e<Ou.length;e+=1)t.push({mip:4-e-1,size:16,sigma:Ou[e]});return t}(i),a=3*Math.max(r,112),s=4*r,{device:o}=this.context,l=GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,c=o.createTexture({label:"pmrem-cubeuv",size:{width:a,height:s},format:"rgba16float",usage:l}),u=o.createTexture({label:"pmrem-cubeuv-ping",size:{width:a,height:s},format:"rgba16float",usage:l}),d=o.createSampler({magFilter:"linear",minFilter:"linear"}),h=o.createCommandEncoder({label:"pmrem-generation"}),p=[],f=Hu(o,new Float32Array([t.width,t.height,r,0]));p.push(f);const m=o.createBindGroup({layout:this.equirectBindGroupLayout,entries:[{binding:0,resource:{buffer:f}},{binding:1,resource:t.view}]}),g=h.beginRenderPass({colorAttachments:[{view:c.createView(),loadOp:"clear",storeOp:"store",clearValue:[0,0,0,1]}]});g.setViewport(0,0,3*r,2*r,0,1),g.setScissorRect(0,0,3*r,2*r),g.setPipeline(this.equirectPipeline),g.setBindGroup(0,m),g.draw(36),g.end();for(let e=1;e<n.length;e+=1){const t=n[e-1],r=n[e],o=Math.sqrt(r.sigma*r.sigma-t.sigma*t.sigma),l=ju[(n.length-e-1)%ju.length];this.encodeBlurPass({encoder:h,source:c,target:u,sampler:d,atlasWidth:a,atlasHeight:s,maxMip:i,inputLevel:t,outputLevel:r,sigma:o,poleAxis:l,latitudinal:!0,clear:!0,transientBuffers:p}),this.encodeBlurPass({encoder:h,source:u,target:c,sampler:d,atlasWidth:a,atlasHeight:s,maxMip:i,inputLevel:r,outputLevel:r,sigma:o,poleAxis:l,latitudinal:!1,clear:!1,transientBuffers:p})}o.queue.submit([h.finish()]),o.queue.onSubmittedWorkDone().then(()=>{for(const e of p)e.destroy();u.destroy()});const v=new Eu;return v.image={width:a,height:s},v.name="PMREM.cubeUv",v.mapping=Uu,v.format=$u,v.type=Au,v.colorSpace=Fu,v.minFilter=ku,v.magFilter=ku,v.generateMipmaps=!1,v.needsUpdate=!0,this.context.registerTextureResource(v,{version:v.version,width:a,height:s,depthOrArrayLayers:1,format:"rgba16float",textureDimension:"2d",viewDimension:"2d",sampleType:"float",samplerBindingType:"filtering",mipLevelCount:1,texture:c,view:c.createView(),sampler:d}),{texture:v,dispose:()=>{c.destroy(),v.dispose()}}}encodeBlurPass(e){const{encoder:t,source:r,target:i,sampler:n,atlasWidth:a,atlasHeight:s,maxMip:o,inputLevel:l,outputLevel:c,sigma:u,poleAxis:d,latitudinal:h,clear:p,transientBuffers:f}=e,m=l.size-1,g=Math.PI/(2*m),v=u/g,x=Math.min(this.maxBlurSamples,1+Math.floor(3*v)),w=function(e,t){const r=new Float32Array(_u);let i=0;for(let n=0;n<_u;n+=1){const a=n/e,s=Math.exp(-a*a/2);r[n]=s,0===n?i+=s:n<t&&(i+=2*s)}for(let e=0;e<r.length;e+=1)r[e]/=i;return r}(v,x),b=Hu(this.context.device,function(e){const t=new ArrayBuffer(144),r=new DataView(t);return r.setFloat32(0,e.atlasWidth,!0),r.setFloat32(4,e.atlasHeight,!0),r.setFloat32(8,e.outputFaceSize,!0),r.setFloat32(12,e.inputMip,!0),r.setFloat32(16,e.dTheta,!0),r.setUint32(20,e.sampleCount,!0),r.setUint32(24,e.latitudinal?1:0,!0),r.setFloat32(28,e.maxMip,!0),r.setFloat32(32,e.poleAxis[0],!0),r.setFloat32(36,e.poleAxis[1],!0),r.setFloat32(40,e.poleAxis[2],!0),new Float32Array(t,48,_u).set(e.weights),new Float32Array(t)}({atlasWidth:a,atlasHeight:s,outputFaceSize:c.size,inputMip:l.mip,dTheta:g,sampleCount:x,latitudinal:h,poleAxis:d,weights:w,maxMip:o}));f.push(b);const y=this.context.device.createBindGroup({layout:this.blurBindGroupLayout,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:r.createView()},{binding:2,resource:n}]}),S=3*c.size*Math.max(0,4-c.mip),C=4*(2**o-c.size),M=t.beginRenderPass({colorAttachments:[{view:i.createView(),loadOp:p?"clear":"load",storeOp:"store",clearValue:[0,0,0,1]}]});M.setViewport(S,C,3*c.size,2*c.size,0,1),M.setScissorRect(S,C,3*c.size,2*c.size),M.setPipeline(this.blurPipeline),M.setBindGroup(0,y),M.draw(36),M.end()}};function Wu(e,t,r,i){const n=e.createShaderModule({code:r,label:`${i}-shader`});return"function"==typeof n.getCompilationInfo&&n.getCompilationInfo().then(e=>{const t=e.messages.filter(e=>"error"===e.type);t.length>0&&console.error(`[WebGpuPMREMGenerator] ${i} WGSL compilation failed.`,t)}),e.createRenderPipeline({label:i,layout:e.createPipelineLayout({bindGroupLayouts:[t]}),vertex:{module:n,entryPoint:"vs"},fragment:{module:n,entryPoint:"fs",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list"}})}function Hu(e,t){const r=e.createBuffer({size:t.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});return e.queue.writeBuffer(r,0,t.buffer,t.byteOffset,t.byteLength),r}var qu="\nstruct VertexOutput {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n @location(1) @interpolate(flat) face: u32,\n};\n\nconst corners = array<vec2f, 6>(\n vec2f(0, 0), vec2f(1, 0), vec2f(1, 1),\n vec2f(0, 0), vec2f(1, 1), vec2f(0, 1),\n);\n\n@vertex\nfn vs(@builtin(vertex_index) index: u32) -> VertexOutput {\n let face = index / 6u;\n let corner = corners[index % 6u];\n var output: VertexOutput;\n output.position = vec4f(\n (corner.x + f32(face % 3u)) / 3.0 * 2.0 - 1.0,\n 1.0 - (corner.y + f32(face / 3u)),\n 0.0,\n 1.0,\n );\n output.uv = corner;\n output.face = face;\n return output;\n}\n\nfn cubeDirection(inputUv: vec2f, face: u32, faceSize: f32) -> vec3f {\n let gutter = 1.0 / (faceSize - 2.0);\n let uv = (inputUv * (1.0 + 2.0 * gutter) - vec2f(gutter)) * 2.0 - 1.0;\n if (face == 0u) { return normalize(vec3f(1.0, uv.y, uv.x)); }\n if (face == 1u) { return normalize(vec3f(-uv.x, 1.0, -uv.y)); }\n if (face == 2u) { return normalize(vec3f(-uv.x, uv.y, 1.0)); }\n if (face == 3u) { return normalize(vec3f(-1.0, uv.y, -uv.x)); }\n if (face == 4u) { return normalize(vec3f(-uv.x, -1.0, uv.y)); }\n return normalize(vec3f(uv.x, uv.y, -1.0));\n}\n",Ku=`${qu}\nstruct EquirectParams {\n sourceSize: vec2f,\n faceSize: f32,\n _padding: f32,\n};\n\n@group(0) @binding(0) var<uniform> params: EquirectParams;\n@group(0) @binding(1) var environmentMap: texture_2d<f32>;\n\nfn sampleEquirectangular(direction: vec3f) -> vec3f {\n let uv = vec2f(\n atan2(direction.z, direction.x) / (2.0 * 3.141592653589793) + 0.5,\n asin(clamp(direction.y, -1.0, 1.0)) / 3.141592653589793 + 0.5,\n );\n let pixel = uv * params.sourceSize - vec2f(0.5);\n let base = vec2i(floor(pixel));\n let fraction = fract(pixel);\n let width = i32(params.sourceSize.x);\n let height = i32(params.sourceSize.y);\n let x0 = (base.x % width + width) % width;\n let x1 = (x0 + 1) % width;\n let y0 = clamp(base.y, 0, height - 1);\n let y1 = min(y0 + 1, height - 1);\n let top = mix(\n textureLoad(environmentMap, vec2i(x0, y0), 0).rgb,\n textureLoad(environmentMap, vec2i(x1, y0), 0).rgb,\n fraction.x,\n );\n let bottom = mix(\n textureLoad(environmentMap, vec2i(x0, y1), 0).rgb,\n textureLoad(environmentMap, vec2i(x1, y1), 0).rgb,\n fraction.x,\n );\n return mix(top, bottom, fraction.y);\n}\n\n@fragment\nfn fs(input: VertexOutput) -> @location(0) vec4f {\n let direction = cubeDirection(input.uv, input.face, params.faceSize);\n return vec4f(sampleEquirectangular(direction), 1.0);\n}\n`,Zu=`${qu}\nstruct BlurParams {\n atlasSize: vec2f,\n outputFaceSize: f32,\n inputMip: f32,\n dTheta: f32,\n samples: u32,\n latitudinal: u32,\n maxMip: f32,\n poleAxis: vec3f,\n _padding: f32,\n weights: array<vec4f, 5>,\n};\n\n@group(0) @binding(0) var<uniform> params: BlurParams;\n@group(0) @binding(1) var environmentMap: texture_2d<f32>;\n@group(0) @binding(2) var environmentSampler: sampler;\n\nfn cubeFace(direction: vec3f) -> f32 {\n let absolute = abs(direction);\n if (absolute.x > absolute.z) {\n if (absolute.x > absolute.y) { return select(3.0, 0.0, direction.x > 0.0); }\n return select(4.0, 1.0, direction.y > 0.0);\n }\n if (absolute.z > absolute.y) { return select(5.0, 2.0, direction.z > 0.0); }\n return select(4.0, 1.0, direction.y > 0.0);\n}\n\nfn cubeUv(direction: vec3f, face: f32) -> vec2f {\n if (face == 0.0) { return 0.5 * (vec2f(direction.z, direction.y) / abs(direction.x) + 1.0); }\n if (face == 1.0) { return 0.5 * (vec2f(-direction.x, -direction.z) / abs(direction.y) + 1.0); }\n if (face == 2.0) { return 0.5 * (vec2f(-direction.x, direction.y) / abs(direction.z) + 1.0); }\n if (face == 3.0) { return 0.5 * (vec2f(-direction.z, direction.y) / abs(direction.x) + 1.0); }\n if (face == 4.0) { return 0.5 * (vec2f(-direction.x, direction.z) / abs(direction.y) + 1.0); }\n return 0.5 * (vec2f(direction.x, direction.y) / abs(direction.z) + 1.0);\n}\n\nfn sampleCubeUv(direction: vec3f) -> vec3f {\n var face = cubeFace(direction);\n let filterOffset = max(4.0 - params.inputMip, 0.0);\n let mip = max(params.inputMip, 4.0);\n let faceSize = exp2(mip);\n var uv = cubeUv(direction, face) * (faceSize - 2.0) + 1.0;\n if (face > 2.0) {\n uv.y += faceSize;\n face -= 3.0;\n }\n uv.x += face * faceSize + filterOffset * 3.0 * 16.0;\n uv.y += 4.0 * (exp2(params.maxMip) - faceSize);\n return textureSampleLevel(environmentMap, environmentSampler, uv / params.atlasSize, 0.0).rgb;\n}\n\nfn weight(index: u32) -> f32 {\n return params.weights[index / 4u][index % 4u];\n}\n\nfn rotatedSample(direction: vec3f, theta: f32, axis: vec3f) -> vec3f {\n let cosine = cos(theta);\n let sampleDirection = direction * cosine\n + cross(axis, direction) * sin(theta)\n + axis * dot(axis, direction) * (1.0 - cosine);\n return sampleCubeUv(sampleDirection);\n}\n\n@fragment\nfn fs(input: VertexOutput) -> @location(0) vec4f {\n let direction = cubeDirection(input.uv, input.face, params.outputFaceSize);\n var axis = select(cross(params.poleAxis, direction), params.poleAxis, params.latitudinal != 0u);\n if (dot(axis, axis) < 0.000001) { axis = vec3f(direction.z, 0.0, -direction.x); }\n axis = normalize(axis);\n var color = weight(0u) * rotatedSample(direction, 0.0, axis);\n for (var index = 1u; index < PMREM_MAX_SAMPLES; index += 1u) {\n if (index >= params.samples) { break; }\n let theta = params.dTheta * f32(index);\n color += weight(index) * rotatedSample(direction, -theta, axis);\n color += weight(index) * rotatedSample(direction, theta, axis);\n }\n return vec4f(color, 1.0);\n}\n`;function Yu(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}function Xu(e,t){const r=Object.entries(e.uniforms).map(([e,t])=>` ${Yu(e)}: ${t.type},`).join("\n"),i=r?`\nstruct MaterialUniforms {\n${r}\n};\n\n@group(1) @binding(0) var<uniform> materialUniforms: MaterialUniforms;\n`:"",n=Object.entries(e.textures).map(([e,r],i)=>{const n=1+2*i,a=Yu(e),s=vt(r,t);return[`@group(1) @binding(${n}) var ${a}Sampler: ${s.wgslSamplerType};`,`@group(1) @binding(${n+1}) var ${a}Texture: ${s.wgslTextureType};`].join("\n")}).join("\n"),a=1+2*Object.keys(e.textures).length;return`${i}\n${n}\n${Object.entries(e.storageBuffers).map(([e,t],r)=>{const i=Yu(e);return`@group(1) @binding(${a+r}) var<storage, read> ${i}: ${t.type};`}).join("\n")}`}function Ju(e){return`\nfn rendererModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererInstanceModelMatrix(instanceIndex);\n}\n\nfn rendererNormalMatrix(instanceIndex: u32) -> mat3x3<f32> {\n ${e?"let view = rendererViewMatrix();\n let viewRotation = mat3x3<f32>(view[0].xyz, view[1].xyz, view[2].xyz);\n return viewRotation * rendererInstanceNormalMatrix(instanceIndex);":"return rendererInstanceNormalMatrix(instanceIndex);"}\n}\n\nfn modelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererModelMatrix(instanceIndex);\n}\n\nfn normalMatrix(instanceIndex: u32) -> mat3x3<f32> {\n return rendererNormalMatrix(instanceIndex);\n}\n${e?`\nfn rendererViewMatrix() -> mat4x4<f32> {\n return ${e}.view;\n}\n\nfn rendererProjectionMatrix() -> mat4x4<f32> {\n return ${e}.projection;\n}\n\nfn rendererModelViewMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererViewMatrix() * rendererModelMatrix(instanceIndex);\n}\n\nfn rendererModelViewProjectionMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererProjectionMatrix() * rendererModelViewMatrix(instanceIndex);\n}\n\nfn rendererCameraPosition() -> vec3<f32> {\n return ${e}.cameraPosition.xyz;\n}\n\nfn rendererCameraNear() -> f32 {\n return ${e}.nearFar.x;\n}\n\nfn rendererCameraFar() -> f32 {\n return ${e}.nearFar.y;\n}\n\n${"rendererCamera"===e?`\nfn rendererFogColor() -> vec3<f32> {\n return ${e}.fogColor.rgb;\n}\n\nfn rendererFogNear() -> f32 {\n return ${e}.fogParams.x;\n}\n\nfn rendererFogFar() -> f32 {\n return ${e}.fogParams.y;\n}\n\nfn rendererFogDensity() -> f32 {\n return ${e}.fogParams.z;\n}\n\nfn rendererFogMode() -> f32 {\n return ${e}.fogParams.w;\n}\n`:""}\n\nfn rendererElapsedTime() -> f32 {\n return ${"rendererCamera"===e?"rendererCamera.viewportAndTime.w":"shadowCamera"===e?"shadowCamera.timeAndPadding.x":null};\n}\n\nfn rendererViewportSize() -> vec2<f32> {\n return ${"rendererCamera"===e?"rendererCamera.viewportAndTime.xy":"shadowCamera"===e?"shadowCamera.timeAndPadding.yz":null};\n}\n\nfn viewMatrix() -> mat4x4<f32> {\n return rendererViewMatrix();\n}\n\nfn projectionMatrix() -> mat4x4<f32> {\n return rendererProjectionMatrix();\n}\n\nfn modelViewMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererModelViewMatrix(instanceIndex);\n}\n\nfn modelViewProjectionMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererModelViewProjectionMatrix(instanceIndex);\n}\n\nfn cameraPosition() -> vec3<f32> {\n return rendererCameraPosition();\n}\n`:""}`}function Qu(e){return e?"\nstruct RendererSkinningUniforms {\n bindMatrix: mat4x4<f32>,\n bindMatrixInverse: mat4x4<f32>,\n};\n\n@group(2) @binding(0) var<storage, read> rendererBoneMatrixColumns: array<vec4<f32>>;\n@group(2) @binding(1) var<uniform> rendererSkinning: RendererSkinningUniforms;\n@group(2) @binding(2) var<storage, read> rendererPreviousBoneMatrixColumns: array<vec4<f32>>;\n\nfn rendererBoneMatrix(index: u32) -> mat4x4<f32> {\n let base = index * 4u;\n return mat4x4<f32>(\n rendererBoneMatrixColumns[base + 0u],\n rendererBoneMatrixColumns[base + 1u],\n rendererBoneMatrixColumns[base + 2u],\n rendererBoneMatrixColumns[base + 3u],\n );\n}\n\nfn rendererPreviousBoneMatrix(index: u32) -> mat4x4<f32> {\n let base = index * 4u;\n return mat4x4<f32>(\n rendererPreviousBoneMatrixColumns[base + 0u],\n rendererPreviousBoneMatrixColumns[base + 1u],\n rendererPreviousBoneMatrixColumns[base + 2u],\n rendererPreviousBoneMatrixColumns[base + 3u],\n );\n}\n\nfn rendererSkinPosition(position: vec3<f32>, skinIndex: vec4<u32>, skinWeight: vec4<f32>) -> vec3<f32> {\n let boundPosition = rendererSkinning.bindMatrix * vec4(position, 1.0);\n let weightSum = skinWeight.x + skinWeight.y + skinWeight.z + skinWeight.w;\n if (weightSum <= 0.0) {\n return position;\n }\n let skinnedPosition =\n (rendererBoneMatrix(skinIndex.x) * boundPosition) * skinWeight.x +\n (rendererBoneMatrix(skinIndex.y) * boundPosition) * skinWeight.y +\n (rendererBoneMatrix(skinIndex.z) * boundPosition) * skinWeight.z +\n (rendererBoneMatrix(skinIndex.w) * boundPosition) * skinWeight.w;\n let fallbackWeight = max(0.0, 1.0 - weightSum);\n return (rendererSkinning.bindMatrixInverse * (skinnedPosition + boundPosition * fallbackWeight)).xyz;\n}\n\nfn rendererPreviousSkinPosition(position: vec3<f32>, skinIndex: vec4<u32>, skinWeight: vec4<f32>) -> vec3<f32> {\n let boundPosition = rendererSkinning.bindMatrix * vec4(position, 1.0);\n let weightSum = skinWeight.x + skinWeight.y + skinWeight.z + skinWeight.w;\n if (weightSum <= 0.0) {\n return position;\n }\n let skinnedPosition =\n (rendererPreviousBoneMatrix(skinIndex.x) * boundPosition) * skinWeight.x +\n (rendererPreviousBoneMatrix(skinIndex.y) * boundPosition) * skinWeight.y +\n (rendererPreviousBoneMatrix(skinIndex.z) * boundPosition) * skinWeight.z +\n (rendererPreviousBoneMatrix(skinIndex.w) * boundPosition) * skinWeight.w;\n let fallbackWeight = max(0.0, 1.0 - weightSum);\n return (rendererSkinning.bindMatrixInverse * (skinnedPosition + boundPosition * fallbackWeight)).xyz;\n}\n\nfn rendererSkinNormal(normal: vec3<f32>, skinIndex: vec4<u32>, skinWeight: vec4<f32>) -> vec3<f32> {\n let boundNormal = rendererSkinning.bindMatrix * vec4(normal, 0.0);\n let weightSum = skinWeight.x + skinWeight.y + skinWeight.z + skinWeight.w;\n if (weightSum <= 0.0) {\n return normalize(normal);\n }\n let skinnedNormal =\n (rendererBoneMatrix(skinIndex.x) * boundNormal) * skinWeight.x +\n (rendererBoneMatrix(skinIndex.y) * boundNormal) * skinWeight.y +\n (rendererBoneMatrix(skinIndex.z) * boundNormal) * skinWeight.z +\n (rendererBoneMatrix(skinIndex.w) * boundNormal) * skinWeight.w;\n let fallbackWeight = max(0.0, 1.0 - weightSum);\n return normalize((rendererSkinning.bindMatrixInverse * (skinnedNormal + boundNormal * fallbackWeight)).xyz);\n}\n":""}function ed(e,t,r="packed",i=!0,n=!1,a){const s="particle"!==r&&!e.transparent&&!e.requiresLatePass(),o=Xu(e,t),l=function(e){return Object.entries(e.getGraphTextureInputs()).map(([e,t],r)=>{const i=Yu(e);return`@group(3) @binding(${2*r}) var ${i}Sampler: ${"comparison"===t.sampler?"sampler_comparison":"sampler"};\n@group(3) @binding(${2*r+1}) var ${i}Texture: ${"depth-2d"===t.dimension?"texture_depth_2d":"3d"===t.dimension?"texture_3d<f32>":"texture_2d<f32>"};`}).join("\n")}(e),c="packed-visible"===r,u=i?"\nfn rendererSampleDirectionalShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n if (lightIndex >= rendererDirectionalLightCount() || !rendererDirectionalShadowEnabledForLight(lightIndex)) {\n return 1.0;\n }\n\n let matrix = rendererDirectionalShadowMatrixForLight(lightIndex);\n let shadowClip = matrix * vec4(worldPosition, 1.0);\n if (shadowClip.w <= 0.0) {\n return 1.0;\n }\n\n let ndc = shadowClip.xyz / shadowClip.w;\n if (ndc.x < -1.0 || ndc.x > 1.0 || ndc.y < -1.0 || ndc.y > 1.0 || ndc.z < 0.0 || ndc.z > 1.0) {\n return 1.0;\n }\n\n let uv = ndc.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n let dims = vec2<f32>(textureDimensions(rendererDirectionalShadowTexture));\n let texel = 1.0 / max(dims, vec2(1.0, 1.0));\n let radius = max(rendererLights.directionalShadowParams2[lightIndex].x, 0.0);\n // Match Three.js/three-shader-graph semantics: negative bias moves the\n // receiver toward the light and therefore reduces self-shadowing.\n let depth = ndc.z + rendererDirectionalShadowBiasForLight(lightIndex);\n let filterOffset = texel * radius;\n\n // Each comparison-level sample is already a hardware-filtered 2x2 PCF\n // lookup. A weighted center plus four cardinal taps gives a compact tent\n // filter (five lookups rather than nine manual depth loads) and is legal in\n // non-uniform control flow because the explicit level computes no derivatives.\n let center = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n uv,\n i32(lightIndex),\n depth\n );\n let left = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n clamp(uv - vec2(filterOffset.x, 0.0), vec2(0.0), vec2(1.0)),\n i32(lightIndex),\n depth\n );\n let right = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n clamp(uv + vec2(filterOffset.x, 0.0), vec2(0.0), vec2(1.0)),\n i32(lightIndex),\n depth\n );\n let up = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n clamp(uv - vec2(0.0, filterOffset.y), vec2(0.0), vec2(1.0)),\n i32(lightIndex),\n depth\n );\n let down = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n clamp(uv + vec2(0.0, filterOffset.y), vec2(0.0), vec2(1.0)),\n i32(lightIndex),\n depth\n );\n let shadow = (center * 4.0 + left + right + up + down) * 0.125;\n return mix(1.0, shadow, rendererDirectionalShadowIntensityForLight(lightIndex));\n}\n\nfn rendererSampleDirectionalShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n let params = rendererLights.directionalShadowParams[lightIndex];\n return rendererSampleDirectionalShadowForLight(lightIndex, worldPosition + normalize(worldNormal) * params.w);\n}\n\nfn rendererPointShadowUvLayer(direction: vec3<f32>, pointIndex: u32) -> vec3<f32> {\n let absDir = abs(direction);\n var face = 0u;\n var uv = vec2<f32>(0.0, 0.0);\n if (absDir.x >= absDir.y && absDir.x >= absDir.z) {\n if (direction.x >= 0.0) {\n face = 0u;\n uv = vec2<f32>(-direction.z, -direction.y) / absDir.x;\n } else {\n face = 1u;\n uv = vec2<f32>(direction.z, -direction.y) / absDir.x;\n }\n } else if (absDir.y >= absDir.x && absDir.y >= absDir.z) {\n if (direction.y >= 0.0) {\n face = 2u;\n uv = vec2<f32>(direction.x, direction.z) / absDir.y;\n } else {\n face = 3u;\n uv = vec2<f32>(direction.x, -direction.z) / absDir.y;\n }\n } else {\n if (direction.z >= 0.0) {\n face = 4u;\n uv = vec2<f32>(direction.x, -direction.y) / absDir.z;\n } else {\n face = 5u;\n uv = vec2<f32>(-direction.x, -direction.y) / absDir.z;\n }\n }\n // WebGPU's framebuffer/texture Y axis points down. The face-local value\n // above is NDC (Y up), so mirror Y just like the projected directional and\n // spot shadow paths do before sampling their render targets.\n let textureUv = uv * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n return vec3<f32>(textureUv, f32(pointIndex * 6u + face));\n}\n\nfn rendererSamplePointShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n if (lightIndex >= rendererPointLightCount() || !rendererPointShadowEnabledForLight(lightIndex)) {\n return 1.0;\n }\n let lightPosition = rendererPointLightPositionForLight(lightIndex);\n let range = rendererPointLightShadowRangeForLight(lightIndex);\n let toFragment = worldPosition - lightPosition;\n let distanceToLight = length(toFragment);\n if (distanceToLight >= range) {\n return 1.0;\n }\n let uvLayer = rendererPointShadowUvLayer(toFragment, lightIndex);\n let dims = vec2<f32>(textureDimensions(rendererPointShadowTexture));\n let sampleUv = clamp(uvLayer.xy, vec2(0.0, 0.0), vec2(1.0, 1.0));\n let pixel = vec2<i32>(clamp(sampleUv * dims, vec2(0.0, 0.0), dims - vec2(1.0, 1.0)));\n let closestDepth = textureLoad(rendererPointShadowTexture, pixel, i32(round(uvLayer.z)), 0).r;\n let currentDepth = clamp(distanceToLight / max(range, 0.0001), 0.0, 1.0) - rendererPointShadowBiasForLight(lightIndex);\n let shadow = select(0.0, 1.0, currentDepth <= closestDepth);\n return mix(1.0, shadow, rendererPointShadowIntensityForLight(lightIndex));\n}\n\nfn rendererSamplePointShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n let params = rendererLights.pointShadowParams[lightIndex];\n let lightDirection = normalize(worldPosition - rendererPointLightPositionForLight(lightIndex));\n return rendererSamplePointShadowForLight(lightIndex, worldPosition + normalize(worldNormal + lightDirection) * params.w);\n}\n\nfn rendererSampleSpotShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n if (lightIndex >= rendererSpotLightCount() || !rendererSpotShadowEnabledForLight(lightIndex)) {\n return 1.0;\n }\n let matrix = rendererSpotShadowMatrixForLight(lightIndex);\n let shadowClip = matrix * vec4(worldPosition, 1.0);\n if (shadowClip.w <= 0.0) {\n return 1.0;\n }\n let ndc = shadowClip.xyz / shadowClip.w;\n if (ndc.x < -1.0 || ndc.x > 1.0 || ndc.y < -1.0 || ndc.y > 1.0 || ndc.z < 0.0 || ndc.z > 1.0) {\n return 1.0;\n }\n let uv = ndc.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n let dims = vec2<f32>(textureDimensions(rendererSpotShadowTexture));\n let texel = 1.0 / max(dims, vec2(1.0, 1.0));\n let radius = max(rendererLights.spotShadowParams2[lightIndex].x, 1.0);\n let depth = ndc.z - rendererSpotShadowBiasForLight(lightIndex);\n var sum = 0.0;\n for (var y: i32 = -1; y <= 1; y = y + 1) {\n for (var x: i32 = -1; x <= 1; x = x + 1) {\n let offset = vec2<f32>(f32(x), f32(y)) * texel * radius;\n let sampleUv = clamp(uv + offset, vec2(0.0, 0.0), vec2(1.0, 1.0));\n let pixel = vec2<i32>(clamp(sampleUv * dims, vec2(0.0, 0.0), dims - vec2(1.0, 1.0)));\n let shadowDepth = textureLoad(rendererSpotShadowTexture, pixel, i32(lightIndex), 0);\n sum += select(0.0, 1.0, depth <= shadowDepth);\n }\n }\n return mix(1.0, sum / 9.0, rendererSpotShadowIntensityForLight(lightIndex));\n}\n\nfn rendererSampleSpotShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n let params = rendererLights.spotShadowParams[lightIndex];\n return rendererSampleSpotShadowForLight(lightIndex, worldPosition + normalize(worldNormal) * params.w);\n}\n\nfn rendererSampleDirectionalShadow(worldPosition: vec3<f32>) -> f32 {\n return rendererSampleDirectionalShadowForLight(0u, worldPosition);\n}\n\nfn rendererSampleDirectionalShadowWithNormal(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n return rendererSampleDirectionalShadowForLightWithNormal(0u, worldPosition, worldNormal);\n}\n\nfn rendererSamplePointShadow(worldPosition: vec3<f32>) -> f32 {\n return rendererSamplePointShadowForLight(0u, worldPosition);\n}\n\nfn rendererSamplePointShadowWithNormal(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n return rendererSamplePointShadowForLightWithNormal(0u, worldPosition, worldNormal);\n}\n\nfn rendererSampleSpotShadow(worldPosition: vec3<f32>) -> f32 {\n return rendererSampleSpotShadowForLight(0u, worldPosition);\n}\n\nfn rendererSampleSpotShadowWithNormal(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n return rendererSampleSpotShadowForLightWithNormal(0u, worldPosition, worldNormal);\n}\n":"\nfn rendererSampleDirectionalShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n _ = lightIndex;\n _ = worldPosition;\n return 1.0;\n}\n\nfn rendererSampleDirectionalShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n _ = worldNormal;\n return rendererSampleDirectionalShadowForLight(lightIndex, worldPosition);\n}\n\nfn rendererSamplePointShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n _ = lightIndex;\n _ = worldPosition;\n return 1.0;\n}\n\nfn rendererSamplePointShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n _ = worldNormal;\n return rendererSamplePointShadowForLight(lightIndex, worldPosition);\n}\n\nfn rendererSampleSpotShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n _ = lightIndex;\n _ = worldPosition;\n return 1.0;\n}\n\nfn rendererSampleSpotShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n _ = worldNormal;\n return rendererSampleSpotShadowForLight(lightIndex, worldPosition);\n}\n\nfn rendererSampleDirectionalShadow(worldPosition: vec3<f32>) -> f32 {\n _ = worldPosition;\n return 1.0;\n}\n\nfn rendererSampleDirectionalShadowWithNormal(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n _ = worldPosition;\n _ = worldNormal;\n return 1.0;\n}\n\nfn rendererSamplePointShadow(worldPosition: vec3<f32>) -> f32 {\n _ = worldPosition;\n return 1.0;\n}\n\nfn rendererSamplePointShadowWithNormal(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n _ = worldPosition;\n _ = worldNormal;\n return 1.0;\n}\n\nfn rendererSampleSpotShadow(worldPosition: vec3<f32>) -> f32 {\n _ = worldPosition;\n return 1.0;\n}\n\nfn rendererSampleSpotShadowWithNormal(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n _ = worldPosition;\n _ = worldNormal;\n return 1.0;\n}\n";return`\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n nearFar: vec4<f32>,\n fogColor: vec4<f32>,\n fogParams: vec4<f32>,\n motionCurrentViewProj: mat4x4<f32>,\n motionPreviousViewProj: mat4x4<f32>,\n motionParams: vec4<f32>,\n};\n\nstruct RendererLightUniforms {\n ambientColor: vec4<f32>,\n lightCounts: vec4<f32>,\n directionalDirections: array<vec4<f32>, 4>,\n directionalColorIntensities: array<vec4<f32>, 4>,\n directionalShadowParams: array<vec4<f32>, 4>,\n directionalShadowParams2: array<vec4<f32>, 4>,\n directionalShadowMatrices: array<mat4x4<f32>, 4>,\n pointPositionRanges: array<vec4<f32>, 64>,\n pointColorIntensities: array<vec4<f32>, 64>,\n pointParams: array<vec4<f32>, 64>,\n pointShadowParams: array<vec4<f32>, 64>,\n pointShadowParams2: array<vec4<f32>, 64>,\n spotPositionRanges: array<vec4<f32>, 64>,\n spotDirectionCones: array<vec4<f32>, 64>,\n spotColorIntensities: array<vec4<f32>, 64>,\n spotShadowParams: array<vec4<f32>, 64>,\n spotShadowParams2: array<vec4<f32>, 64>,\n spotParams: array<vec4<f32>, 64>,\n spotShadowMatrices: array<mat4x4<f32>, 64>,\n csmCascadeRanges: array<vec4<f32>, 4>,\n hemisphereSkyColorIntensity: vec4<f32>,\n hemisphereGroundColorIntensity: vec4<f32>,\n hemisphereDirection: vec4<f32>,\n};\n\n${"particle"===r?`\n@group(1) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(1) @binding(1) var<uniform> rendererLights: RendererLightUniforms;\n@group(1) @binding(2) var rendererShadowSampler: sampler_comparison;\n@group(1) @binding(3) var rendererDirectionalShadowTexture: texture_depth_2d_array;\n@group(1) @binding(4) var rendererLinearClampSampler: sampler;\n@group(1) @binding(5) var rendererPointShadowTexture: texture_2d_array<f32>;\n@group(1) @binding(6) var rendererSpotShadowTexture: texture_depth_2d_array;\n@group(1) @binding(7) var rendererSpotLightMapAtlas: texture_2d<f32>;\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 { return instanceIndex; }\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n ${a??"_ = instanceIndex;\n return mat4x4<f32>(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));"}\n}\nfn rendererPreviousInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> { return rendererInstanceModelMatrix(instanceIndex); }\nfn rendererMotionBlurParams(instanceIndex: u32) -> vec4<f32> { _ = instanceIndex; return vec4<f32>(1.0, 1.0, 0.0, 0.0); }\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> { _ = instanceIndex; return vec4<f32>(1.0); }\n`:"instanced-direct"===r?"\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> rendererLights: RendererLightUniforms;\n@group(0) @binding(2) var<storage, read> rendererInstanceMatrices: array<vec4<f32>>;\n@group(0) @binding(3) var<storage, read> rendererInstanceColors: array<vec4<f32>>;\n@group(0) @binding(4) var rendererShadowSampler: sampler_comparison;\n@group(0) @binding(5) var rendererDirectionalShadowTexture: texture_depth_2d_array;\n@group(0) @binding(6) var rendererLinearClampSampler: sampler;\n@group(0) @binding(7) var rendererPointShadowTexture: texture_2d_array<f32>;\n@group(0) @binding(8) var rendererSpotShadowTexture: texture_depth_2d_array;\n@group(0) @binding(10) var rendererSpotLightMapAtlas: texture_2d<f32>;\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 {\n return instanceIndex;\n}\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let base = instanceIndex * 4u;\n return mat4x4<f32>(\n rendererInstanceMatrices[base + 0u],\n rendererInstanceMatrices[base + 1u],\n rendererInstanceMatrices[base + 2u],\n rendererInstanceMatrices[base + 3u]\n );\n}\n\nfn rendererPreviousInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n return rendererInstanceModelMatrix(instanceIndex);\n}\n\nfn rendererMotionBlurParams(instanceIndex: u32) -> vec4<f32> {\n _ = instanceIndex;\n return vec4<f32>(1.0, 1.0, 0.0, 0.0);\n}\n\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> {\n return rendererInstanceColors[instanceIndex];\n}\n":`\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> rendererLights: RendererLightUniforms;\n@group(0) @binding(2) var<storage, read> rendererInstances: array<RendererInstanceData>;\n@group(0) @binding(3) var rendererShadowSampler: sampler_comparison;\n@group(0) @binding(4) var rendererDirectionalShadowTexture: texture_depth_2d_array;\n@group(0) @binding(5) var rendererLinearClampSampler: sampler;\n@group(0) @binding(6) var rendererPointShadowTexture: texture_2d_array<f32>;\n@group(0) @binding(7) var rendererSpotShadowTexture: texture_depth_2d_array;\n@group(0) @binding(9) var rendererSpotLightMapAtlas: texture_2d<f32>;\n${c?"@group(0) @binding(8) var<storage, read> rendererVisibleInstanceIndices: array<u32>;":""}\n\nfn rendererResolveInstanceIndex(instanceIndex: u32) -> u32 {\n ${c?"return rendererVisibleInstanceIndices[instanceIndex];":"return instanceIndex;"}\n}\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[rendererResolveInstanceIndex(instanceIndex)];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\nfn rendererPreviousInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[rendererResolveInstanceIndex(instanceIndex)];\n return mat4x4<f32>(instance.previousModel0, instance.previousModel1, instance.previousModel2, instance.previousModel3);\n}\n\nfn rendererMotionBlurParams(instanceIndex: u32) -> vec4<f32> {\n return vec4<f32>(rendererInstances[rendererResolveInstanceIndex(instanceIndex)].batching.yzw, 0.0);\n}\n\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> {\n return rendererInstances[rendererResolveInstanceIndex(instanceIndex)].color;\n}\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 {\n return u32(round(rendererInstances[rendererResolveInstanceIndex(instanceIndex)].batching.x));\n}\n`}\n\n${s?"@group(0) @binding(11) var rendererPointLightTiles: texture_2d<u32>;":""}\n\nfn rendererFullPointLightMask() -> vec2<u32> {\n let count = min(rendererPointLightCount(), 64u);\n // Shifts by 32 wrap to zero in WGSL; explicitly handle empty words.\n let low = 0xffffffffu >> (32u - min(count, 32u));\n let high = 0xffffffffu >> (32u - min(count - min(count, 32u), 32u));\n return vec2<u32>(select(low, 0u, count == 0u), select(high, 0u, count <= 32u));\n}\n\nfn rendererPointLightMask(pixel: vec2<f32>) -> vec2<u32> {\n ${s?"\n if (rendererCamera.nearFar.w > 0.5 && rendererPointLightCount() > 0u) {\n // Tile boundaries align to derivative quads; clamp edge helpers.\n let tile = min(vec2<u32>(max(pixel, vec2<f32>(0.0))) / 16u, textureDimensions(rendererPointLightTiles) - 1u);\n return textureLoad(rendererPointLightTiles, vec2<i32>(tile), 0).xy;\n }":"_ = pixel;"}\n return rendererFullPointLightMask();\n}\n\nfn rendererInverseMat3(m: mat3x3<f32>) -> mat3x3<f32> {\n let a = m[0];\n let b = m[1];\n let c = m[2];\n let r0 = cross(b, c);\n let r1 = cross(c, a);\n let r2 = cross(a, b);\n let det = dot(r2, c);\n let safeDet = select(det, select(-1e-8, 1e-8, det >= 0.0), abs(det) < 1e-8);\n let invDet = 1.0 / safeDet;\n return transpose(mat3x3<f32>(r0 * invDet, r1 * invDet, r2 * invDet));\n}\n\nfn rendererInstanceNormalMatrix(instanceIndex: u32) -> mat3x3<f32> {\n let model = rendererInstanceModelMatrix(instanceIndex);\n let model3x3 = mat3x3<f32>(model[0].xyz, model[1].xyz, model[2].xyz);\n return transpose(rendererInverseMat3(model3x3));\n}\n\nfn rendererWorldPosition(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n return rendererInstanceModelMatrix(instanceIndex) * vec4(localPosition, 1.0);\n}\n\nfn rendererClipPosition(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n return rendererCamera.viewProj * rendererWorldPosition(localPosition, instanceIndex);\n}\n\nfn rendererMotionCurrentClip(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(localPosition, 1.0);\n return rendererCamera.motionCurrentViewProj * world;\n}\n\nfn rendererMotionPreviousClip(\n currentLocalPosition: vec3<f32>,\n previousLocalPosition: vec3<f32>,\n instanceIndex: u32\n) -> vec4<f32> {\n let params = rendererMotionBlurParams(instanceIndex);\n let useObjectHistory = params.x >= 1.5 && params.z >= 0.5;\n var previousModel = rendererInstanceModelMatrix(instanceIndex);\n var previousLocal = currentLocalPosition;\n if (useObjectHistory) {\n previousModel = rendererPreviousInstanceModelMatrix(instanceIndex);\n previousLocal = previousLocalPosition;\n }\n return rendererCamera.motionPreviousViewProj * previousModel * vec4(previousLocal, 1.0);\n}\n\nfn rendererWorldNormal(localNormal: vec3<f32>, instanceIndex: u32) -> vec3<f32> {\n return normalize(rendererInstanceNormalMatrix(instanceIndex) * localNormal);\n}\n\n${Ju("rendererCamera")}\n\nfn rendererDirectionalLightDirection() -> vec3<f32> {\n return rendererDirectionalLightDirectionForLight(0u);\n}\n\nfn rendererDirectionalLightColor() -> vec3<f32> {\n return rendererDirectionalLightColorForLight(0u);\n}\n\nfn rendererPointLightPosition() -> vec3<f32> {\n return rendererPointLightPositionForLight(0u);\n}\n\nfn rendererPointLightRange() -> f32 {\n return rendererPointLightRangeForLight(0u);\n}\n\nfn rendererPointLightColor() -> vec3<f32> {\n return rendererPointLightColorForLight(0u);\n}\n\nfn rendererAmbientLight() -> vec3<f32> {\n return rendererLights.ambientColor.xyz * rendererLights.ambientColor.w;\n}\n\nfn rendererHemisphereLight(worldNormal: vec3<f32>) -> vec3<f32> {\n let directionLength = length(rendererLights.hemisphereDirection.xyz);\n if (directionLength <= 0.0) {\n return vec3<f32>(0.0);\n }\n let sky = rendererLights.hemisphereSkyColorIntensity;\n let ground = rendererLights.hemisphereGroundColorIntensity;\n let weight = dot(normalize(worldNormal), rendererLights.hemisphereDirection.xyz / directionLength) * 0.5 + 0.5;\n return mix(ground.xyz * ground.w, sky.xyz * sky.w, weight);\n}\n\nfn rendererIndirectDiffuse(worldNormal: vec3<f32>) -> vec3<f32> {\n return rendererAmbientLight() + rendererHemisphereLight(worldNormal);\n}\n\nfn rendererDirectionalLightCount() -> u32 {\n return u32(round(rendererLights.lightCounts.x));\n}\n\nfn rendererPointLightCount() -> u32 {\n return u32(round(rendererLights.lightCounts.y));\n}\n\nfn rendererSpotLightCount() -> u32 {\n return u32(round(rendererLights.lightCounts.z));\n}\n\nfn rendererCsmCascadeCount() -> u32 {\n return u32(round(rendererLights.lightCounts.w));\n}\n\nfn rendererCsmCascadeRangeForLight(lightIndex: u32) -> vec2<f32> {\n return rendererLights.csmCascadeRanges[lightIndex].xy;\n}\n\nfn rendererDirectionalLightDirectionForLight(lightIndex: u32) -> vec3<f32> {\n return normalize(-rendererLights.directionalDirections[lightIndex].xyz);\n}\n\nfn rendererDirectionalLightColorForLight(lightIndex: u32) -> vec3<f32> {\n let value = rendererLights.directionalColorIntensities[lightIndex];\n return value.xyz * value.w;\n}\n\nfn rendererPointLightPositionForLight(lightIndex: u32) -> vec3<f32> {\n return rendererLights.pointPositionRanges[lightIndex].xyz;\n}\n\nfn rendererPointLightRangeForLight(lightIndex: u32) -> f32 {\n return rendererLights.pointParams[lightIndex].x;\n}\n\nfn rendererPointLightShadowRangeForLight(lightIndex: u32) -> f32 {\n return rendererLights.pointPositionRanges[lightIndex].w;\n}\n\nfn rendererPointLightDecayForLight(lightIndex: u32) -> f32 {\n return rendererLights.pointParams[lightIndex].y;\n}\n\nfn rendererPointLightColorForLight(lightIndex: u32) -> vec3<f32> {\n let value = rendererLights.pointColorIntensities[lightIndex];\n return value.xyz * value.w;\n}\n\nfn rendererSpotLightPositionForLight(lightIndex: u32) -> vec3<f32> {\n return rendererLights.spotPositionRanges[lightIndex].xyz;\n}\n\nfn rendererSpotLightRangeForLight(lightIndex: u32) -> f32 {\n return rendererLights.spotPositionRanges[lightIndex].w;\n}\n\nfn rendererSpotLightDirectionForLight(lightIndex: u32) -> vec3<f32> {\n // The packed value points from the light towards its target. Material\n // lighting evaluates the incident direction from the fragment back to the\n // light, matching rendererDirectionalLightDirectionForLight().\n return normalize(-rendererLights.spotDirectionCones[lightIndex].xyz);\n}\n\nfn rendererSpotLightConeCosForLight(lightIndex: u32) -> f32 {\n return rendererLights.spotDirectionCones[lightIndex].w;\n}\n\nfn rendererSpotLightPenumbraCosForLight(lightIndex: u32) -> f32 {\n return rendererLights.spotParams[lightIndex].y;\n}\n\nfn rendererSpotLightDecayForLight(lightIndex: u32) -> f32 {\n return rendererLights.spotParams[lightIndex].z;\n}\n\nfn rendererSpotLightColorForLight(lightIndex: u32) -> vec3<f32> {\n let value = rendererLights.spotColorIntensities[lightIndex];\n return value.xyz * value.w;\n}\n\n// These structs make the renderer's packed light buffer available to generic\n// graph nodes. The graph only depends on the semantic fields; this header can\n// later source them from Forward+ storage buffers without changing materials.\nstruct RendererDirectionalLight {\n direction: vec3<f32>,\n color: vec3<f32>,\n};\n\nfn rendererDirectionalLightForLight(lightIndex: u32) -> RendererDirectionalLight {\n return RendererDirectionalLight(\n rendererDirectionalLightDirectionForLight(lightIndex),\n rendererDirectionalLightColorForLight(lightIndex)\n );\n}\n\n// These records match three-shader-graph's established shadow structs. They\n// intentionally expose metadata only; sampling stays behind the renderer's\n// semantic shadow functions so graph code never depends on the atlas layout.\nstruct RendererDirectionalLightShadow {\n shadowBias: f32,\n shadowNormalBias: f32,\n shadowRadius: f32,\n shadowMapSize: vec2<f32>,\n};\n\nfn rendererDirectionalLightShadowForLight(lightIndex: u32) -> RendererDirectionalLightShadow {\n let params = rendererLights.directionalShadowParams[lightIndex];\n let params2 = rendererLights.directionalShadowParams2[lightIndex];\n return RendererDirectionalLightShadow(\n params.x,\n params.w,\n params2.x,\n vec2<f32>(params.z)\n );\n}\n\nstruct RendererPointLight {\n position: vec3<f32>,\n color: vec3<f32>,\n distance: f32,\n decay: f32,\n};\n\nfn rendererPointLightForLight(lightIndex: u32) -> RendererPointLight {\n return RendererPointLight(\n rendererPointLightPositionForLight(lightIndex),\n rendererPointLightColorForLight(lightIndex),\n rendererPointLightRangeForLight(lightIndex),\n rendererPointLightDecayForLight(lightIndex)\n );\n}\n\nstruct RendererPointLightShadow {\n shadowBias: f32,\n shadowNormalBias: f32,\n shadowRadius: f32,\n shadowMapSize: vec2<f32>,\n shadowCameraNear: f32,\n shadowCameraFar: f32,\n};\n\nfn rendererPointLightShadowForLight(lightIndex: u32) -> RendererPointLightShadow {\n let params = rendererLights.pointShadowParams[lightIndex];\n let params2 = rendererLights.pointShadowParams2[lightIndex];\n return RendererPointLightShadow(\n params.x,\n params.w,\n params2.x,\n vec2<f32>(params.z),\n params2.z,\n params2.w\n );\n}\n\nstruct RendererSpotLight {\n position: vec3<f32>,\n direction: vec3<f32>,\n color: vec3<f32>,\n distance: f32,\n decay: f32,\n coneCos: f32,\n penumbraCos: f32,\n};\n\nfn rendererSpotLightForLight(lightIndex: u32) -> RendererSpotLight {\n return RendererSpotLight(\n rendererSpotLightPositionForLight(lightIndex),\n rendererSpotLightDirectionForLight(lightIndex),\n rendererSpotLightColorForLight(lightIndex),\n rendererSpotLightRangeForLight(lightIndex),\n rendererSpotLightDecayForLight(lightIndex),\n rendererSpotLightConeCosForLight(lightIndex),\n rendererSpotLightPenumbraCosForLight(lightIndex)\n );\n}\n\nstruct RendererSpotLightShadow {\n shadowBias: f32,\n shadowNormalBias: f32,\n shadowRadius: f32,\n shadowMapSize: vec2<f32>,\n};\n\nfn rendererSpotLightShadowForLight(lightIndex: u32) -> RendererSpotLightShadow {\n let params = rendererLights.spotShadowParams[lightIndex];\n let params2 = rendererLights.spotShadowParams2[lightIndex];\n return RendererSpotLightShadow(\n params.x,\n params.w,\n params2.x,\n vec2<f32>(params.z)\n );\n}\n\nfn rendererDirectionalShadowMatrixForLight(lightIndex: u32) -> mat4x4<f32> {\n return rendererLights.directionalShadowMatrices[lightIndex];\n}\n\nfn rendererDirectionalShadowMatrix() -> mat4x4<f32> {\n return rendererDirectionalShadowMatrixForLight(0u);\n}\n\nfn rendererDirectionalShadowBias() -> f32 {\n return rendererDirectionalShadowBiasForLight(0u);\n}\n\nfn rendererDirectionalShadowBiasForLight(lightIndex: u32) -> f32 {\n return rendererLights.directionalShadowParams[lightIndex].x;\n}\n\nfn rendererDirectionalShadowEnabled() -> bool {\n return rendererDirectionalShadowEnabledForLight(0u);\n}\n\nfn rendererDirectionalShadowEnabledForLight(lightIndex: u32) -> bool {\n return rendererLights.directionalShadowParams[lightIndex].y >= 0.5;\n}\n\nfn rendererDirectionalShadowIntensityForLight(lightIndex: u32) -> f32 {\n return rendererLights.directionalShadowParams2[lightIndex].y;\n}\n\nfn rendererDirectionalShadowMapSize() -> f32 {\n return rendererLights.directionalShadowParams[0].z;\n}\n\nfn rendererPointShadowBias() -> f32 {\n return rendererPointShadowBiasForLight(0u);\n}\n\nfn rendererPointShadowBiasForLight(lightIndex: u32) -> f32 {\n return rendererLights.pointShadowParams[lightIndex].x;\n}\n\nfn rendererPointShadowEnabled() -> bool {\n return rendererPointShadowEnabledForLight(0u);\n}\n\nfn rendererPointShadowEnabledForLight(lightIndex: u32) -> bool {\n return rendererLights.pointShadowParams[lightIndex].y >= 0.5;\n}\n\nfn rendererPointShadowIntensityForLight(lightIndex: u32) -> f32 {\n return rendererLights.pointShadowParams2[lightIndex].y;\n}\n\nfn rendererSpotShadowMatrixForLight(lightIndex: u32) -> mat4x4<f32> {\n return rendererLights.spotShadowMatrices[lightIndex];\n}\n\nfn rendererSpotShadowBiasForLight(lightIndex: u32) -> f32 {\n return rendererLights.spotShadowParams[lightIndex].x;\n}\n\nfn rendererSpotShadowEnabledForLight(lightIndex: u32) -> bool {\n return rendererLights.spotShadowParams[lightIndex].y >= 0.5;\n}\n\nfn rendererSpotShadowIntensityForLight(lightIndex: u32) -> f32 {\n return rendererLights.spotShadowParams2[lightIndex].y;\n}\n\nfn rendererSampleSpotLightMapForLight(lightIndex: u32, worldPosition: vec3<f32>) -> vec3<f32> {\n if (lightIndex >= rendererSpotLightCount() || rendererLights.spotParams[lightIndex].w < 0.5) {\n return vec3<f32>(1.0);\n }\n let clip = rendererSpotShadowMatrixForLight(lightIndex) * vec4<f32>(worldPosition, 1.0);\n if (clip.w <= 0.0) { return vec3<f32>(1.0); }\n let ndc = clip.xyz / clip.w;\n if (any(ndc < vec3<f32>(-1.0, -1.0, 0.0)) || any(ndc > vec3<f32>(1.0))) {\n return vec3<f32>(1.0);\n }\n let projectedUv = ndc.xy * vec2<f32>(0.5, -0.5) + vec2<f32>(0.5);\n let cell = vec2<f32>(f32(lightIndex % 8u), f32(lightIndex / 8u));\n let cellUv = clamp(projectedUv, vec2<f32>(0.0), vec2<f32>(1.0)) * (255.0 / 256.0) + vec2<f32>(0.5 / 256.0);\n let atlasUv = (cell + cellUv) / 8.0;\n return textureSampleLevel(rendererSpotLightMapAtlas, rendererLinearClampSampler, atlasUv, 0.0).rgb;\n}\n\n${u}\n${Qu(n)}\n${o}\n${l}\n`}function td(e=!0,t){return ed({uniforms:{},textures:{},storageBuffers:{},getGraphTextureInputs:()=>({})},void 0,"particle",e,!1,t)}function rd(e,t,r,i="packed",n=!1){const a="camera"===t?`\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n nearFar: vec4<f32>,\n fogColor: vec4<f32>,\n fogParams: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> rendererLights: array<vec4<f32>, 11>;\n${"instanced-direct"===i?"@group(0) @binding(2) var<storage, read> rendererInstanceMatrices: array<vec4<f32>>;\n@group(0) @binding(3) var<storage, read> rendererInstanceColors: array<vec4<f32>>;":"@group(0) @binding(2) var<storage, read> rendererInstances: array<RendererInstanceData>;"}\n\nfn rendererClipPosition(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n return rendererCamera.viewProj * rendererWorldPosition(localPosition, instanceIndex);\n}\n`:`\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n nearFar: vec4<f32>,\n timeAndPadding: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n${"instanced-direct"===i?"@group(0) @binding(1) var<storage, read> rendererInstanceMatrices: array<vec4<f32>>;\n@group(0) @binding(2) var<storage, read> rendererInstanceColors: array<vec4<f32>>;":"@group(0) @binding(1) var<storage, read> rendererInstances: array<RendererInstanceData>;"}\n\nfn rendererClipPosition(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n return shadowCamera.viewProj * rendererWorldPosition(localPosition, instanceIndex);\n}\n`,s=Xu(e,r),o="instanced-direct"===i?"\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let base = instanceIndex * 4u;\n return mat4x4<f32>(\n rendererInstanceMatrices[base + 0u],\n rendererInstanceMatrices[base + 1u],\n rendererInstanceMatrices[base + 2u],\n rendererInstanceMatrices[base + 3u]\n );\n}\n\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> {\n return rendererInstanceColors[instanceIndex];\n}\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 {\n return instanceIndex;\n}\n":"\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> {\n return rendererInstances[instanceIndex].color;\n}\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 {\n return u32(round(rendererInstances[instanceIndex].batching.x));\n}\n",l="packed-visible"===i;return`\n${a}\n${l?`@group(0) @binding(${"shadow"===t?2:3}) var<storage, read> rendererVisibleInstanceIndices: array<u32>;\nfn rendererResolveInstanceIndex(instanceIndex: u32) -> u32 { return rendererVisibleInstanceIndices[instanceIndex]; }`:""}\n\n${l?o.replaceAll("rendererInstances[instanceIndex]","rendererInstances[rendererResolveInstanceIndex(instanceIndex)]"):o}\n\nfn rendererInverseMat3(m: mat3x3<f32>) -> mat3x3<f32> {\n let a = m[0];\n let b = m[1];\n let c = m[2];\n let r0 = cross(b, c);\n let r1 = cross(c, a);\n let r2 = cross(a, b);\n let det = dot(r2, c);\n let safeDet = select(det, select(-1e-8, 1e-8, det >= 0.0), abs(det) < 1e-8);\n let invDet = 1.0 / safeDet;\n return transpose(mat3x3<f32>(r0 * invDet, r1 * invDet, r2 * invDet));\n}\n\nfn rendererInstanceNormalMatrix(instanceIndex: u32) -> mat3x3<f32> {\n let model = rendererInstanceModelMatrix(instanceIndex);\n let model3x3 = mat3x3<f32>(model[0].xyz, model[1].xyz, model[2].xyz);\n return transpose(rendererInverseMat3(model3x3));\n}\n\nfn rendererWorldPosition(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n return rendererInstanceModelMatrix(instanceIndex) * vec4(localPosition, 1.0);\n}\n\nfn rendererWorldNormal(localNormal: vec3<f32>, instanceIndex: u32) -> vec3<f32> {\n return normalize(rendererInstanceNormalMatrix(instanceIndex) * localNormal);\n}\n\n${Ju("camera"===t?"rendererCamera":"shadowCamera")}\n${Qu(n)}\n${s}\n`}var id=class{constructor(e,t,r={}){this.name=e,this.callback=t,this.reads=r.reads,this.writes=r.writes,this.dependsOn=r.dependsOn}name;callback;reads;writes;dependsOn;execute(e){this.callback(e)}},nd=class{constructor(e){this.device=e}device;timestamps=[];visibility=[];disposed=!1;acquire(e,t){if(this.disposed)return null;const r=t?this.timestamps:this.visibility;let i=r.find(t=>!t.busy&&t.capacity>=e);if(!i){const n=r.findIndex(e=>!e.busy);if(n<0&&r.length>=3)return null;n>=0&&this.destroy(r[n]);const a=Math.max(8,t?8*e:e);i={busy:!1,capacity:e,readBuffer:this.device.createBuffer({label:"renderer-profile-read",size:a,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ})},t&&(i.querySet=this.device.createQuerySet({label:"renderer-profile-timestamps",type:"timestamp",count:e}),i.resolveBuffer=this.device.createBuffer({label:"renderer-profile-resolve",size:a,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC})),n>=0?r[n]=i:r.push(i)}return i.busy=!0,i}release(e,t){if(this.disposed)return;if(t)return void(e.busy=!1);this.destroy(e);const r=e.querySet?this.timestamps:this.visibility,i=r.indexOf(e);i>=0&&r.splice(i,1)}dispose(){this.disposed=!0;for(const e of this.timestamps)this.destroy(e);for(const e of this.visibility)this.destroy(e);this.timestamps.length=this.visibility.length=0}destroy(e){e.readBuffer.destroy(),e.querySet?.destroy(),e.resolveBuffer?.destroy()}},ad=new WeakMap,sd=new WeakMap,od=new WeakSet;function ld(e){ad.get(e)?.dispose(),ad.delete(e)}function cd(e,t){od.has(t)||((!e.latestFrameProfile||t.profile.frameIndex>=e.latestFrameProfile.frameIndex)&&(e.latestFrameProfile=hd(t.profile)),(t.pendingGpuRead||t.pendingVisibilityRead)&&Promise.all([t.pendingGpuRead?ud(t.profile,t.pendingGpuRead):Promise.resolve(),t.pendingVisibilityRead?dd(t.profile,t.pendingVisibilityRead):Promise.resolve()]).then(()=>{if(sd.get(t)!==ad.get(e))return;const r=hd(t.profile);(!e.latestFrameProfile||r.frameIndex>=e.latestFrameProfile.frameIndex)&&(e.latestFrameProfile=r),(!e.latestCompletedFrameProfile||r.frameIndex>=e.latestCompletedFrameProfile.frameIndex)&&(e.latestCompletedFrameProfile=r)}))}async function ud(e,t){let r=!1;try{await t.readBuffer.mapAsync(GPUMapMode.READ);const i=t.readBuffer.getMappedRange(),n=new BigUint64Array(i);let a=0;const s=t.profile.passes.map((e,t)=>{const r=Number(n[2*t]??0n),i=Number(n[2*t+1]??0n),s=Math.max(0,i-r)/1e6;return a+=s,{...e,gpuTimeMs:s}});e.gpuTimeMs=a,e.gpuProfilingReason=null,e.passes=s,r=!0}catch{e.timestampQueryActive=!1,e.gpuTimeMs=null,e.gpuProfilingReason="timestamp readback failed after submission",e.passes=e.passes.map(e=>({...e,gpuTimeMs:null}))}finally{"mapped"===t.readBuffer.mapState&&t.readBuffer.unmap(),t.release?t.release(r):(t.querySet.destroy(),t.resolveBuffer.destroy(),t.readBuffer.destroy())}}async function dd(e,t){let r=!1;try{await t.readBuffer.mapAsync(GPUMapMode.READ);const i=new Uint32Array(t.readBuffer.getMappedRange());let n=0,a=0,s=0,o=0,l=0;for(const e of t.regions){let t=0;const r=e.byteOffset/Uint32Array.BYTES_PER_ELEMENT;for(let n=0;n<e.drawCount;n+=1)t+=i[r+5*n+1]??0,l+=Math.floor((i[r+5*n]??0)/3)*(i[r+5*n+1]??0);"dynamic"===e.kind?(n+=e.totalInstances,a+=t):(s+=e.totalInstances,o+=t)}const c=n+s,u=a+o;e.visibility={visibleTriangles:l,totalInstances:c,visibleInstances:u,culledInstances:Math.max(0,c-u),dynamicTotalInstances:n,dynamicVisibleInstances:a,staticTotalInstances:s,staticVisibleInstances:o},r=!0}catch{e.visibility=null}finally{"mapped"===t.readBuffer.mapState&&t.readBuffer.unmap(),t.release?t.release(r):t.readBuffer.destroy()}}function hd(e){return{...e,cpuPhases:{...e.cpuPhases},passes:e.passes.map(e=>({...e})),visibility:e.visibility?{...e.visibility}:null}}import{Frustum as pd,Matrix4 as fd,Sphere as md}from"three";function gd(e,t,r,i,n,a,s,o){const l=e[t+3];if(n>0&&!(l*i>=n*(s?.85:1.15)))return!1;const c=e[t],u=e[t+1],d=e[t+2];if(a>0){const e=c-o.x,t=u-o.y,r=d-o.z,i=a+l;if(!(e*e+t*t+r*r<=i*i))return!1}for(let e=0;e<6;e++){const t=r.planes[e],i=t.normal;if(i.x*c+i.y*u+i.z*d+t.constant<-l)return!1}return!0}var vd=class{draws=[];directDraws=[];bundles=[];signatures=[];count=-1;bindGroup=null;pipeline=null;invalidation=null;matches(e,t,r){let i=this.count===this.draws.length&&this.bindGroup===e&&this.pipeline===t&&this.invalidation===r;for(let e=0;e<this.draws.length;e++){const t=this.draws[e],r=t.geometryResource,n=this.signatures[e];n&&n.geometry===t.geometryKey&&n.position===r.position&&n.index===r.index&&n.binding===t.residentInstanceBinding&&n.start===t.start&&n.count===t.count&&n.firstInstance===t.instanceStart&&n.instances===t.instanceCount||(i=!1)}return i}store(e,t,r,i){for(let e=0;e<this.draws.length;e++){const t=this.draws[e],r=t.geometryResource;let i=this.signatures[e];i||(i={},this.signatures[e]=i),i.geometry=t.geometryKey,i.position=r.position,i.index=r.index,i.binding=t.residentInstanceBinding,i.start=t.start,i.count=t.count,i.firstInstance=t.instanceStart,i.instances=t.instanceCount}this.count=this.draws.length,this.bindGroup=t,this.pipeline=r,this.invalidation=i,e?this.bundles[0]=e:this.bundles.length=0}},xd=class{valid=!1;matrix=new Float64Array(16);policies=new Float64Array(0);size=0;x=0;y=0;z=0;update(e,t,r,i){let n=!this.valid||this.size!==t;for(let t=0;t<16;t++)this.matrix[t]!==e.elements[t]&&(n=!0);this.policies.length!==3*r.length&&(this.policies=new Float64Array(3*r.length),n=!0);let a=!1;for(let e=0;e<r.length;e++){const t=r[e],i=t.detailCulling,s=3*e,o=t.castShadow?1:0;this.policies[s]===i.shadowMinScreenSize&&this.policies[s+1]===i.shadowMaxDistance&&this.policies[s+2]===o||(n=!0),this.policies[s]=i.shadowMinScreenSize,this.policies[s+1]=i.shadowMaxDistance,this.policies[s+2]=o,a||=0!==o&&i.shadowMaxDistance>0}return!a||this.x===i.x&&this.y===i.y&&this.z===i.z||(n=!0),this.matrix.set(e.elements),this.size=t,this.x=i.x,this.y=i.y,this.z=i.z,this.valid=!0,n}},wd=new WeakMap,bd={drawCallCount:0,triangleCount:0},yd=new pd,Sd=new fd,Cd=new md,Md=new WeakMap,Pd=new WeakMap,Bd=F.clone();function Dd(e,t,r,i,n=0){let a=Md.get(e);a||(a=new WeakMap,Md.set(e,a));let s=a.get(t);s||(s={pool:[],draws:[],key:new xd},a.set(t,s));if(!s.key.update(Sd,r,e.draws,Bd)&&s.excluded===i&&s.exclusionVersion===n)return this.directionalShadowSubmissionStats.selectionHits++,s.draws;s.excluded=i,s.exclusionVersion=n,this.directionalShadowSubmissionStats.selections++;const o=s.pool,l=s.draws;l.length=0;const c=e.instanceVisibilityResource.metadata,u=Math.max(Math.abs(t.projectionMatrix.elements[0])*r,Math.abs(t.projectionMatrix.elements[5])*r);let d=Pd.get(e);d||(d=new WeakMap,Pd.set(e,d));let h=d.get(t);h||(h=new Uint8Array(e.instanceCount),d.set(t,h));let p=0;for(const t of e.shadowChunks)if(Cd.center.copy(t.boundsCenter),Cd.radius=t.boundsRadius,yd.intersectsSphere(Cd))for(const r of t.drawIndices){if(i?.[r])continue;const t=e.draws[r];if(!t.castShadow)continue;const n=t.detailCulling;let a=-1;const s=t.instanceStart+t.instanceCount;for(let e=t.instanceStart;e<=s;e++){let r=!1;if(e<s){r=gd(c,8*e,yd,u,n.shadowMinScreenSize,n.shadowMaxDistance,0!==h[e],Bd),h[e]=r?1:0}if(r&&a<0&&(a=e),!r&&a>=0){let r=o[p];r?r.source!==t&&(Object.assign(r.draw,t),r.source=t):(r={source:t,draw:{...t}},o[p]=r);const i=r.draw;i.instanceStart=a,i.instanceCount=e-a,l.push(i),p++,a=-1}}}return l}function Td(e){return e.usesBatching}function Id(e){return!e.wireframe&&e.material.primitiveTopology.startsWith("triangle")}function Vd(e,t){return"pointShadow"===t?null!==e.material.pointShadowVertexShader&&null!==e.material.pointShadowFragmentShader:null!==e.material.depthVertexShader}function Gd(e,t){if(!this.state.visibilityKernel||!this.state.drawMetadataResource||0===this.state.drawMetadataResource.count)return;const r=e.beginComputePass({label:"renderer-visibility-pass"});r.setPipeline(this.state.visibilityKernel.pipeline),r.setBindGroup(0,t),r.dispatchWorkgroups(Math.ceil(this.state.drawMetadataResource.count/64)),r.end()}var Ld=new WeakMap;function zd(e,t){if(!(this.state.staticVisibilityClearKernel&&this.state.staticVisibilityCullKernel&&this.state.staticVisibilityIndirectBuildKernel&&this.getHiZOcclusionCullingActive()&&this.state.device))return;let r=Ld.get(this);r||(r=[],Ld.set(this,r)),r.length=0;for(const e of this.staticDrawSets){if(!e.publicSet.enabled||0===e.drawMetadataResource.count)continue;if("postpass"===t&&e.lastPreVisibilityFrameToken!==this.staticFrameToken)continue;if(!this.state.device)continue;const i="prepass"===t?e.visibilityParamsUpload:e.postVisibilityParamsUpload,n="prepass"===t?e.visibilityParamsBuffer:e.postVisibilityParamsBuffer,a="prepass"===t?this.state.temporalHiZHistoryValid?3:0:5;i[1]===this.state.hizMipCount&&i[3]===a||(i[1]=this.state.hizMipCount,i[3]=a,this.state.device.queue.writeBuffer(n,0,ii(i),0,4));this.getOrCreateStaticVisibilityBindGroup(e,t)&&("prepass"!==t||e.visibilityClearBindGroup&&e.visibilityIndirectBuildBindGroup&&e.postVisibilityIndirectBuildBindGroup||(e.visibilityClearBindGroup=this.state.staticVisibilityClearKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:e.visibilityParamsBuffer}},{binding:1,resource:{buffer:e.instanceVisibilityResource.visibleCountsBuffer}},{binding:2,resource:{buffer:e.instanceVisibilityResource.postVisibleCountsBuffer}},{binding:3,resource:{buffer:e.instanceVisibilityResource.visibleInstanceMaskBuffer}}],`${e.label}-visibility-clear-bind-group`),e.visibilityIndirectBuildBindGroup=this.state.staticVisibilityIndirectBuildKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:e.visibilityParamsBuffer}},{binding:1,resource:{buffer:e.instanceVisibilityResource.visibleCountsBuffer}},{binding:2,resource:{buffer:e.instanceVisibilityResource.postVisibleCountsBuffer}},{binding:3,resource:{buffer:e.drawMetadataResource.indirectBuffer}},{binding:4,resource:{buffer:e.drawMetadataResource.postIndirectBuffer}}],`${e.label}-visibility-indirect-build-bind-group`),e.postVisibilityIndirectBuildBindGroup=this.state.staticVisibilityIndirectBuildKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:e.postVisibilityParamsBuffer}},{binding:1,resource:{buffer:e.instanceVisibilityResource.visibleCountsBuffer}},{binding:2,resource:{buffer:e.instanceVisibilityResource.postVisibleCountsBuffer}},{binding:3,resource:{buffer:e.drawMetadataResource.indirectBuffer}},{binding:4,resource:{buffer:e.drawMetadataResource.postIndirectBuffer}}],`${e.label}-post-visibility-indirect-build-bind-group`)),r.push(e))}if(0===r.length)return;if("prepass"===t){const t=e.beginComputePass({label:"static-temporal-visibility-clear-pass"});t.setPipeline(this.state.staticVisibilityClearKernel.pipeline);for(const e of r)t.setBindGroup(0,e.visibilityClearBindGroup),t.dispatchWorkgroups(Math.ceil(Math.max(e.drawMetadataResource.count,e.instanceVisibilityResource.instanceCount)/64));t.end()}const i=e.beginComputePass({label:`static-temporal-visibility-${t}-cull-pass`});i.setPipeline(this.state.staticVisibilityCullKernel.pipeline);for(const e of r)i.setBindGroup(0,"prepass"===t?e.visibilityBindGroup:e.postVisibilityBindGroup),i.dispatchWorkgroups(Math.ceil(e.instanceVisibilityResource.instanceCount/64));i.end();const n=e.beginComputePass({label:`static-temporal-visibility-${t}-indirect-build-pass`});n.setPipeline(this.state.staticVisibilityIndirectBuildKernel.pipeline);for(const e of r)n.setBindGroup(0,"prepass"===t?e.visibilityIndirectBuildBindGroup:e.postVisibilityIndirectBuildBindGroup),n.dispatchWorkgroups(Math.ceil(e.drawMetadataResource.count/64)),"prepass"===t?e.lastPreVisibilityFrameToken=this.staticFrameToken:e.lastVisibilityFrameToken=this.staticFrameToken;n.end(),r.length=0}function Rd(e,t){if(!(this.state.device&&this.state.staticVisibilityCullKernel&&this.state.hizTexture&&this.state.temporalVisibilityBuffer&&this.state.nearestClampSampler))return null;const r="prepass"===t?e.visibilityBindGroup:e.postVisibilityBindGroup;if(r&&e.visibilityBindGroupHizVersion===this.hizResourceVersion)return r;const i=this.state.staticVisibilityCullKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:this.state.temporalVisibilityBuffer}},{binding:1,resource:{buffer:"prepass"===t?e.visibilityParamsBuffer:e.postVisibilityParamsBuffer}},{binding:2,resource:this.state.nearestClampSampler},{binding:3,resource:this.state.hizTexture.createView()},{binding:4,resource:{buffer:e.instanceVisibilityResource.instanceMetadataBuffer}},{binding:5,resource:{buffer:e.drawMetadataResource.metadataBuffer}},{binding:6,resource:{buffer:e.instanceVisibilityResource.visibleCountsBuffer}},{binding:7,resource:{buffer:e.instanceVisibilityResource.visibleInstanceIndicesBuffer}},{binding:8,resource:{buffer:e.instanceVisibilityResource.visibleInstanceMaskBuffer}},{binding:9,resource:{buffer:e.instanceVisibilityResource.postVisibleCountsBuffer}}],`${e.label}-temporal-visibility-${t}-bind-group`);return"prepass"===t?e.visibilityBindGroup=i:e.postVisibilityBindGroup=i,e.visibilityBindGroupHizVersion=this.hizResourceVersion,i}function Ud(e,t,r,i){if(!this.state.shadowDepthPipeline||0===this.state.directionalShadowLayerViews.length)return void this.clearDirectionalShadow(e);let n=!1;r.camera.getWorldPosition(Bd);for(let t=0;t<r.lights.directionals.length;t+=1){const a=r.lights.directionals[t],s=this.state.directionalShadowLayerViews[t];if(!a.castShadow||!s)continue;n=!0;const o=this.directionalShadowCameras[t];if(!(this.directionalShadowScheduler.updateMask&1<<t)){i.directionalShadowReused=(i.directionalShadowReused??0)+1;continue}i.directionalShadowUpdates=(i.directionalShadowUpdates??0)+1,i.directionalShadowUpdateMask=(i.directionalShadowUpdateMask??0)|1<<t,this.directionalShadowScheduler.forcedMask&1<<t&&(i.directionalShadowForced=(i.directionalShadowForced??0)+1),yd.setFromProjectionMatrix(Sd.multiplyMatrices(o.projectionMatrix,o.matrixWorldInverse));const l=this.getShadowCameraBuffer(t);this.writeShadowCameraBuffer(yi(o,this.shadowViewProjScratch),0,0,0,1,l,o);const c=this.getSharedShadowBindGroupForCameraBuffer(l);let u;for(const i of this.staticDrawSets)i.publicSet.enabled&&0!==i.draws.length&&"late"!==i.drawStage&&(!u&&this.directionalShadowGpu.enabled&&this.directionalShadowGpu.available&&(u=e.beginComputePass({label:`renderer-directional-shadow-selection-${t}`})),this.directionalShadowGpu.prepare(this,e,i,o,l,r.camera,this.state.directionalShadowTextureSize,u,Bd));u?.end();const d=e.beginRenderPass({label:`renderer-directional-shadow-pass-${t}`,colorAttachments:[],depthStencilAttachment:{view:s,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});d.setPipeline(this.state.shadowDepthPipeline),d.setBindGroup(0,c),this.drawDepthLike(d,r.shadowDraws??[...r.gpuOpaqueDraws,...r.directOpaqueDraws],i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"});for(const e of this.staticDrawSets){if(!e.publicSet.enabled||0===e.draws.length||"late"===e.drawStage)continue;const t=this.directionalShadowGpu.submit(d,e,l,i)?this.directionalShadowGpu.sets.get(e):void 0;t?.eligibleDrawCount!==e.draws.length&&Ad.call(this,d,e,o,Dd.call(this,e,o,this.state.directionalShadowTextureSize,t?.eligibility,t?.eligibilityVersion),c,l,i)}d.end(),this.directionalShadowScheduler.commit(t)}n||this.clearDirectionalShadow(e)}function Ad(e,t,r,i,n,a,s){let o=wd.get(t);o||(o=new WeakMap,wd.set(t,o));let l=o.get(r);l||(l=new vd,o.set(r,l)),l.draws.length=0,l.directDraws.length=0;let c=0;for(const e of i)e.customDepthMaterial||Vd(e,"directionalShadow")||e.hasRenderCallbacks||e.skinning||!e.indexed||e.wireframe||!Id(e)||"packed"!==this.getDrawInstanceAccessMode(e)?l.directDraws.push(e):(l.draws.push(e),c+=Ti(e));if(l.draws.length>0){const r=this.state.shadowDepthPipeline,i=this.resolveShadowBindGroupForDraw(l.draws[0],n,a),o=l.matches(i,r,t.shadowBundles);if(o)if(0===l.bundles.length){const e=this.state.device.createRenderBundleEncoder({label:`${t.label}-directional-selected-runs`,colorFormats:[],depthStencilFormat:"depth32float",sampleCount:1});bd.drawCallCount=0,bd.triangleCount=0,ah.call(this,e,l.draws,bd,{fallbackPipeline:r,fallbackBindGroup:n,shadowCameraBuffer:a,passKind:"directionalShadow",customDepthMode:"ignore",preculled:!0}),l.store(e.finish(),i,r,t.shadowBundles),this.directionalShadowSubmissionStats.bundleBuilds++}else this.directionalShadowSubmissionStats.bundleHits++;else l.store(null,i,r,t.shadowBundles),bd.drawCallCount=0,bd.triangleCount=0,ah.call(this,e,l.draws,bd,{fallbackPipeline:r,fallbackBindGroup:n,shadowCameraBuffer:a,passKind:"directionalShadow",customDepthMode:"ignore",preculled:!0});o&&e.executeBundles(l.bundles),s.drawCallCount+=l.draws.length,s.triangleCount+=c}l.directDraws.length>0&&this.drawDepthLike(e,l.directDraws,s,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackBindGroup:n,shadowCameraBuffer:a,passKind:"directionalShadow",customDepthMode:"use"})}function kd(e,t,r,i){if(!r.lights.points.some(e=>e.castShadow))return;if(!this.state.pointShadowPipeline||!this.state.pointShadowFaceViews.length||!this.state.pointShadowDepthFaceViews.length)return void this.clearPointShadow(e);let n=!1;for(let t=0;t<r.lights.points.length;t+=1){const a=r.lights.points[t];if(a.castShadow){n=!0;for(let n=0;n<6;n+=1){const s=6*t+n,o=this.pointShadowCameras[t][n];o.near=a.shadowCameraNear,o.far=a.shadowCameraFar,o.position.copy(a.position),F.copy(a.position).add(G[n]),o.up.copy(V[n]),o.lookAt(F),o.updateMatrixWorld(!0),o.updateProjectionMatrix();const l=this.getShadowCameraBuffer(4+s);this.writeShadowCameraBuffer(yi(o,this.shadowViewProjScratch),a.position.x,a.position.y,a.position.z,a.range,l,o);const c=this.getSharedShadowBindGroupForCameraBuffer(l),u=e.beginRenderPass({label:`renderer-point-shadow-pass-${t}-${n}`,colorAttachments:[{view:this.state.pointShadowFaceViews[s],clearValue:{r:1,g:1,b:1,a:1},loadOp:"clear",storeOp:"store"}],depthStencilAttachment:{view:this.state.pointShadowDepthFaceViews[s],depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});u.setPipeline(this.state.pointShadowPipeline),u.setBindGroup(0,c),this.drawDepthLike(u,r.gpuOpaqueDraws,i,{fallbackPipeline:this.state.pointShadowPipeline,fallbackPipelineDirect:this.state.pointShadowPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedPointShadowPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"pointShadow",customDepthMode:"use"}),this.drawDepthLike(u,r.directOpaqueDraws,i,{fallbackPipeline:this.state.pointShadowPipeline,fallbackPipelineDirect:this.state.pointShadowPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedPointShadowPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"pointShadow",customDepthMode:"use"});for(const e of this.staticDrawSets)e.publicSet.enabled&&0!==e.draws.length&&"late"!==e.drawStage&&(this.renderBundleScratch[0]=Hd.call(this,e,c,l,"pointShadow",this.state.pointShadowPipeline,this.state.pointShadowPipelineDirect),u.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(e,i));u.end()}}}n||this.clearPointShadow(e)}function Fd(e,t,r,i){if(!r.lights.spots.some(e=>e.castShadow))return;if(!this.state.shadowDepthPipeline||0===this.state.spotShadowLayerViews.length)return void this.clearSpotShadow(e);let n=!1;for(let t=0;t<r.lights.spots.length;t+=1){const a=r.lights.spots[t],s=this.state.spotShadowLayerViews[t];if(!a.castShadow||!s)continue;n=!0;const o=this.spotShadowCameras[t];o.near=a.shadowCameraNear,o.far=a.shadowCameraFar,o.fov=a.shadowCameraFov,o.aspect=1,o.position.copy(a.position),F.copy(a.position).add(a.direction),o.lookAt(F),o.updateMatrixWorld(!0),o.updateProjectionMatrix();const l=this.getShadowCameraBuffer(28+t);this.writeShadowCameraBuffer(yi(o,this.shadowViewProjScratch),0,0,0,1,l,o);const c=this.getSharedShadowBindGroupForCameraBuffer(l),u=e.beginRenderPass({label:`renderer-spot-shadow-pass-${t}`,colorAttachments:[],depthStencilAttachment:{view:s,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});u.setPipeline(this.state.shadowDepthPipeline),u.setBindGroup(0,c),this.drawDepthLike(u,r.gpuOpaqueDraws,i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"}),this.drawDepthLike(u,r.directOpaqueDraws,i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"});for(const e of this.staticDrawSets)e.publicSet.enabled&&0!==e.draws.length&&"late"!==e.drawStage&&(this.renderBundleScratch[0]=Hd.call(this,e,c,l,"directionalShadow",this.state.shadowDepthPipeline,this.state.shadowDepthPipelineDirect),u.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(e,i));u.end()}n||this.clearSpotShadow(e)}function $d(e,t,r,i){if(!this.state.depthPrepassPipeline||!this.state.mainDepthView)return;const n=e.beginRenderPass({label:"renderer-depth-prepass",colorAttachments:[],depthStencilAttachment:{view:this.state.mainDepthView,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});n.setPipeline(this.state.depthPrepassPipeline),n.setBindGroup(0,t),this.executeStaticDepthPrepass(n,t,i),this.drawDepthLike(n,r.gpuOpaqueDraws,i,{fallbackPipeline:this.state.depthPrepassPipeline,fallbackPipelineDirect:this.state.depthPrepassPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedDepthPrepassPipeline,fallbackBindGroup:t,passKind:"prepass",customDepthMode:"skip"}),this.drawDepthLike(n,r.directOpaqueDraws,i,{fallbackPipeline:this.state.depthPrepassPipeline,fallbackPipelineDirect:this.state.depthPrepassPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedDepthPrepassPipeline,fallbackBindGroup:t,passKind:"prepass",customDepthMode:"skip"}),n.end()}function Ed(e,t,r){for(const i of this.staticDrawSets){if(!i.publicSet.enabled||0===i.draws.length||"late"===i.drawStage)continue;if(this.getHiZOcclusionCullingActive()&&i.lastPreVisibilityFrameToken===this.staticFrameToken&&jd(i)){const e=this.getOrCreateStaticVisibleDepthSceneBindGroup(i);this.renderBundleScratch[0]=Od.call(this,i,e)}else this.renderBundleScratch[0]=this.getOrCreateStaticDepthPrepassBundle(i,t);e.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(i,r)}}function Od(e,t,r=e.drawMetadataResource.indirectBuffer,i="prepass"){if(!this.state.device||!this.state.depthPrepassPipelineVisible)throw new Error("Renderer visible depth prepass resources are not initialized.");const n=e.indirectDepthPrepassBundles[i];if(n?.sceneBindGroup===t&&n.indirectBuffer===r)return n.bundle;const a=`${e.label}-static-temporal-depth-${i}-bundle-${e.id}`,s=this.state.device.createRenderBundleEncoder({label:a,colorFormats:[],depthStencilFormat:"depth32float",sampleCount:1});s.setPipeline(this.state.depthPrepassPipelineVisible),s.setBindGroup(0,t);let o=null;for(let t=0;t<e.draws.length;t+=1){const i=e.draws[t];i.customDepthMaterial||Vd(i,"prepass")||oh(i.material)||!Id(i)||(o!==i.geometryKey&&(o=i.geometryKey,this.bindGeometryVertexBuffers(s,i.geometry,i.geometryResource,z,0,1,i.wireframe)),s.drawIndexedIndirect(r,5*t*Uint32Array.BYTES_PER_ELEMENT))}const l=s.finish({label:a});return e.indirectDepthPrepassBundles[i]={sceneBindGroup:t,indirectBuffer:r,bundle:l},l}function _d(e){if(this.sampleCount<=1||!this.state.mainDepthView||!this.getHiZOcclusionCullingActive())return;let t=null;for(const r of this.staticDrawSets){if(!r.publicSet.enabled||0===r.draws.length||"late"===r.drawStage||r.lastVisibilityFrameToken!==this.staticFrameToken||!jd(r))continue;t||(t=e.beginRenderPass({label:"renderer-static-temporal-depth-resolve",colorAttachments:[],depthStencilAttachment:{view:this.state.mainDepthView,depthLoadOp:"load",depthStoreOp:"store"}}));const i=this.getOrCreateStaticVisibleDepthSceneBindGroup(r);this.renderBundleScratch[0]=Od.call(this,r,i,r.drawMetadataResource.postIndirectBuffer,"postpass"),t.executeBundles(this.renderBundleScratch)}t?.end()}function jd(e){for(const t of e.draws)if(t.customDepthMaterial||Vd(t,"prepass")||oh(t.material)||!Id(t))return!1;return!0}function Nd(e,t){if(!this.state.device||!this.state.depthPrepassPipeline)throw new Error("Renderer is not initialized.");const r=this.resolveSceneBindGroupForDraw(e.draws[0],t);if(e.depthPrepassBundle&&e.depthPrepassBundleSceneBindGroup===r)return e.depthPrepassBundle;const i=Wd.call(this,e,"prepass"),n=`${e.label}-static-depth-prepass-bundle-${e.id}`,a=this.state.device.createRenderBundleEncoder({label:n,colorFormats:[],depthStencilFormat:"depth32float",sampleCount:1});a.setBindGroup(0,r);let s=null,o=null,l=null;for(let t=0;t<e.draws.length;t+=1){const r=e.draws[t],n=i[t];if(r.customDepthMaterial||!n&&(oh(r.material)||!Id(r)))continue;const c=n?.pipeline??this.state.depthPrepassPipeline;s!==c&&(s=c,o=null,l=null,a.setPipeline(c)),n&&o!==n.bindGroup&&(o=n.bindGroup,a.setBindGroup(1,o)),l!==r.geometryKey&&(l=r.geometryKey,this.bindGeometryVertexBuffers(a,r.geometry,r.geometryResource,n?.vertexAttributes??z,r.instanceStart,r.instanceCount,r.wireframe)),a.drawIndexed(r.count,r.instanceCount,r.start,0,r.instanceStart)}const c=a.finish({label:n});return e.depthPrepassBundle=c,e.depthPrepassBundleSceneBindGroup=r,c}function Wd(e,t){const r=t,i=e.depthMaterialResources.get(r);if(i)return i;const n=e.draws.map(e=>{const r=Vd(e,t);if(e.customDepthMaterial||!r)return null;return this.getDepthPassMaterialResourceForDraw(e.material,t,e)});return e.depthMaterialResources.set(r,n),n}function Hd(e,t,r,i,n,a,s){if(!this.state.device)throw new Error("Renderer is not initialized.");const o=this.resolveShadowBindGroupForDraw(e.draws[0],t,r),l=s?null:e.shadowBundles.get(o),c=s?s.bundles.get(o):l?.[i];if(c)return c;const u=Wd.call(this,e,i),d=`${e.label}-static-${i}-bundle-${e.id}`,h=this.state.device.createRenderBundleEncoder({label:d,colorFormats:"pointShadow"===i?["rgba16float"]:[],depthStencilFormat:"depth32float",sampleCount:1});h.setBindGroup(0,o);let p=null,f=null,m=null;const g=s?.drawIndices;for(let t=0;t<(g?.length??e.draws.length);t+=1){const r=g?.[t]??t,i=e.draws[r];if(!i.castShadow)continue;const s=u[r],o=s?.pipeline??("instanced-direct"===this.getDrawInstanceAccessMode(i)&&a?a:n);p!==o&&(p=o,f=null,m=null,h.setPipeline(o)),s&&f!==s.bindGroup&&(f=s.bindGroup,h.setBindGroup(1,f)),m!==i.geometryKey&&(m=i.geometryKey,this.bindGeometryVertexBuffers(h,i.geometry,i.geometryResource,s?.vertexAttributes??z,i.instanceStart,i.instanceCount,i.wireframe)),h.drawIndexed(i.count,i.instanceCount,i.start,0,i.instanceStart)}const v=h.finish({label:d});return s?s.bundles.set(o,v):e.shadowBundles.set(o,{...l,[i]:v}),v}function qd(e,t=!1,r=!1){if(!(this.state.device&&this.state.hizTexture&&this.state.mainDepthTexture&&this.state.mainDepthView&&this.state.hizCopyKernel&&this.state.hizReduceKernel))return;let i=this.state.hizCopyBindGroup;i||(i=this.state.hizCopyKernel.createBindGroup(this.state.device,[{binding:0,resource:this.state.mainDepthView},{binding:1,resource:this.state.hizMipViews[0]}],"renderer-hiz-copy-bind-group"),this.state.hizCopyBindGroup=i);const n=e.beginComputePass({label:"renderer-hiz-copy-pass"});if(n.setPipeline(this.state.hizCopyKernel.pipeline),n.setBindGroup(0,i),n.dispatchWorkgroups(Math.ceil(this.state.width/8),Math.ceil(this.state.height/8)),n.end(),!r){for(let t=1;t<this.state.hizMipCount;t+=1){const r=Math.max(1,this.state.width>>t),i=Math.max(1,this.state.height>>t);let n=this.state.hizReduceBindGroups[t];n||(n=this.state.hizReduceKernel.createBindGroup(this.state.device,[{binding:0,resource:this.state.hizMipViews[t-1]},{binding:1,resource:this.state.hizMipViews[t]}],`renderer-hiz-reduce-bind-group-${t}`),this.state.hizReduceBindGroups[t]=n);const a=e.beginComputePass({label:`renderer-hiz-reduce-pass-${t}`});a.setPipeline(this.state.hizReduceKernel.pipeline),a.setBindGroup(0,n),a.dispatchWorkgroups(Math.ceil(r/8),Math.ceil(i/8)),a.end()}t&&this.commitTemporalHiZHistory()}}function Kd(e,t,r,i,n,a,s=!1,o="all",l=!1,c=this.sampleCount){if(!this.state.mainDepthView)return;const u=c>1,d=u?this.ensureMsaaColorTarget(t):null,h=u?this.ensureMsaaDepthTarget(d.width,d.height):null,p=e.beginRenderPass({label:"renderer-forward-pass",colorAttachments:[{view:d?.view??r,resolveTarget:d?r:void 0,clearValue:{r:this.clearColor[0],g:this.clearColor[1],b:this.clearColor[2],a:this.clearColor[3]},loadOp:l?"load":"clear",storeOp:d?"discard":"store"}],depthStencilAttachment:{view:h?.view??this.state.mainDepthView,depthClearValue:1,depthLoadOp:h||s?"clear":"load",depthStoreOp:h?"discard":"store"}});let f=null,m=null,g=null,v=null,x=null;const w=e=>{e.sourceObject&&e.hasRenderCallbacks&&e.sourceObject.onBeforeRender(this,n.scene,n.camera,e.geometry,e.material,e.geometryGroup);const t=e.geometryResource,r=this.getMaterialResourceForDraw(e,[D],c),s=this.resolveSceneBindGroupForDraw(e,i);if(f!==r.pipeline&&(f=r.pipeline,g=null,x=null,p.setPipeline(f)),g!==e.geometryKey&&(g=e.geometryKey,this.bindGeometryVertexBuffers(p,e.geometry,t,r.vertexAttributes,e.instanceStart,e.instanceCount,e.wireframe)),v!==s&&(v=s,p.setBindGroup(0,s)),m!==e.material){if(m=e.material,p.setBindGroup(1,r.bindGroup),!r.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");p.setBindGroup(3,this.createGraphTextureBindGroup(e.material,r.graphTextureBindGroupLayout))}r.usesSkinning&&e.skinning&&x!==e.skinning.bindGroup&&(x=e.skinning.bindGroup,p.setBindGroup(2,x)),e.indexed&&(e.wireframe?t.wireframeIndex:t.index)?p.drawIndexed(e.count,e.instanceCount,e.start,0,e.instanceStart):p.draw(e.count,e.instanceCount,e.start,e.instanceStart),this.recordDraw(e,a),e.sourceObject&&e.hasRenderCallbacks&&e.sourceObject.onAfterRender(this,n.scene,n.camera,e.geometry,e.material,e.geometryGroup)};if(this.executeStaticForwardPass(p,i,a,o,c),f=null,m=null,g=null,v=null,x=null,"late"!==o&&this.getHiZOcclusionCullingActive()&&this.state.drawMetadataResource){const e=this.buildIndirectSubmissionStreams(n.gpuOpaqueDraws,i),t=this.renderBundleScratch;t.length=0;for(let r=0;r<e.length;r+=1){const i=e[r];t[0]=this.getOrCreateIndirectForwardBundle(i),p.executeBundles(t),a.drawCallCount+=i.drawCallCount,a.triangleCount+=i.triangleCount}f=null,m=null,g=null,v=null}else if("late"!==o){const e=hi(n.gpuOpaqueDraws)||n.gpuOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(n.gpuOpaqueDraws,i,a);if(e)this.renderBundleScratch[0]=e,p.executeBundles(this.renderBundleScratch);else for(const e of n.gpuOpaqueDraws)w(e)}const b="late"===o||hi(n.directOpaqueDraws)||n.directOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(n.directOpaqueDraws,i,a);if(b)this.renderBundleScratch[0]=b,p.executeBundles(this.renderBundleScratch);else if("late"!==o)for(const e of n.directOpaqueDraws)w(e);if("opaque"!==o)for(const e of n.transparentDraws)w(e);p.end()}function Zd(e,t,r,i="all",n=this.sampleCount){for(const a of this.staticDrawSets)if(a.publicSet.enabled&&0!==a.draws.length&&("all"===i||a.drawStage===i)){if("opaque"===a.drawStage&&this.getHiZOcclusionCullingActive()&&a.lastVisibilityFrameToken===this.staticFrameToken){const t=this.getOrCreateStaticVisibleSceneBindGroup(a),i=this.getOrCreateStaticIndirectSubmissionStreams(a,t);for(const t of i)if(this.getMultiDrawIndirectActive()){if(e.setPipeline(t.materialResource.pipeline),this.bindGeometryVertexBuffers(e,t.geometry,t.geometryResource,t.materialResource.vertexAttributes,0,1,t.material.wireframe),e.setBindGroup(0,t.sceneBindGroup),e.setBindGroup(1,t.materialResource.bindGroup),!t.materialResource.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");e.setBindGroup(3,this.createGraphTextureBindGroup(t.material,t.materialResource.graphTextureBindGroupLayout)),e.multiDrawIndexedIndirect(a.drawMetadataResource.indirectBuffer,5*t.indirectStartIndex*Uint32Array.BYTES_PER_ELEMENT,t.indirectCount),r.drawCallCount+=t.drawCallCount,r.triangleCount+=t.triangleCount}else this.renderBundleScratch[0]=this.getOrCreateIndirectForwardBundle(t,a.drawMetadataResource,a.indirectForwardBundleCache,`${a.label}-static-indirect-forward-bundle`),e.executeBundles(this.renderBundleScratch),r.drawCallCount+=t.drawCallCount,r.triangleCount+=t.triangleCount;continue}this.renderBundleScratch[0]=this.getOrCreateStaticDirectForwardBundle(a,t,n),e.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(a,r)}}function Yd(e,t,r=this.sampleCount){if(!this.state.device||!this.state.format)throw new Error("Renderer is not initialized.");const i=this.resolveSceneBindGroupForDraw(e.draws[0],t);if(e.directForwardBundle&&e.directForwardBundleSceneBindGroup===i&&e.directForwardBundleSampleCount===r)return e.directForwardBundle;null==e.draws[0]?.materialResource&&(this.refreshStaticDrawMaterialResources(e.draws),this.syncStaticVisibleMaterialBindingCaches(e));const n=`${e.label}-static-forward-direct-bundle-${e.id}`,a=this.state.device.createRenderBundleEncoder({label:n,colorFormats:[D],depthStencilFormat:"depth32float",sampleCount:r});let s=null,o=null,l=null;a.setBindGroup(0,i);for(const t of e.draws){const i=("opaque"===e.drawStage?t.materialResource:null)??this.getMaterialResource(t.material,this.getDrawInstanceAccessMode(t),t.receiveShadow,void 0,null!==t.skinning,Td(t),r);if(s!==i.pipeline&&(s=i.pipeline,l=null,a.setPipeline(s)),l!==t.geometryKey&&(l=t.geometryKey,this.bindGeometryVertexBuffers(a,t.geometry,t.geometryResource,i.vertexAttributes,t.instanceStart,t.instanceCount,t.wireframe)),o!==i.bindGroup){if(o=i.bindGroup,a.setBindGroup(1,o),!i.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");a.setBindGroup(3,this.createGraphTextureBindGroup(t.material,i.graphTextureBindGroupLayout))}a.drawIndexed(t.count,t.instanceCount,t.start,0,t.instanceStart)}const c=a.finish({label:n});return e.directForwardBundle=c,e.directForwardBundleSceneBindGroup=i,e.directForwardBundleSampleCount=r,c}function Xd(e){for(const t of e.visibleMaterialBindings){const r=t.drawIndices[0];t.resource=e.draws[r]?.materialResource??e.visibleDrawMaterialResources[r]??null}}function Jd(e){for(const t of e)t.materialResource=this.getMaterialResource(t.material,this.getDrawInstanceAccessMode(t),t.receiveShadow,void 0,null!==t.skinning,Td(t))}function Qd(e,t){t.drawCallCount+=e.drawCallCount,t.triangleCount+=e.triangleCount}function eh(){return this.staticDrawSets.some(e=>e.publicSet.enabled&&e.draws.length>0)}function th(e,t,r){if(!(this.state.device&&this.state.presentPipeline&&this.state.fullscreenTextureBindGroupLayout&&this.state.linearClampSampler))return;let i=this.state.presentBindGroups.get(t);i||(i=this.state.device.createBindGroup({label:"renderer-present-bind-group",layout:this.state.fullscreenTextureBindGroupLayout,entries:[{binding:0,resource:this.state.linearClampSampler},{binding:1,resource:t}]}),this.state.presentBindGroups.set(t,i));const n=e.beginRenderPass({label:"renderer-present-pass",colorAttachments:[{view:r,clearValue:{r:this.clearColor[0],g:this.clearColor[1],b:this.clearColor[2],a:this.clearColor[3]},loadOp:"clear",storeOp:"store"}]});n.setPipeline(this.state.presentPipeline),n.setBindGroup(0,i),n.draw(3),n.end()}function rh(e){for(let t=0;t<this.state.directionalShadowLayerViews.length;t+=1){e.beginRenderPass({label:`renderer-clear-directional-shadow-${t}`,colorAttachments:[],depthStencilAttachment:{view:this.state.directionalShadowLayerViews[t],depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}}).end()}}function ih(e){for(let t=0;t<this.state.pointShadowFaceViews.length;t+=1){e.beginRenderPass({label:`renderer-clear-point-shadow-${t}`,colorAttachments:[{view:this.state.pointShadowFaceViews[t],clearValue:{r:1,g:1,b:1,a:1},loadOp:"clear",storeOp:"store"}],depthStencilAttachment:{view:this.state.pointShadowDepthFaceViews[t],depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}}).end()}}function nh(e){for(let t=0;t<this.state.spotShadowLayerViews.length;t+=1){e.beginRenderPass({label:`renderer-clear-spot-shadow-${t}`,colorAttachments:[],depthStencilAttachment:{view:this.state.spotShadowLayerViews[t],depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}}).end()}}function ah(e,t,r,i){let n=null,a=null,s=null,o=null,l=null;for(const c of t){if("directionalShadow"===i.passKind&&!i.preculled){if(Cd.center.copy(c.boundsCenter),Cd.radius=c.boundsRadius,!yd.intersectsSphere(Cd))continue;const e=c.detailCulling??g(c.sourceObject);if(!c.staticLocalBoundsCenter&&!v(c.boundsCenter,c.boundsRadius,Sd,this.state.directionalShadowTextureSize,this.state.directionalShadowTextureSize,Bd,.85*e.shadowMinScreenSize,e.shadowMaxDistance))continue}if("prepass"!==i.passKind&&!c.castShadow)continue;if("prepass"===i.passKind&&null===c.material.depthVertexShader&&oh(c.material))continue;if("skip"===i.customDepthMode&&c.customDepthMaterial)continue;const t=Vd(c,i.passKind),u="use"===i.customDepthMode&&c.customDepthMaterial?c.customDepthMaterial:"ignore"!==i.customDepthMode&&t?c.material:null,d=u?this.getDepthPassMaterialResourceForDraw(u,i.passKind,c):null;if(!d&&!Id(c))continue;const h=null!==c.skinning,p=d?.pipeline??(h&&i.fallbackSkinnedPipeline?i.fallbackSkinnedPipeline:"instanced-direct"===this.getDrawInstanceAccessMode(c)&&i.fallbackPipelineDirect?i.fallbackPipelineDirect:i.fallbackPipeline);a!==p&&(a=p,s=null,o=null,l=null,n=null,e.setPipeline(p));const f="prepass"===i.passKind?this.resolveSceneBindGroupForDraw(c,i.fallbackBindGroup):this.resolveShadowBindGroupForDraw(c,i.fallbackBindGroup,i.shadowCameraBuffer);s!==f&&(s=f,e.setBindGroup(0,f)),d?o!==d.bindGroup&&(o=d.bindGroup,e.setBindGroup(1,d.bindGroup)):o=null,(d?.usesSkinning??h)&&c.skinning&&l!==c.skinning.bindGroup&&(l=c.skinning.bindGroup,e.setBindGroup(2,l));const m=c.geometryResource;n!==c.geometryKey&&(n=c.geometryKey,this.bindGeometryVertexBuffers(e,c.geometry,m,d?.vertexAttributes??(h?R:z),c.instanceStart,c.instanceCount,c.wireframe)),c.indexed&&(c.wireframe?m.wireframeIndex:m.index)?e.drawIndexed(c.count,c.instanceCount,c.start,0,c.instanceStart):e.draw(c.count,c.instanceCount,c.start,c.instanceStart),this.recordDraw(c,r)}}var sh=new WeakMap;function oh(e){if(e.transparent)return!0;let t=sh.get(e);return null==t&&(t=e.transparent||e.alphaTest>0||/\bdiscard\b/.test(e.fragmentShader),sh.set(e,t)),t}import{Matrix4 as lh,OrthographicCamera as ch,Vector3 as uh}from"three";var dh=(e,t)=>void 0!==e&&Number.isFinite(e)&&e>0?e:t,hh=class{constructor(e){this.cameras=e,this.layers=e.map(()=>({valid:!1,source:null,direction:new uh,rangeX:0,rangeY:0,nextUpdateMs:0,lastUpdateMs:-1/0,candidate:new ch}))}cameras;layers;updateMask=0;forcedMask=0;settings={enabled:!1,maxUpdateHz:60,cascadeUpdateHz:[60,30,15,7.5],maxUpdatesPerFrame:2,coverageMargin:.05,teleportDistance:10};previousProjection=new lh;previousPosition=new uh;viewerPosition=new uh;corner=new uh;viewerValid=!1;revision=-1;timeMs=0;setOptions(e){this.settings={enabled:e.enabled??!1,maxUpdateHz:dh(e.maxUpdateHz,60),cascadeUpdateHz:(e.cascadeUpdateHz?.length?e.cascadeUpdateHz:[60,30,15,7.5]).map(e=>dh(e,60)),maxUpdatesPerFrame:Math.max(1,Math.floor(dh(e.maxUpdatesPerFrame,2))),coverageMargin:Number.isFinite(e.coverageMargin)?Math.max(0,Math.min(.5,e.coverageMargin)):.05,teleportDistance:dh(e.teleportDistance,10)},this.invalidate()}invalidate(){for(const e of this.layers)e.valid=!1}interval(e){const t=this.settings.cascadeUpdateHz;return 1e3/Math.min(this.settings.maxUpdateHz,t[Math.min(e,t.length-1)])}prepare(e,t,r,i,n,a){this.timeMs=n,this.updateMask=this.forcedMask=0,t.getWorldPosition(this.viewerPosition);let s=this.revision!==a;if(this.viewerValid){s||=this.viewerPosition.distanceToSquared(this.previousPosition)>this.settings.teleportDistance**2;const e=t.projectionMatrix.elements,r=this.previousProjection.elements,i=!0===t.isPerspectiveCamera;for(let t=0;t<16;t++)if((i?8!==t&&9!==t:12!==t&&13!==t)&&Math.abs(e[t]-r[t])>1e-6){s=!0;break}}this.revision=a,this.previousPosition.copy(this.viewerPosition),this.previousProjection.copy(t.projectionMatrix),this.viewerValid=!0,s&&this.invalidate();for(let t=0;t<this.layers.length;t++){const n=this.layers[t],a=e[t];if(!a?.castShadow){n.valid=!1;continue}const s=n.candidate;s.left=a.shadowCameraLeft,s.right=a.shadowCameraRight,s.top=a.shadowCameraTop,s.bottom=a.shadowCameraBottom,s.near=a.shadowCameraNear,s.far=a.shadowCameraFar,s.position.copy(a.position),s.lookAt(a.target),s.updateMatrixWorld(!0),s.updateProjectionMatrix();const o=t<i?r[t].x:0,l=t<i?r[t].y:0,c=!n.valid||n.source!==a.sourceLight||n.direction.distanceToSquared(a.direction)>1e-12||n.rangeX!==o||n.rangeY!==l||!this.containsCandidate(this.cameras[t],s);this.settings.enabled&&!c||(this.updateMask|=1<<t,c&&(this.forcedMask|=1<<t))}let o=this.settings.maxUpdatesPerFrame;for(;this.settings.enabled&&o-- >0;){let t=-1,r=1/0;for(let i=0;i<e.length;i++){if(!e[i].castShadow||this.updateMask&1<<i)continue;const a=this.layers[i].nextUpdateMs;n+1e-6>=a&&a<r&&(r=a,t=i)}if(t<0)break;this.updateMask|=1<<t}for(let t=0;t<e.length;t++){if(!(this.updateMask&1<<t))continue;const n=e[t],a=this.layers[t],s=this.cameras[t];if(s.copy(a.candidate),this.settings.enabled){const e=this.settings.coverageMargin,t=s.right-s.left,r=s.top-s.bottom,i=s.far-s.near;s.left-=t*e,s.right+=t*e,s.bottom-=r*e,s.top+=r*e,s.near-=i*e,s.far+=i*e,s.updateProjectionMatrix()}a.source=n.sourceLight,a.direction.copy(n.direction),a.rangeX=t<i?r[t].x:0,a.rangeY=t<i?r[t].y:0}}commit(e){const t=this.layers[e],r=this.interval(e);!t.valid||this.forcedMask&1<<e||!Number.isFinite(t.nextUpdateMs)?t.nextUpdateMs=this.timeMs+r+e*(1e3/this.settings.maxUpdateHz)/this.layers.length:(t.nextUpdateMs+=Math.max(1,Math.floor((this.timeMs-t.nextUpdateMs)/r)+1)*r,t.nextUpdateMs<=this.timeMs&&(t.nextUpdateMs=this.timeMs+r)),t.lastUpdateMs=this.timeMs,t.valid=!0}containsCandidate(e,t){for(let r=0;r<2;r++)for(let i=0;i<2;i++)for(let n=0;n<2;n++){this.corner.set(r?t.right:t.left,i?t.top:t.bottom,-(n?t.far:t.near)).applyMatrix4(t.matrixWorld).applyMatrix4(e.matrixWorldInverse);const a=1e-5;if(this.corner.x<e.left-a||this.corner.x>e.right+a||this.corner.y<e.bottom-a||this.corner.y>e.top+a||this.corner.z<-e.far-a||this.corner.z>-e.near+a)return!1}return!0}};import{Vector3 as ph}from"three";function fh(e){return`${Math.floor(e.x/32)}:${Math.floor(e.y/32)}:${Math.floor(e.z/32)}`}function mh(e,t){if(!t)return[e];const r=new Map;for(const t of e){const e=fh(t.boundsCenter);let i=r.get(e);i||(i=[],r.set(e,i)),i.push(t)}return[...r.values()]}var gh=class{constructor(e,t,r,i,n){this.state=e,this.staticDrawSets=t,this.getGeometryResourceForGeometry=r,this.resolveMaterial=i,this.ensureWireframeIndex=n}state;staticDrawSets;getGeometryResourceForGeometry;resolveMaterial;ensureWireframeIndex;nextStaticDrawSetId=1;activeObject=null;activeDetailDefaults;activeMaterialSnapshots=null;getGeometryResource(e){return this.getGeometryResourceForGeometry(e)}resolveStaticMaterial(e){const t=this.resolveMaterial(e);if(!t||!this.activeMaterialSnapshots)return t;let r=this.activeMaterialSnapshots.get(t);return r||(r=t.clone(),r.name=t.name?`${t.name} (static snapshot)`:"Static draw-set material snapshot",this.activeMaterialSnapshots.set(t,r)),r}createStaticDrawSet(e,t={}){if(!(this.state.initialized&&this.state.device&&this.state.staticVisibilityClearKernel&&this.state.staticVisibilityCullKernel&&this.state.staticVisibilityIndirectBuildKernel))throw new Error("WebGpuRenderer.initialize() must complete before creating a static draw set.");const r=t.label??`static-draw-set-${this.nextStaticDrawSetId}`,i=t.onUnsupported??"throw",n=t.allowUnsortedLateDraws??!1,a=[],s=new Li(4096),o=(e,t)=>{if("skip"!==i)throw new Error(`StaticDrawSet "${r}" does not support ${e.type||"Object3D"} "${e.name||e.uuid}": ${t}.`)};this.activeDetailDefaults=t.detailCulling,e.updateMatrixWorld(!0);const l=new Map;this.activeMaterialSnapshots=l;try{e.traverseVisible(e=>{this.activeObject=e,e.isSkinnedMesh?o(e,"skinned meshes are dynamic"):e.isBatchedMesh?this.collectStaticBatchedMesh(e,s,a,r,o,n):e.isInstancedMesh?this.collectStaticInstancedMesh(e,s,a,r,o,n):e.isMesh&&this.collectStaticMesh(e,s,a,r,o,n)})}catch(e){for(const e of l.values())e.dispose();throw e}finally{this.activeMaterialSnapshots=null,this.activeObject=null,this.activeDetailDefaults=void 0}const{draws:c,instanceData:u}=this.mergeStaticDraws(a,s),d=c.some(e=>e.transparent),h=c.some(e=>!e.transparent);if(d&&h)throw new Error(`StaticDrawSet "${r}" cannot mix opaque and late materials; register them as separate sets.`);const p=this.createVisibleMaterialBindings(c),f=this.createShadowChunks(c),m=Math.max(4,u.byteLength),g=this.state.device.createBuffer({label:`${r}-static-instance-buffer`,size:256*Math.ceil(m/256),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});u.floatLength>0?this.state.device.queue.writeBuffer(g,0,u.rawData.buffer,0,u.byteLength):this.state.device.queue.writeBuffer(g,0,P,0,C);const v={mode:"packed",buffer:g,colorBuffer:null,sceneBindGroup:null,shadowBindGroup:null,shadowBindGroups:new Map,sceneBindGroupVersion:0,shadowBindGroupVersion:0};for(const e of c)e.residentInstanceBinding=v;const x=this.createStaticDrawMetadataResource(r,c),w=this.createStaticInstanceVisibilityResource(r,c,u),b=new Uint32Array([c.length,this.state.hizMipCount,u.instanceCount,0]),y=this.state.device.createBuffer({label:`${r}-visibility-params-buffer`,size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),S=new Uint32Array([c.length,this.state.hizMipCount,u.instanceCount,0]),M=this.state.device.createBuffer({label:`${r}-post-visibility-params-buffer`,size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});this.state.device.queue.writeBuffer(y,0,b,0,4),this.state.device.queue.writeBuffer(M,0,S,0,4);const B={id:this.nextStaticDrawSetId++,label:r,publicSet:null,ownedMaterials:[...l.values()],draws:c,shadowChunks:f,drawStage:d?"late":"opaque",drawCallCount:c.length,triangleCount:c.reduce((e,t)=>e+Math.floor(Math.max(0,t.count)/3)*Math.max(0,t.instanceCount),0),instanceCount:u.instanceCount,instanceBuffer:g,residentInstanceBinding:v,drawMetadataResource:x,instanceVisibilityResource:w,visibilityParamsBuffer:y,visibilityParamsUpload:b,postVisibilityParamsBuffer:M,postVisibilityParamsUpload:S,visibilityBindGroup:null,postVisibilityBindGroup:null,visibilityClearBindGroup:null,visibilityIndirectBuildBindGroup:null,postVisibilityIndirectBuildBindGroup:null,visibleSceneBindGroup:null,visibleSceneBindGroupVersion:0,visibleDepthSceneBindGroup:null,visibleDepthSceneBindGroupVersion:0,visibleMaterialBindings:p,visibleDrawMaterialResources:new Array(c.length),visibleIndirectSubmissionStreams:null,visibleIndirectStreamsSceneBindGroup:null,visibleIndirectStreamsSampleCount:-1,visibleIndirectStreamsColorFormatsKey:"",visibilityBindGroupHizVersion:0,lastPreVisibilityFrameToken:0,lastVisibilityFrameToken:0,indirectForwardBundleCache:new Map,directForwardBundle:null,directForwardBundleSampleCount:-1,directForwardBundleSceneBindGroup:null,depthPrepassBundle:null,depthPrepassBundleSceneBindGroup:null,indirectDepthPrepassBundles:{prepass:null,postpass:null},shadowBundles:new WeakMap,depthMaterialResources:new Map},D={label:r,enabled:!0,get drawCount(){return B.draws.length},get instanceCount(){return B.instanceCount},dispose:()=>{this.disposeStaticDrawSetResource(B)}};return B.publicSet=D,this.staticDrawSets.push(B),D}createVisibleMaterialBindings(e){const t=new Map;for(let r=0;r<e.length;r+=1){const i=e[r],n=`${oi(i.material)}:${i.receiveShadow?1:0}:${i.usesBatching?1:0}`;let a=t.get(n);a||(a={material:i.material,receiveShadow:i.receiveShadow,usesBatching:i.usesBatching,drawIndices:[],resource:null},t.set(n,a)),a.drawIndices.push(r)}return[...t.values()]}createShadowChunks(e){const t=new Map;for(let r=0;r<e.length;r+=1){const i=e[r];if(!i.castShadow||i.transparent)continue;const n=fh(i.boundsCenter);let a=t.get(n);a||(a=[],t.set(n,a)),a.push(r)}const r=[];for(const i of t.values())for(let t=0;t<i.length;t+=64){const n=i.slice(t,t+64);let a=1/0,s=1/0,o=1/0,l=-1/0,c=-1/0,u=-1/0;for(const t of n){const r=e[t],i=r.boundsCenter,n=r.boundsRadius;a=Math.min(a,i.x-n),s=Math.min(s,i.y-n),o=Math.min(o,i.z-n),l=Math.max(l,i.x+n),c=Math.max(c,i.y+n),u=Math.max(u,i.z+n)}const d=new ph(.5*(a+l),.5*(s+c),.5*(o+u)),h=l-d.x,p=c-d.y,f=u-d.z;r.push({drawIndices:n,drawCallCount:n.length,triangleCount:n.reduce((t,r)=>{const i=e[r];return t+Math.floor(Math.max(0,i.count)/3)*Math.max(0,i.instanceCount)},0),boundsCenter:d,boundsRadius:Math.sqrt(h*h+p*p+f*f),bundles:new WeakMap})}return r}mergeStaticDraws(e,t){e.sort((e,t)=>ui(e,t)||(e.transparent||t.transparent?0:fh(e.boundsCenter).localeCompare(fh(t.boundsCenter))));const r=[],i=new Li(Math.max(1024,t.floatLength));for(let n=0;n<e.length;){const a=e[n],s=i.instanceCount;i.appendRange(t,a.instanceStart,a.instanceCount);let o=a.instanceCount,l=a.boundsCenter.x-a.boundsRadius,c=a.boundsCenter.y-a.boundsRadius,u=a.boundsCenter.z-a.boundsRadius,d=a.boundsCenter.x+a.boundsRadius,h=a.boundsCenter.y+a.boundsRadius,p=a.boundsCenter.z+a.boundsRadius,f=n+1;for(;f<e.length&&mi(a,e[f])&&(a.transparent||fh(a.boundsCenter)===fh(e[f].boundsCenter));){const r=e[f];i.appendRange(t,r.instanceStart,r.instanceCount),o+=r.instanceCount;const n=r.boundsCenter.x-r.boundsRadius,a=r.boundsCenter.y-r.boundsRadius,s=r.boundsCenter.z-r.boundsRadius,m=r.boundsCenter.x+r.boundsRadius,g=r.boundsCenter.y+r.boundsRadius,v=r.boundsCenter.z+r.boundsRadius;n<l&&(l=n),a<c&&(c=a),s<u&&(u=s),m>d&&(d=m),g>h&&(h=g),v>p&&(p=v),f+=1}const m=.5*(l+d),g=.5*(c+h),v=.5*(u+p),x=d-m,w=h-g,b=p-v;a.instanceStart=s,a.instanceCount=o,a.boundsCenter.set(m,g,v),a.boundsRadius=Math.sqrt(x*x+w*w+b*b),r.push(a),n=f}return{draws:r,instanceData:i}}collectStaticMesh(e,t,r,i,n,a){if(!(null!==e.geometry.index))return void n(e,"non-indexed geometry cannot use the v1 indirect static path");if(Vi(e))return void n(e,"custom depth materials are not supported by StaticDrawSet v1");const s=this.getGeometryResource(e.geometry),o=Mi(e.geometry),l=F.copy(o.center).applyMatrix4(e.matrixWorld),c=o.radius*Pi(e.matrixWorld),u=ai(t,e.matrixWorld,1,1,1,1),d=Array.isArray(e.material)?e.material:null,h=Array.isArray(e.material)?null:e.material;if(e.geometry.groups.length>0){for(const t of e.geometry.groups){const i=d?d[t.materialIndex??0]??d[0]:h,p=this.resolveStaticMaterial(i);if(!p){n(e,"all static mesh materials must be WGSLShaderMaterial");continue}if(p.transparent&&!a){n(e,"transparent materials are not supported by StaticDrawSet v1");continue}if(Object.keys(p.getGraphTextureInputs()).length>0&&!a){n(e,"scene-texture materials are not supported by StaticDrawSet v1");continue}const f=Jr(e.geometry,!0,t.start,t.count);f<=0||r.push(this.createStaticDrawRecord(e.geometry,e.geometry,s,p,!1,t.start,f,u,1,l.x,l.y,l.z,c,o.center,o.radius,e.matrixWorld.determinant()<0))}return}const p=h??d?.[0]??null,f=this.resolveStaticMaterial(p);if(!f)return void n(e,"all static mesh materials must be WGSLShaderMaterial");if(f.transparent&&!a)return void n(e,"transparent materials are not supported by StaticDrawSet v1");if(Object.keys(f.getGraphTextureInputs()).length>0&&!a)return void n(e,"scene-texture materials are not supported by StaticDrawSet v1");const m=Qr(e.geometry,!0);m.count<=0||r.push(this.createStaticDrawRecord(e.geometry,e.geometry,s,f,!1,m.start,m.count,u,1,l.x,l.y,l.z,c,o.center,o.radius,e.matrixWorld.determinant()<0))}collectStaticInstancedMesh(e,t,r,i,n,a){const s=this.resolveStaticMaterial(e.material);if(!s)return void n(e,"static instanced meshes must use WGSLShaderMaterial");if(s.transparent&&!a)return void n(e,"transparent materials are not supported by StaticDrawSet v1");if(Object.keys(s.getGraphTextureInputs()).length>0&&!a)return void n(e,"scene-texture materials are not supported by StaticDrawSet v1");if(Vi(e))return void n(e,"custom depth materials are not supported by StaticDrawSet v1");if(null===e.geometry.index)return void n(e,"non-indexed geometry cannot use the v1 indirect static path");const o=Qr(e.geometry,!0);if(o.count<=0||e.count<=0)return;const l=Mi(e.geometry),c=this.getGeometryResource(e.geometry),u=[];for(let t=0;t<e.count;t+=1){e.getMatrixAt(t,U),A.multiplyMatrices(e.matrixWorld,U);const r=e.instanceColor?e.instanceColor.getComponent(t,0):1,i=e.instanceColor&&e.instanceColor.itemSize>1?e.instanceColor.getComponent(t,1):1,n=e.instanceColor&&e.instanceColor.itemSize>2?e.instanceColor.getComponent(t,2):1,a=e.instanceColor&&e.instanceColor.itemSize>3?e.instanceColor.getComponent(t,3):1,s=E.copy(l.center).applyMatrix4(A),o=l.radius*Pi(A);u.push({matrix:new Float32Array(A.elements),color0:r,color1:i,color2:n,color3:a,batchingId:t,boundsCenter:s.clone(),boundsRadius:o})}for(const i of mh(u,!s.transparent&&!s.requiresLatePass())){const n=F.set(1/0,1/0,1/0),a=$.set(-1/0,-1/0,-1/0),u=t.instanceCount;for(const e of i)t.appendMatrixAndColorValues(e.matrix,e.color0,e.color1,e.color2,e.color3),Di(n,a,e.boundsCenter,e.boundsRadius);const d=.5*(n.x+a.x),h=.5*(n.y+a.y),p=.5*(n.z+a.z),f=a.x-d,m=a.y-h,g=a.z-p;r.push(this.createStaticDrawRecord(e.geometry,e.geometry,c,s,!1,o.start,o.count,u,i.length,d,h,p,Math.sqrt(f*f+m*m+g*g),l.center,l.radius))}}collectStaticBatchedMesh(e,t,r,i,n,a){const s=this.resolveStaticMaterial(e.material);if(!s)return void n(e,"static batched meshes must use WGSLShaderMaterial");if(s.transparent&&!a)return void n(e,"transparent materials are not supported by StaticDrawSet v1");if(Object.keys(s.getGraphTextureInputs()).length>0&&!a)return void n(e,"scene-texture materials are not supported by StaticDrawSet v1");if(Vi(e))return void n(e,"custom depth materials are not supported by StaticDrawSet v1");if(null===e.geometry.index)return void n(e,"non-indexed geometry cannot use the v1 indirect static path");const o=e,l=this.getGeometryResource(e.geometry),c=o._geometryCount??0,u=[],d=new Map;for(let t=0;t<c;t+=1){const r=e.getGeometryRangeAt(t);if(!r||r.count<=0)continue;const i=Jr(e.geometry,!0,r.start,r.count);if(i<=0)continue;const n=e.getBoundingSphereAt(t,k),a={geometryId:t,start:r.start,count:i,localBoundsCenter:n?n.center.clone():new ph,localBoundsRadius:n?.radius??1,instances:[]};d.set(t,a),u.push(a)}const h=o._instanceInfo??o._drawInfo??[],p=o._matricesTexture?.image.data,f=o._colorsTexture?.image.data;for(let t=0;t<h.length;t+=1){const r=h[t];if(!r?.active||!r.visible)continue;const i=d.get(r.geometryIndex);if(!i)continue;p?si(U,p,16*t):e.getMatrixAt(t,U),A.multiplyMatrices(e.matrixWorld,U);const n=4*t,a=f?f[n+0]??1:1,s=f?f[n+1]??1:1,o=f?f[n+2]??1:1,l=f?f[n+3]??1:1,c=E.copy(i.localBoundsCenter).applyMatrix4(A),u=i.localBoundsRadius*Pi(A);i.instances.push({matrix:new Float32Array(A.elements),color0:a,color1:s,color2:o,color3:l,batchingId:t,boundsCenter:c.clone(),boundsRadius:u})}for(const i of u)if(0!==i.instances.length)for(const n of mh(i.instances,!s.transparent&&!s.requiresLatePass())){const a=F.set(1/0,1/0,1/0),o=$.set(-1/0,-1/0,-1/0),c=t.instanceCount;for(const e of n)t.appendMatrixAndColorValues(e.matrix,e.color0,e.color1,e.color2,e.color3,e.batchingId),Di(a,o,e.boundsCenter,e.boundsRadius);const u=.5*(a.x+o.x),d=.5*(a.y+o.y),h=.5*(a.z+o.z),p=o.x-u,f=o.y-d,m=o.z-h,g=Math.sqrt(p*p+f*f+m*m);r.push(this.createStaticDrawRecord(e.geometry,e.geometry,l,s,!0,i.start,i.count,c,n.length,u,d,h,g,i.localBoundsCenter,i.localBoundsRadius))}}createStaticDrawRecord(e,t,r,i,n,a,s,o,l,c,u,d,h,p,f,m=!1){const v=oi(i),x=i.wireframe&&"triangle-list"===i.primitiveTopology;x&&this.ensureWireframeIndex(e,r);const w=oi(t);return{geometry:e,geometryKey:x?r.wireframeIndex:t,geometryResource:r,material:i,customDepthMaterial:null,residentInstanceBinding:null,sourceObject:null,detailCulling:g(this.activeObject,this.activeDetailDefaults),frontFaceCW:m,usesBatching:n,geometryGroup:null,batchKey:li(i,t,!0,a,s,null),batchHash:ci(v,w,!0,a,s,0),indexed:!0,wireframe:x,start:x?2*a:a,count:x?2*s:s,transparent:i.transparent||i.requiresLatePass(),renderOrder:0,hasRenderCallbacks:!1,castShadow:this.activeObject?.castShadow??!1,receiveShadow:this.activeObject?.receiveShadow??!1,sortMaterialId:v,sortGeometryId:w,sortCustomDepthMaterialId:0,skinning:null,materialResource:null,instanceStart:o,instanceCount:l,boundsCenter:new ph(c,u,d),boundsRadius:h,sortDepth:0,transparentSortGroup:0,transparentSortOrder:0,staticLocalBoundsCenter:p.clone(),staticLocalBoundsRadius:f}}createStaticDrawMetadataResource(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=Math.max(1,t.length),i=new Float32Array(r*M),n=new Uint32Array(5*r),a=new Uint32Array(5*r);for(let e=0;e<t.length;e+=1){const r=t[e],s=e*M;i[s+0]=r.boundsCenter.x,i[s+1]=r.boundsCenter.y,i[s+2]=r.boundsCenter.z,i[s+3]=r.boundsRadius,i[s+4]=r.count,i[s+5]=r.start,i[s+6]=r.instanceStart,i[s+7]=r.instanceCount,i[s+8]=1,i[s+9]=0,i[s+10]=0,i[s+11]=0;const o=5*e;n[o+0]=r.count,n[o+1]=r.instanceCount,n[o+2]=r.start,n[o+3]=0,n[o+4]=r.instanceStart,a[o+0]=r.count,a[o+1]=0,a[o+2]=r.start,a[o+3]=0,a[o+4]=r.instanceStart}const s=this.state.device.createBuffer({label:`${e}-static-draw-metadata-buffer`,size:r*M*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),o=this.state.device.createBuffer({label:`${e}-static-indirect-draw-buffer`,size:5*r*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.INDIRECT|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC}),l=this.state.device.createBuffer({label:`${e}-static-post-indirect-draw-buffer`,size:5*r*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.INDIRECT|GPUBufferUsage.COPY_DST});return this.state.device.queue.writeBuffer(s,0,i,0,i.length),this.state.device.queue.writeBuffer(o,0,n,0,n.length),this.state.device.queue.writeBuffer(l,0,a,0,a.length),{count:t.length,capacity:r,metadataBuffer:s,indirectBuffer:o,postIndirectBuffer:l}}createStaticInstanceVisibilityResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const i=r.instanceCount,n=Math.max(32,32*i),a=new ArrayBuffer(n),s=new Float32Array(a),o=new Uint32Array(a);for(let e=0;e<t.length;e+=1){const i=t[e],n=i.staticLocalBoundsCenter??Mi(i.geometry).center,a=i.staticLocalBoundsRadius??Mi(i.geometry).radius;for(let t=0;t<i.instanceCount;t+=1){const l=i.instanceStart+t,c=l*C,u=8*l;U.fromArray(r.rawData,c);const d=F.copy(n).applyMatrix4(U),h=a*Pi(U);s[u+0]=d.x,s[u+1]=d.y,s[u+2]=d.z,s[u+3]=h,o[u+4]=e,o[u+5]=l,s[u+6]=i.detailCulling?.minScreenSize??0,s[u+7]=i.detailCulling?.maxDistance??0}}const l=this.state.device.createBuffer({label:`${e}-static-instance-visibility-metadata`,size:256*Math.ceil(n/256),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),c=this.state.device.createBuffer({label:`${e}-static-visible-instance-indices`,size:256*Math.ceil(Math.max(4,4*i)/256),usage:GPUBufferUsage.STORAGE}),u=this.state.device.createBuffer({label:`${e}-static-visible-instance-counts`,size:256*Math.ceil(Math.max(4,4*t.length)/256),usage:GPUBufferUsage.STORAGE}),d=this.state.device.createBuffer({label:`${e}-static-post-visible-instance-counts`,size:256*Math.ceil(Math.max(4,4*t.length)/256),usage:GPUBufferUsage.STORAGE}),h=this.state.device.createBuffer({label:`${e}-static-visible-instance-mask`,size:256*Math.ceil(Math.max(4,4*i)/256),usage:GPUBufferUsage.STORAGE});return i>0&&this.state.device.queue.writeBuffer(l,0,a),{metadata:s,instanceMetadataBuffer:l,visibleInstanceIndicesBuffer:c,visibleCountsBuffer:u,postVisibleCountsBuffer:d,visibleInstanceMaskBuffer:h,instanceCount:i}}disposeStaticDrawSetResource(e){e.disposeDirectionalGpuShadows?.();const t=this.staticDrawSets.indexOf(e);if(t<0)return;this.staticDrawSets.splice(t,1);const r=new Set;for(const t of e.draws)t.materialResource&&r.add(t.materialResource);for(const t of e.visibleMaterialBindings)t.resource&&r.add(t.resource);for(const t of e.visibleDrawMaterialResources)t&&r.add(t);for(const t of e.depthMaterialResources.values())for(const e of t)e&&r.add(e);for(const e of r)e.uniformBuffer?.destroy();e.instanceBuffer.destroy(),e.drawMetadataResource.metadataBuffer.destroy(),e.drawMetadataResource.indirectBuffer.destroy(),e.drawMetadataResource.postIndirectBuffer.destroy(),e.instanceVisibilityResource.instanceMetadataBuffer.destroy(),e.instanceVisibilityResource.visibleInstanceIndicesBuffer.destroy(),e.instanceVisibilityResource.visibleCountsBuffer.destroy(),e.instanceVisibilityResource.postVisibleCountsBuffer.destroy(),e.instanceVisibilityResource.visibleInstanceMaskBuffer.destroy(),e.visibilityParamsBuffer.destroy(),e.postVisibilityParamsBuffer.destroy();for(const t of e.ownedMaterials)t.dispose();e.ownedMaterials.length=0,e.residentInstanceBinding.buffer=null,e.residentInstanceBinding.colorBuffer=null,e.residentInstanceBinding.sceneBindGroup=null,e.residentInstanceBinding.shadowBindGroup=null,e.residentInstanceBinding.shadowBindGroups.clear(),e.visibilityBindGroup=null,e.postVisibilityBindGroup=null,e.visibilityClearBindGroup=null,e.visibilityIndirectBuildBindGroup=null,e.postVisibilityIndirectBuildBindGroup=null,e.visibleSceneBindGroup=null,e.visibleDepthSceneBindGroup=null,e.visibleMaterialBindings.length=0,e.visibleDrawMaterialResources.length=0,e.visibleIndirectSubmissionStreams=null,e.visibleIndirectStreamsSceneBindGroup=null,e.visibleIndirectStreamsSampleCount=-1,e.visibleIndirectStreamsColorFormatsKey="",e.indirectForwardBundleCache.clear(),e.directForwardBundle=null,e.directForwardBundleSceneBindGroup=null,e.depthPrepassBundle=null,e.depthPrepassBundleSceneBindGroup=null,e.indirectDepthPrepassBundles.prepass=null,e.indirectDepthPrepassBundles.postpass=null,e.shadowBundles=new WeakMap,e.depthMaterialResources.clear()}},vh=class{constructor(e,t){this.state=e,this.textureCache=t}state;textureCache;skippedExternalTextureWarnings=new WeakSet;destroyTextureResource(e){e?.texture.destroy()}createTextureSampler(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r="non-filtering"===t,i=r?"nearest":ti(e.magFilter),n=r?"nearest":ti(e.minFilter),a=r?"nearest":ti(e.minFilter),s="comparison"===t?function(e){switch(e){case Sr:return"never";case gr:return"less";case hr:return"equal";case vr:return"less-equal";case pr:return"greater";case Cr:return"not-equal";case fr:return"greater-equal";case ur:return"always";default:return}}(e.compareFunction):void 0,o=r||"linear"!==i||"linear"!==n||"linear"!==a?1:Math.max(1,e.anisotropy);return this.state.device.createSampler({label:`${e.uuid}-sampler`,addressModeU:ei(e.wrapS),addressModeV:ei(e.wrapT),addressModeW:ei(e.wrapR??e.wrapT),magFilter:i,minFilter:n,mipmapFilter:a,maxAnisotropy:o,compare:s})}uploadDataTextureResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const i=function(e){switch(e){case"r8unorm":case"r8snorm":case"r8uint":case"r8sint":return 1;case"r16uint":case"r16sint":case"r16float":case"rg8unorm":case"rg8snorm":case"rg8uint":case"rg8sint":case"depth16unorm":return 2;case"r32uint":case"r32sint":case"r32float":case"rg16uint":case"rg16sint":case"rg16float":case"rgba8unorm":case"rgba8unorm-srgb":case"rgba8snorm":case"rgba8uint":case"rgba8sint":case"bgra8unorm":case"bgra8unorm-srgb":case"rgb9e5ufloat":case"rgb10a2unorm":case"rg11b10ufloat":case"depth32float":return 4;case"rg32uint":case"rg32sint":case"rg32float":case"rgba16uint":case"rgba16sint":case"rgba16float":return 8;case"rgba32uint":case"rgba32sint":case"rgba32float":return 16;default:return null}}(r.format);if(null===i)throw new Error(`Texture format "${r.format}" from "${e.constructor.name}" cannot be uploaded with queue.writeTexture.`);const n=e.mipmaps;if(n&&n.length>0){for(let e=0;e<n.length;e+=1){const a=n[e];if(!a?.data)continue;const s=a.width??Math.max(1,r.width>>e),o=a.height??Math.max(1,r.height>>e),l=a.depth??r.depthOrArrayLayers;this.state.device.queue.writeTexture({texture:t,mipLevel:e},ii(a.data),{bytesPerRow:s*i,rowsPerImage:o},{width:s,height:o,depthOrArrayLayers:l})}return}const a=e.image;a?.data&&this.state.device.queue.writeTexture({texture:t},a.data,{bytesPerRow:r.width*i,rowsPerImage:r.height},{width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers})}uploadCompressedTextureResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const i="bc1-rgba-unorm"===(n=r.format)||"bc1-rgba-unorm-srgb"===n?{byteLength:8,width:4,height:4}:"bc2-rgba-unorm"===n||"bc2-rgba-unorm-srgb"===n||"bc3-rgba-unorm"===n||"bc3-rgba-unorm-srgb"===n?{byteLength:16,width:4,height:4}:"bc4-r-unorm"===n||"bc4-r-snorm"===n?{byteLength:8,width:4,height:4}:"bc5-rg-unorm"===n||"bc5-rg-snorm"===n||"bc6h-rgb-ufloat"===n||"bc6h-rgb-float"===n||"bc7-rgba-unorm"===n||"bc7-rgba-unorm-srgb"===n?{byteLength:16,width:4,height:4}:"etc2-rgb8unorm"===n||"etc2-rgb8unorm-srgb"===n||"etc2-rgb8a1unorm"===n||"etc2-rgb8a1unorm-srgb"===n?{byteLength:8,width:4,height:4}:"etc2-rgba8unorm"===n||"etc2-rgba8unorm-srgb"===n?{byteLength:16,width:4,height:4}:"eac-r11unorm"===n||"eac-r11snorm"===n?{byteLength:8,width:4,height:4}:"eac-rg11unorm"===n||"eac-rg11snorm"===n||"astc-4x4-unorm"===n||"astc-4x4-unorm-srgb"===n?{byteLength:16,width:4,height:4}:"astc-5x4-unorm"===n||"astc-5x4-unorm-srgb"===n?{byteLength:16,width:5,height:4}:"astc-5x5-unorm"===n||"astc-5x5-unorm-srgb"===n?{byteLength:16,width:5,height:5}:"astc-6x5-unorm"===n||"astc-6x5-unorm-srgb"===n?{byteLength:16,width:6,height:5}:"astc-6x6-unorm"===n||"astc-6x6-unorm-srgb"===n?{byteLength:16,width:6,height:6}:"astc-8x5-unorm"===n||"astc-8x5-unorm-srgb"===n?{byteLength:16,width:8,height:5}:"astc-8x6-unorm"===n||"astc-8x6-unorm-srgb"===n?{byteLength:16,width:8,height:6}:"astc-8x8-unorm"===n||"astc-8x8-unorm-srgb"===n?{byteLength:16,width:8,height:8}:"astc-10x5-unorm"===n||"astc-10x5-unorm-srgb"===n?{byteLength:16,width:10,height:5}:"astc-10x6-unorm"===n||"astc-10x6-unorm-srgb"===n?{byteLength:16,width:10,height:6}:"astc-10x8-unorm"===n||"astc-10x8-unorm-srgb"===n?{byteLength:16,width:10,height:8}:"astc-10x10-unorm"===n||"astc-10x10-unorm-srgb"===n?{byteLength:16,width:10,height:10}:"astc-12x10-unorm"===n||"astc-12x10-unorm-srgb"===n?{byteLength:16,width:12,height:10}:"astc-12x12-unorm"===n||"astc-12x12-unorm-srgb"===n?{byteLength:16,width:12,height:12}:null;var n;if(!i)throw new Error(`Compressed texture format "${r.format}" is not supported for upload.`);if(!0===e.isCompressedCubeTexture){const n=e.image;for(let e=0;e<n.length;e+=1){const a=n[e]?.mipmaps??[];for(let n=0;n<a.length;n+=1){const s=a[n];if(!s?.data)continue;const o=s.width??Math.max(1,r.width>>n),l=s.height??Math.max(1,r.height>>n),c=Math.max(1,Math.ceil(o/i.width)),u=Math.max(1,Math.ceil(l/i.height));this.state.device.queue.writeTexture({texture:t,mipLevel:n,origin:{x:0,y:0,z:e}},ii(s.data),{bytesPerRow:c*i.byteLength,rowsPerImage:u},{width:c*i.width,height:u*i.height,depthOrArrayLayers:1})}}return}const a=e.mipmaps;for(let e=0;e<a.length;e+=1){const n=a[e];if(!n?.data)continue;const s=n.width??Math.max(1,r.width>>e),o=n.height??Math.max(1,r.height>>e),l=Math.max(1,Math.ceil(s/i.width)),c=Math.max(1,Math.ceil(o/i.height));this.state.device.queue.writeTexture({texture:t,mipLevel:e},ii(n.data),{bytesPerRow:l*i.byteLength,rowsPerImage:c},{width:l*i.width,height:c*i.height,depthOrArrayLayers:r.depthOrArrayLayers})}}uploadExternalTextureResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");if(!0===e.isCubeTexture){const i=e.image;if(!Array.isArray(i)||6!==i.length)return void this.warnSkippedExternalTextureUpload(e,r,"CubeTexture must provide exactly six face images.");for(let n=0;n<i.length;n+=1){const a=ri(i[n]);if(!a)return void this.warnSkippedExternalTextureUpload(e,r,`CubeTexture face ${n} is not a copyable image source.`);try{this.state.device.queue.copyExternalImageToTexture({source:a,flipY:e.flipY},{texture:t,origin:{x:0,y:0,z:n}},{width:r.width,height:r.height,depthOrArrayLayers:1})}catch(t){return void this.warnSkippedExternalTextureUpload(e,r,`CubeTexture face ${n} could not be copied: ${xh(t)}`)}}return}const i=function(e){return ri(e.image)}(e);if(i)try{this.state.device.queue.copyExternalImageToTexture({source:i,flipY:e.flipY},{texture:t},{width:r.width,height:r.height,depthOrArrayLayers:1})}catch(t){this.warnSkippedExternalTextureUpload(e,r,`copyExternalImageToTexture failed: ${xh(t)}`)}else this.warnSkippedExternalTextureUpload(e,r,"Texture.image is not an HTML image, canvas, video, ImageBitmap, or OffscreenCanvas.")}warnSkippedExternalTextureUpload(e,t,r){if(this.skippedExternalTextureWarnings.has(e))return;this.skippedExternalTextureWarnings.add(e);const i=e.image;console.warn(`[WebGpuRenderer] Skipped upload for texture "${e.name||e.uuid}"; the WebGPU material remains active and samples a zero-cleared fallback texture. ${r}`,{texture:e,textureClass:e.constructor.name,textureName:e.name||void 0,textureUuid:e.uuid,textureFlags:{isRenderTargetTexture:!0===e.isRenderTargetTexture,isVideoTexture:!0===e.isVideoTexture,isCanvasTexture:!0===e.isCanvasTexture,isCubeTexture:!0===e.isCubeTexture},descriptor:t,image:{className:i?.constructor?.name??typeof i,width:i?.width,height:i?.height,depth:i?.depth,src:i?.currentSrc??i?.src,hasData:null!=i?.data,keys:null==i?[]:Object.keys(i).slice(0,16)},userData:e.userData})}uploadTextureResource(e,t,r){!function(e){return!0===e.isCompressedTexture||!0===e.isCompressedArrayTexture}(e)&&!0!==e.isCompressedCubeTexture?!0!==e.isDataTexture&&!0!==e.isDataArrayTexture&&!0!==e.isData3DTexture?this.uploadExternalTextureResource(e,t,r):this.uploadDataTextureResource(e,t,r):this.uploadCompressedTextureResource(e,t,r)}getTextureResource(e){if(!this.state.device)throw new Error("Renderer is not initialized.");const t=this.textureCache.get(e),r=vt(e,this.state.device);if(t&&t.version===e.version&&t.width===r.width&&t.height===r.height&&t.depthOrArrayLayers===r.depthOrArrayLayers&&t.format===r.format&&t.textureDimension===r.textureDimension&&t.viewDimension===r.viewDimension&&t.sampleType===r.sampleType&&t.samplerBindingType===r.samplerBindingType&&t.mipLevelCount===r.mipLevelCount)return t;this.destroyTextureResource(t);const i=this.state.device.createTexture({label:`${e.uuid}-texture`,size:{width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers},dimension:r.textureDimension,format:r.format,mipLevelCount:r.mipLevelCount,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|(r.compressed||"3d"===r.textureDimension?0:GPUTextureUsage.RENDER_ATTACHMENT)});this.uploadTextureResource(e,i,r);const n=this.createTextureSampler(e,r.samplerBindingType),a={version:e.version,width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers,format:r.format,textureDimension:r.textureDimension,viewDimension:r.viewDimension,sampleType:r.sampleType,samplerBindingType:r.samplerBindingType,mipLevelCount:r.mipLevelCount,texture:i,view:i.createView("2d"===r.viewDimension?void 0:"2d-array"===r.viewDimension?{dimension:"2d-array",arrayLayerCount:r.depthOrArrayLayers}:{dimension:r.viewDimension}),sampler:n};return this.textureCache.set(e,a),a}};function xh(e){return e instanceof Error?e.message:String(e)}function wh(e){if(e.transparent)switch(e.blending){case Wc:return{color:{srcFactor:"src-alpha",dstFactor:"one",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one",operation:"add"}};case lu:return{color:{srcFactor:"zero",dstFactor:"one-minus-src",operation:"subtract"},alpha:{srcFactor:"one",dstFactor:"one",operation:"subtract"}};case tu:return{color:{srcFactor:"zero",dstFactor:"src",operation:"add"},alpha:{srcFactor:"zero",dstFactor:"src-alpha",operation:"add"}};default:return{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}}function bh(e,t,r,i){if(t<0||e[t]!==r)return-1;let n=0;for(let a=t;a<e.length;a+=1)if(e[a]===r&&(n+=1),e[a]===i&&(n-=1,0===n))return a;return-1}function yh(e,t,r){const i=function(e,t="fsMain"){const r=e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,""),i=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp(`@fragment\\s+fn\\s+${i}\\s*\\(`).exec(r);if(!n)return null;const a=r.indexOf("(",n.index),s=bh(r,a,"(",")");if(s<0)return null;const o=r.indexOf("{",s+1);if(o<0)return null;const l=r.slice(s+1,o),c=/->\s*@location\s*\(\s*(\d+)\s*\)/.exec(l);if(c)return new Set([Number(c[1])]);const u=/->\s*((?:@\w+(?:\s*\([^)]*\))?\s*)*)([A-Za-z_]\w*)/.exec(l);if(!u)return new Set;const d=u[2].replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),h=new RegExp(`\\bstruct\\s+${d}\\s*\\{`).exec(r);if(!h)return null;const p=r.indexOf("{",h.index),f=bh(r,p,"{","}");if(f<0)return null;const m=new Set,g=/@location\s*\(\s*(\d+)\s*\)/g,v=r.slice(p+1,f);for(const e of v.matchAll(g))m.add(Number(e[1]));return m}(e);return t.map((e,t)=>null===i||i.has(t)?{format:e,blend:r}:{format:e,writeMask:0})}function Sh(e){const t=e.userData.motionBlurMode;if(null==t&&e.isSkinnedMesh)return 1;if("number"==typeof t&&Number.isFinite(t))return Math.max(0,Math.min(3,Math.round(t)));switch(t){case"disabled":case"Disabled":return 0;case"cameraOnly":case"CameraOnly":return 1;case"forceObjectBlur":case"ForceObjectBlur":return 3;default:return 2}}function Ch(e){const t=Number(e.userData.motionBlurScale??1);return Number.isFinite(t)?Math.max(0,Math.min(t,8)):1}var Mh="chromium-experimental-multi-draw-indirect";function Ph(e,t){return Number(t.castShadow)-Number(e.castShadow)}var Bh=[D],Dh=[{name:"position",shaderLocation:0,format:"float32x3"},{name:"normal",shaderLocation:1,format:"float32x3",defaultValue:[0,0,1]},{name:"uv",shaderLocation:2,format:"float32x2",defaultValue:[0,0]},{name:"color",shaderLocation:3,format:"float32x4",defaultValue:[1,1,1,1]},{name:"skinIndex",shaderLocation:4,format:"uint32x4"},{name:"skinWeight",shaderLocation:5,format:"float32x4"}];function Th(e){return e.wireframe&&"triangle-list"===e.primitiveTopology?"line-list":e.primitiveTopology}function Ih(e,t,r){if(!Th(e).startsWith("triangle"))return"none";if("directionalShadow"===t){if(r&&null===e.shadowSide)return"none";const t=e.shadowSide??(e.side===Hc?Xc:e.side===Yc?Yc:Hc);return t===Yc?"none":t===Hc?"front":"back"}return e.side===Yc?"none":e.side===Hc?"front":"back"}function Vh(e){if(void 0===e)return 1;if(!Number.isFinite(e)||e<=0||e>1)throw new RangeError("renderScale must be a finite number greater than 0 and at most 1.");return e}var Gh=class{pipelineCompilationDiagnostics;canvas;clearColor;powerPreference;shadowMapSize;directionalShadowsEnabled=!0;spotShadowMapSize;pointShadowMapSize;fallbackMaterial;materialResolver;toonOutlineMaterialCache=new WeakMap;fallbackSkinnedMaterial;invokeObjectRenderCallbacks;sampleCount;renderScale;hiZOcclusionCullingEnabled;multiDrawIndirectEnabled;dynamicBatchingEnabled;multiDrawIndirectSupported=!1;tiledPointLights=null;tiledLightingEnabled;renderGraphProfilingEnabled;indirectFirstInstanceSupported=!1;timestampQuerySupported=!1;geometryCache=new WeakMap;skinnedGeometryCache=new Map;skinPaletteCache=new WeakMap;skinPaletteResources=new Set;meshExtractionCache=new WeakMap;resolvedMaterialFrameCache=new WeakMap;repeatedMeshInstances=new WeakMap;repeatedInstanceResources=new Map;instancedMeshExtractionCache=new WeakMap;batchedMeshExtractionCache=new WeakMap;materialCache=new WeakMap;skinnedMaterialCache=new WeakMap;materialCacheVisible=new WeakMap;materialCacheDirect=new WeakMap;materialNoReceiveShadowCache=new WeakMap;skinnedMaterialNoReceiveShadowCache=new WeakMap;materialNoReceiveShadowCacheVisible=new WeakMap;materialNoReceiveShadowCacheDirect=new WeakMap;depthPrepassMaterialCache=new WeakMap;directionalShadowMaterialCache=new WeakMap;skinnedDirectionalShadowMaterialCache=new WeakMap;directionalShadowMaterialCacheDirect=new WeakMap;lineMaterialCache=new WeakMap;lineBasicMaterialCache=new WeakMap;lineProxyCache=new WeakMap;spriteProxyCache=new WeakMap;depthMaterialFrameCache=new WeakMap;forwardMaterialFastCache=new WeakMap;forwardMaterialTargetFastCache=new WeakMap;forwardMaterialFrameCache=new WeakMap;drawMaterialResourceFrameValidation=new WeakMap;depthMaterialFastCache=new WeakMap;sharedForwardPipelineCache=new Map;sharedForwardPipelinePromiseCache=new Map;sharedDepthPipelineCache=new Map;sharedDepthPipelinePromiseCache=new Map;state=function(){return{device:null,context:null,format:null,mainDepthTexture:null,mainDepthView:null,sceneColorTexture:null,sceneColorView:null,sceneColorSnapshotTexture:null,sceneColorSnapshotView:null,sceneDepthSnapshotTexture:null,sceneDepthSnapshotView:null,postProcessColorTexture:null,postProcessColorView:null,cameraBuffer:null,lightBuffer:null,shadowCameraBuffer:null,shadowCameraBufferPool:[],sharedShadowBindGroupByCameraBuffer:new Map,instanceBuffer:null,instanceBufferSize:0,drawMetadataResource:null,sharedSceneBindGroup:null,sharedShadowBindGroup:null,indirectForwardBundleCache:new Map,directForwardBundleCache:new Map,sceneBindGroupLayout:null,directSceneBindGroupLayout:null,visibleSceneBindGroupLayout:null,visibleDepthSceneBindGroupLayout:null,shadowBindGroupLayout:null,directShadowBindGroupLayout:null,emptyBindGroupLayout:null,skinningBindGroupLayout:null,sceneTextureBindGroupLayout:null,sceneTextureBindGroup:null,shadowComparisonSampler:null,linearClampSampler:null,nearestClampSampler:null,fullscreenTextureBindGroupLayout:null,directionalShadowTexture:null,directionalShadowView:null,directionalShadowLayerViews:[],pointShadowTexture:null,pointShadowArrayView:null,pointShadowFaceViews:[],pointShadowDepthTexture:null,pointShadowDepthFaceViews:[],spotShadowTexture:null,spotShadowView:null,spotShadowLayerViews:[],spotLightMapTexture:null,spotLightMapView:null,hizTexture:null,hizView:null,hizMipViews:[],hizCopyBindGroup:null,hizReduceBindGroups:[],visibilityBindGroup:null,visibilityBindGroupMetadataResource:null,presentBindGroups:new WeakMap,hizMipCount:1,temporalHiZHistoryValid:!1,temporalVisibilityBuffer:null,visibilityParamsBuffer:null,hizCopyKernel:null,hizReduceKernel:null,visibilityKernel:null,staticVisibilityClearKernel:null,staticVisibilityCullKernel:null,staticVisibilityIndirectBuildKernel:null,depthPrepassPipeline:null,depthPrepassPipelineVisible:null,depthPrepassPipelineDirect:null,skinnedDepthPrepassPipeline:null,shadowDepthPipeline:null,shadowDepthPipelineDirect:null,skinnedShadowDepthPipeline:null,pointShadowPipeline:null,pointShadowPipelineDirect:null,skinnedPointShadowPipeline:null,presentPipeline:null,sceneColorSnapshotPipeline:null,sceneColorSnapshotBindGroups:new WeakMap,pixelRatio:1,width:1,height:1,presentationWidth:1,presentationHeight:1,frameTimeSeconds:0,frameIndex:0,directionalShadowTextureSize:1,pointShadowTextureSize:1,spotShadowTextureSize:1,latestFrameProfile:null,latestCompletedFrameProfile:null,residentSceneBindGroupVersion:0,residentShadowBindGroupVersion:0,initialized:!1}}();textureCache=new WeakMap;graphTextureBindGroupCache=new WeakMap;materialGraphTextureReadCache=new WeakMap;defaultInstanceAttributeBuffers=new Map;textureManager=new vh(this.state,this.textureCache);renderGraph=new Ru;nativePostSubmit;presentationOverlay;presentationOverlayContext={device:null,encoder:null,targetView:null,targetFormat:"bgra8unorm",presentationWidth:1,presentationHeight:1};directionalShadowCameras=Array.from({length:4},()=>new nu(-10,10,10,-10,.1,80));directionalShadowScheduler=new hh(this.directionalShadowCameras);directionalShadowGpu=new _c;directionalShadowSubmissionStats={bundleHits:0,bundleBuilds:0,selectionHits:0,selections:0};pointShadowCameras=Array.from({length:4},()=>G.map(()=>new au(90,1,.1,25)));spotShadowCameras=Array.from({length:4},()=>new au(60,1,.5,500));colorTargetCache=new Map;msaaColorTargetCache=new Map;msaaDepthTargetCache=new Map;sourceInstanceDataScratch=new Li(4096);opaqueInstanceDataScratch=new Li(4096);finalInstanceDataScratch=new Li(4096);residentInstanceUploadsScratch=[];gpuOpaqueDrawsScratch=[];directOpaqueDrawsScratch=[];stagedOpaqueDrawsScratch=[];residentOpaqueDrawsScratch=[];retiredGeometryResources=[];retiredGeometryBuffers=[];vertexAttributeBufferKeyCache=new WeakMap;standardVertexAttributeCache=new WeakMap;geometryVertexBufferFastCache=new WeakMap;vertexAttributeGroupCache=new WeakMap;materialVertexAttributeCache=new WeakMap;vertexBufferBindingPlanCache=new WeakMap;preparedVertexBufferCache=new WeakMap;vertexAttributeGroupBufferKeyCache=new WeakMap;compileDrawScratch=[];dynamicIndirectSubmissionCache=new WeakMap;indirectStreamKeyCache=new WeakMap;nextIndirectStreamKey=1;indirectBundleInvalidationVersion=0;colorFormatsIdentityCache=new WeakMap;colorFormatsValueCache=new Map([[D,1]]);nextColorFormatsId=2;renderBundleScratch=[];indirectMaterialResourcesScratch=[];directBundleDrawStatsScratch={drawCallCount:0,triangleCount:0};sortedOpaqueBatchesScratch=[];opaqueBatchPool=[];opaqueBatchPoolCount=0;drawCallPool=[];drawCallPoolCount=0;staticDrawSets=[];materialPassStaticBundleCache=new WeakMap;staticDrawSetManager=new gh(this.state,this.staticDrawSets,e=>this.getGeometryResource(e),e=>this.resolveMaterial(e),(e,t)=>this.ensureWireframeIndex(e,t));staticFrameToken=0;hizResourceVersion=0;graphTextureResourceVersion=0;transmissionSnapshotTexture=null;transmissionSnapshotView=null;transmissionSnapshotSize={width:0,height:0};transmissionMipViews=[];transmissionMipBindGroups=[];transmissionSourceBindGroups=new WeakMap;transmissionSnapshotPipeline=null;transmissionSampler=null;visibilityParamsUpload=new Uint32Array(4);drawMetadataUpload=new Float32Array(0);indirectDrawUpload=new Uint32Array(0);extractedAmbientScratch=new du;extractedHemisphereScratch=this.createExtractedHemisphereLightScratch();extractedBoundsMinScratch=new uu;extractedBoundsMaxScratch=new uu;extractedDirectionalLightsScratch=Array.from({length:4},()=>this.createExtractedDirectionalLightScratch());extractedPointLightsScratch=Array.from({length:y},()=>this.createExtractedPointLightScratch());extractedSpotLightsScratch=Array.from({length:S},()=>this.createExtractedSpotLightScratch());activeDirectionalLightsScratch=[];activePointLightsScratch=[];activeSpotLightsScratch=[];fogVolumeObjectsScratch=[];resolvedMeshMaterialsScratch=[];extractedLightsScratch={ambient:this.extractedAmbientScratch,hemisphere:null,directionals:this.activeDirectionalLightsScratch,points:this.activePointLightsScratch,spots:this.activeSpotLightsScratch,directional:null,point:null,spot:null};extractedFrameScratch={scene:null,camera:null,fogVolumeObjects:this.fogVolumeObjectsScratch,gpuOpaqueDraws:this.gpuOpaqueDrawsScratch,directOpaqueDraws:this.directOpaqueDrawsScratch,transparentDraws:[],instanceData:this.finalInstanceDataScratch,residentInstanceUploads:this.residentInstanceUploadsScratch,lights:this.extractedLightsScratch,boundsMin:this.extractedBoundsMinScratch,boundsMax:this.extractedBoundsMaxScratch};cameraUniformScratch=new Float32Array(104);temporalVisibilityUniformScratch=new Float32Array(44);lightUniformScratch=new Float32Array(L);spotLightMapAtlasSignature="";spotLightMapAtlasSize=0;spotLightMapAtlasLayout=null;spotLightMapAtlasPipeline=null;csmCascadeRanges=Array.from({length:4},()=>new cu);csmCascadeCount=0;csmCascadeLights=[];shadowCameraUniformScratch=new Float32Array(64);cameraViewProjScratch=new ru;cameraProjectionScratch=new ru;projectionJitterPixels=new cu;temporalVisibilityCurrentViewProj=new ru;temporalVisibilityPreviousViewProj=new ru;motionVectorProjection=new ru;motionVectorCurrentViewProj=new ru;motionVectorPreviousViewProj=new ru;motionVectorProjectionPending=!1;motionVectorHistoryValid=!1;motionVectorHistoryGeneration=1;lastMotionVectorTimeSeconds=Number.NaN;objectMotionHistory=new WeakMap;cameraFrustumPlanesScratch=new Float32Array(24);objectTraversalStackScratch=[];shadowDrawsScratch=[];extractingCaster=!1;cameraDetailHistory=new WeakMap;isSphereVisibleScratch=(e,t,r,i,n)=>this.extractingCaster||!n||Ci(this.cameraFrustumPlanesScratch,e,t,r,i);isSphereVisibleForCompilationScratch=()=>!0;updateExtractedBoundsFromMatrixScratch=e=>{const t=this.extractedBoundsMinScratch,r=this.extractedBoundsMaxScratch,i=e[12],n=e[13],a=e[14];i<t.x&&(t.x=i),n<t.y&&(t.y=n),a<t.z&&(t.z=a),i>r.x&&(r.x=i),n>r.y&&(r.y=n),a>r.z&&(r.z=a)};transparentSortCameraPositionScratch=new uu;transparentSortCameraForwardScratch=new uu;temporalVisibilityCurrentCameraPosition=new uu;temporalVisibilityPreviousCameraPosition=new uu;shadowViewProjScratch=new ru;extractionVersion=0;graphBuilder=(e,t)=>{t.addDirectionalShadowPass(),t.addPointShadowPass(),t.addSpotShadowPass(),t.addDepthPrepass(),t.addHiZPasses(),t.addVisibilityPass(),t.addForwardPass(),t.addPresentPass()};createExtractedDirectionalLightScratch(){return{sourceLight:null,position:new uu,target:new uu,direction:new uu,color:new uu,intensity:0,volumetricIntensity:1,castShadow:!1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowIntensity:1,shadowMapSize:this.shadowMapSize,shadowCameraLeft:-5,shadowCameraRight:5,shadowCameraTop:5,shadowCameraBottom:-5,shadowCameraNear:.5,shadowCameraFar:500}}createExtractedHemisphereLightScratch(){return{direction:new uu(0,1,0),skyColor:new uu,groundColor:new uu,intensity:0}}createExtractedPointLightScratch(){return{sourceLight:null,position:new uu,color:new uu,intensity:0,volumetricIntensity:1,distance:0,range:25,decay:2,castShadow:!1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowIntensity:1,shadowMapSize:this.pointShadowMapSize,shadowCameraNear:.5,shadowCameraFar:500}}createExtractedSpotLightScratch(){return{sourceLight:null,position:new uu,direction:new uu(0,-1,0),color:new uu,intensity:0,volumetricIntensity:1,range:500,angle:Math.PI/3,penumbra:0,decay:2,castShadow:!1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowIntensity:1,shadowMapSize:this.shadowMapSize,shadowCameraNear:.5,shadowCameraFar:500,shadowCameraFov:60,map:null}}skinnedDrawKeys=new jc;skeletonPalettes=new Gi;getSkeletonBoneBufferForPass=e=>{const t=this.getSkinningPalette(e);return this.refreshSkinningPalette(t),this.uploadSkinningPalette(t),t.matrixBuffer};outlineResolvedFrameCache=new WeakMap;opaqueSortMs=0;opaqueSortSamples=new Float64Array(120);opaqueSortSampleIndex=0;opaqueSortSampleCount=0;opaqueSortSampleTotal=0;sortOpaqueDraws(e){const t=this.renderGraphProfilingEnabled?performance.now():0;e.sort(ui),this.renderGraphProfilingEnabled&&(this.opaqueSortMs+=performance.now()-t)}constructor(e){this.canvas=e.canvas,this.nativePostSubmit=e.nativePostSubmit,this.presentationOverlay=e.presentationOverlay,this.clearColor=[...e.clearColor??[0,0,0,1]],this.powerPreference=e.powerPreference,this.directionalShadowScheduler.setOptions(e.directionalShadowUpdates??{}),this.directionalShadowGpu.enabled=e.directionalShadowGpuCulling??!0,this.shadowMapSize=e.shadowMapSize??2048,this.spotShadowMapSize=this.shadowMapSize,this.pointShadowMapSize=e.pointShadowMapSize??1024,this.fallbackMaterial=e.fallbackMaterial??null,this.materialResolver=e.materialResolver,this.fallbackSkinnedMaterial=e.fallbackSkinnedMaterial??new Ir({vertexShader:"\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n @location(3) color: vec4<f32>,\n @location(4) skinIndex: vec4<u32>,\n @location(5) skinWeight: vec4<f32>,\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldNormal: vec3<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let skinnedPosition = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight);\n let skinnedNormal = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n output.position = rendererClipPosition(skinnedPosition, input.instanceIndex);\n output.worldNormal = rendererWorldNormal(skinnedNormal, input.instanceIndex);\n return output;\n}\n",fragmentShader:"\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldNormal: vec3<f32>,\n};\n\n@fragment\nfn fsMain(input: VertexOutput) -> @location(0) vec4<f32> {\n let normal = normalize(input.worldNormal);\n let diffuse = max(dot(normal, normalize(rendererDirectionalLightDirection())), 0.0);\n let lighting = rendererIndirectDiffuse(normal) + rendererDirectionalLightColor() * diffuse;\n return vec4<f32>(vec3<f32>(0.72, 0.76, 0.82) * lighting, 1.0);\n}\n",vertexAttributes:Dh}),this.invokeObjectRenderCallbacks=e.invokeObjectRenderCallbacks??!0,this.state.directionalShadowTextureSize=this.shadowMapSize,this.state.pointShadowTextureSize=this.pointShadowMapSize,this.state.spotShadowTextureSize=this.shadowMapSize,this.sampleCount=Ii(e.sampleCount),this.renderScale=Vh(e.renderScale),this.hiZOcclusionCullingEnabled=e.hiZOcclusionCulling??!1,this.multiDrawIndirectEnabled=e.multiDrawIndirect??!0,this.dynamicBatchingEnabled=e.dynamicBatching??!0,this.tiledLightingEnabled=e.tiledLighting??!0,this.renderGraphProfilingEnabled=e.renderGraphProfiling??!1}resolveMaterial(e){if(!1===e?.visible)return null;if(e&&Vr(e))return e;if(!e)return this.fallbackMaterial;if(!0===e.isLineMaterial)return this.resolveLineMaterial(e);const t=this.resolvedMaterialFrameCache.get(e);if(t?.extractionVersion===this.extractionVersion)return t.material;let r=e.transparent||function(e){if(e.transparent||(e.transmission??0)>0)return!0;if(e instanceof hu)return null!=e.uniforms.hology_depth_map||null!=e.uniforms.hology_scene_map||null!=e.uniforms.hology_transmission_map;if(e instanceof Ir)return e.requiresLatePass();return!1}(e)?"late":"opaque",i=this.materialResolver?.(e,r);"opaque"===r&&i?.requiresLatePass()&&(r="late",i=this.materialResolver?.(e,r));const n=void 0===i?this.fallbackMaterial:i;return t?(t.extractionVersion=this.extractionVersion,t.material=n):this.resolvedMaterialFrameCache.set(e,{extractionVersion:this.extractionVersion,material:n}),void 0!==i?i:n}resolveLineMaterial(e){let t=this.lineMaterialCache.get(e);t||(t=new Ir({vertexShader:"\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(4) instanceStart: vec3<f32>,\n @location(5) instanceEnd: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) color: vec4<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let start = rendererCamera.view * rendererWorldPosition(input.instanceStart, input.instanceIndex);\n let end = rendererCamera.view * rendererWorldPosition(input.instanceEnd, input.instanceIndex);\n let clipStart = rendererCamera.projection * start;\n let clipEnd = rendererCamera.projection * end;\n let ndcStart = clipStart.xy / clipStart.w;\n let ndcEnd = clipEnd.xy / clipEnd.w;\n let aspect = rendererCamera.viewportAndTime.x / max(rendererCamera.viewportAndTime.y, 1.0);\n var direction = ndcEnd - ndcStart;\n direction.x *= aspect;\n direction = normalize(select(vec2<f32>(1.0, 0.0), direction, length(direction) > 0.00001));\n var offset = vec2<f32>(direction.y, -direction.x);\n direction.x /= aspect;\n offset.x /= aspect;\n if (input.position.x < 0.0) { offset = -offset; }\n if (input.position.y < 0.0) {\n offset -= direction;\n } else if (input.position.y > 1.0) {\n offset += direction;\n }\n offset *= materialUniforms.linewidth / max(rendererCamera.viewportAndTime.y, 1.0);\n var clip = select(clipEnd, clipStart, input.position.y < 0.5);\n // clip.xy += offset * clip.w;\n let offsetW = offset * clip.w;\n clip = vec4<f32>(clip.x + offsetW.x, clip.y + offsetW.y, clip.z, clip.w);\n output.position = clip;\n output.color = vec4<f32>(materialUniforms.color, materialUniforms.opacity);\n return output;\n}\n",fragmentShader:"\nstruct FragmentInput {\n @builtin(position) position: vec4<f32>,\n @location(0) color: vec4<f32>,\n};\n\n@fragment\nfn fsMain(input: FragmentInput) -> @location(0) vec4<f32> {\n return input.color;\n}\n",uniforms:{color:new Zc(1,1,1),opacity:1,linewidth:1},vertexAttributes:[{name:"position",shaderLocation:0,format:"float32x3"},{name:"instanceStart",shaderLocation:4,format:"float32x3",stepMode:"instance"},{name:"instanceEnd",shaderLocation:5,format:"float32x3",stepMode:"instance"}],transparent:!0,side:Yc,depthTest:e.depthTest,depthWrite:e.depthWrite}),this.lineMaterialCache.set(e,t));const r=e,i=r.color;return i&&t.uniforms.color.value.copy(i),t.uniforms.opacity.value=r.opacity??1,t.uniforms.linewidth.value=r.linewidth??1,t.transparent=e.transparent||(r.opacity??1)<1,t.depthTest=e.depthTest,t.depthWrite=e.depthWrite,t}resolveLineBasicMaterial(e,t){let r=this.lineBasicMaterialCache.get(e);r||(r=new Map,this.lineBasicMaterialCache.set(e,r));let i=r.get(t);i||(i=new Ir({vertexShader:"\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32,\n};\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n};\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n return VertexOutput(rendererClipPosition(input.position, input.instanceIndex));\n}\n",fragmentShader:"\n@fragment\nfn fsMain() -> @location(0) vec4<f32> {\n return vec4<f32>(materialUniforms.color, materialUniforms.opacity);\n}\n",uniforms:{color:new Zc(1,1,1),opacity:1},primitiveTopology:t,depthTest:e.depthTest,depthWrite:e.depthWrite}),r.set(t,i));const n=e;return n.color&&i.uniforms.color.value.copy(n.color),i.uniforms.opacity.value=n.opacity??1,i.transparent=e.transparent||(n.opacity??1)<1,i.depthTest=e.depthTest,i.depthWrite=e.depthWrite,i}resolveSkinnedMaterial(e){const t=this.resolveMaterial(e);return null===t?null:function(e){const t=e.vertexAttributes.find(e=>"skinIndex"===e.name),r=e.vertexAttributes.find(e=>"skinWeight"===e.name);return e.vertexShader.includes("USE_SKINNING")||"uint32x4"===t?.format&&"float32x4"===r?.format&&e.vertexShader.includes("rendererSkinPosition(")}(t)?t:this.fallbackSkinnedMaterial}hasRenderCallbacks(e){return null!==e&&this.invokeObjectRenderCallbacks&&function(e){return null!==e&&(e.onBeforeRender!==Mr.prototype.onBeforeRender||e.onAfterRender!==Mr.prototype.onAfterRender)}(e)}async initialize(t){if(!("gpu"in navigator))throw new Error("WebGPU is not available in this browser.");const r=t??await navigator.gpu.requestAdapter({powerPreference:this.powerPreference});if(!r)throw new Error("A WebGPU adapter could not be created.");const i=[];r.features.has("indirect-first-instance")&&i.push("indirect-first-instance"),r.features.has("timestamp-query")&&i.push("timestamp-query"),r.features.has("texture-compression-bc")&&i.push("texture-compression-bc"),r.features.has("texture-compression-etc2")&&i.push("texture-compression-etc2"),r.features.has("texture-compression-astc")&&i.push("texture-compression-astc"),r.features.has("float32-filterable")&&i.push("float32-filterable"),r.features.has(Mh)&&i.push(Mh);const l=r.limits;try{this.state.device=await r.requestDevice({requiredFeatures:i,requiredLimits:{maxTextureArrayLayers:l.maxTextureArrayLayers,maxBufferSize:l.maxBufferSize,maxStorageBufferBindingSize:l.maxStorageBufferBindingSize,maxStorageBuffersPerShaderStage:l.maxStorageBuffersPerShaderStage}})}catch(e){throw new Error("A WebGPU device could not be created.")}!function(t){if(e.has(t))return;const r={loadingStartedAt:performance.now(),loadingRequests:[],loading:!0,phase:"initializing",objects:new WeakMap,origins:new Map,descriptorOrigins:new WeakMap,history:new Map};e.set(t,r);for(const e of["createShaderModule","createBindGroupLayout","createPipelineLayout"]){const i=t[e];t[e]=function(s){const o=i.call(t,s);return r.objects.set(o,"createShaderModule"===e?{shaderHash:n(s.code),codeLength:s.code.length}:a(s,r)),o}}for(const e of["createRenderPipeline","createRenderPipelineAsync","createComputePipeline","createComputePipelineAsync"]){const i=t[e];"function"==typeof i&&(t[e]=function(n){const l=r.descriptorOrigins.get(n)??r.origins.get(n.label),c=e.includes("Render")?"render":"compute",u=c+":"+(l?.key??n.label??"unlabelled"),d=a(n,r),h=r.history.get(u)??[],p=JSON.stringify(d);let f;for(let e=h.length-1;e>=0;e--)if(h[e].signature===p){f=h[e];break}const m=f??h[h.length-1],g={signature:p,state:d,origin:l,label:n.label,phase:r.phase,status:"pending"},v=!r.loading,x=v?void 0:{kind:c,signature:p,state:d,shaders:o(d),label:n.label,origin:l,status:"pending",durationMs:0,async:e.endsWith("Async")};x&&r.loadingRequests.push(x);let w=0;v&&console.warn("[WebGPU pipeline] Created after loading",{method:e,label:n.label,phase:r.phase,origin:l,reason:"failed"===f?.status?"retry after a failed creation request":"pending"===f?.status?"identical descriptor requested while prior compilation is pending":f?"identical descriptor requested again; cache miss, eviction, or another owner":m?"new variant or changed shader/layout/render state":"first recorded pipeline for this origin",previous:m?{label:m.label,phase:m.phase,status:m.status,origin:m.origin}:null,changes:m?s(m.state,d):[],originChanges:m?s(m.origin,l):[],descriptor:d,stack:new Error("Pipeline creation request").stack,historyLimit:"last 16 requests per origin; up to 4096 origins"}),h.push(g),h.length>16&&h.shift(),r.history.size>=4096&&!r.history.has(u)&&r.history.delete(r.history.keys().next().value),r.history.set(u,h);const b=(t,r)=>{g.status=t,x&&(x.status=t,x.durationMs=performance.now()-w),v&&console.info("[WebGPU pipeline] Creation result",{method:e,label:n.label,status:t,[e.endsWith("Async")?"readyAfterMs":"creationCallMs"]:performance.now()-w,error:r,timingMeaning:e.endsWith("Async")?"time until pipeline ready":"handle creation only; GPU compilation may stall at first use"})};w=performance.now();try{const r=i.call(t,n);return e.endsWith("Async")?r.then(e=>(b("ready"),e),e=>{throw b("failed",e),e}):(b("handle returned"),r)}catch(e){throw b("failed",e),e}})}}(this.state.device);let c=!1;if("function"==typeof this.state.device.addEventListener&&this.state.device.addEventListener("uncapturederror",e=>{c||(console.error("Uncaptured WebGPU device error",e.error.message,e.error),c=!0)}),this.state.device.lost.then(e=>{"destroyed"!==e.reason&&console.error("WebGPU device lost",e.reason,e.message)}),this.indirectFirstInstanceSupported=i.includes("indirect-first-instance"),this.timestampQuerySupported=i.includes("timestamp-query"),this.multiDrawIndirectSupported=i.includes(Mh),this.state.context=this.canvas.getContext("webgpu"),!this.state.context)throw new Error("The canvas does not provide a WebGPU context.");this.state.format=navigator.gpu.getPreferredCanvasFormat(),this.state.context.configure({device:this.state.device,format:this.state.format,alphaMode:"premultiplied"}),this.state.cameraBuffer=this.state.device.createBuffer({label:"renderer-camera-buffer",size:416,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.state.temporalVisibilityBuffer=this.state.device.createBuffer({label:"renderer-temporal-visibility-buffer",size:176,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.state.lightBuffer=this.state.device.createBuffer({label:"renderer-light-buffer",size:16016,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});const u=[];u.push(Nc.createAsync(this.state.device,this.state.cameraBuffer,this.state.lightBuffer).then(e=>{this.tiledPointLights=e,e.resize(this.state.width,this.state.height)})),this.state.shadowCameraBuffer=this.state.device.createBuffer({label:"renderer-shadow-camera-buffer",size:256,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.state.sceneBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-scene-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"comparison"}},{binding:4,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:5,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:6,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d-array"}},{binding:7,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:9,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}},{binding:11,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"uint",viewDimension:"2d"}}]}),this.state.directSceneBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-direct-scene-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:4,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"comparison"}},{binding:5,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:6,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:7,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d-array"}},{binding:8,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:10,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}},{binding:11,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"uint",viewDimension:"2d"}}]}),this.state.visibleSceneBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-visible-scene-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"comparison"}},{binding:4,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:5,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:6,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d-array"}},{binding:7,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:8,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:9,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}},{binding:11,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"uint",viewDimension:"2d"}}]}),this.state.visibleDepthSceneBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-visible-depth-scene-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),this.state.shadowBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-shadow-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),this.state.directShadowBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-direct-shadow-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),this.state.emptyBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-empty-layout",entries:[]}),this.state.skinningBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-skinning-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),this.state.sceneTextureBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-scene-texture-layout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"non-filtering"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth"}}]}),this.state.residentSceneBindGroupVersion+=1,this.state.residentShadowBindGroupVersion+=1,u.push(this.directionalShadowGpu.initialize(this.state.device,this.state.directShadowBindGroupLayout)),this.state.fullscreenTextureBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-fullscreen-texture-layout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}}]}),this.state.shadowComparisonSampler=this.state.device.createSampler({label:"renderer-shadow-comparison-sampler",compare:"less-equal",magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),this.transmissionSampler=this.state.device.createSampler({label:"physical-transmission-sampler",magFilter:"linear",minFilter:"linear",mipmapFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),this.state.linearClampSampler=this.state.device.createSampler({label:"renderer-linear-clamp-sampler",magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",addressModeW:"clamp-to-edge"}),this.state.nearestClampSampler=this.state.device.createSampler({label:"renderer-nearest-clamp-sampler",magFilter:"nearest",minFilter:"nearest",mipmapFilter:"nearest",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",addressModeW:"clamp-to-edge"}),u.push(W.createAsync(this.state.device,{label:"renderer-hiz-copy",code:"\n@group(0) @binding(0) var sourceDepth: texture_depth_2d;\n@group(0) @binding(1) var targetMip: texture_storage_2d<r32float, write>;\n\n@compute @workgroup_size(8, 8, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let dims = textureDimensions(targetMip);\n if (globalId.x >= dims.x || globalId.y >= dims.y) {\n return;\n }\n\n let depthValue = textureLoad(sourceDepth, vec2<i32>(globalId.xy), 0);\n textureStore(targetMip, vec2<i32>(globalId.xy), vec4(depthValue, 0.0, 0.0, 1.0));\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"depth"}},{binding:1,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"r32float"}}]}).then(e=>{this.state.hizCopyKernel=e})),u.push(W.createAsync(this.state.device,{label:"renderer-hiz-reduce",code:"\n@group(0) @binding(0) var sourceMip: texture_2d<f32>;\n@group(0) @binding(1) var targetMip: texture_storage_2d<r32float, write>;\n\nfn readSource(coord: vec2<i32>, dims: vec2<i32>) -> f32 {\n let clamped = clamp(coord, vec2(0, 0), dims - vec2(1, 1));\n return textureLoad(sourceMip, clamped, 0).r;\n}\n\n@compute @workgroup_size(8, 8, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let outDims = textureDimensions(targetMip);\n if (globalId.x >= outDims.x || globalId.y >= outDims.y) {\n return;\n }\n\n let srcOrigin = vec2<i32>(globalId.xy * 2u);\n let srcDims = vec2<i32>(textureDimensions(sourceMip));\n // This renderer uses conventional depth (near = 0, far = 1). Keep the\n // farthest depth in each footprint so an object is rejected only when the\n // whole footprint is covered by closer geometry. A min reduction would let\n // a single nearby texel occlude an otherwise visible object.\n var reduced = max(\n max(readSource(srcOrigin, srcDims), readSource(srcOrigin + vec2(1, 0), srcDims)),\n max(readSource(srcOrigin + vec2(0, 1), srcDims), readSource(srcOrigin + vec2(1, 1), srcDims))\n );\n\n // WebGPU mip dimensions round down. When a source dimension is odd, fold\n // its otherwise-unrepresented final row/column into the last destination\n // texel so no depth coverage disappears from the hierarchy.\n let hasExtraColumn = (srcDims.x & 1) != 0 && globalId.x + 1u == outDims.x;\n let hasExtraRow = (srcDims.y & 1) != 0 && globalId.y + 1u == outDims.y;\n if (hasExtraColumn) {\n reduced = max(reduced, readSource(srcOrigin + vec2(2, 0), srcDims));\n reduced = max(reduced, readSource(srcOrigin + vec2(2, 1), srcDims));\n }\n if (hasExtraRow) {\n reduced = max(reduced, readSource(srcOrigin + vec2(0, 2), srcDims));\n reduced = max(reduced, readSource(srcOrigin + vec2(1, 2), srcDims));\n }\n if (hasExtraColumn && hasExtraRow) {\n reduced = max(reduced, readSource(srcOrigin + vec2(2, 2), srcDims));\n }\n\n textureStore(targetMip, vec2<i32>(globalId.xy), vec4(reduced, 0.0, 0.0, 1.0));\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:1,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"r32float"}}]}).then(e=>{this.state.hizReduceKernel=e})),u.push(W.createAsync(this.state.device,{label:"renderer-visibility-cull",code:"\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\nstruct RendererVisibilityParams {\n drawCount: u32,\n hizMipCount: u32,\n reserved0: u32,\n reserved1: u32,\n};\n\nstruct DrawMetadata {\n centerRadius: vec4<f32>,\n args0: vec4<f32>,\n extra: vec4<f32>,\n};\n\nstruct IndirectIndexedArgs {\n indexCount: u32,\n instanceCount: u32,\n firstIndex: u32,\n baseVertex: i32,\n firstInstance: u32,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> visibilityParams: RendererVisibilityParams;\n@group(0) @binding(2) var drawMetaTextureSampler: sampler;\n@group(0) @binding(3) var hizTexture: texture_2d<f32>;\n@group(0) @binding(4) var<storage, read> drawMetadata: array<DrawMetadata>;\n@group(0) @binding(5) var<storage, read_write> indirectArgs: array<IndirectIndexedArgs>;\n\nfn saturate(value: f32) -> f32 {\n return clamp(value, 0.0, 1.0);\n}\n\nfn projectedSphereRadius(\n viewProj: mat4x4<f32>,\n ndc: vec3<f32>,\n clipW: f32,\n radius: f32,\n) -> vec2<f32> {\n // Account for both numerator and perspective-denominator variation over the\n // sphere. Offsetting along world X/Y is not conservative once the camera is\n // rotated because those axes can also change clip W.\n let rowX = vec3(viewProj[0].x, viewProj[1].x, viewProj[2].x);\n let rowY = vec3(viewProj[0].y, viewProj[1].y, viewProj[2].y);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let denominator = max(clipW - radius * length(rowW), 0.0001);\n return radius * vec2(\n length(rowX) + abs(ndc.x) * length(rowW),\n length(rowY) + abs(ndc.y) * length(rowW),\n ) / denominator;\n}\n\nfn spherePlaneRadius(viewProj: mat4x4<f32>, plane: vec4<f32>, radius: f32) -> f32 {\n let worldNormal = vec3(\n dot(viewProj[0], plane),\n dot(viewProj[1], plane),\n dot(viewProj[2], plane),\n );\n return radius * length(worldNormal);\n}\n\nfn isSphereInFrustum(viewProj: mat4x4<f32>, center: vec3<f32>, radius: f32) -> bool {\n let clip = viewProj * vec4(center, 1.0);\n return\n clip.w + clip.x >= -spherePlaneRadius(viewProj, vec4( 1.0, 0.0, 0.0, 1.0), radius) &&\n clip.w - clip.x >= -spherePlaneRadius(viewProj, vec4(-1.0, 0.0, 0.0, 1.0), radius) &&\n clip.w + clip.y >= -spherePlaneRadius(viewProj, vec4( 0.0, 1.0, 0.0, 1.0), radius) &&\n clip.w - clip.y >= -spherePlaneRadius(viewProj, vec4( 0.0, -1.0, 0.0, 1.0), radius) &&\n clip.z >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, 1.0, 0.0), radius) &&\n clip.w - clip.z >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, -1.0, 1.0), radius);\n}\n\nfn nearestSphereDepth(viewProj: mat4x4<f32>, clip: vec4<f32>, radius: f32) -> f32 {\n let rowZ = vec3(viewProj[0].z, viewProj[1].z, viewProj[2].z);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let minClipZ = clip.z - radius * length(rowZ);\n let maxClipW = clip.w + radius * length(rowW);\n return max(0.0, minClipZ / max(maxClipW, 0.0001));\n}\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let drawIndex = globalId.x;\n if (drawIndex >= visibilityParams.drawCount) {\n return;\n }\n\n let drawData = drawMetadata[drawIndex];\n let center = vec4(drawData.centerRadius.xyz, 1.0);\n let radius = drawData.centerRadius.w;\n var visible = isSphereInFrustum(\n rendererCamera.viewProj,\n drawData.centerRadius.xyz,\n radius,\n );\n\n let clip = rendererCamera.viewProj * center;\n let cameraDistance = distance(drawData.centerRadius.xyz, rendererCamera.cameraPosition.xyz);\n // A sphere that intersects the near plane, surrounds the camera, or has a\n // very large projected extent cannot be safely represented by its center.\n // Keep it rather than allowing a false negative to remove large terrain or\n // nearby geometry.\n let clipWRadius = radius * length(vec3(\n rendererCamera.viewProj[0].w,\n rendererCamera.viewProj[1].w,\n rendererCamera.viewProj[2].w,\n ));\n let needsConservativeVisibility =\n clip.w - clipWRadius <= 0.0001 || radius >= cameraDistance * 0.1;\n\n if (!needsConservativeVisibility) {\n let ndc = clip.xyz / clip.w;\n let projectedRadius = projectedSphereRadius(rendererCamera.viewProj, ndc, clip.w, radius);\n let clipRadiusX = projectedRadius.x;\n let clipRadiusY = projectedRadius.y;\n\n if (\n visible &&\n ndc.x - clipRadiusX >= -1.0 && ndc.x + clipRadiusX <= 1.0 &&\n ndc.y - clipRadiusY >= -1.0 && ndc.y + clipRadiusY <= 1.0\n ) {\n let uvCenter = ndc.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n let uvRadius = vec2(clipRadiusX, clipRadiusY) * 0.5;\n let viewport = rendererCamera.viewportAndTime.xy;\n let screenDiameter = max(\n max(clipRadiusX * viewport.x * 0.5, clipRadiusY * viewport.y * 0.5),\n 1.0,\n ) * 2.0;\n let maxMipLevel = max(f32(visibilityParams.hizMipCount) - 1.0, 0.0);\n // Round up from the full diameter. Using floor(log2(radius)) leaves\n // unsampled texels between the corner probes, especially for small\n // objects, and can turn partial coverage into a false occlusion.\n let mipLevel = clamp(ceil(log2(screenDiameter)), 0.0, maxMipLevel);\n // Cover the projected bounds rather than testing only their center. The\n // max-reduced pyramid makes background or a gap at any corner retain the\n // draw, avoiding false occlusion for partially covered objects.\n let hizDepth = max(\n max(\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2(-uvRadius.x, -uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2( uvRadius.x, -uvRadius.y), mipLevel).r,\n ),\n max(\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2(-uvRadius.x, uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2( uvRadius.x, uvRadius.y), mipLevel).r,\n ),\n );\n let conservativeDepth = nearestSphereDepth(rendererCamera.viewProj, clip, radius);\n visible = conservativeDepth <= hizDepth + 0.0005;\n }\n }\n\n let baseVertex = i32(round(drawData.extra.y));\n indirectArgs[drawIndex].indexCount = u32(round(drawData.args0.x));\n indirectArgs[drawIndex].instanceCount = select(0u, u32(round(drawData.args0.w)), visible);\n indirectArgs[drawIndex].firstIndex = u32(round(drawData.args0.y));\n indirectArgs[drawIndex].baseVertex = baseVertex;\n indirectArgs[drawIndex].firstInstance = u32(round(drawData.args0.z));\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.COMPUTE,sampler:{type:"non-filtering"}},{binding:3,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:5,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}).then(e=>{this.state.visibilityKernel=e})),u.push(W.createAsync(this.state.device,{label:"renderer-static-visibility-clear",code:"\nstruct RendererVisibilityParams {\n drawCount: u32,\n hizMipCount: u32,\n instanceCount: u32,\n flags: u32,\n};\n\n@group(0) @binding(0) var<uniform> visibilityParams: RendererVisibilityParams;\n@group(0) @binding(1) var<storage, read_write> visibleCounts: array<atomic<u32>>;\n@group(0) @binding(2) var<storage, read_write> postVisibleCounts: array<atomic<u32>>;\n@group(0) @binding(3) var<storage, read_write> visibleInstanceMask: array<atomic<u32>>;\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let index = globalId.x;\n if (index < visibilityParams.drawCount) {\n atomicStore(&visibleCounts[index], 0u);\n atomicStore(&postVisibleCounts[index], 0u);\n }\n if (index < visibilityParams.instanceCount) {\n // Bit 2 is persistent detail hysteresis; bit 0 is frame-local visibility.\n atomicStore(&visibleInstanceMask[index], atomicLoad(&visibleInstanceMask[index]) & 4u);\n }\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}).then(e=>{this.state.staticVisibilityClearKernel=e})),u.push(W.createAsync(this.state.device,{label:"renderer-static-visibility-cull",code:"\nstruct RendererTemporalVisibilityUniforms {\n currentViewProj: mat4x4<f32>,\n previousViewProj: mat4x4<f32>,\n currentCameraPosition: vec4<f32>,\n previousCameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\nstruct RendererVisibilityParams {\n drawCount: u32,\n hizMipCount: u32,\n instanceCount: u32,\n flags: u32,\n};\n\nstruct DrawMetadata {\n centerRadius: vec4<f32>,\n args0: vec4<f32>,\n extra: vec4<f32>,\n};\n\nstruct StaticInstanceMetadata {\n centerRadius: vec4<f32>,\n drawAndSourceIndex: vec4<u32>,\n};\n\n@group(0) @binding(0) var<uniform> temporalVisibility: RendererTemporalVisibilityUniforms;\n@group(0) @binding(1) var<uniform> visibilityParams: RendererVisibilityParams;\n@group(0) @binding(2) var hizSampler: sampler;\n@group(0) @binding(3) var hizTexture: texture_2d<f32>;\n@group(0) @binding(4) var<storage, read> instanceMetadata: array<StaticInstanceMetadata>;\n@group(0) @binding(5) var<storage, read> drawMetadata: array<DrawMetadata>;\n@group(0) @binding(6) var<storage, read_write> visibleCounts: array<atomic<u32>>;\n@group(0) @binding(7) var<storage, read_write> visibleInstanceIndices: array<u32>;\n@group(0) @binding(8) var<storage, read_write> visibleInstanceMask: array<atomic<u32>>;\n@group(0) @binding(9) var<storage, read_write> postVisibleCounts: array<atomic<u32>>;\n\nfn spherePlaneRadius(viewProj: mat4x4<f32>, plane: vec4<f32>, radius: f32) -> f32 {\n let worldNormal = vec3(\n dot(viewProj[0], plane),\n dot(viewProj[1], plane),\n dot(viewProj[2], plane),\n );\n return radius * length(worldNormal);\n}\n\nfn projectedSphereRadius(\n viewProj: mat4x4<f32>,\n ndc: vec3<f32>,\n clipW: f32,\n radius: f32,\n) -> vec2<f32> {\n let rowX = vec3(viewProj[0].x, viewProj[1].x, viewProj[2].x);\n let rowY = vec3(viewProj[0].y, viewProj[1].y, viewProj[2].y);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let denominator = max(clipW - radius * length(rowW), 0.0001);\n return radius * vec2(\n length(rowX) + abs(ndc.x) * length(rowW),\n length(rowY) + abs(ndc.y) * length(rowW),\n ) / denominator;\n}\n\nfn nearestSphereDepth(viewProj: mat4x4<f32>, clip: vec4<f32>, radius: f32) -> f32 {\n let rowZ = vec3(viewProj[0].z, viewProj[1].z, viewProj[2].z);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let minClipZ = clip.z - radius * length(rowZ);\n let maxClipW = clip.w + radius * length(rowW);\n return max(0.0, minClipZ / max(maxClipW, 0.0001));\n}\n\nfn isSphereInFrustum(\n viewProj: mat4x4<f32>,\n center: vec3<f32>,\n radius: f32,\n) -> bool {\n let clip = viewProj * vec4(center, 1.0);\n let left = clip.w + clip.x;\n let right = clip.w - clip.x;\n let bottom = clip.w + clip.y;\n let top = clip.w - clip.y;\n let near = clip.z;\n let far = clip.w - clip.z;\n\n return\n left >= -spherePlaneRadius(viewProj, vec4(1.0, 0.0, 0.0, 1.0), radius) &&\n right >= -spherePlaneRadius(viewProj, vec4(-1.0, 0.0, 0.0, 1.0), radius) &&\n bottom >= -spherePlaneRadius(viewProj, vec4(0.0, 1.0, 0.0, 1.0), radius) &&\n top >= -spherePlaneRadius(viewProj, vec4(0.0, -1.0, 0.0, 1.0), radius) &&\n near >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, 1.0, 0.0), radius) &&\n far >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, -1.0, 1.0), radius);\n}\n\nfn isSphereNearFrustumBoundary(\n viewProj: mat4x4<f32>,\n center: vec3<f32>,\n radius: f32,\n) -> bool {\n let clip = viewProj * vec4(center, 1.0);\n return\n clip.w + clip.x <= spherePlaneRadius(viewProj, vec4(1.0, 0.0, 0.0, 1.0), radius) ||\n clip.w - clip.x <= spherePlaneRadius(viewProj, vec4(-1.0, 0.0, 0.0, 1.0), radius) ||\n clip.w + clip.y <= spherePlaneRadius(viewProj, vec4(0.0, 1.0, 0.0, 1.0), radius) ||\n clip.w - clip.y <= spherePlaneRadius(viewProj, vec4(0.0, -1.0, 0.0, 1.0), radius) ||\n clip.z <= spherePlaneRadius(viewProj, vec4(0.0, 0.0, 1.0, 0.0), radius) ||\n clip.w - clip.z <= spherePlaneRadius(viewProj, vec4(0.0, 0.0, -1.0, 1.0), radius);\n}\n\nfn isSphereVisible(center: vec3<f32>, radius: f32) -> bool {\n let currentViewProj = temporalVisibility.currentViewProj;\n if (!isSphereInFrustum(currentViewProj, center, radius)) {\n return false;\n }\n\n let clip = currentViewProj * vec4(center, 1.0);\n // Near-plane intersections are deliberately kept. A false negative here would\n // incorrectly remove geometry surrounding the camera.\n if (clip.w <= 0.0001) {\n return true;\n }\n\n if ((visibilityParams.flags & 1u) == 0u) {\n return true;\n }\n\n let usesPreviousHiZ = (visibilityParams.flags & 2u) != 0u;\n var hizViewProj = temporalVisibility.currentViewProj;\n var hizCameraPosition = temporalVisibility.currentCameraPosition.xyz;\n if (usesPreviousHiZ) {\n hizViewProj = temporalVisibility.previousViewProj;\n hizCameraPosition = temporalVisibility.previousCameraPosition.xyz;\n }\n\n let hizClip = hizViewProj * vec4(center, 1.0);\n let hizClipWRadius = radius * length(vec3(\n hizViewProj[0].w,\n hizViewProj[1].w,\n hizViewProj[2].w,\n ));\n if (hizClip.w - hizClipWRadius <= 0.0001) {\n return true;\n }\n let hizNdc = hizClip.xyz / hizClip.w;\n let hizProjectedRadius = projectedSphereRadius(\n hizViewProj,\n hizNdc,\n hizClip.w,\n radius,\n );\n let hizClipRadiusX = hizProjectedRadius.x;\n let hizClipRadiusY = hizProjectedRadius.y;\n let hizClipRadiusZ = radius / max(distance(center, hizCameraPosition), 0.001);\n\n // Samples close to the viewport boundary cannot cover the whole projected\n // sphere. This also retains newly revealed regions during camera motion.\n if (\n isSphereNearFrustumBoundary(hizViewProj, center, radius) ||\n hizNdc.x - hizClipRadiusX < -1.0 || hizNdc.x + hizClipRadiusX > 1.0 ||\n hizNdc.y - hizClipRadiusY < -1.0 || hizNdc.y + hizClipRadiusY > 1.0 ||\n hizNdc.z < -hizClipRadiusZ || hizNdc.z > 1.0 + hizClipRadiusZ\n ) {\n return true;\n }\n\n let viewport = temporalVisibility.viewportAndTime.xy;\n let screenDiameter = max(\n max(hizClipRadiusX * viewport.x * 0.5, hizClipRadiusY * viewport.y * 0.5),\n 1.0,\n ) * 2.0;\n let maxMipLevel = max(f32(visibilityParams.hizMipCount) - 1.0, 0.0);\n let mipLevel = clamp(ceil(log2(screenDiameter)), 0.0, maxMipLevel);\n let uvCenter = hizNdc.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n let uvRadius = vec2(hizClipRadiusX, hizClipRadiusY) * 0.5;\n let hizDepth = max(\n max(\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2(-uvRadius.x, -uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2( uvRadius.x, -uvRadius.y), mipLevel).r,\n ),\n max(\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2(-uvRadius.x, uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2( uvRadius.x, uvRadius.y), mipLevel).r,\n ),\n );\n let conservativeNearestDepth = nearestSphereDepth(hizViewProj, hizClip, radius);\n return conservativeNearestDepth <= hizDepth + 0.001;\n}\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let instanceIndex = globalId.x;\n if (instanceIndex >= visibilityParams.instanceCount) {\n return;\n }\n\n let instance = instanceMetadata[instanceIndex];\n if ((visibilityParams.flags & 4u) != 0u && (atomicLoad(&visibleInstanceMask[instanceIndex]) & 1u) != 0u) {\n return;\n }\n let drawIndex = instance.drawAndSourceIndex.x;\n let threshold = bitcast<f32>(instance.drawAndSourceIndex.z);\n let maxDistance = bitcast<f32>(instance.drawAndSourceIndex.w);\n let center = instance.centerRadius.xyz;\n let radius = instance.centerRadius.w;\n if (maxDistance > 0.0 && distance(center, temporalVisibility.currentCameraPosition.xyz) - radius > maxDistance) {\n return;\n }\n if (threshold > 0.0) {\n let vp = temporalVisibility.currentViewProj;\n let clip = vp * vec4(center, 1.0);\n let wRadius = radius * length(vec3(vp[0].w, vp[1].w, vp[2].w));\n if (clip.w - wRadius > 0.0001) {\n let projected = projectedSphereRadius(vp, clip.xyz / clip.w, clip.w, radius);\n let diameter = max(projected.x * temporalVisibility.viewportAndTime.x, projected.y * temporalVisibility.viewportAndTime.y);\n let wasDetailed = (atomicLoad(&visibleInstanceMask[instanceIndex]) & 4u) != 0u;\n let boundary = threshold * select(1.15, 0.85, wasDetailed);\n if (diameter < boundary) {\n atomicAnd(&visibleInstanceMask[instanceIndex], ~4u);\n return;\n }\n }\n }\n atomicOr(&visibleInstanceMask[instanceIndex], 4u);\n if (drawIndex >= visibilityParams.drawCount || !isSphereVisible(instance.centerRadius.xyz, instance.centerRadius.w)) {\n return;\n }\n\n let isPostpass = (visibilityParams.flags & 4u) != 0u;\n if (!isPostpass) {\n atomicOr(&visibleInstanceMask[instanceIndex], 1u);\n }\n let firstInstance = u32(round(drawMetadata[drawIndex].args0.z));\n if (isPostpass) {\n let primaryVisibleCount = atomicLoad(&visibleCounts[drawIndex]);\n let postVisibleIndex = atomicAdd(&postVisibleCounts[drawIndex], 1u);\n visibleInstanceIndices[firstInstance + primaryVisibleCount + postVisibleIndex] = instance.drawAndSourceIndex.y;\n } else {\n let visibleIndex = atomicAdd(&visibleCounts[drawIndex], 1u);\n visibleInstanceIndices[firstInstance + visibleIndex] = instance.drawAndSourceIndex.y;\n }\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.COMPUTE,sampler:{type:"non-filtering"}},{binding:3,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:5,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:6,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:7,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:8,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:9,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}).then(e=>{this.state.staticVisibilityCullKernel=e})),u.push(W.createAsync(this.state.device,{label:"renderer-static-visibility-indirect-build",code:"\nstruct RendererVisibilityParams {\n drawCount: u32,\n hizMipCount: u32,\n instanceCount: u32,\n flags: u32,\n};\n\nstruct IndirectIndexedArgs {\n indexCount: u32,\n instanceCount: u32,\n firstIndex: u32,\n baseVertex: i32,\n firstInstance: u32,\n};\n\n@group(0) @binding(0) var<uniform> visibilityParams: RendererVisibilityParams;\n@group(0) @binding(1) var<storage, read_write> visibleCounts: array<atomic<u32>>;\n@group(0) @binding(2) var<storage, read_write> postVisibleCounts: array<atomic<u32>>;\n@group(0) @binding(3) var<storage, read_write> indirectArgs: array<IndirectIndexedArgs>;\n@group(0) @binding(4) var<storage, read_write> postIndirectArgs: array<IndirectIndexedArgs>;\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let drawIndex = globalId.x;\n if (drawIndex >= visibilityParams.drawCount) {\n return;\n }\n\n let primaryVisibleCount = atomicLoad(&visibleCounts[drawIndex]);\n let postVisibleCount = atomicLoad(&postVisibleCounts[drawIndex]);\n indirectArgs[drawIndex].instanceCount = primaryVisibleCount + postVisibleCount;\n if ((visibilityParams.flags & 4u) != 0u) {\n postIndirectArgs[drawIndex].instanceCount = postVisibleCount;\n postIndirectArgs[drawIndex].firstInstance = indirectArgs[drawIndex].firstInstance + primaryVisibleCount;\n }\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}).then(e=>{this.state.staticVisibilityIndirectBuildKernel=e})),this.state.visibilityParamsBuffer=this.state.device.createBuffer({label:"renderer-visibility-params-buffer",size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),u.push(this.createStaticPipelines()),await Promise.all(u),this.setSize(this.canvas.clientWidth||this.canvas.width||1,this.canvas.clientHeight||this.canvas.height||1),this.state.initialized=!0}createComputeKernel(e){if(!this.state.device)throw new Error("WebGpuRenderer.initialize() must complete before creating compute kernels.");return new W(this.state.device,e)}getDevice(){return this.state.device??null}setRenderGraphBuilder(e){this.graphBuilder=e}setCascadedShadowRanges(e,t=[]){this.csmCascadeCount=Math.min(e.length,4),this.csmCascadeLights=t.slice(0,this.csmCascadeCount);for(let t=0;t<this.csmCascadeCount;t+=1)this.csmCascadeRanges[t].set(e[t].x,e[t].y);for(let e=this.csmCascadeCount;e<4;e+=1)this.csmCascadeRanges[e].set(0,0)}setDirectionalShadowMapSize(e){const t=Math.max(1,Math.floor(e));t!==this.shadowMapSize&&(this.shadowMapSize=t,t!==this.state.directionalShadowTextureSize&&(this.state.directionalShadowTextureSize=t,this.recreateDirectionalShadowResources()))}setDirectionalShadowUpdateOptions(e){this.directionalShadowScheduler.setOptions(e)}invalidateDirectionalShadows(){this.directionalShadowScheduler.invalidate()}setDirectionalShadowGpuCullingEnabled(e){this.directionalShadowGpu.enabled=e,this.invalidateDirectionalShadows()}setDirectionalShadowsEnabled(e){this.directionalShadowsEnabled=e}setRenderGraphProfilingEnabled(e){this.renderGraphProfilingEnabled=e,e||ld(this.state)}getRenderGraphProfilingEnabled(){return this.renderGraphProfilingEnabled}getTimestampQuerySupported(){return this.timestampQuerySupported}getSampleCount(){return this.sampleCount}setSampleCount(e){const t=Ii(e);t!==this.sampleCount&&(this.sampleCount=t,this.destroyMsaaResources(),this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches())}setRenderScale(e){const t=Vh(e);if(t===this.renderScale)return;this.renderScale=t;const r=this.state.pixelRatio;this.setSize(this.state.presentationWidth/r,this.state.presentationHeight/r,r)}getRenderScale(){return this.renderScale}setProjectionJitter(e,t){if(!Number.isFinite(e)||!Number.isFinite(t))throw new RangeError("Projection jitter must contain finite pixel offsets.");this.projectionJitterPixels.set(e,t)}clearProjectionJitter(){this.projectionJitterPixels.set(0,0)}setMotionVectorProjection(e){this.motionVectorProjection.copy(e),this.motionVectorProjectionPending=!0}invalidateObjectMotion(e){this.objectMotionHistory.delete(e)}getLastFrameProfile(){const e=this.state.latestFrameProfile?.timestampQueryActive&&null===this.state.latestFrameProfile.gpuTimeMs&&this.state.latestCompletedFrameProfile?this.state.latestCompletedFrameProfile:this.state.latestFrameProfile;return e?{...e,cpuPhases:{...e.cpuPhases},passes:e.passes.map(e=>({...e})),visibility:e.visibility?{...e.visibility}:null}:null}resetViewHistory(){this.state.temporalHiZHistoryValid=!1,this.motionVectorHistoryValid=!1,this.motionVectorHistoryGeneration+=1}setHiZOcclusionCullingEnabled(e){this.hiZOcclusionCullingEnabled!==e&&(this.state.temporalHiZHistoryValid=!1),this.hiZOcclusionCullingEnabled=e}getHiZOcclusionCullingEnabled(){return this.hiZOcclusionCullingEnabled}getHiZOcclusionCullingActive(){return this.hiZOcclusionCullingEnabled&&this.indirectFirstInstanceSupported}setMultiDrawIndirectEnabled(e){this.multiDrawIndirectEnabled=e}getMultiDrawIndirectEnabled(){return this.multiDrawIndirectEnabled}setTiledLightingEnabled(e){this.tiledLightingEnabled=e}setDynamicBatchingEnabled(e){this.dynamicBatchingEnabled=e}getDynamicBatchingEnabled(){return this.dynamicBatchingEnabled}getMultiDrawIndirectSupported(){return this.multiDrawIndirectSupported}getMultiDrawIndirectActive(){return this.multiDrawIndirectEnabled&&this.multiDrawIndirectSupported&&this.getHiZOcclusionCullingActive()}setSize(e,t,r=window.devicePixelRatio||1){if(this.state.pixelRatio=r,this.state.presentationWidth=Math.max(1,Math.floor(e*r)),this.state.presentationHeight=Math.max(1,Math.floor(t*r)),this.state.width=Math.max(1,Math.floor(this.state.presentationWidth*this.renderScale)),this.state.height=Math.max(1,Math.floor(this.state.presentationHeight*this.renderScale)),this.canvas.width=this.state.presentationWidth,this.canvas.height=this.state.presentationHeight,this.canvas.style.width=`${Math.max(1,Math.floor(e))}px`,this.canvas.style.height=`${Math.max(1,Math.floor(t))}px`,this.state.device){for(const[e,t]of this.colorTargetCache){const r="presentation"===t.resolution?this.state.presentationWidth:this.state.width,i="presentation"===t.resolution?this.state.presentationHeight:this.state.height,n=Math.max(1,Math.floor(r*t.scale)),a=Math.max(1,Math.floor(i*t.scale));t.width===n&&t.height===a||(t.texture.destroy(),this.colorTargetCache.delete(e))}this.destroyMsaaResources(),this.state.mainDepthTexture?.destroy(),this.state.mainDepthTexture=this.state.device.createTexture({label:"renderer-main-depth",size:{width:this.state.width,height:this.state.height},format:"depth32float",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),this.state.mainDepthView=this.state.mainDepthTexture.createView(),this.state.hizCopyBindGroup=null,this.state.sceneColorTexture?.destroy(),this.state.sceneColorTexture=this.state.device.createTexture({label:"renderer-scene-color",size:{width:this.state.width,height:this.state.height},format:D,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),this.state.sceneColorView=this.state.sceneColorTexture.createView(),this.state.sceneColorSnapshotTexture?.destroy(),this.state.sceneColorSnapshotTexture=this.state.device.createTexture({label:"renderer-scene-color-snapshot",size:{width:this.state.width,height:this.state.height},format:T,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),this.state.sceneColorSnapshotView=this.state.sceneColorSnapshotTexture.createView(),this.state.sceneDepthSnapshotTexture?.destroy(),this.state.sceneDepthSnapshotTexture=this.state.device.createTexture({label:"renderer-scene-depth-snapshot",size:{width:this.state.width,height:this.state.height},format:"depth32float",usage:GPUTextureUsage.COPY_DST|GPUTextureUsage.TEXTURE_BINDING}),this.state.sceneDepthSnapshotView=this.state.sceneDepthSnapshotTexture.createView(),this.state.postProcessColorTexture?.destroy(),this.state.postProcessColorTexture=this.state.device.createTexture({label:"renderer-post-process-color",size:{width:this.state.width,height:this.state.height},format:D,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),this.state.postProcessColorView=this.state.postProcessColorTexture.createView(),this.state.sceneTextureBindGroupLayout&&this.state.linearClampSampler&&this.state.nearestClampSampler&&(this.state.sceneTextureBindGroup=this.state.device.createBindGroup({label:"renderer-scene-texture-bind-group",layout:this.state.sceneTextureBindGroupLayout,entries:[{binding:0,resource:this.state.linearClampSampler},{binding:1,resource:this.state.sceneColorSnapshotView},{binding:2,resource:this.state.nearestClampSampler},{binding:3,resource:this.state.sceneDepthSnapshotView}]})),this.state.hizTexture?.destroy(),this.state.hizMipCount=Math.max(1,Math.floor(Math.log2(Math.max(this.state.width,this.state.height)))+1),this.state.hizTexture=this.state.device.createTexture({label:"renderer-hiz-pyramid",size:{width:this.state.width,height:this.state.height},format:"r32float",mipLevelCount:this.state.hizMipCount,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING}),this.state.hizView=this.state.hizTexture.createView(),this.state.hizMipViews=[],this.state.hizCopyBindGroup=null,this.state.hizReduceBindGroups=[],this.state.visibilityBindGroup=null,this.state.visibilityBindGroupMetadataResource=null;for(let e=0;e<this.state.hizMipCount;e+=1)this.state.hizMipViews.push(this.state.hizTexture.createView({baseMipLevel:e,mipLevelCount:1}));this.hizResourceVersion+=1,this.graphTextureResourceVersion+=1,this.state.temporalHiZHistoryValid=!1,this.motionVectorHistoryValid=!1,this.motionVectorHistoryGeneration+=1;for(const e of this.staticDrawSets)e.visibilityBindGroup=null,e.postVisibilityBindGroup=null,e.visibilityBindGroupHizVersion=0;this.recreateShadowResources()}}setClearColor(e){this.clearColor[0]=e[0],this.clearColor[1]=e[1],this.clearColor[2]=e[2],this.clearColor[3]=e[3]}render(e,t,r=.001*performance.now()){this.renderFrame(e,t,r,!1)}async renderAsync(e,t,r=.001*performance.now()){await this.renderFrame(e,t,r,!0)}compile(e,t){this.prepareSceneForCompilation(e,t,!1)}async compileAsync(e,t){this.state.initialized||await this.initialize();const r={startedAt:performance.now(),preparationMs:0,phases:{},drawCount:0,materialRequestCount:0,cpuTotalsMs:{},slowTextureLookups:[],pipelines:[]};this.pipelineCompilationDiagnostics=r;try{const i=this.prepareSceneForCompilation(e,t,!0);r.preparationMs=performance.now()-r.startedAt,await i}finally{this.pipelineCompilationDiagnostics===r&&(this.pipelineCompilationDiagnostics=void 0);const e=performance.now()-r.startedAt,t=r.pipelines,i=[...t].sort((e,t)=>t.durationMs-e.durationMs).slice(0,12);console.info("[WebGPU] Scene compilation",{elapsedMs:Math.round(e),preparationMs:Math.round(r.preparationMs),phasesMs:r.phases,drawCount:r.drawCount,materialRequestCount:r.materialRequestCount,cpuTotalsMs:Object.fromEntries(Object.entries(r.cpuTotalsMs).map(([e,t])=>[e,Math.round(t)])),slowTextureLookups:r.slowTextureLookups.sort((e,t)=>t.durationMs-e.durationMs).slice(0,12).map(e=>({...e,durationMs:Math.round(e.durationMs)})),pipelineCount:t.length,forwardCount:t.filter(e=>"forward"===e.kind).length,depthCount:t.filter(e=>"depth"===e.kind).length,slowestPipelines:i.map(e=>({kind:e.kind,material:e.material,durationMs:Math.round(e.durationMs),vertexCodeLength:e.vertexCodeLength,fragmentCodeLength:e.fragmentCodeLength}))})}}createPMREMGenerator(e=20){if(!this.state.device)throw new Error("WebGpuRenderer.initialize() must complete before creating a PMREM generator.");return new Nu({device:this.state.device,getTextureResource:e=>this.getTextureResource(e),registerTextureResource:(e,t)=>this.textureCache.set(e,t)},e)}initTexture(e){this.textureManager.getTextureResource(e)}createStaticDrawSet(e,t={}){return this.staticDrawSetManager.createStaticDrawSet(e,t)}disposeStaticDrawSetResource(e){this.staticDrawSetManager.disposeStaticDrawSetResource(e)}renderFrame(e,t,r,i){if(!(this.state.initialized&&this.state.device&&this.state.context&&this.state.mainDepthView&&this.state.sceneColorView&&this.state.postProcessColorView&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.shadowCameraBuffer&&this.state.sceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.shadowComparisonSampler&&this.state.linearClampSampler&&this.state.nearestClampSampler&&this.state.visibilityParamsBuffer&&this.state.directionalShadowView&&this.state.pointShadowArrayView&&this.state.spotShadowView&&this.state.hizCopyKernel&&this.state.hizReduceKernel&&this.state.visibilityKernel&&this.state.presentPipeline))throw new Error("WebGpuRenderer.initialize() must complete before render().");const n=r-this.lastMotionVectorTimeSeconds;Number.isFinite(this.lastMotionVectorTimeSeconds)&&(!Number.isFinite(n)||n<=0||n>.25)&&(this.motionVectorHistoryValid=!1,this.motionVectorHistoryGeneration+=1),this.lastMotionVectorTimeSeconds=r,this.state.frameTimeSeconds=r,this.staticFrameToken+=1,e.matrixWorldAutoUpdate&&e.updateMatrixWorld(),null===t.parent&&t.matrixWorldAutoUpdate&&t.updateMatrixWorld(),this.opaqueSortMs=0;const a=performance.now(),s=this.extractScene(e,t);for(const e of s.gpuOpaqueDraws)this.prepareDrawGeometryVertexBuffers(e);for(const e of s.directOpaqueDraws)this.prepareDrawGeometryVertexBuffers(e);for(const e of s.transparentDraws)this.prepareDrawGeometryVertexBuffers(e);this.ensureShadowTextureSizes(s);const o=performance.now()-a;this.renderGraphProfilingEnabled&&(this.opaqueSortSampleTotal-=this.opaqueSortSamples[this.opaqueSortSampleIndex],this.opaqueSortSamples[this.opaqueSortSampleIndex]=this.opaqueSortMs,this.opaqueSortSampleTotal+=this.opaqueSortMs,this.opaqueSortSampleIndex=(this.opaqueSortSampleIndex+1)%this.opaqueSortSamples.length,this.opaqueSortSampleCount=Math.min(this.opaqueSortSampleCount+1,this.opaqueSortSamples.length));const l={drawCallCount:0,triangleCount:0},c=performance.now();this.uploadInstanceData(s.instanceData),this.uploadResidentInstanceData(s.residentInstanceUploads);const u=this.getHiZOcclusionCullingActive();this.uploadDrawMetadata(u?s.gpuOpaqueDraws:[]),this.ensureTiledLightingSize(),this.updateCameraUniforms(t,e),this.updateTemporalVisibilityUniforms(t),this.updateLightUniforms(s);const d=performance.now()-c,h=this.state.device.createCommandEncoder({label:"renderer-command-encoder"}),p=this.state.context.getCurrentTexture().createView(),f=this.getSharedSceneBindGroup(),m=this.getSharedShadowBindGroup();let g=null;const v=this.state.drawMetadataResource;u&&v&&v.count>0&&this.state.hizView&&(this.state.visibilityBindGroup&&this.state.visibilityBindGroupMetadataResource===v||(this.state.visibilityBindGroup=this.state.visibilityKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:1,resource:{buffer:this.state.visibilityParamsBuffer}},{binding:2,resource:this.state.nearestClampSampler},{binding:3,resource:this.state.hizView},{binding:4,resource:{buffer:v.metadataBuffer}},{binding:5,resource:{buffer:v.indirectBuffer}}],"renderer-visibility-bind-group"),this.state.visibilityBindGroupMetadataResource=v),g=this.state.visibilityBindGroup),this.renderGraph.reset();const x=this.createGraphBuilderContext(this.renderGraph,h,f,m,g,p,s,l);this.graphBuilder(this.renderGraph,x);const w={device:this.state.device,encoder:h},b=function(e,t,r,i,n){if(!t.renderGraphProfilingEnabled||!e.device)return null;let a=ad.get(e);a&&a.device===e.device||(a?.dispose(),a=new nd(e.device),ad.set(e,a));const s=a,o={frameIndex:e.frameIndex+=1,cpuTimeMs:0,gpuTimeMs:null,drawCallCount:i.drawCallCount,triangleCount:i.triangleCount,cpuPhases:{extractSceneMs:n.extractSceneMs,opaqueSortMs:n.opaqueSortMs,opaqueSortAverageMs:n.opaqueSortAverageMs,uploadMs:n.uploadMs,renderGraphMs:0},passes:[],timestampQuerySupported:t.timestampQuerySupported,timestampQueryActive:t.timestampQuerySupported,gpuProfilingReason:null,hiZOcclusionCullingEnabled:t.hiZOcclusionCullingEnabled,hiZOcclusionCullingActive:r,visibility:null};let l=null,c=0,u=0;const d={begin:(e,r)=>{if(o.passes=e.map(e=>({name:e.name,cpuTimeMs:0,gpuTimeMs:null})),!t.timestampQuerySupported)return o.timestampQueryActive=!1,void(o.gpuProfilingReason="timestamp-query is not supported by this adapter/device");if(0===e.length)return o.timestampQueryActive=!1,void(o.gpuProfilingReason="no render graph passes were recorded");const i=2*e.length,n=s.acquire(i,!0);if(!n)return od.add(h),o.timestampQueryActive=!1,void(o.gpuProfilingReason="GPU profiling readbacks are still pending");l={profile:o,querySet:n.querySet,resolveBuffer:n.resolveBuffer,readBuffer:n.readBuffer,queryCount:i,release:e=>s.release(n,e)}},beforePass:(e,t,r)=>{c=i.triangleCount,u=i.drawCallCount,l&&0===t&&(Zr(r.encoder,l.querySet,{endOfPassWriteIndex:2*t})||(o.timestampQueryActive=!1,o.gpuProfilingReason="timestampWrites marker pass is not available on this browser/runtime",l.release(!1),l=null))},afterPass:(e,t,r,n)=>{o.passes[t].cpuTimeMs=r,o.passes[t].triangleCount=i.triangleCount-c,o.passes[t].drawCallCount=i.drawCallCount-u,l&&(Zr(n.encoder,l.querySet,{beginningOfPassWriteIndex:2*t+1,...t+1<o.passes.length?{endOfPassWriteIndex:2*t+2}:{}})||(o.timestampQueryActive=!1,o.gpuProfilingReason="timestampWrites marker pass is not available on this browser/runtime",l.release(!1),l=null))},end:(t,r,n)=>{if(!od.has(h)){if(o.cpuPhases.renderGraphMs=r,o.cpuTimeMs=o.cpuPhases.extractSceneMs+o.cpuPhases.uploadMs+o.cpuPhases.renderGraphMs,o.drawCallCount=i.drawCallCount,o.triangleCount=i.triangleCount,o.directionalShadows={updatedLayers:i.directionalShadowUpdates??0,reusedLayers:i.directionalShadowReused??0,forcedLayers:i.directionalShadowForced??0,updateMask:i.directionalShadowUpdateMask??0,gpuIndirectDraws:i.directionalShadowGpuDraws??0},!l){const t=hd(o);return e.latestFrameProfile=t,void(e.latestCompletedFrameProfile=t)}n.encoder.resolveQuerySet(l.querySet,0,l.queryCount,l.resolveBuffer,0),n.encoder.copyBufferToBuffer(l.resolveBuffer,0,l.readBuffer,0,8*l.queryCount),e.latestFrameProfile=hd(o)}}},h={profile:o,observer:d,pendingVisibilityRead:null,get pendingGpuRead(){return l},set pendingGpuRead(e){l=e}};return sd.set(h,s),h}(this.state,{renderGraphProfilingEnabled:this.renderGraphProfilingEnabled,timestampQuerySupported:this.timestampQuerySupported,hiZOcclusionCullingEnabled:this.hiZOcclusionCullingEnabled},u,l,{extractSceneMs:o,opaqueSortMs:this.opaqueSortMs,opaqueSortAverageMs:this.opaqueSortSampleTotal/Math.max(1,this.opaqueSortSampleCount),uploadMs:d}),y=()=>{if(!b||!u)return;const e=[];v&&v.count>0&&e.push({buffer:v.indirectBuffer,drawCount:v.count,totalInstances:s.gpuOpaqueDraws.reduce((e,t)=>e+Math.max(0,t.instanceCount),0),kind:"dynamic"});for(const t of this.staticDrawSets)t.publicSet.enabled&&t.lastVisibilityFrameToken===this.staticFrameToken&&e.push({buffer:t.drawMetadataResource.indirectBuffer,drawCount:t.drawMetadataResource.count,totalInstances:t.instanceCount,kind:"static"});!function(e,t,r,i){if(od.has(e))return;const n=i.filter(e=>e.drawCount>0);if(0===n.length)return void(e.profile.visibility={totalInstances:0,visibleInstances:0,culledInstances:0,dynamicTotalInstances:0,dynamicVisibleInstances:0,staticTotalInstances:0,staticVisibleInstances:0});let a=0;const s=n.map(e=>{const t={byteOffset:a,drawCount:e.drawCount,totalInstances:e.totalInstances,kind:e.kind};return a+=5*e.drawCount*Uint32Array.BYTES_PER_ELEMENT,t}),o=sd.get(e),l=o?.acquire(a,!1);if(o&&!l)return;const c=l?.readBuffer??t.createBuffer({label:`renderer-visibility-profile-read-${e.profile.frameIndex}`,size:Math.max(4,a),usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});for(let e=0;e<n.length;e+=1){const t=n[e];r.copyBufferToBuffer(t.buffer,0,c,s[e].byteOffset,5*t.drawCount*Uint32Array.BYTES_PER_ELEMENT)}e.pendingVisibilityRead={readBuffer:c,regions:s,release:l&&o?e=>o.release(l,e):void 0}}(b,this.state.device,h,e)};if(i)return this.renderGraph.executeAsync(w,b?.observer).then(()=>{y(),null==this.nativePostSubmit&&this.recordPresentationOverlay(h,p),this.state.device.queue.submit([h.finish()]),this.nativePostSubmit?.({device:this.state.device,presentationView:p,presentationWidth:this.state.presentationWidth,presentationHeight:this.state.presentationHeight,present:e=>{const t=this.state.device.createCommandEncoder({label:"native-present-encoder"});this.executePresentPass(t,e,p),this.recordPresentationOverlay(t,p),this.state.device.queue.submit([t.finish()])}}),this.commitTemporalHiZHistory(),this.releaseRetiredGeometryResourcesAfterSubmit(),b&&cd(this.state,b)});this.renderGraph.execute(w,b?.observer),y(),null==this.nativePostSubmit&&this.recordPresentationOverlay(h,p),this.state.device.queue.submit([h.finish()]),this.nativePostSubmit?.({device:this.state.device,presentationView:p,presentationWidth:this.state.presentationWidth,presentationHeight:this.state.presentationHeight,present:e=>{const t=this.state.device.createCommandEncoder({label:"native-present-encoder"});this.executePresentPass(t,e,p),this.recordPresentationOverlay(t,p),this.state.device.queue.submit([t.finish()])}}),this.commitTemporalHiZHistory(),this.releaseRetiredGeometryResourcesAfterSubmit(),b&&cd(this.state,b)}recordPresentationOverlay(e,t){if(null==this.presentationOverlay)return;const r=this.presentationOverlayContext;r.device=this.state.device,r.encoder=e,r.targetView=t,r.targetFormat=this.state.format,r.presentationWidth=this.state.presentationWidth,r.presentationHeight=this.state.presentationHeight,this.presentationOverlay(r)}destroy(){ld(this.state),this.directionalShadowGpu.dispose();for(const e of this.repeatedInstanceResources.values())e();this.skeletonPalettes.dispose(),this.clearIndirectBundleCache();for(const e of this.staticDrawSets.slice())this.disposeStaticDrawSetResource(e);this.sharedForwardPipelineCache.clear(),this.sharedForwardPipelinePromiseCache.clear(),this.sharedDepthPipelineCache.clear(),this.sharedDepthPipelinePromiseCache.clear();for(const e of this.skinnedGeometryCache.values())e.skinning.bindUniformBuffer.destroy();this.skinnedGeometryCache.clear();for(const e of this.skinPaletteResources)e.matrixBuffer.destroy(),e.previousMatrixBuffer.destroy();this.skinPaletteResources.clear();for(const e of this.retiredGeometryResources)this.destroyGeometryResource(e);this.retiredGeometryResources.length=0;for(const e of this.colorTargetCache.values())e.texture.destroy();this.colorTargetCache.clear(),this.destroyMsaaResources(),this.state.mainDepthTexture?.destroy(),this.state.sceneColorTexture?.destroy(),this.state.sceneColorSnapshotTexture?.destroy(),this.transmissionSnapshotTexture?.destroy(),this.transmissionSnapshotTexture=null,this.state.sceneDepthSnapshotTexture?.destroy(),this.state.postProcessColorTexture?.destroy(),this.directionalShadowScheduler.invalidate(),this.state.directionalShadowTexture?.destroy(),this.state.pointShadowTexture?.destroy(),this.state.pointShadowDepthTexture?.destroy(),this.state.spotShadowTexture?.destroy(),this.state.spotLightMapTexture?.destroy(),this.state.hizTexture?.destroy(),this.state.cameraBuffer?.destroy(),this.state.temporalVisibilityBuffer?.destroy(),this.state.lightBuffer?.destroy(),this.tiledPointLights?.destroy(),this.state.shadowCameraBuffer?.destroy();for(const e of this.state.shadowCameraBufferPool)e.destroy();this.state.shadowCameraBufferPool.length=0,this.state.sharedShadowBindGroupByCameraBuffer.clear(),this.state.instanceBuffer?.destroy();for(const e of this.defaultInstanceAttributeBuffers.values())for(const t of e.values())t.destroy();this.defaultInstanceAttributeBuffers.clear(),this.state.visibilityParamsBuffer?.destroy(),this.state.drawMetadataResource?.metadataBuffer.destroy(),this.state.drawMetadataResource?.indirectBuffer.destroy(),this.state.drawMetadataResource?.postIndirectBuffer.destroy(),this.state.initialized=!1;const e=this.state.device?.destroy;"function"==typeof e&&e.call(this.state.device),this.state.device=null}async createStaticPipelines(){if(!(this.state.device&&this.state.sceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.visibleDepthSceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&this.state.emptyBindGroupLayout&&this.state.skinningBindGroupLayout&&this.state.fullscreenTextureBindGroupLayout&&this.state.format))return;const e=[],t=this.state.device.createPipelineLayout({label:"renderer-depth-prepass-layout",bindGroupLayouts:[this.state.sceneBindGroupLayout]});e.push(j(this.state.device,{label:"renderer-depth-prepass-pipeline",layout:t,vertex:{module:this.state.device.createShaderModule({label:"renderer-depth-prepass-module",code:"\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> rendererLights: array<vec4<f32>, 11>;\n@group(0) @binding(2) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> @builtin(position) @invariant vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n return rendererCamera.viewProj * world;\n}\n"}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.depthPrepassPipeline=e}));const r=this.state.device.createPipelineLayout({label:"renderer-depth-prepass-visible-layout",bindGroupLayouts:[this.state.visibleDepthSceneBindGroupLayout]});e.push(j(this.state.device,{label:"renderer-depth-prepass-visible-pipeline",layout:r,vertex:{module:this.state.device.createShaderModule({label:"renderer-depth-prepass-visible-module",code:"\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(2) var<storage, read> rendererInstances: array<RendererInstanceData>;\n@group(0) @binding(3) var<storage, read> rendererVisibleInstanceIndices: array<u32>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[rendererVisibleInstanceIndices[instanceIndex]];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> @builtin(position) @invariant vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n return rendererCamera.viewProj * world;\n}\n"}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.depthPrepassPipelineVisible=e}));const i=this.state.device.createPipelineLayout({label:"renderer-depth-prepass-direct-layout",bindGroupLayouts:[this.state.directSceneBindGroupLayout]});e.push(j(this.state.device,{label:"renderer-depth-prepass-direct-pipeline",layout:i,vertex:{module:this.state.device.createShaderModule({label:"renderer-depth-prepass-direct-module",code:"\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> rendererLights: array<vec4<f32>, 11>;\n@group(0) @binding(2) var<storage, read> rendererInstanceMatrices: array<vec4<f32>>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let base = instanceIndex * 4u;\n return mat4x4<f32>(\n rendererInstanceMatrices[base + 0u],\n rendererInstanceMatrices[base + 1u],\n rendererInstanceMatrices[base + 2u],\n rendererInstanceMatrices[base + 3u]\n );\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> @builtin(position) @invariant vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n return rendererCamera.viewProj * world;\n}\n"}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.depthPrepassPipelineDirect=e}));const n=this.state.device.createPipelineLayout({label:"renderer-skinned-depth-prepass-layout",bindGroupLayouts:[this.state.sceneBindGroupLayout,this.state.emptyBindGroupLayout,this.state.skinningBindGroupLayout]});e.push(j(this.state.device,{label:"renderer-skinned-depth-prepass-pipeline",layout:n,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-depth-prepass-module",code:Uc}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(R)},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.skinnedDepthPrepassPipeline=e}));const a=this.state.device.createPipelineLayout({label:"renderer-shadow-layout",bindGroupLayouts:[this.state.shadowBindGroupLayout]}),s=this.state.device.createPipelineLayout({label:"renderer-direct-shadow-pipeline-layout",bindGroupLayouts:[this.state.directShadowBindGroupLayout]});e.push(j(this.state.device,{label:"renderer-directional-shadow-pipeline",layout:a,vertex:{module:this.state.device.createShaderModule({label:"renderer-directional-shadow-module",code:Gc}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"front",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}}).then(e=>{this.state.shadowDepthPipeline=e})),e.push(j(this.state.device,{label:"renderer-directional-shadow-direct-pipeline",layout:s,vertex:{module:this.state.device.createShaderModule({label:"renderer-directional-shadow-direct-module",code:"\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstanceMatrices: array<vec4<f32>>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let base = instanceIndex * 4u;\n return mat4x4<f32>(\n rendererInstanceMatrices[base + 0u],\n rendererInstanceMatrices[base + 1u],\n rendererInstanceMatrices[base + 2u],\n rendererInstanceMatrices[base + 3u]\n );\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> @builtin(position) vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n return shadowCamera.viewProj * world;\n}\n"}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"front",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}}).then(e=>{this.state.shadowDepthPipelineDirect=e}));const o=this.state.device.createPipelineLayout({label:"renderer-skinned-shadow-layout",bindGroupLayouts:[this.state.shadowBindGroupLayout,this.state.emptyBindGroupLayout,this.state.skinningBindGroupLayout]});e.push(j(this.state.device,{label:"renderer-skinned-directional-shadow-pipeline",layout:o,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-directional-shadow-module",code:Ac}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(R)},primitive:{topology:"triangle-list",cullMode:"front",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}}).then(e=>{this.state.skinnedShadowDepthPipeline=e})),e.push(j(this.state.device,{label:"renderer-point-shadow-pipeline",layout:a,vertex:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-module",code:Lc}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},fragment:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-fragment-module",code:Lc}),entryPoint:"fsMain",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.pointShadowPipeline=e})),e.push(j(this.state.device,{label:"renderer-point-shadow-direct-pipeline",layout:s,vertex:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-direct-module",code:zc}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},fragment:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-direct-fragment-module",code:zc}),entryPoint:"fsMain",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.pointShadowPipelineDirect=e})),e.push(j(this.state.device,{label:"renderer-skinned-point-shadow-pipeline",layout:o,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-point-shadow-module",code:kc}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(R)},fragment:{module:this.state.device.createShaderModule({label:"renderer-skinned-point-shadow-fragment-module",code:kc}),entryPoint:"fsMain",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}).then(e=>{this.state.skinnedPointShadowPipeline=e}));const l=this.state.device.createPipelineLayout({label:"renderer-present-layout",bindGroupLayouts:[this.state.fullscreenTextureBindGroupLayout]});e.push(j(this.state.device,{label:"renderer-present-pipeline",layout:l,vertex:{module:this.state.device.createShaderModule({label:"renderer-present-module",code:Fc}),entryPoint:"vsMain"},fragment:{module:this.state.device.createShaderModule({label:"renderer-present-fragment-module",code:Fc}),entryPoint:"fsMain",targets:[{format:this.state.format}]},primitive:{topology:"triangle-list"}}).then(e=>{this.state.presentPipeline=e}));const c=this.state.device.createShaderModule({label:"renderer-scene-color-snapshot-module",code:Ec});e.push(j(this.state.device,{label:"renderer-scene-color-snapshot-pipeline",layout:l,vertex:{module:c,entryPoint:"vsMain"},fragment:{module:c,entryPoint:"fsMain",targets:[{format:T}]},primitive:{topology:"triangle-list"}}).then(e=>{this.state.sceneColorSnapshotPipeline=e}));const u=this.state.device.createShaderModule({label:"physical-transmission-snapshot-module",code:Oc});e.push(j(this.state.device,{label:"physical-transmission-snapshot-pipeline",layout:l,vertex:{module:u,entryPoint:"vsMain"},fragment:{module:u,entryPoint:"fsMain",targets:[{format:D}]},primitive:{topology:"triangle-list"}}).then(e=>{this.transmissionSnapshotPipeline=e})),await Promise.all(e)}ensureTransmissionSnapshot(){if(this.transmissionSnapshotTexture&&this.transmissionSnapshotSize.width===this.state.width&&this.transmissionSnapshotSize.height===this.state.height)return;this.transmissionSnapshotTexture?.destroy(),this.transmissionSnapshotSize.width=this.state.width,this.transmissionSnapshotSize.height=this.state.height;const e=1+Math.floor(Math.log2(Math.max(this.state.width,this.state.height)));this.transmissionSnapshotTexture=this.state.device.createTexture({label:"physical-transmission-snapshot",size:this.transmissionSnapshotSize,format:D,mipLevelCount:e,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),this.transmissionSnapshotView=this.transmissionSnapshotTexture.createView(),this.transmissionMipViews=[],this.transmissionMipBindGroups=[],this.transmissionSourceBindGroups=new WeakMap;for(let t=0;t<e;t++)this.transmissionMipViews.push(this.transmissionSnapshotTexture.createView({baseMipLevel:t,mipLevelCount:1})),t>0&&this.transmissionMipBindGroups.push(this.state.device.createBindGroup({layout:this.state.fullscreenTextureBindGroupLayout,entries:[{binding:0,resource:this.transmissionSampler},{binding:1,resource:this.transmissionMipViews[t-1]}]}));this.graphTextureResourceVersion++}copyTransmissionSnapshot(e,t){let r=this.transmissionSourceBindGroups.get(t);r||(r=this.state.device.createBindGroup({layout:this.state.fullscreenTextureBindGroupLayout,entries:[{binding:0,resource:this.transmissionSampler},{binding:1,resource:t}]}),this.transmissionSourceBindGroups.set(t,r));for(let t=0;t<this.transmissionMipViews.length;t++){const i=e.beginRenderPass({label:"physical-transmission-snapshot-mip",colorAttachments:[{view:this.transmissionMipViews[t],loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:1}}]});i.setPipeline(this.transmissionSnapshotPipeline),i.setBindGroup(0,0===t?r:this.transmissionMipBindGroups[t-1]),i.draw(3),i.end()}}recreateShadowResources(){if(this.state.device){this.recreateDirectionalShadowResources(),this.state.pointShadowTexture?.destroy(),this.state.pointShadowTexture=this.state.device.createTexture({label:"renderer-point-shadow-texture",size:{width:this.state.pointShadowTextureSize,height:this.state.pointShadowTextureSize,depthOrArrayLayers:24},format:"rgba16float",dimension:"2d",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),this.state.pointShadowArrayView=this.state.pointShadowTexture.createView({dimension:"2d-array"}),this.state.pointShadowFaceViews=[];for(let e=0;e<24;e+=1)this.state.pointShadowFaceViews.push(this.state.pointShadowTexture.createView({dimension:"2d",baseArrayLayer:e,arrayLayerCount:1}));this.state.pointShadowDepthTexture?.destroy(),this.state.pointShadowDepthTexture=this.state.device.createTexture({label:"renderer-point-shadow-depth-texture",size:{width:this.state.pointShadowTextureSize,height:this.state.pointShadowTextureSize,depthOrArrayLayers:24},format:"depth32float",dimension:"2d",usage:GPUTextureUsage.RENDER_ATTACHMENT}),this.state.pointShadowDepthFaceViews=[];for(let e=0;e<24;e+=1)this.state.pointShadowDepthFaceViews.push(this.state.pointShadowDepthTexture.createView({dimension:"2d",baseArrayLayer:e,arrayLayerCount:1}));this.state.spotShadowTexture?.destroy(),this.state.spotShadowTexture=this.state.device.createTexture({label:"renderer-spot-shadow-texture",size:{width:this.state.spotShadowTextureSize,height:this.state.spotShadowTextureSize,depthOrArrayLayers:4},format:"depth32float",dimension:"2d",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),this.state.spotShadowView=this.state.spotShadowTexture.createView({dimension:"2d-array"}),this.state.spotShadowLayerViews=[];for(let e=0;e<4;e+=1)this.state.spotShadowLayerViews.push(this.state.spotShadowTexture.createView({dimension:"2d",baseArrayLayer:e,arrayLayerCount:1}))}}recreateDirectionalShadowResources(){if(this.state.device){this.state.residentSceneBindGroupVersion+=1,this.state.sharedSceneBindGroup=null,this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches(),this.directionalShadowScheduler.invalidate(),this.state.directionalShadowTexture?.destroy(),this.state.directionalShadowTexture=this.state.device.createTexture({label:"renderer-directional-shadow-texture",size:{width:this.state.directionalShadowTextureSize,height:this.state.directionalShadowTextureSize,depthOrArrayLayers:4},format:"depth32float",dimension:"2d",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),this.state.directionalShadowView=this.state.directionalShadowTexture.createView({dimension:"2d-array"}),this.state.directionalShadowLayerViews=[];for(let e=0;e<4;e+=1)this.state.directionalShadowLayerViews.push(this.state.directionalShadowTexture.createView({dimension:"2d",baseArrayLayer:e,arrayLayerCount:1}))}}ensureShadowTextureSizes(e){const t=Math.max(this.shadowMapSize,...e.lights.directionals.map(e=>Math.ceil(e.shadowMapSize))),r=Math.max(this.pointShadowMapSize,...e.lights.points.map(e=>Math.ceil(e.shadowMapSize))),i=Math.max(this.spotShadowMapSize,...e.lights.spots.map(e=>Math.ceil(e.shadowMapSize)));t===this.state.directionalShadowTextureSize&&r===this.state.pointShadowTextureSize&&i===this.state.spotShadowTextureSize||(this.state.directionalShadowTextureSize=t,this.state.pointShadowTextureSize=r,this.state.spotShadowTextureSize=i,this.recreateShadowResources())}ensureColorTarget(e,t={}){if(!this.state.device||!this.state.format)throw new Error("Renderer is not initialized.");if("sceneColor"===e||"postProcessColor"===e)throw new Error(`Color target "${e}" is reserved by the renderer.`);const r=t.scale??1,i=t.resolution??"render",n=t.format??D,a="presentation"===i?this.state.presentationWidth:this.state.width,s="presentation"===i?this.state.presentationHeight:this.state.height,o=Math.max(1,Math.floor(a*r)),l=Math.max(1,Math.floor(s*r)),c=this.colorTargetCache.get(e);if(c&&c.format===n&&c.width===o&&c.height===l&&c.scale===r&&c.resolution===i)return c;c?.texture.destroy();const u=this.state.device.createTexture({label:`renderer-color-target-${e}`,size:{width:o,height:l},format:n,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),d={name:e,format:n,width:o,height:l,scale:r,resolution:i,texture:u,view:u.createView()};return this.colorTargetCache.set(e,d),this.graphTextureResourceVersion+=1,d}ensureMsaaColorTarget(e){if(!this.state.device)throw new Error("Renderer is not initialized.");const t=this.getColorTargetDimensions(e),r=this.getColorTargetFormat(e),i=this.msaaColorTargetCache.get(e);if(i&&i.format===r&&i.width===t.width&&i.height===t.height&&1===i.scale)return i;i?.texture.destroy();const n=this.state.device.createTexture({label:`renderer-msaa-color-target-${e}`,size:{width:t.width,height:t.height},sampleCount:this.sampleCount,format:r,usage:GPUTextureUsage.RENDER_ATTACHMENT}),a={name:e,format:r,width:t.width,height:t.height,scale:1,texture:n,view:n.createView()};return this.msaaColorTargetCache.set(e,a),a}ensureMsaaDepthTarget(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=`${e}x${t}`,i=this.msaaDepthTargetCache.get(r);if(i&&i.width===e&&i.height===t&&i.sampleCount===this.sampleCount)return i;i?.texture.destroy();const n=this.state.device.createTexture({label:`renderer-msaa-depth-${r}`,size:{width:e,height:t},sampleCount:this.sampleCount,format:"depth32float",usage:GPUTextureUsage.RENDER_ATTACHMENT}),a={width:e,height:t,sampleCount:this.sampleCount,texture:n,view:n.createView()};return this.msaaDepthTargetCache.set(r,a),a}destroyMsaaResources(){for(const e of this.msaaColorTargetCache.values())e.texture.destroy();this.msaaColorTargetCache.clear();for(const e of this.msaaDepthTargetCache.values())e.texture.destroy();this.msaaDepthTargetCache.clear()}getColorTargetView(e){if("sceneColor"===e){if(!this.state.sceneColorView)throw new Error("Scene color target is not available.");return this.state.sceneColorView}if("postProcessColor"===e){if(!this.state.postProcessColorView)throw new Error("Post-process color target is not available.");return this.state.postProcessColorView}const t=this.colorTargetCache.get(e);if(!t)throw new Error(`Color target "${e}" has not been defined.`);return t.view}ensureTextureTarget(e,t={}){if("2d"===(t.dimension??"2d")&&null==t.usage)return this.ensureColorTarget(e,t);if(!this.state.device)throw new Error("Renderer is not initialized.");const r=t.scale??1,i=t.resolution??"render",n="presentation"===i?this.state.presentationWidth:this.state.width,a="presentation"===i?this.state.presentationHeight:this.state.height,s=Math.max(1,Math.floor(n*r)),o=Math.max(1,Math.floor(a*r)),l=Math.max(1,t.depthOrArrayLayers??1),c=t.format??D,u=this.colorTargetCache.get(e),d=t.dimension??"2d",h=t.usage??GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.COPY_SRC;if(u&&u.format===c&&u.width===s&&u.height===o&&u.resolution===i&&u.dimension===d&&u.depthOrArrayLayers===l&&u.usage===h)return u;u?.texture.destroy();const p=this.state.device.createTexture({label:`renderer-texture-target-${e}`,size:{width:s,height:o,depthOrArrayLayers:l},dimension:d,format:c,usage:h}),f={name:e,format:c,width:s,height:o,scale:r,resolution:i,dimension:d,depthOrArrayLayers:l,usage:h,texture:p,view:p.createView({dimension:d})};return this.colorTargetCache.set(e,f),this.graphTextureResourceVersion+=1,f}getColorTargetTexture(e){if("sceneColor"===e){if(!this.state.sceneColorTexture)throw new Error("Scene color target is not available.");return this.state.sceneColorTexture}if("postProcessColor"===e){if(!this.state.postProcessColorTexture)throw new Error("Post-process color target is not available.");return this.state.postProcessColorTexture}const t=this.colorTargetCache.get(e);if(!t)throw new Error(`Color target "${e}" has not been defined.`);return t.texture}getColorTargetDimensions(e){if("sceneColor"===e||"postProcessColor"===e)return{width:this.state.width,height:this.state.height};const t=this.colorTargetCache.get(e);if(!t)throw new Error(`Color target "${e}" has not been defined.`);return{width:t.width,height:t.height}}getColorTargetFormat(e){if(!this.state.format)throw new Error("Renderer is not initialized.");if("sceneColor"===e||"postProcessColor"===e)return D;const t=this.colorTargetCache.get(e);if(!t)throw new Error(`Color target "${e}" has not been defined.`);return t.format}getMaterialGraphTextureReads(e){const t=this.materialGraphTextureReadCache.get(e);if(t?.materialVersion===e.version)return t.resources;const r=e.getGraphTextureInputs(),i=[];for(const e in r){const t=r[e].resource;i.includes(t)||i.push(t)}return this.materialGraphTextureReadCache.set(e,{materialVersion:e.version,resources:i}),i}createGraphBuilderContext(e,t,r,i,n,a,s,o,l){let c=!1;const u=()=>{c||(c=!0,e.addPass(new id("TiledPointLightsPass",()=>{this.tiledLightingEnabled&&s.lights.points.length>0&&this.tiledPointLights.execute(t)},{writes:["tiledPointLights"]})))};let d=!1,h=!1;const p=e=>{const t=new Set;for(let r=0;r<e.length;r+=1){const i=this.getMaterialGraphTextureReads(e[r].material);for(let e=0;e<i.length;e+=1)t.add(i[e])}return Array.from(t)},f={device:this.state.device,encoder:t,camera:s.camera,sceneColorView:this.state.sceneColorView,postProcessColorView:this.state.postProcessColorView,presentationColorView:a,depthView:this.state.mainDepthView,colorFormat:D,width:this.state.width,height:this.state.height,presentationWidth:this.state.presentationWidth,presentationHeight:this.state.presentationHeight,linearClampSampler:this.state.linearClampSampler,nearestClampSampler:this.state.nearestClampSampler,comparisonSampler:this.state.shadowComparisonSampler,getColorView:e=>this.getColorTargetView(e),getTextureView:e=>this.getGraphTextureView(e),getExternalTexture:e=>{const t=this.textureManager.getTextureResource(e);return{view:t.view,sampler:t.sampler}},getGeometryVertexBuffer:(e,t)=>this.getGeometryResource(e)[t],getSkeletonBoneBuffer:this.getSkeletonBoneBufferForPass,getColorFormat:e=>this.getColorTargetFormat(e),getShadowMapDebugInfo:()=>({directional:{view:this.state.directionalShadowView,size:this.state.directionalShadowTextureSize,layerCount:4,activeLightCount:s.lights.directionals.length,activeLayerCount:s.lights.directionals.length},point:{view:this.state.pointShadowArrayView,size:this.state.pointShadowTextureSize,layerCount:24,activeLightCount:Math.min(4,s.lights.points.length),activeLayerCount:6*Math.min(4,s.lights.points.length)},spot:{view:this.state.spotShadowView,size:this.state.spotShadowTextureSize,layerCount:4,activeLightCount:Math.min(4,s.lights.spots.length),activeLayerCount:Math.min(4,s.lights.spots.length)}}),getSceneLightingResources:()=>{if(!(this.state.cameraBuffer&&this.state.lightBuffer&&this.state.shadowComparisonSampler&&this.state.linearClampSampler&&this.state.directionalShadowView&&this.state.pointShadowArrayView&&this.state.spotShadowView&&this.state.spotLightMapView))throw new Error("Renderer scene lighting resources are not initialized.");return{cameraBuffer:this.state.cameraBuffer,lightBuffer:this.state.lightBuffer,shadowSampler:this.state.shadowComparisonSampler,linearSampler:this.state.linearClampSampler,directionalShadowView:this.state.directionalShadowView,pointShadowView:this.state.pointShadowArrayView,spotShadowView:this.state.spotShadowView,spotLightMapView:this.state.spotLightMapView}}};return{fogVolumeObjects:s.fogVolumeObjects,extractedLights:s.lights,addDirectionalShadowPass:()=>{e.addPass(new id("DirectionalShadowPass",()=>{this.executeDirectionalShadowPass(t,i,s,o)},{writes:["directionalShadow"]}))},addPointShadowPass:()=>{s.lights.points.some(e=>e.castShadow)&&e.addPass(new id("PointShadowPass",()=>{this.executePointShadowPass(t,i,s,o)},{writes:["pointShadow"]}))},addSpotShadowPass:()=>{s.lights.spots.some(e=>e.castShadow)&&e.addPass(new id("SpotShadowPass",()=>{this.executeSpotShadowPass(t,i,s,o)},{writes:["spotShadow"]}))},addDepthPrepass:()=>{d=!0,this.getHiZOcclusionCullingActive()&&this.hasEnabledStaticDrawSets()&&e.addPass(new id("TemporalStaticVisibilityPrepass",()=>{this.executeStaticVisibilityPasses(t,"prepass")},{reads:["hiz"],writes:["staticIndirectArgs"]})),e.addPass(new id("DepthPrepass",()=>{this.executeDepthPrepass(t,r,s,o)},{writes:["mainDepth"]}))},addHiZPasses:()=>{this.getHiZOcclusionCullingActive()&&e.addPass(new id("HiZPasses",()=>{this.executeHiZPasses(t)},{reads:["mainDepth"],writes:["hiz"]}))},addVisibilityPass:()=>{this.getHiZOcclusionCullingActive()&&(n||this.hasEnabledStaticDrawSets())&&(e.addPass(new id("VisibilityPass",()=>{n&&this.executeVisibilityPass(t,n),this.executeStaticVisibilityPasses(t,"postpass")},{reads:["hiz"],writes:["indirectArgs","staticIndirectArgs"]})),this.sampleCount>1&&this.hasEnabledStaticDrawSets()&&e.addPass(new id("TemporalStaticDepthResolvePass",()=>{this.executeStaticTemporalDepthResolvePass(t)},{reads:["staticIndirectArgs"],writes:["mainDepth"]})))},defineColorTarget:(e,t={})=>{this.ensureColorTarget(e,t)},defineTextureTarget:(e,t={})=>{this.ensureTextureTarget(e,t)},addForwardPass:(i="sceneColor")=>{u();const n=!d,a=[...s.gpuOpaqueDraws,...s.directOpaqueDraws,...s.transparentDraws],c=p(a);if(l?.push({draws:a,colorTargetFormats:[this.getColorTargetFormat(i)],sampleCount:this.sampleCount,staticDrawStage:"all"}),c.includes("mainDepth")){if(!d)throw new Error("Materials that sample mainDepth require a depth prepass.");e.addPass(new id("ForwardDepthSnapshotPass",()=>{this.state.mainDepthTexture&&this.state.sceneDepthSnapshotTexture&&t.copyTextureToTexture({texture:this.state.mainDepthTexture},{texture:this.state.sceneDepthSnapshotTexture},{width:this.state.width,height:this.state.height})},{reads:["mainDepth"],writes:["sceneDepthSnapshot"]})),h=!0}e.addPass(new id("ForwardPass",()=>{this.executeForwardPass(t,i,this.getColorTargetView(i),r,s,o,n)},{reads:["tiledPointLights","directionalShadow","pointShadow","spotShadow","mainDepth","indirectArgs",...c.map(e=>"mainDepth"===e?"sceneDepthSnapshot":e)],writes:[i]})),this.getHiZOcclusionCullingActive()&&this.hasEnabledStaticDrawSets()&&e.addPass(new id("TemporalHiZHistoryPass",()=>{this.executeHiZPasses(t,!0)},{reads:["mainDepth"],writes:["hiz"],dependsOn:["ForwardPass"]}))},addOpaquePass:(i="sceneColor")=>{u();const n=!d,a=[...s.gpuOpaqueDraws,...s.directOpaqueDraws],c=p(a);if(l?.push({draws:a,colorTargetFormats:[this.getColorTargetFormat(i)],sampleCount:this.sampleCount,staticDrawStage:"opaque"}),c.includes("mainDepth")){if(!d)throw new Error("Materials that sample mainDepth require a depth prepass.");e.addPass(new id("OpaqueDepthSnapshotPass",()=>{this.state.mainDepthTexture&&this.state.sceneDepthSnapshotTexture&&t.copyTextureToTexture({texture:this.state.mainDepthTexture},{texture:this.state.sceneDepthSnapshotTexture},{width:this.state.width,height:this.state.height})},{reads:["mainDepth"],writes:["sceneDepthSnapshot"]})),h=!0}e.addPass(new id("OpaquePass",()=>{this.executeForwardPass(t,i,this.getColorTargetView(i),r,s,o,n,"opaque")},{reads:["tiledPointLights","directionalShadow","pointShadow","spotShadow","mainDepth","indirectArgs",...c.map(e=>"mainDepth"===e?"sceneDepthSnapshot":e)],writes:[i]}))},addSceneTextureCopyPass:(r="sceneColor",i)=>{const n=this.staticDrawSets.filter(e=>e.publicSet.enabled&&"late"===e.drawStage).flatMap(e=>e.draws),a=[...s.transparentDraws,...n],o=p(a),l=o.includes("physicalTransmissionSnapshot");l&&this.ensureTransmissionSnapshot();const c=!0===i?.sceneColor||a.some(e=>e.material.usesSceneColor()),u=!0===i?.sceneDepth||a.some(e=>e.material.usesSceneDepth()),d=o.includes("mainDepth");if(!(l||c||u||d))return;const f=this.getColorTargetDimensions(r);if(f.width!==this.state.width||f.height!==this.state.height||this.getColorTargetFormat(r)!==D)throw new Error("Scene texture snapshots currently require a full-resolution rgba16float source.");e.addPass(new id("SceneTextureCopyPass",()=>{if(l&&this.copyTransmissionSnapshot(t,this.getColorTargetView(r)),c){const e=this.getColorTargetView(r);let i=this.state.sceneColorSnapshotBindGroups.get(e);i||(i=this.state.device.createBindGroup({label:"renderer-scene-color-snapshot-bind-group",layout:this.state.fullscreenTextureBindGroupLayout,entries:[{binding:0,resource:this.state.linearClampSampler},{binding:1,resource:e}]}),this.state.sceneColorSnapshotBindGroups.set(e,i));const n=t.beginRenderPass({label:"renderer-scene-color-snapshot-pass",colorAttachments:[{view:this.state.sceneColorSnapshotView,loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}]});n.setPipeline(this.state.sceneColorSnapshotPipeline),n.setBindGroup(0,i),n.draw(3),n.end()}u&&this.executeHiZPasses(t,!1,!0),d&&this.state.mainDepthTexture&&this.state.sceneDepthSnapshotTexture&&t.copyTextureToTexture({texture:this.state.mainDepthTexture},{texture:this.state.sceneDepthSnapshotTexture},{width:this.state.width,height:this.state.height})},{reads:[...c||l?[r]:[],...u||d?["mainDepth"]:[]],writes:[...c?["sceneColorSnapshot"]:[],...l?["physicalTransmissionSnapshot"]:[],...u||d?["sceneDepthSnapshot"]:[]]})),(u||d)&&(h=!0)},addLatePass:(i="sceneColor")=>{const n=this.staticDrawSets.filter(e=>e.publicSet.enabled&&"late"===e.drawStage).flatMap(e=>e.draws);if(0===s.transparentDraws.length&&0===n.length)return;l?.push({draws:s.transparentDraws,colorTargetFormats:[this.getColorTargetFormat(i)],sampleCount:1,staticDrawStage:"late"});const a=[...s.transparentDraws,...n],c=[i,"mainDepth",...p(a)];a.some(e=>e.material.usesSceneColor())&&c.push("sceneColorSnapshot"),a.some(e=>e.material.usesSceneDepth())&&c.push("sceneDepthSnapshot"),e.addPass(new id("LatePass",()=>{this.executeForwardPass(t,i,this.getColorTargetView(i),r,s,o,!1,"late",!0,1)},{reads:c,writes:[i,"mainDepth"]}))},addHiZHistoryPass:(r="ForwardPass")=>{if(!this.getHiZOcclusionCullingActive()||!this.hasEnabledStaticDrawSets())return;const i="LatePass"===r&&0===s.transparentDraws.length?"OpaquePass":r;e.addPass(new id("TemporalHiZHistoryPass",()=>{this.executeHiZPasses(t,!0)},{reads:["mainDepth"],writes:["hiz"],dependsOn:[i]}))},addMaterialPass:(i={})=>{u();const n="string"==typeof i.outputs?[i.outputs]:Array.from(i.outputs??["sceneColor"]),a=i.drawStage??"all",c="opaque"===a?[...s.gpuOpaqueDraws,...s.directOpaqueDraws]:"late"===a?s.transparentDraws:[...s.gpuOpaqueDraws,...s.directOpaqueDraws,...s.transparentDraws],d=i.objectFilter?c.filter(e=>i.objectFilter(e.sourceObject)||!0===e.sourceRanges?.some(e=>i.objectFilter(e.sourceObject))):c,h=e=>"function"==typeof i.overrideMaterial?i.overrideMaterial(e.material,null!==e.skinning):i.overrideMaterial,p=i.overrideMaterial?d.map(e=>({...e,material:h(e)})):d;l?.push({draws:p,colorTargetFormats:n.map(e=>this.getColorTargetFormat(e)),sampleCount:this.sampleCount,staticDrawStage:a}),e.addPass(new id(i.name??"MaterialPass",()=>{this.executeMaterialPass(t,n,r,s,o,i)},{reads:["tiledPointLights","directionalShadow","pointShadow","spotShadow",..."late"!==a?["indirectArgs","staticIndirectArgs"]:[],...i.loadDepth?["mainDepth"]:[],...i.loadColor?n:[]],writes:this.sampleCount>1?n:[...n,"mainDepth"]}))},addCustomPass:t=>{e.addPass(new id(t.name,()=>{t.execute(f)},{reads:t.reads,writes:t.writes,dependsOn:t.dependsOn}))},addPresentPass:(r="sceneColor")=>{e.addPass(new id("PresentPass",()=>{const e=this.getColorTargetView(r);this.executePresentPass(t,e,a)},{reads:[r],writes:["mainColor"]}))}}}transparentDraws=[];opaqueBatches=new Map;acquireDrawCall(){const e=this.drawCallPoolCount;this.drawCallPoolCount+=1;let t=this.drawCallPool[e];return t||(t={geometry:null,geometryKey:{},geometryResource:null,material:null,customDepthMaterial:null,residentInstanceBinding:null,sourceObject:null,frontFaceCW:!1,usesBatching:!1,geometryGroup:null,batchKey:"",batchHash:0,indexed:!1,wireframe:!1,start:0,count:0,transparent:!1,renderOrder:0,hasRenderCallbacks:!1,castShadow:!0,receiveShadow:!0,sortMaterialId:0,sortGeometryId:0,sortCustomDepthMaterialId:0,skinning:null,materialResource:null,instanceStart:0,instanceCount:0,boundsCenter:new uu,boundsRadius:0,sortDepth:0,transparentSortGroup:0,transparentSortOrder:0},this.drawCallPool[e]=t),t}acquireOpaqueBatchBuilder(){const e=this.opaqueBatchPoolCount;this.opaqueBatchPoolCount+=1;let t=this.opaqueBatchPool[e];return t||(t={template:null,totalInstanceCount:0,rangePairCount:0,firstInstanceStart:0,firstInstanceCount:0,sourceRanges:[],boundsMin:new uu,boundsMax:new uu},this.opaqueBatchPool[e]=t),t}populateDrawCall(e,t,r,i,n,a,s,o){const l=t.wireframe;l&&this.ensureWireframeIndex(t.geometry,t.geometryResource);const c=t.sourceObject?Boolean(t.sourceObject.receiveShadow):t.receiveShadow;return this.shouldInvalidateDrawMaterialResource(e,t.material,c,t.usesBatching,null)&&(e.materialResource=null),e.geometry=t.geometry,e.geometryKey=l?t.geometryResource.wireframeIndex:t.geometryKey,e.geometryResource=t.geometryResource,e.material=t.material,e.customDepthMaterial=t.customDepthMaterial,e.residentInstanceBinding=t.residentInstanceBinding,e.sourceObject=t.sourceObject,e.cameraDetailRejected=t.cameraDetailRejected,e.detailCulling=g(t.sourceObject),e.frontFaceCW=null!==t.sourceObject&&!0===t.sourceObject.isMesh?t.sourceObject.matrixWorld.determinant()<0:t.frontFaceCW,e.usesBatching=t.usesBatching,e.geometryGroup=t.geometryGroup,e.batchKey=t.batchKey,e.batchHash=t.batchHash,e.indexed=l||t.indexed,e.wireframe=l,e.start=l?2*t.start:t.start,e.count=l?2*t.count:t.count,e.transparent=t.transparent,e.renderOrder=t.sourceObject?.renderOrder??t.renderOrder,e.hasRenderCallbacks=this.hasRenderCallbacks(t.sourceObject),e.castShadow=t.sourceObject?Boolean(t.sourceObject.castShadow):t.castShadow,e.receiveShadow=c,e.sortMaterialId=t.sortMaterialId,e.sortGeometryId=t.sortGeometryId,e.sortCustomDepthMaterialId=t.sortCustomDepthMaterialId,e.skinning=null,e.instanceStart=r,e.instanceCount=i,e.boundsCenter.set(n,a,s),e.boundsRadius=o,e.sortDepth=0,e.transparentSortGroup=0,e.transparentSortOrder=0,e.sourceRanges=void 0,e}populateDynamicDrawCall(e,t,r,i,n,a,s,o,l,c,u,d,h,p,f,m,v,x,w,b,y,S,C,M,P,B,D,T,I=null){const V=!0===o?.isBatchedMesh,G=n.wireframe&&"triangle-list"===n.primitiveTopology;return G&&this.ensureWireframeIndex(t,i),this.shouldInvalidateDrawMaterialResource(e,n,w,V,I)&&(e.materialResource=null),e.geometry=t,e.geometryKey=G?i.wireframeIndex:r,e.geometryResource=i,e.material=n,e.customDepthMaterial=a,e.residentInstanceBinding=s,e.sourceObject=o,e.cameraDetailRejected=void 0,e.detailCulling=g(o),e.frontFaceCW=null!==o&&!0===o.isMesh&&o.matrixWorld.determinant()<0,e.usesBatching=V,e.geometryGroup=l,e.batchKey=c,e.batchHash=u,e.indexed=G||d,e.wireframe=G,e.start=G?2*h:h,e.count=G?2*p:p,e.transparent=f,e.renderOrder=m,e.hasRenderCallbacks=v,e.castShadow=x,e.receiveShadow=w,e.sortMaterialId=b,e.sortGeometryId=y,e.sortCustomDepthMaterialId=S,e.skinning=I,e.instanceStart=C,e.instanceCount=M,e.boundsCenter.set(P,B,D),e.boundsRadius=T,e.sortDepth=0,e.transparentSortGroup=0,e.transparentSortOrder=0,e.sourceRanges=void 0,e}pushOpaqueDrawTemplate(e,t,r,i,n,a,s){e.detailCulling=g(e.sourceObject),e.cameraDetailRejected=!v(F.set(i,n,a),s,this.cameraViewProjScratch,this.state.width,this.state.height,this.transparentSortCameraPositionScratch,e.detailCulling.minScreenSize*(e.sourceObject&&this.cameraDetailHistory.get(e.sourceObject)?.85:1.15),e.detailCulling.maxDistance),e.sourceObject&&this.cameraDetailHistory.set(e.sourceObject,!e.cameraDetailRejected);const o=e.batchHash,l=this.opaqueBatches.get(o);let c=null;if(l)if(Array.isArray(l))for(let t=0;t<l.length;t+=1){const r=l[t];if(fi(r.template,e)){c=r;break}}else fi(l.template,e)&&(c=l);if(c){if(c.totalInstanceCount+=r,1===c.rangePairCount){const e=c.sourceRanges;e.length=4,e[0]=c.firstInstanceStart,e[1]=c.firstInstanceCount,e[2]=t,e[3]=r}else{const e=c.sourceRanges,i=2*c.rangePairCount;e[i]=t,e[i+1]=r}c.rangePairCount+=1;const e=c.boundsMin,o=c.boundsMax,l=i-s,u=n-s,d=a-s,h=i+s,p=n+s,f=a+s;return l<e.x&&(e.x=l),u<e.y&&(e.y=u),d<e.z&&(e.z=d),h>o.x&&(o.x=h),p>o.y&&(o.y=p),void(f>o.z&&(o.z=f))}const u=this.acquireOpaqueBatchBuilder();u.template=e,u.totalInstanceCount=r,u.rangePairCount=1,u.firstInstanceStart=t,u.firstInstanceCount=r,u.sourceRanges.length=0,u.boundsMin.set(i-s,n-s,a-s),u.boundsMax.set(i+s,n+s,a+s),l?Array.isArray(l)?l.push(u):this.opaqueBatches.set(o,[l,u]):this.opaqueBatches.set(o,u)}pushDraw(e){e.transparent?this.transparentDraws.push(e):e.skinning||e.hasRenderCallbacks&&e.residentInstanceBinding?this.directOpaqueDrawsScratch.push(e):e.residentInstanceBinding?this.residentOpaqueDrawsScratch.push(e):this.stagedOpaqueDrawsScratch.push(e)}getToonOutlineParameters(e){if(!e||!e.visible||!0===e.wireframe||!e.depthTest)return null;const t=e.userData?.outlineParameters;return t&&!1!==t.visible?t:null}getToonOutlineMaterial(e,t){const r=this.getToonOutlineParameters(e);if(!r)return null;if("darkenedAlbedo"===r.colorMode){let t=this.outlineResolvedFrameCache.get(e);if(!t||t.extractionVersion!==this.extractionVersion){const r=this.materialResolver?.(e,"outline");t?(t.extractionVersion=this.extractionVersion,t.material=r):(t={extractionVersion:this.extractionVersion,material:r},this.outlineResolvedFrameCache.set(e,t))}const r=t.material;if(r)return r}let i=this.toonOutlineMaterialCache.get(e);if(!i){const t=t=>new Ir({vertexShader:t?"\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @location(4) skinIndex: vec4<u32>,\n @location(5) skinWeight: vec4<f32>,\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n let localPosition = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight);\n let localNormal = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n let worldPosition = rendererWorldPosition(localPosition, input.instanceIndex);\n let viewPosition = rendererCamera.view * worldPosition;\n let worldNormal = rendererWorldNormal(localNormal, input.instanceIndex);\n let viewNormal = normalize((rendererCamera.view * vec4(worldNormal, 0.0)).xyz);\n let distanceScale = sqrt(max(length(viewPosition.xyz), 0.0001)) * 0.5;\n let displaced = viewPosition.xyz + viewNormal * materialUniforms.outlineThickness * distanceScale;\n return VertexOutput(rendererCamera.projection * vec4(displaced, 1.0));\n}\n":"\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n let worldPosition = rendererWorldPosition(input.position, input.instanceIndex);\n let viewPosition = rendererCamera.view * worldPosition;\n let worldNormal = rendererWorldNormal(input.normal, input.instanceIndex);\n let viewNormal = normalize((rendererCamera.view * vec4(worldNormal, 0.0)).xyz);\n let distanceScale = sqrt(max(length(viewPosition.xyz), 0.0001)) * 0.5;\n let displaced = viewPosition.xyz + viewNormal * materialUniforms.outlineThickness * distanceScale;\n return VertexOutput(rendererCamera.projection * vec4(displaced, 1.0));\n}\n",fragmentShader:"\n@fragment\nfn fsMain() -> @location(0) vec4<f32> {\n return vec4(materialUniforms.outlineColor, materialUniforms.outlineAlpha);\n}\n",vertexAttributes:t?Dh:[{name:"position",shaderLocation:0,format:"float32x3"},{name:"normal",shaderLocation:1,format:"float32x3",defaultValue:[0,0,1]}],uniforms:{outlineThickness:r.thickness??.003,outlineColor:(new Zc).fromArray(r.color??[0,0,0]),outlineAlpha:r.alpha??e.opacity},side:Hc,depthTest:!0,depthWrite:!0,transparent:!0});i={regular:t(!1),skinned:t(!0)},this.toonOutlineMaterialCache.set(e,i)}const n=t?i.skinned:i.regular;return n.uniforms.outlineThickness.value=r.thickness??.003,n.uniforms.outlineColor.value.fromArray(r.color??[0,0,0]),n.uniforms.outlineAlpha.value=r.alpha??e.opacity,n}pushToonOutlineDraw(e,t){const r=t?this.getToonOutlineMaterial(t,null!==e.skinning):null;if(!r||e.usesBatching)return;const i=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e.geometryKey,e.geometryResource,r,null,e.residentInstanceBinding,e.sourceObject,e.geometryGroup,"",0,e.indexed,e.start,e.count,!0,e.renderOrder,!1,!1,!1,oi(r),e.sortGeometryId,0,e.instanceStart,e.instanceCount,e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius,e.skinning);this.transparentDraws.push(i)}updateTransparentDrawSortDepths(e,t,r){for(let i=0;i<e.length;i+=1){const n=e[i];0===n.transparentSortGroup&&(n.sortDepth=(n.boundsCenter.x-t.x)*r.x+(n.boundsCenter.y-t.y)*r.y+(n.boundsCenter.z-t.z)*r.z)}}extractScene(e,t,r=!1){this.extractionVersion+=1,this.drawCallPoolCount=0,this.opaqueBatchPoolCount=0;this.opaqueBatches.clear();const i=this.transparentDraws;i.length=0;const n=this.residentInstanceUploadsScratch;n.length=0;const a=this.sourceInstanceDataScratch;a.reset();const s=this.gpuOpaqueDrawsScratch;s.length=0;const o=this.directOpaqueDrawsScratch;o.length=0;const l=this.stagedOpaqueDrawsScratch;l.length=0;const c=this.residentOpaqueDrawsScratch;c.length=0;const u=this.opaqueInstanceDataScratch;u.reset();const d=this.finalInstanceDataScratch;d.reset();const h=this.extractedAmbientScratch;h.set(0,0,0,0);let p=null;const f=this.activeDirectionalLightsScratch,m=this.activePointLightsScratch,x=this.activeSpotLightsScratch,w=this.fogVolumeObjectsScratch;f.length=0,m.length=0,x.length=0,w.length=0;const b=this.extractedBoundsMinScratch;b.set(1/0,1/0,1/0);const C=this.extractedBoundsMaxScratch;C.set(-1/0,-1/0,-1/0),function(e,t){const r=e.elements,i=r[0],n=r[1],a=r[2],s=r[3],o=r[4],l=r[5],c=r[6],u=r[7],d=r[8],h=r[9],p=r[10],f=r[11],m=r[12],g=r[13],v=r[14],x=r[15];Si(t,0,s-i,u-o,f-d,x-m),Si(t,4,s+i,u+o,f+d,x+m),Si(t,8,s+n,u+l,f+h,x+g),Si(t,12,s-n,u-l,f-h,x-g),Si(t,16,s-a,u-c,f-p,x-v),Si(t,20,a,c,p,v)}(yi(t,this.cameraViewProjScratch),this.cameraFrustumPlanesScratch);const M=this.transparentSortCameraPositionScratch,P=this.transparentSortCameraForwardScratch;t.getWorldPosition(M),t.getWorldDirection(P);const B=r?this.isSphereVisibleForCompilationScratch:this.isSphereVisibleScratch,D=this.updateExtractedBoundsFromMatrixScratch,T=this.objectTraversalStackScratch;T.length=0,T.push(e);for(let e=this.csmCascadeLights.length-1;e>=0;e-=1)T.push(this.csmCascadeLights[e]);for(;T.length>0;){const e=T.pop();if(this.extractingCaster=e.castShadow,!e.visible)continue;const r=0!==(e.layers.mask&t.layers.mask);if(!0===e.isFogVolumeObject&&null!=e.volume)w.push(e);else if(e.isAmbientLight){if(r){const t=e;h.x+=t.color.r*t.intensity,h.y+=t.color.g*t.intensity,h.z+=t.color.b*t.intensity,h.w=1}}else if(e.isHemisphereLight){if(r&&null==p){const t=e,r=this.extractedHemisphereScratch;F.setFromMatrixPosition(t.matrixWorld),r.direction.copy(F),r.direction.lengthSq()<=1e-10?r.direction.set(0,1,0):r.direction.normalize(),r.skyColor.set(t.color.r,t.color.g,t.color.b),r.groundColor.set(t.groundColor.r,t.groundColor.g,t.groundColor.b),r.intensity=t.intensity,p=r}}else if(e.isDirectionalLight){if(r&&f.length<4&&!this.hasExtractedDirectionalLight(f,e)){const t=e,r=t.shadow,i=r.camera,n=this.extractedDirectionalLightsScratch[f.length];n.sourceLight=t,t.target.matrixWorldAutoUpdate&&t.target.updateMatrixWorld(!0),F.setFromMatrixPosition(t.matrixWorld),$.setFromMatrixPosition(t.target.matrixWorld),n.position.copy(F),n.target.copy($),n.direction.copy($).sub(F).normalize(),n.color.set(t.color.r,t.color.g,t.color.b),n.intensity=t.intensity,n.volumetricIntensity=t.userData?.volumetricIntensity??0,n.castShadow=t.castShadow&&this.directionalShadowsEnabled,n.shadowBias=r.bias,n.shadowNormalBias=r.normalBias,n.shadowRadius=r.radius,n.shadowIntensity=r.intensity,n.shadowMapSize=Math.max(1,r.mapSize.width,r.mapSize.height),n.shadowCameraLeft=i.left,n.shadowCameraRight=i.right,n.shadowCameraTop=i.top,n.shadowCameraBottom=i.bottom,n.shadowCameraNear=i.near,n.shadowCameraFar=i.far,f.push(n)}}else if(e.isPointLight){if(r&&m.length<y){const t=e,r=t.shadow,i=r.camera;F.setFromMatrixPosition(t.matrixWorld);const n=t.distance>0?t.distance:Math.max(i.far,25);if(!Ci(this.cameraFrustumPlanesScratch,F.x,F.y,F.z,n))continue;const a=this.extractedPointLightsScratch[m.length];a.sourceLight=t,a.position.copy(F),a.color.set(t.color.r,t.color.g,t.color.b),a.intensity=t.intensity,a.volumetricIntensity=t.userData?.volumetricIntensity??0,a.distance=t.distance,a.range=n,a.decay=t.decay,a.castShadow=t.castShadow,a.shadowBias=r.bias,a.shadowNormalBias=r.normalBias,a.shadowRadius=r.radius,a.shadowIntensity=r.intensity,a.shadowMapSize=Math.max(1,r.mapSize.width,r.mapSize.height),a.shadowCameraNear=i.near,a.shadowCameraFar=t.distance>0?t.distance:i.far,m.push(a)}}else if(e.isSpotLight){if(r&&x.length<S){const t=e,r=t.shadow,i=r.camera,n=this.extractedSpotLightsScratch[x.length];n.sourceLight=t,t.target.matrixWorldAutoUpdate&&t.target.updateMatrixWorld(!0),F.setFromMatrixPosition(t.matrixWorld),$.setFromMatrixPosition(t.target.matrixWorld);const a=t.distance>0?t.distance:i.far;if(!Ci(this.cameraFrustumPlanesScratch,F.x,F.y,F.z,a))continue;n.position.copy(F),n.direction.copy($).sub(F).normalize(),n.color.set(t.color.r,t.color.g,t.color.b),n.intensity=t.intensity,n.volumetricIntensity=t.userData?.volumetricIntensity??0,n.range=a,n.angle=t.angle,n.penumbra=t.penumbra,n.decay=t.decay,n.castShadow=t.castShadow,n.shadowBias=r.bias,n.shadowNormalBias=r.normalBias,n.shadowRadius=r.radius,n.shadowIntensity=r.intensity,n.shadowMapSize=Math.max(1,r.mapSize.width,r.mapSize.height),n.shadowCameraNear=i.near,n.shadowCameraFar=t.distance>0?t.distance:i.far,n.shadowCameraFov=t.angle*(360/Math.PI)*r.focus,n.map=t.map??null,x.push(n)}}else r&&e.isBatchedMesh?this.collectBatchedMesh(e,a,D,B,t,M,P):r&&e.isInstancedMesh?this.collectInstancedMesh(e,a,D,B):r&&e.isSkinnedMesh?this.collectSkinnedMesh(e,a,D,B):r&&e.isLine?this.collectLine(e,a,D,B):r&&e.isSprite?this.collectSprite(e,a,D,B):r&&e.isMesh&&this.collectMesh(e,a,D,B);const i=e.children;for(let e=i.length-1;e>=0;e-=1)T.push(i[e])}if(this.csmCascadeLights.length>0){const e=new Map;for(let t=0;t<this.csmCascadeLights.length;t+=1)e.set(this.csmCascadeLights[t],t);f.sort((t,r)=>((null==t.sourceLight?void 0:e.get(t.sourceLight))??4)-((null==r.sourceLight?void 0:e.get(r.sourceLight))??4))}const I=o.length;this.updateTransparentDrawSortDepths(i,M,P),i.sort(di),Number.isFinite(b.x)||(b.set(-6,-6,-6),C.set(6,6,6)),this.sortOpaqueDraws(l);for(let e=0;e<l.length;){const t=l[e],r=u.instanceCount;u.appendRange(a,t.instanceStart,t.instanceCount);let i,n=t.instanceCount,c=t.boundsCenter.x-t.boundsRadius,d=t.boundsCenter.y-t.boundsRadius,h=t.boundsCenter.z-t.boundsRadius,p=t.boundsCenter.x+t.boundsRadius,f=t.boundsCenter.y+t.boundsRadius,m=t.boundsCenter.z+t.boundsRadius,g=e+1;for(;this.dynamicBatchingEnabled&&g<l.length&&mi(t,l[g]);){const e=l[g];u.appendRange(a,e.instanceStart,e.instanceCount),i??=[{sourceObject:t.sourceObject,instanceStart:r,instanceCount:t.instanceCount}],i.push({sourceObject:e.sourceObject,instanceStart:r+n,instanceCount:e.instanceCount}),n+=e.instanceCount;const s=e.boundsCenter.x-e.boundsRadius,o=e.boundsCenter.y-e.boundsRadius,v=e.boundsCenter.z-e.boundsRadius,x=e.boundsCenter.x+e.boundsRadius,w=e.boundsCenter.y+e.boundsRadius,b=e.boundsCenter.z+e.boundsRadius;s<c&&(c=s),o<d&&(d=o),v<h&&(h=v),x>p&&(p=x),w>f&&(f=w),b>m&&(m=b),g+=1}const v=.5*(c+p),x=.5*(d+f),w=.5*(h+m),b=p-v,y=f-x,S=m-w;t.instanceStart=r,t.instanceCount=n,t.sourceRanges=i,t.boundsCenter.set(v,x,w),t.boundsRadius=Math.sqrt(b*b+y*y+S*S),t.indexed&&!t.hasRenderCallbacks?s.push(t):o.push(t),e=g}this.sortOpaqueDraws(c);for(let e=0;e<c.length;e+=1){const t=c[e];t.indexed&&!t.hasRenderCallbacks?s.push(t):o.push(t)}d.appendBuilder(u);for(let e=0;e<I;e+=1){const t=o[e];if(t.residentInstanceBinding)continue;const r=d.instanceCount;d.appendRange(a,t.instanceStart,t.instanceCount),t.instanceStart=r}this.sortOpaqueDraws(s),this.sortOpaqueDraws(o);for(let e=0;e<i.length;e+=1){const t=i[e];if(t.residentInstanceBinding)continue;const r=d.instanceCount;d.appendRange(a,t.instanceStart,t.instanceCount),t.instanceStart=r}m.sort(Ph),x.sort(Ph);for(let e=4;e<m.length;e+=1)m[e].castShadow=!1;for(let e=4;e<x.length;e+=1)x[e].castShadow=!1;const V=this.extractedLightsScratch;V.hemisphere=p,V.directional=f[0]??null,V.point=m[0]??null,V.spot=x[0]??null;const G=this.extractedFrameScratch;G.scene=e,G.camera=t,G.fogVolumeObjects=w,G.transparentDraws=i,G.instanceData=d,G.residentInstanceUploads=n,this.extractingCaster=!1;const L=this.shadowDrawsScratch;L.length=0;for(const e of[s,o,i]){for(const t of e)t.castShadow&&!t.transparent&&L.push(t);if(!r){let t=0;for(const r of e){const i=r.detailCulling??g(r.sourceObject);!r.cameraDetailRejected&&this.isSphereVisibleScratch(r.boundsCenter.x,r.boundsCenter.y,r.boundsCenter.z,r.boundsRadius,r.sourceObject?.frustumCulled??!0)&&v(r.boundsCenter,r.boundsRadius,this.cameraViewProjScratch,this.state.width,this.state.height,M,!1===r.cameraDetailRejected?0:i.minScreenSize,i.maxDistance)&&(e[t++]=r)}e.length=t}}return G.shadowDraws=L,G}collectLine(e,t,r,i){if(Array.isArray(e.material)||!e.geometry.getAttribute("position"))return;const n=e.geometry,a=e.material;if(!1===a.visible)return;if((!0===a.isLineBasicMaterial||!0===a.isMeshBasicMaterial)&&!0!==a.isLineMaterial){const s=e.isLineSegments?"line-list":"line-strip",o=this.resolveLineBasicMaterial(a,s),l=`${$r(n)}:${s}`;let c=this.lineProxyCache.get(e);c&&c.sourceGeometry===n?c.signature!==l&&(c.signature=l):(c={signature:l,sourceGeometry:n,mesh:new iu(n,o)},this.lineProxyCache.set(e,c));const u=c.mesh;return u.material=o,u.matrixWorld.copy(e.matrixWorld),u.frustumCulled=e.frustumCulled,u.renderOrder=e.renderOrder,u.castShadow=!1,u.receiveShadow=!1,u.onBeforeRender=(...t)=>e.onBeforeRender(...t),void this.collectMesh(u,t,r,i)}const s=$r(n);let o=this.lineProxyCache.get(e);if(!o||o.sourceGeometry!==n||o.signature!==s){const t=n.getAttribute("position"),r=n.index,i=r?.count??t.count,a=Math.max(0,Math.min(i,n.drawRange.start)),l=Number.isFinite(n.drawRange.count)?n.drawRange.count:i-a,c=Math.max(a,Math.min(i,a+l)),u=e.isLineSegments?2:1,d=[],h=[],p=e=>r?r.getX(e):e;for(let e=a;e+1<c;e+=u){const r=p(e),i=p(e+1);d.push(t.getX(r),t.getY(r),t.getZ(r)),h.push(t.getX(i),t.getY(i),t.getZ(i))}const f=new Kc;f.setIndex([0,2,1,2,3,1,2,4,3,4,5,3,4,6,5,6,7,5]),f.setAttribute("position",new qc(new Float32Array([-1,2,0,1,2,0,-1,1,0,1,1,0,-1,0,0,1,0,0,-1,-1,0,1,-1,0]),3)),f.setAttribute("instanceStart",new Jc(new Float32Array(d),3)),f.setAttribute("instanceEnd",new Jc(new Float32Array(h),3)),f.instanceCount=d.length/3;const m=Mi(n);f.boundingSphere=new ou(m.center.clone(),m.radius),o={signature:s,sourceGeometry:n,mesh:new iu(f,e.material)},this.lineProxyCache.set(e,o)}const l=o.mesh;l.matrixWorld.copy(e.matrixWorld),l.frustumCulled=e.frustumCulled,l.renderOrder=e.renderOrder,l.castShadow=e.castShadow??!1,l.receiveShadow=e.receiveShadow??!1,l.onBeforeRender=(...t)=>e.onBeforeRender(...t),this.collectMesh(l,t,r,i)}collectSprite(e,t,r,i){let n=this.spriteProxyCache.get(e);if(!n){const t=e.geometry.clone();n={mesh:new iu(t,e.material),centerX:Number.NaN,centerY:Number.NaN},this.spriteProxyCache.set(e,n)}if(n.centerX!==e.center.x||n.centerY!==e.center.y){const t=n.mesh.geometry.getAttribute("position"),r=e.geometry.getAttribute("position");for(let i=0;i<t.count;i+=1)t.setXYZ(i,r.getX(i)+.5-e.center.x,r.getY(i)+.5-e.center.y,r.getZ(i));t.needsUpdate=!0,n.mesh.geometry.computeBoundingSphere(),n.centerX=e.center.x,n.centerY=e.center.y}const a=n.mesh;a.material=e.material,a.matrixWorld.copy(e.matrixWorld),a.frustumCulled=e.frustumCulled,a.renderOrder=e.renderOrder,a.castShadow=e.castShadow,a.receiveShadow=e.receiveShadow,a.onBeforeRender=(...t)=>e.onBeforeRender(...t),a.onAfterRender=(...t)=>e.onAfterRender(...t),this.collectMesh(a,t,r,i)}hasExtractedDirectionalLight(e,t){for(let r=0;r<e.length;r+=1)if(e[r].sourceLight===t)return!0;return!1}getObjectMotionHistory(e,t){let r=this.objectMotionHistory.get(e);if(!r)return r={matrix:new Float32Array(16),generation:this.motionVectorHistoryGeneration,lastExtractionVersion:-1,valid:!1},r.matrix.set(t),this.objectMotionHistory.set(e,r),r;const i=!0===e.userData.motionBlurTeleported;i&&(e.userData.motionBlurTeleported=!1);const n=(t[12]??0)-r.matrix[12],a=(t[13]??0)-r.matrix[13],s=(t[14]??0)-r.matrix[14],o=Math.max(0,Number(e.userData.motionBlurTeleportDistance??10));return r.valid=this.motionVectorHistoryValid&&r.generation===this.motionVectorHistoryGeneration&&r.lastExtractionVersion===this.extractionVersion-1&&!i&&n*n+a*a+s*s<=o*o,r}commitObjectMotionHistory(e,t){e.matrix.set(t),e.generation=this.motionVectorHistoryGeneration,e.lastExtractionVersion=this.extractionVersion}collectMesh(e,t,r,i){const n=e.geometry;if(void 0===n.attributes.position)return;const a=e.material,s=Array.isArray(a);if(!s&&!1===a.visible||s&&a.every(e=>!1===e.visible))return;const o=this.getGeometryResource(n),l=this.meshExtractionCache.get(e),c=l?.geometryResource===o?l:null,u=c?null:Mi(n),d=c?c.localBoundsCenter:u.center,h=c?c.localBoundsRadius:u.radius,p=e.matrixWorld.elements,f=d.x,m=d.y,g=d.z,v=p[0]*f+p[4]*m+p[8]*g+p[12],x=p[1]*f+p[5]*m+p[9]*g+p[13],w=p[2]*f+p[6]*m+p[10]*g+p[14],b=p[0]*p[0]+p[1]*p[1]+p[2]*p[2],y=p[4]*p[4]+p[5]*p[5]+p[6]*p[6],S=p[8]*p[8]+p[9]*p[9]+p[10]*p[10],C=h*Math.sqrt(Math.max(b,y,S,1e-10));if(!i(v,x,w,C,e.frustumCulled))return;const M=this.resolvedMeshMaterialsScratch;M.length=0;let P=null;if(s)for(let e=0;e<a.length;e+=1)M[e]=this.resolveMaterial(a[e]);else{if(!a.visible)return;P=this.resolveMaterial(a)}const B=Vi(e),D=l&&l.customDepthMaterial===B&&l.geometryResource.lastValidatedExtractionVersion===this.extractionVersion&&(!s&&l.material===a&&l.resolvedMaterial===P||s&&null!==l.materials&&null!==l.resolvedMaterials&&Nr(l.materials,a)&&qr(l.resolvedMaterials,M))?l:this.getMeshExtractionCacheEntry(e,a,P,M,B,o),T=D.templates.length;if(0===T)return;const I=function(e){const t=e.attributes;let r=!1,i=1/0;for(const e in t){const n=t[e];!0!==n.isInstancedBufferAttribute&&!0!==n.data?.isInstancedInterleavedBuffer||(r=!0,n.count<i&&(i=n.count))}if(!r)return 1;const n=e.instanceCount;return Number.isFinite(n)?Math.max(0,Math.floor(n)):Math.max(0,i)}(n),V=this.getObjectMotionHistory(e,p),G=Sh(e),L=Ch(e);let z=0,R=null;if(!(n instanceof Qc&&I>1)||e instanceof su||this.hasRenderCallbacks(e))for(let e=0;e<I;e+=1){const r=ni(t,p,1,1,1,1,void 0,V.matrix,G,L,V.valid?1:0);0===e&&(z=r)}else{let t=this.repeatedMeshInstances.get(e);if(!t||t.geometry!==n||t.data.disposed){t&&this.repeatedInstanceResources.get(t.data)?.();const r=new zi,i=()=>{n.removeEventListener("dispose",i),r.dispose(),this.repeatedInstanceResources.delete(r)};n.addEventListener("dispose",i),this.repeatedInstanceResources.set(r,i),t={geometry:n,data:r},this.repeatedMeshInstances.set(e,t)}R=t.data,R.update(I,p,V.matrix,G,L,V.valid?1:0),!R.residentBufferDirty&&R.residentInstanceBinding.buffer||this.residentInstanceUploadsScratch.push(R)}this.commitObjectMotionHistory(V,p),r(p);for(let e=0;e<T;e+=1){const t=D.templates[e],r=this.populateDrawCall(this.acquireDrawCall(),t,z,I,v,x,w,C);R&&(r.residentInstanceBinding=R.residentInstanceBinding),t.transparent?this.transparentDraws.push(r):this.pushDraw(r);const i=s?a[t.geometryGroup?.materialIndex??0]:a;this.pushToonOutlineDraw(r,i)}}prepareSceneForCompilation(e,t,r){if(!(this.state.initialized&&this.state.device&&this.state.context&&this.state.mainDepthView&&this.state.sceneColorView&&this.state.postProcessColorView&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.shadowCameraBuffer&&this.state.sceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.shadowComparisonSampler&&this.state.linearClampSampler&&this.state.nearestClampSampler&&this.state.visibilityParamsBuffer&&this.state.directionalShadowView&&this.state.pointShadowArrayView&&this.state.spotShadowView&&this.state.hizCopyKernel&&this.state.hizReduceKernel&&this.state.visibilityKernel&&this.state.presentPipeline))throw new Error("WebGpuRenderer.initialize() must complete before compile().");const i=r?this.pipelineCompilationDiagnostics:void 0;let n=performance.now();const a=e=>{i&&(i.phases[e]=Math.round(performance.now()-n)),n=performance.now()};e.matrixWorldAutoUpdate&&e.updateMatrixWorld(),null===t.parent&&t.matrixWorldAutoUpdate&&t.updateMatrixWorld(),a("worldMatrices");const s=this.extractScene(e,t,!0);a("extractScene"),this.ensureShadowTextureSizes(s),this.uploadInstanceData(s.instanceData),this.uploadResidentInstanceData(s.residentInstanceUploads),this.uploadDrawMetadata(this.getHiZOcclusionCullingActive()?s.gpuOpaqueDraws:[]),this.ensureTiledLightingSize(),this.updateCameraUniforms(t,e),this.updateLightUniforms(s),a("sceneUploads");const o=this.compileDrawScratch;o.length=0,o.push(...s.gpuOpaqueDraws,...s.directOpaqueDraws,...s.transparentDraws);for(const e of o)this.prepareDrawGeometryVertexBuffers(e);if(i&&(i.drawCount=o.length),a("geometryBuffers"),r){const e=[];this.renderGraph.reset();const t=this.state.device.createCommandEncoder({label:"renderer-graph-compilation-encoder"}),r=this.createGraphBuilderContext(this.renderGraph,t,this.getSharedSceneBindGroup(),this.getSharedShadowBindGroup(),null,this.state.sceneColorView,s,{drawCallCount:0,triangleCount:0},e);this.graphBuilder(this.renderGraph,r),i&&(i.materialRequestCount=e.length),a("renderGraph");const n=[],o=new Set;for(const t of e){n.push(this.compileDrawMaterialsAsync(t.draws,t.colorTargetFormats,t.sampleCount));const e=`${t.sampleCount}:${t.colorTargetFormats.join("|")}:${t.staticDrawStage}`;o.has(e)||(o.add(e),n.push(this.compileStaticDrawMaterialsAsync(t.colorTargetFormats,t.sampleCount,t.staticDrawStage)))}return a("scheduleMaterials"),Promise.all(n).then(()=>{})}this.compileDrawMaterials(o)}collectInstancedMesh(e,t,r,i){if(void 0===e.geometry?.getAttribute("position"))return;const n=e.material;if(!1===n.visible)return;const a=this.instancedMeshExtractionCache.get(e),s=!0===e.userData.webGpuCacheMaterial&&a?.sourceMaterial===n&&a.sourceMaterialVersion===n.version&&a.material!==this.fallbackMaterial?a.material:this.resolveMaterial(n);if(!s)return;const o=Vi(e),l=this.getGeometryResource(e.geometry),c=this.getInstancedMeshExtractionCacheEntry(e,s,o,l),u=e.instanceMatrix.array,d=e.instanceMatrix.version,h=e.instanceColor?.array,p=e.instanceColor?.itemSize??0,f=e.instanceColor?.version??-1,m=c.cacheValid&&c.cachedCount===e.count&&c.cachedInstanceMatrixVersion===d&&c.cachedInstanceColorVersion===f&&xi(c.cachedMatrixWorld,e.matrixWorld.elements),g=wi(e.matrixWorld.elements),v=g&&!e.frustumCulled;if(!m){const t=c.cachedInstanceMatrixVersion!==d||c.cachedCount!==e.count,r=c.cachedInstanceColorVersion!==f||c.cachedCount!==e.count;if(v){const i=e.matrixWorld.elements,n=i[12]??0,a=i[13]??0,s=i[14]??0;c.cachedDrawBoundsCenter.set(n,a,s),c.cachedDrawBoundsRadius=0,c.cachedBoundsMin.set(n,a,s),c.cachedBoundsMax.set(n,a,s),c.cachedInstanceMatrixVersion=d,c.cachedInstanceColorVersion=f,c.cachedCount=e.count,c.cachedDefaultColorData=null,vi(e.matrixWorld.elements,c.cachedMatrixWorld),c.residentBufferDirty||=t,c.residentColorBufferDirty||=r,c.cacheValid=!0}else{const t=c.cachedInstanceData.beginWriteInstances(e.count),r=c.cachedBoundsMin,i=c.cachedBoundsMax;r.set(1/0,1/0,1/0),i.set(-1/0,-1/0,-1/0);const n=c.localBoundsCenter,a=c.localBoundsRadius,s=e.matrixWorld.elements,o=wi(s),l=n.x,m=n.y,g=n.z,v=s[0],x=s[4],w=s[8],b=s[12],y=s[1],S=s[5],M=s[9],P=s[13],B=s[2],D=s[6],T=s[10],I=s[14],V=s[3],G=s[7],L=s[11],z=s[15];for(let n=0;n<e.count;n+=1){const e=16*n,s=n*C,c=u[e+0]??0,d=u[e+1]??0,f=u[e+2]??0,R=u[e+3]??0,U=u[e+4]??0,A=u[e+5]??0,k=u[e+6]??0,$=u[e+7]??0,E=u[e+8]??0,O=u[e+9]??0,_=u[e+10]??0,j=u[e+11]??0,N=u[e+12]??0,W=u[e+13]??0,H=u[e+14]??0,q=u[e+15]??0;let K,Z,Y,X,J,Q,ee,te,re,ie,ne,ae,se,oe,le,ce;o?(K=c,Z=d,Y=f,X=R,J=U,Q=A,ee=k,te=$,re=E,ie=O,ne=_,ae=j,se=N,oe=W,le=H,ce=q):(K=v*c+x*d+w*f+b*R,J=v*U+x*A+w*k+b*$,re=v*E+x*O+w*_+b*j,se=v*N+x*W+w*H+b*q,Z=y*c+S*d+M*f+P*R,Q=y*U+S*A+M*k+P*$,ie=y*E+S*O+M*_+P*j,oe=y*N+S*W+M*H+P*q,Y=B*c+D*d+T*f+I*R,ee=B*U+D*A+T*k+I*$,ne=B*E+D*O+T*_+I*j,le=B*N+D*W+T*H+I*q,X=V*c+G*d+L*f+z*R,te=V*U+G*A+L*k+z*$,ae=V*E+G*O+L*_+z*j,ce=V*N+G*W+L*H+z*q),t[s+0]=K,t[s+1]=Z,t[s+2]=Y,t[s+3]=X,t[s+4]=J,t[s+5]=Q,t[s+6]=ee,t[s+7]=te,t[s+8]=re,t[s+9]=ie,t[s+10]=ne,t[s+11]=ae,t[s+12]=se,t[s+13]=oe,t[s+14]=le,t[s+15]=ce;const ue=n*p;t[s+16]=h?h[ue+0]??1:1,t[s+17]=h?h[ue+1]??1:1,t[s+18]=h?h[ue+2]??1:1,t[s+19]=h&&p>=4?h[ue+3]??1:1,t[s+20]=n,t[s+21]=1,t[s+22]=1,t[s+23]=0;for(let e=0;e<16;e+=1)t[s+24+e]=t[s+e];const de=K*l+J*m+re*g+se,he=Z*l+Q*m+ie*g+oe,pe=Y*l+ee*m+ne*g+le,fe=Math.sqrt(K*K+Z*Z+Y*Y),me=Math.sqrt(J*J+Q*Q+ee*ee),ge=Math.sqrt(re*re+ie*ie+ne*ne),ve=a*Math.max(fe,me,ge,1e-5);Di(r,i,F.set(de,he,pe),ve)}c.cachedDrawBoundsCenter.copy(r).add(i).multiplyScalar(.5);const R=i.x-c.cachedDrawBoundsCenter.x,U=i.y-c.cachedDrawBoundsCenter.y,A=i.z-c.cachedDrawBoundsCenter.z;c.cachedDrawBoundsRadius=Math.sqrt(R*R+U*U+A*A),c.cachedInstanceMatrixVersion=d,c.cachedInstanceColorVersion=f,c.cachedCount=e.count,c.cachedDefaultColorData=null,vi(e.matrixWorld.elements,c.cachedMatrixWorld),c.residentBufferDirty=!0,c.residentColorBufferDirty=!0,c.cacheValid=!0}}if(!i(c.cachedDrawBoundsCenter.x,c.cachedDrawBoundsCenter.y,c.cachedDrawBoundsCenter.z,c.cachedDrawBoundsRadius,e.frustumCulled))return;c.residentInstanceBinding&&c.residentInstanceBinding.mode!==(g?"instanced-direct":"packed")&&(c.residentInstanceBinding.mode=g?"instanced-direct":"packed",c.residentInstanceBinding.sceneBindGroup=null,c.residentInstanceBinding.shadowBindGroup=null,c.residentInstanceBinding.shadowBindGroups.clear(),c.residentInstanceBinding.sceneBindGroupVersion=0,c.residentInstanceBinding.shadowBindGroupVersion=0,c.residentBufferDirty=!0,c.residentColorBufferDirty=!0),(c.residentBufferDirty||c.residentColorBufferDirty||!c.residentInstanceBinding)&&this.residentInstanceUploadsScratch.push(c),bi(this.extractedBoundsMinScratch,this.extractedBoundsMaxScratch,c.cachedBoundsMin,c.cachedBoundsMax);const x=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e.geometry,l,s,o,c.residentInstanceBinding,e,null,c.batchKey,c.batchHash,c.indexed,c.drawRangeStart,c.drawRangeCount,s.transparent||s.requiresLatePass(),e.renderOrder,this.hasRenderCallbacks(e),e.castShadow,e.receiveShadow,c.sortMaterialId,c.sortGeometryId,c.sortCustomDepthMaterialId,0,e.count,c.cachedDrawBoundsCenter.x,c.cachedDrawBoundsCenter.y,c.cachedDrawBoundsCenter.z,c.cachedDrawBoundsRadius);v&&!x.transparent?this.directOpaqueDrawsScratch.push(x):this.pushDraw(x)}collectSkinnedMesh(e,t,r,i){if(void 0===e.geometry?.getAttribute("position"))return;const n=e.boundingSphere,a=F;let s=0;if(null!==n){const t=n.center,r=e.matrixWorld.elements,a=r[0]*t.x+r[4]*t.y+r[8]*t.z+r[12],o=r[1]*t.x+r[5]*t.y+r[9]*t.z+r[13],l=r[2]*t.x+r[6]*t.y+r[10]*t.z+r[14];if(s=n.radius*Pi(e.matrixWorld),e.frustumCulled&&!i(a,o,l,s,!0))return}const o=Array.isArray(e.material)?e.material:null,l=o?o[0]:e.material,c=Vi(e),u=null!==e.geometry.index,d=this.getSkinnedGeometryResource(e);if(this.refreshSkinningPalette(d.skinning.palette),this.refreshSkinningBindMatrices(e,d.skinning),null===n){if(this.updateSkinnedBounds(e,d),a.copy(d.localBoundsCenter).applyMatrix4(e.matrixWorld),s=d.localBoundsRadius*Pi(e.matrixWorld),!i(a.x,a.y,a.z,s,e.frustumCulled))return}else a.copy(n.center).applyMatrix4(e.matrixWorld);this.uploadSkinningResources(d.skinning);const h=this.getObjectMotionHistory(e,e.matrixWorld.elements),p=ai(t,e.matrixWorld,1,1,1,1,void 0,h.matrix,Sh(e),Ch(e),h.valid?1:0);if(this.commitObjectMotionHistory(h,e.matrixWorld.elements),r(e.matrixWorld.elements),e.geometry.groups.length>0&&(null===o||o.length>0)){for(let t=0;t<e.geometry.groups.length;t++){const r=e.geometry.groups[t],i=o?o[r.materialIndex??0]??l:l,n=this.resolveSkinnedMaterial(i);if(!n)continue;const h=Jr(e.geometry,u,r.start,r.count),f=this.skinnedDrawKeys.get(e,t,n,u,r.start,h,c),m=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e,d.resource,n,c,null,e,r,f.batchKey,f.batchHash,u,r.start,h,n.transparent,e.renderOrder,this.hasRenderCallbacks(e),e.castShadow,e.receiveShadow,f.materialId,f.geometryId,f.depthMaterialId,p,1,a.x,a.y,a.z,s,d.skinning);this.pushDraw(m),this.pushToonOutlineDraw(m,i)}return}const f=this.resolveSkinnedMaterial(l);if(!f)return;const m=Qr(e.geometry,u),g=this.skinnedDrawKeys.get(e,0,f,u,m.start,m.count,c),v=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e,d.resource,f,c,null,e,null,g.batchKey,g.batchHash,u,m.start,m.count,f.transparent,e.renderOrder,this.hasRenderCallbacks(e),e.castShadow,e.receiveShadow,g.materialId,g.geometryId,g.depthMaterialId,p,1,a.x,a.y,a.z,s,d.skinning);this.pushDraw(v),this.pushToonOutlineDraw(v,l)}collectBatchedMesh(e,t,r,i,n,a,s){if(void 0===e.geometry?.getAttribute("position"))return;const o=this.resolveMaterial(e.material);if(!o)return;const l=Vi(e),c=(e.geometry.index,this.getGeometryResource(e.geometry)),u=e,d=u._instanceInfo??u._drawInfo??[],h=d.length,p=u._matricesTexture?.image.data,f=u._colorsTexture?.image.data,m=this.getBatchedMeshExtractionCacheEntry(e,o,l,c,u),g=e.matrixWorld.elements,v=u._matricesTexture?.version??0,x=u._colorsTexture?.version??-1;if(m.cacheValid&&!o.transparent&&m.cachedMatricesVersion===v&&m.cachedColorsVersion===x&&m.cachedInstanceInfoLength===d.length&&m.cachedGeometryCount===(u._geometryCount??0)&&xi(m.cachedMatrixWorld,g)&&this.batchedGeometryIdsMatchSnapshot(m.geometryIdsSnapshot,d)){let t=!1;for(let r=0;r<m.cachedDraws.length;r+=1){const n=m.cachedDraws[r];i(n.boundsCenter.x,n.boundsCenter.y,n.boundsCenter.z,n.boundsRadius,e.frustumCulled)&&(t=!0,this.pushDraw(this.populateDynamicDrawCall(this.acquireDrawCall(),n.template.geometry,n.template.geometryKey,n.template.geometryResource,n.template.material,n.template.customDepthMaterial,m.residentInstanceBinding,n.template.sourceObject,n.template.geometryGroup,n.template.batchKey,n.template.batchHash,n.template.indexed,n.template.start,n.template.count,n.template.transparent,n.template.sourceObject?.renderOrder??n.template.renderOrder,this.hasRenderCallbacks(n.template.sourceObject),n.template.sourceObject?Boolean(n.template.sourceObject.castShadow):n.template.castShadow,n.template.sourceObject?Boolean(n.template.sourceObject.receiveShadow):n.template.receiveShadow,n.template.sortMaterialId,n.template.sortGeometryId,n.template.sortCustomDepthMaterialId,n.instanceStart,n.instanceCount,n.boundsCenter.x,n.boundsCenter.y,n.boundsCenter.z,n.boundsRadius)))}if(!t)return;return!m.residentBufferDirty&&m.residentInstanceBinding||this.residentInstanceUploadsScratch.push(m),void bi(this.extractedBoundsMinScratch,this.extractedBoundsMaxScratch,m.cachedBoundsMin,m.cachedBoundsMax)}if(o.transparent){const o=[],l=!e.sortObjects||null!==e.customSort;for(let n=0;n<h;n+=1){const c=d[n];if(!c?.active||!c.visible)continue;const u=m.templates[c.geometryIndex];if(!u)continue;p?U.fromArray(p,16*n):e.getMatrixAt(n,U),A.multiplyMatrices(e.matrixWorld,U);const h=u.localBoundsCenter,g=A.elements,v=g[0]*h.x+g[4]*h.y+g[8]*h.z+g[12],x=g[1]*h.x+g[5]*h.y+g[9]*h.z+g[13],w=g[2]*h.x+g[6]*h.y+g[10]*h.z+g[14],b=Math.sqrt(g[0]*g[0]+g[1]*g[1]+g[2]*g[2]),y=Math.sqrt(g[4]*g[4]+g[5]*g[5]+g[6]*g[6]),S=Math.sqrt(g[8]*g[8]+g[9]*g[9]+g[10]*g[10]),C=u.localBoundsRadius*Math.max(b,y,S,1e-5);if(!i(v,x,w,C,e.frustumCulled&&e.perObjectFrustumCulled))continue;const M=f?f[4*n+0]??1:1,P=f?f[4*n+1]??1:1,B=f?f[4*n+2]??1:1,D=f?f[4*n+3]??1:1,T=ai(t,A,M,P,B,D,n);r(A.elements);const I=this.populateDrawCall(this.acquireDrawCall(),u,T,1,v,x,w,C),V=(v-a.x)*s.x+(x-a.y)*s.y+(w-a.z)*s.z;l?o.push({start:u.start,count:u.count,z:V,index:n,draw:I}):(I.sortDepth=V,this.transparentDraws.push(I))}if(l&&o.length>0){e.sortObjects&&e.customSort?e.customSort.call(e,o,n):e.sortObjects&&o.sort((e,t)=>t.z-e.z);let t=0;for(let e=0;e<o.length;e+=1)t+=o[e].z;t/=o.length;const r=oi(e);for(let e=0;e<o.length;e+=1){const i=o[e].draw;i.sortDepth=t,i.transparentSortGroup=r,i.transparentSortOrder=e,this.transparentDraws.push(i)}}return}const w=m.activeGroups;for(let e=0;e<w.length;e+=1){const t=w[e];t.activeInFrame=!1,t.activeCount=0}w.length=0;const b=m.cachedBoundsMin,y=m.cachedBoundsMax;b.set(1/0,1/0,1/0),y.set(-1/0,-1/0,-1/0),m.geometryIdsSnapshot.length!==d.length&&(m.geometryIdsSnapshot=new Int32Array(d.length));let S=0;for(let e=0;e<h;e+=1){const t=d[e];if(!t?.active||!t.visible){m.geometryIdsSnapshot[e]=-1;continue}const r=m.groups[t.geometryIndex];r?(m.geometryIdsSnapshot[e]=t.geometryIndex,r.activeInFrame||(r.activeInFrame=!0,r.activeCount=0,r.boundsMin.set(1/0,1/0,1/0),r.boundsMax.set(-1/0,-1/0,-1/0),w.push(r)),r.activeCount+=1,S+=1):m.geometryIdsSnapshot[e]=-1}const M=m.cachedInstanceData.beginWriteInstances(S);let P=0;for(let e=0;e<w.length;e+=1){const t=w[e];t.instanceStart=P,t.writeOffset=P*C,P+=t.activeCount}const B=wi(g),D=g[0],T=g[4],I=g[8],V=g[12],G=g[1],L=g[5],z=g[9],R=g[13],k=g[2],F=g[6],$=g[10],E=g[14],O=g[3],_=g[7],j=g[11],N=g[15];for(let t=0;t<h;t+=1){const r=m.geometryIdsSnapshot[t]??-1;if(r<0)continue;const i=m.groups[r];if(!i)continue;let n,a,s,o,l,c,u,d,h,g,v,x,w,S,P,A,W,H,q,K,Z,Y,X,J,Q,ee,te,re,ie,ne,ae,se;if(p){const e=16*t;n=p[e+0]??0,a=p[e+1]??0,s=p[e+2]??0,o=p[e+3]??0,l=p[e+4]??0,c=p[e+5]??0,u=p[e+6]??0,d=p[e+7]??0,h=p[e+8]??0,g=p[e+9]??0,v=p[e+10]??0,x=p[e+11]??0,w=p[e+12]??0,S=p[e+13]??0,P=p[e+14]??0,A=p[e+15]??0}else{e.getMatrixAt(t,U);const r=U.elements;n=r[0]??0,a=r[1]??0,s=r[2]??0,o=r[3]??0,l=r[4]??0,c=r[5]??0,u=r[6]??0,d=r[7]??0,h=r[8]??0,g=r[9]??0,v=r[10]??0,x=r[11]??0,w=r[12]??0,S=r[13]??0,P=r[14]??0,A=r[15]??0}B?(W=n,H=a,q=s,K=o,Z=l,Y=c,X=u,J=d,Q=h,ee=g,te=v,re=x,ie=w,ne=S,ae=P,se=A):(W=D*n+T*a+I*s+V*o,Z=D*l+T*c+I*u+V*d,Q=D*h+T*g+I*v+V*x,ie=D*w+T*S+I*P+V*A,H=G*n+L*a+z*s+R*o,Y=G*l+L*c+z*u+R*d,ee=G*h+L*g+z*v+R*x,ne=G*w+L*S+z*P+R*A,q=k*n+F*a+$*s+E*o,X=k*l+F*c+$*u+E*d,te=k*h+F*g+$*v+E*x,ae=k*w+F*S+$*P+E*A,K=O*n+_*a+j*s+N*o,J=O*l+_*c+j*u+N*d,re=O*h+_*g+j*v+N*x,se=O*w+_*S+j*P+N*A);const oe=f?f[4*t+0]??1:1,le=f?f[4*t+1]??1:1,ce=f?f[4*t+2]??1:1,ue=f?f[4*t+3]??1:1,de=i.writeOffset;M[de+0]=W,M[de+1]=H,M[de+2]=q,M[de+3]=K,M[de+4]=Z,M[de+5]=Y,M[de+6]=X,M[de+7]=J,M[de+8]=Q,M[de+9]=ee,M[de+10]=te,M[de+11]=re,M[de+12]=ie,M[de+13]=ne,M[de+14]=ae,M[de+15]=se,M[de+16]=oe,M[de+17]=le,M[de+18]=ce,M[de+19]=ue,M[de+20]=t,M[de+21]=1,M[de+22]=1,M[de+23]=0;for(let e=0;e<16;e+=1)M[de+24+e]=M[de+e];i.writeOffset+=C;const he=i.template.localBoundsCenter,pe=W*he.x+Z*he.y+Q*he.z+ie,fe=H*he.x+Y*he.y+ee*he.z+ne,me=q*he.x+X*he.y+te*he.z+ae,ge=Math.sqrt(W*W+H*H+q*q),ve=Math.sqrt(Z*Z+Y*Y+X*X),xe=Math.sqrt(Q*Q+ee*ee+te*te),we=i.template.localBoundsRadius*Math.max(ge,ve,xe,1e-5),be=pe-we,ye=fe-we,Se=me-we,Ce=pe+we,Me=fe+we,Pe=me+we;be<i.boundsMin.x&&(i.boundsMin.x=be),ye<i.boundsMin.y&&(i.boundsMin.y=ye),Se<i.boundsMin.z&&(i.boundsMin.z=Se),Ce>i.boundsMax.x&&(i.boundsMax.x=Ce),Me>i.boundsMax.y&&(i.boundsMax.y=Me),Pe>i.boundsMax.z&&(i.boundsMax.z=Pe),be<b.x&&(b.x=be),ye<b.y&&(b.y=ye),Se<b.z&&(b.z=Se),Ce>y.x&&(y.x=Ce),Me>y.y&&(y.y=Me),Pe>y.z&&(y.z=Pe)}const W=m.cachedDraws;let H=0;for(let e=0;e<w.length;e+=1){const t=w[e],r=.5*(t.boundsMin.x+t.boundsMax.x),i=.5*(t.boundsMin.y+t.boundsMax.y),n=.5*(t.boundsMin.z+t.boundsMax.z),a=t.boundsMax.x-r,s=t.boundsMax.y-i,o=t.boundsMax.z-n,l=Math.sqrt(a*a+s*s+o*o);let c=W[H];c||(c={template:t.template,instanceStart:0,instanceCount:0,boundsCenter:new uu,boundsRadius:0},W[H]=c),c.template=t.template,c.instanceStart=t.instanceStart,c.instanceCount=t.activeCount,c.boundsCenter.set(r,i,n),c.boundsRadius=l,H+=1}W.length=H,m.cachedMatricesVersion=v,m.cachedColorsVersion=x,m.cachedInstanceInfoLength=d.length,m.cachedGeometryCount=u._geometryCount??0,vi(g,m.cachedMatrixWorld),m.residentBufferDirty=!0,m.cacheValid=!0;let q=!1;for(let t=0;t<W.length;t+=1){const r=W[t];i(r.boundsCenter.x,r.boundsCenter.y,r.boundsCenter.z,r.boundsRadius,e.frustumCulled)&&(q=!0,this.pushDraw(this.populateDynamicDrawCall(this.acquireDrawCall(),r.template.geometry,r.template.geometryKey,r.template.geometryResource,r.template.material,r.template.customDepthMaterial,m.residentInstanceBinding,r.template.sourceObject,r.template.geometryGroup,r.template.batchKey,r.template.batchHash,r.template.indexed,r.template.start,r.template.count,r.template.transparent,r.template.sourceObject?.renderOrder??r.template.renderOrder,this.hasRenderCallbacks(r.template.sourceObject),r.template.sourceObject?Boolean(r.template.sourceObject.castShadow):r.template.castShadow,r.template.sourceObject?Boolean(r.template.sourceObject.receiveShadow):r.template.receiveShadow,r.template.sortMaterialId,r.template.sortGeometryId,r.template.sortCustomDepthMaterialId,r.instanceStart,r.instanceCount,r.boundsCenter.x,r.boundsCenter.y,r.boundsCenter.z,r.boundsRadius)))}q&&(this.residentInstanceUploadsScratch.push(m),bi(this.extractedBoundsMinScratch,this.extractedBoundsMaxScratch,b,y))}uploadInstanceData(e){if(!this.state.device)return;const t=Math.max(4,e.byteLength);(!this.state.instanceBuffer||t>this.state.instanceBufferSize)&&(this.state.instanceBuffer?.destroy(),this.state.instanceBufferSize=256*Math.ceil(t/256),this.state.instanceBuffer=this.state.device.createBuffer({label:"renderer-instance-buffer",size:this.state.instanceBufferSize,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.state.sharedSceneBindGroup=null,this.state.sharedShadowBindGroup=null,this.state.sharedShadowBindGroupByCameraBuffer.clear(),this.clearIndirectBundleCache()),e.floatLength>0?this.state.device.queue.writeBuffer(this.state.instanceBuffer,0,e.rawData.buffer,0,e.byteLength):this.state.device.queue.writeBuffer(this.state.instanceBuffer,0,P,0,C)}uploadResidentInstanceData(e){if(this.state.device)for(let t=0;t<e.length;t+=1){const r=e[t],i=r.residentInstanceBinding;if(!i)continue;if("instanced-direct"===i.mode){const e=r,t=e.sourceMesh,n=t.instanceMatrix.array,a=Math.max(4,16*t.count*Float32Array.BYTES_PER_ELEMENT),s=Math.max(t.count,1),o=Math.max(16,4*s*Float32Array.BYTES_PER_ELEMENT);if((!i.buffer||a>r.residentBufferSize)&&(i.buffer?.destroy(),r.residentBufferSize=256*Math.ceil(a/256),i.buffer=this.state.device.createBuffer({label:"renderer-instanced-mesh-matrix-buffer",size:r.residentBufferSize,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),i.sceneBindGroup=null,i.shadowBindGroup=null,i.shadowBindGroups.clear(),i.sceneBindGroupVersion=0,i.shadowBindGroupVersion=0,r.residentBufferDirty=!0),(!i.colorBuffer||o>r.residentColorBufferSize)&&(i.colorBuffer?.destroy(),r.residentColorBufferSize=256*Math.ceil(o/256),i.colorBuffer=this.state.device.createBuffer({label:"renderer-instanced-mesh-color-buffer",size:r.residentColorBufferSize,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),i.sceneBindGroup=null,i.shadowBindGroup=null,i.shadowBindGroups.clear(),i.sceneBindGroupVersion=0,i.shadowBindGroupVersion=0,r.residentColorBufferDirty=!0),r.residentBufferDirty&&i.buffer&&(t.count>0?this.state.device.queue.writeBuffer(i.buffer,0,ii(n),0,16*t.count):this.state.device.queue.writeBuffer(i.buffer,0,B,0,4),r.residentBufferDirty=!1),r.residentColorBufferDirty&&i.colorBuffer){if(t.instanceColor&&4===t.instanceColor.itemSize&&t.instanceColor.array instanceof Float32Array)this.state.device.queue.writeBuffer(i.colorBuffer,0,ii(t.instanceColor.array),0,4*s);else{let r=e.cachedDefaultColorData;r&&r.length===4*s||(r=new Float32Array(4*s),e.cachedDefaultColorData=r);for(let e=0;e<s;e+=1){const i=4*e;t.instanceColor?(r[i+0]=t.instanceColor.getComponent(e,0),r[i+1]=t.instanceColor.itemSize>1?t.instanceColor.getComponent(e,1):1,r[i+2]=t.instanceColor.itemSize>2?t.instanceColor.getComponent(e,2):1,r[i+3]=t.instanceColor.itemSize>3?t.instanceColor.getComponent(e,3):1):(r[i+0]=1,r[i+1]=1,r[i+2]=1,r[i+3]=1)}this.state.device.queue.writeBuffer(i.colorBuffer,0,ii(r),0,r.length)}r.residentColorBufferDirty=!1}continue}const n=Math.max(4,r.cachedInstanceData.byteLength);if((!i.buffer||n>r.residentBufferSize)&&(i.buffer?.destroy(),r.residentBufferSize=256*Math.ceil(n/256),i.buffer=this.state.device.createBuffer({label:"renderer-instanced-mesh-buffer",size:r.residentBufferSize,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),i.sceneBindGroup=null,i.shadowBindGroup=null,i.shadowBindGroups.clear(),i.sceneBindGroupVersion=0,i.shadowBindGroupVersion=0,r.residentBufferDirty=!0),r.residentBufferDirty){if(!i.buffer)continue;r.cachedInstanceData.floatLength>0?this.state.device.queue.writeBuffer(i.buffer,0,r.cachedInstanceData.rawData.buffer,0,r.cachedInstanceData.byteLength):this.state.device.queue.writeBuffer(i.buffer,0,P,0,C),r.residentBufferDirty=!1}}}clearIndirectBundleCache(){this.state.indirectForwardBundleCache.clear(),this.state.directForwardBundleCache.clear(),this.indirectBundleInvalidationVersion+=1}clearStaticDrawSetBundleCaches(){this.materialPassStaticBundleCache=new WeakMap;for(const e of this.staticDrawSets){for(const t of e.visibleIndirectSubmissionStreams??[])t.forwardBundle=null;e.indirectForwardBundleCache.clear(),e.directForwardBundle=null,e.directForwardBundleSceneBindGroup=null,e.depthPrepassBundle=null,e.depthPrepassBundleSceneBindGroup=null,e.indirectDepthPrepassBundles.prepass=null,e.indirectDepthPrepassBundles.postpass=null,e.shadowBundles=new WeakMap;for(const t of e.shadowChunks)t.bundles=new WeakMap;e.depthMaterialResources.clear()}}getViewport(e){return e.set(0,0,this.state.width,this.state.height)}getSharedSceneBindGroup(){if(!(this.state.device&&this.state.sceneBindGroupLayout&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.instanceBuffer&&this.state.shadowComparisonSampler&&this.state.directionalShadowView&&this.state.linearClampSampler&&this.state.pointShadowArrayView&&this.state.spotShadowView&&this.state.spotLightMapView))throw new Error("Renderer scene bind group resources are not initialized.");return this.state.sharedSceneBindGroup||(this.state.sharedSceneBindGroup=this.state.device.createBindGroup({label:"renderer-scene-bind-group",layout:this.state.sceneBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:1,resource:{buffer:this.state.lightBuffer}},{binding:2,resource:{buffer:this.state.instanceBuffer}},{binding:3,resource:this.state.shadowComparisonSampler},{binding:4,resource:this.state.directionalShadowView},{binding:5,resource:this.state.linearClampSampler},{binding:6,resource:this.state.pointShadowArrayView},{binding:7,resource:this.state.spotShadowView},{binding:9,resource:this.state.spotLightMapView},{binding:11,resource:this.tiledPointLights.view}]})),this.state.sharedSceneBindGroup}getSharedShadowBindGroup(){if(!(this.state.device&&this.state.shadowBindGroupLayout&&this.state.shadowCameraBuffer&&this.state.instanceBuffer))throw new Error("Renderer shadow bind group resources are not initialized.");return this.state.sharedShadowBindGroup||(this.state.sharedShadowBindGroup=this.state.device.createBindGroup({label:"renderer-shadow-bind-group",layout:this.state.shadowBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.shadowCameraBuffer}},{binding:1,resource:{buffer:this.state.instanceBuffer}}]})),this.state.sharedShadowBindGroup}getShadowCameraBuffer(e){if(!this.state.device)throw new Error("Renderer is not initialized.");for(;this.state.shadowCameraBufferPool.length<=e;)this.state.shadowCameraBufferPool.push(this.state.device.createBuffer({label:`renderer-shadow-camera-buffer-${this.state.shadowCameraBufferPool.length}`,size:256,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}));return this.state.shadowCameraBufferPool[e]}getSharedShadowBindGroupForCameraBuffer(e){if(!(this.state.device&&this.state.sceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.instanceBuffer))throw new Error("Renderer shadow bind group resources are not initialized.");const t=this.state.sharedShadowBindGroupByCameraBuffer.get(e);if(t)return t;const r=this.state.device.createBindGroup({label:"renderer-shadow-bind-group-per-camera",layout:this.state.shadowBindGroupLayout,entries:[{binding:0,resource:{buffer:e}},{binding:1,resource:{buffer:this.state.instanceBuffer}}]});return this.state.sharedShadowBindGroupByCameraBuffer.set(e,r),r}buildIndirectSubmissionStreams(e,t,r,i){let n=this.dynamicIndirectSubmissionCache.get(e);n||(n=[],this.dynamicIndirectSubmissionCache.set(e,n));const a=void 0!==i;let s=n.find(e=>e.lastUsedExtractionVersion!==this.extractionVersion&&e.sceneBindGroup===t&&e.instanceAccessMode===r&&e.usesExplicitMaterialResources===a);s||(s={sceneBindGroup:t,instanceAccessMode:r,usesExplicitMaterialResources:a,lastUsedExtractionVersion:-1,streams:[]},n.push(s)),s.lastUsedExtractionVersion=this.extractionVersion;const o=s.streams;let l=0,c=null,u=0;for(let n=0;n<e.length;n+=1){const a=e[n],s=i?.[n]??(r?this.getMaterialResource(a.material,r,a.receiveShadow,void 0,null!==a.skinning,this.drawUsesBatching(a)):this.getMaterialResourceForDraw(a)),d=r?t:this.resolveSceneBindGroupForDraw(a,t),h=this.getIndirectStreamKey(s.pipeline,s.bindGroup,d,a.geometryKey),p=Ti(a);if(c&&c.key===h&&c.indirectStartIndex+c.indirectCount===n){c.indirectCount+=1,c.drawCallCount+=1,c.triangleCount+=p;continue}c&&c.indirectCount!==u&&(c.forwardBundle=null,c.forwardBundleColorFormatsId=0,c.forwardBundleDrawMetadataResource=null,c.forwardBundleCandidateExtractionVersion=-1),c=o[l],u=c?.indirectCount??0;const f=void 0!==c&&c.key===h&&c.material===a.material&&c.materialResource===s&&c.sceneBindGroup===d&&c.geometry===a.geometry&&c.geometryKey===a.geometryKey&&c.geometryResource===a.geometryResource&&c.indirectStartIndex===n;c?(f||(c.forwardBundle=null,c.forwardBundleColorFormatsId=0,c.forwardBundleDrawMetadataResource=null,c.forwardBundleCandidateExtractionVersion=-1),c.key=h,c.material=a.material,c.materialResource=s,c.sceneBindGroup=d,c.geometry=a.geometry,c.geometryKey=a.geometryKey,c.geometryResource=a.geometryResource,c.indirectStartIndex=n,c.indirectCount=1,c.drawCallCount=1,c.triangleCount=p):(c={key:h,material:a.material,materialResource:s,sceneBindGroup:d,geometry:a.geometry,geometryKey:a.geometryKey,geometryResource:a.geometryResource,indirectStartIndex:n,indirectCount:1,drawCallCount:1,triangleCount:p,forwardBundle:null,forwardBundleMaterialVersion:-1,forwardBundleGraphTextureResourceVersion:-1,forwardBundleInvalidationVersion:-1,forwardBundleDrawMetadataResource:null,forwardBundleSampleCount:0,forwardBundleColorFormatsId:0,forwardBundleCandidateExtractionVersion:-1},o[l]=c),l+=1}return c&&c.indirectCount!==u&&(c.forwardBundle=null,c.forwardBundleColorFormatsId=0,c.forwardBundleDrawMetadataResource=null,c.forwardBundleCandidateExtractionVersion=-1),o.length!==l&&(o.length=l),o}getIndirectStreamKey(e,t,r,i){let n=this.indirectStreamKeyCache.get(e);n||(n=new WeakMap,this.indirectStreamKeyCache.set(e,n));let a=n.get(t);a||(a=new WeakMap,n.set(t,a));let s=a.get(r);s||(s=new WeakMap,a.set(r,s));let o=s.get(i);return void 0===o&&(o=this.nextIndirectStreamKey,this.nextIndirectStreamKey+=1,s.set(i,o)),o}getOrCreateStaticIndirectSubmissionStreams(e,t,r=Bh){const i=r.join("|"),n=null!==e.visibleIndirectSubmissionStreams&&e.visibleIndirectStreamsSceneBindGroup===t&&e.visibleIndirectStreamsSampleCount===this.sampleCount&&e.visibleIndirectStreamsColorFormatsKey===i;if(n)return e.visibleIndirectSubmissionStreams;let a=!n;for(const t of e.visibleMaterialBindings){const i=this.getMaterialResource(t.material,"packed-visible",t.receiveShadow,r,!1,t.usesBatching),n=t.resource;t.resource=i,n!==i&&(a=!0);for(const r of t.drawIndices)e.visibleDrawMaterialResources[r]!==i&&(a=!0),e.visibleDrawMaterialResources[r]=i}return!a&&e.visibleIndirectSubmissionStreams||(e.visibleIndirectSubmissionStreams=this.buildIndirectSubmissionStreams(e.draws,t,"packed-visible",e.visibleDrawMaterialResources).slice(),e.visibleIndirectStreamsSceneBindGroup=t,e.visibleIndirectStreamsSampleCount=this.sampleCount,e.visibleIndirectStreamsColorFormatsKey=i,e.indirectForwardBundleCache.clear()),e.visibleIndirectSubmissionStreams}getOrCreateIndirectForwardBundle(e,t=this.state.drawMetadataResource,r=this.state.indirectForwardBundleCache,i="renderer-indirect-forward-bundle",n=Bh,a=!1,s=this.getColorFormatsId(n)){if(!this.state.device||!this.state.format)throw new Error("Renderer is not initialized.");if(!t)throw new Error("Indirect draw metadata is not available.");if(null!==e.forwardBundle&&e.forwardBundleMaterialVersion===e.material.version&&e.forwardBundleGraphTextureResourceVersion===this.graphTextureResourceVersion&&e.forwardBundleInvalidationVersion===this.indirectBundleInvalidationVersion&&e.forwardBundleDrawMetadataResource===t&&e.forwardBundleSampleCount===this.sampleCount&&e.forwardBundleColorFormatsId===s)return e.forwardBundle;e.forwardBundle=null;const o=this.getIndirectBundleHash(e,t,s),l=r.get(o),c=l?.find(r=>r.streamKey===e.key&&r.positionBuffer===e.geometryResource.position&&r.indexBuffer===e.geometryResource.index&&r.indirectBuffer===t.indirectBuffer&&r.indirectStartIndex===e.indirectStartIndex&&r.indirectCount===e.indirectCount&&r.sampleCount===this.sampleCount&&r.materialVersion===e.material.version&&r.graphTextureResourceVersion===this.graphTextureResourceVersion&&r.colorFormatsId===s);if(c)return this.setRetainedIndirectBundleState(e,c.bundle,t,s),c.bundle;if(a&&e.forwardBundleCandidateExtractionVersion<0)return e.forwardBundleCandidateExtractionVersion=this.extractionVersion,null;if(a&&e.forwardBundleCandidateExtractionVersion===this.extractionVersion)return null;const u=this.state.device.createRenderBundleEncoder({label:`${i}-${o}`,colorFormats:n,depthStencilFormat:"depth32float",sampleCount:this.sampleCount});if(u.setPipeline(e.materialResource.pipeline),this.bindGeometryVertexBuffers(u,e.geometry,e.geometryResource,e.materialResource.vertexAttributes,0,1,e.material.wireframe),u.setBindGroup(0,e.sceneBindGroup),u.setBindGroup(1,e.materialResource.bindGroup),!e.materialResource.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");u.setBindGroup(3,this.createGraphTextureBindGroup(e.material,e.materialResource.graphTextureBindGroupLayout));for(let r=0;r<e.indirectCount;r+=1)u.drawIndexedIndirect(t.indirectBuffer,20*(e.indirectStartIndex+r));const d=u.finish({label:`${i}-${o}`}),h={streamKey:e.key,positionBuffer:e.geometryResource.position,indexBuffer:e.geometryResource.index,indirectBuffer:t.indirectBuffer,indirectStartIndex:e.indirectStartIndex,indirectCount:e.indirectCount,sampleCount:this.sampleCount,materialVersion:e.material.version,graphTextureResourceVersion:this.graphTextureResourceVersion,colorFormatsId:s,bundle:d};return l?l.push(h):r.set(o,[h]),this.setRetainedIndirectBundleState(e,d,t,s),d}submitIndirectStreamDirect(e,t,r){e.setPipeline(t.materialResource.pipeline),this.bindGeometryVertexBuffers(e,t.geometry,t.geometryResource,t.materialResource.vertexAttributes,0,1,t.material.wireframe),e.setBindGroup(0,t.sceneBindGroup),e.setBindGroup(1,t.materialResource.bindGroup);const i=t.materialResource.graphTextureBindGroupLayout;if(!i)throw new Error("Graph texture layout is missing.");e.setBindGroup(3,this.createGraphTextureBindGroup(t.material,i));for(let i=0;i<t.indirectCount;i+=1)e.drawIndexedIndirect(r.indirectBuffer,20*(t.indirectStartIndex+i))}setRetainedIndirectBundleState(e,t,r,i){e.forwardBundle=t,e.forwardBundleMaterialVersion=e.material.version,e.forwardBundleGraphTextureResourceVersion=this.graphTextureResourceVersion,e.forwardBundleInvalidationVersion=this.indirectBundleInvalidationVersion,e.forwardBundleDrawMetadataResource=r,e.forwardBundleSampleCount=this.sampleCount,e.forwardBundleColorFormatsId=i}getIndirectBundleHash(e,t,r){let i=2166136261;return i=pi(i,e.key),i=pi(i,oi(e.geometryResource.position)),i=pi(i,e.geometryResource.index?oi(e.geometryResource.index):0),i=pi(i,oi(t.indirectBuffer)),i=pi(i,e.indirectStartIndex),i=pi(i,e.indirectCount),i=pi(i,this.sampleCount),i=pi(i,e.material.version),i=pi(i,this.graphTextureResourceVersion),i=pi(i,r),i>>>0}getColorFormatsId(e){if(e===Bh)return 1;const t=this.colorFormatsIdentityCache.get(e);if(void 0!==t)return t;const r=1===e.length?e[0]:e.join("|");let i=this.colorFormatsValueCache.get(r);return void 0===i&&(i=this.nextColorFormatsId,this.nextColorFormatsId+=1,this.colorFormatsValueCache.set(r,i)),this.colorFormatsIdentityCache.set(e,i),i}getDirectForwardBundleKey(e,t,r){let i=2166136261;i=pi(i,e.length),i=pi(i,this.sampleCount),i=pi(i,oi(t));for(let n=0;n<e.length;n+=1){const a=e[n],s=this.getMaterialResourceForDraw(a,r),o=this.resolveSceneBindGroupForDraw(a,t);i=pi(i,oi(a.material)),i=pi(i,a.receiveShadow?1:0),i=pi(i,a.material.version??0),i=pi(i,oi(s.pipeline)),i=pi(i,oi(s.bindGroup)),i=pi(i,oi(o)),i=pi(i,oi(a.geometryKey)),i=pi(i,oi(a.geometryResource.position)),i=pi(i,oi(a.geometryResource.normal)),i=pi(i,oi(a.geometryResource.uv)),i=pi(i,oi(a.geometryResource.color)),i=pi(i,a.geometryResource.index?oi(a.geometryResource.index):0);for(const e of a.geometryResource.extraAttributeBuffers.values())i=pi(i,oi(e));i=pi(i,a.indexed?1:0),i=pi(i,a.start),i=pi(i,a.count),i=pi(i,a.instanceStart),i=pi(i,a.instanceCount);const l=a.material.getTexturesList();i=pi(i,l.length);for(let e=0;e<l.length;e+=1){const t=l[e];i=pi(i,oi(t)),i=pi(i,t.version)}}return`forward-direct:${i}:${e.length}:samples=${this.sampleCount}:formats=${r.join("|")}`}getOrCreateDirectForwardBundle(e,t,r,i=Bh){if(!this.state.device||!this.state.format||0===e.length)return null;const n=this.getDirectForwardBundleKey(e,t,i),a=this.state.directForwardBundleCache.get(n);if(a){for(let t=0;t<e.length;t+=1){const i=e[t];i.materialResource&&this.updateMaterialUniformBuffer(i.material,i.materialResource),this.recordDraw(i,r)}return a}const s=this.state.device.createRenderBundleEncoder({label:`renderer-direct-forward-bundle-${n}`,colorFormats:i,depthStencilFormat:"depth32float",sampleCount:this.sampleCount});let o=null,l=null,c=null,u=null;for(let n=0;n<e.length;n+=1){const a=e[n],d=a.geometryResource,h=this.getMaterialResourceForDraw(a,i),p=this.resolveSceneBindGroupForDraw(a,t);if(o!==h.pipeline&&(o=h.pipeline,c=null,s.setPipeline(o)),c!==a.geometryKey&&(c=a.geometryKey,this.bindGeometryVertexBuffers(s,a.geometry,d,h.vertexAttributes,a.instanceStart,a.instanceCount,a.wireframe)),u!==p&&(u=p,s.setBindGroup(0,p)),l!==a.material){if(l=a.material,s.setBindGroup(1,h.bindGroup),!h.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");s.setBindGroup(3,this.createGraphTextureBindGroup(a.material,h.graphTextureBindGroupLayout))}a.indexed&&(a.wireframe?d.wireframeIndex:d.index)?s.drawIndexed(a.count,a.instanceCount,a.start,0,a.instanceStart):s.draw(a.count,a.instanceCount,a.start,a.instanceStart),this.recordDraw(a,r)}const d=s.finish({label:`renderer-direct-forward-bundle-${n}`});return this.state.directForwardBundleCache.set(n,d),d}getOrCreateStaticMaterialBundle(e,t,r,i){const n=`${oi(t)}:${this.sampleCount}:${i.join("|")}`,a=this.materialPassStaticBundleCache.get(e)?.get(n);if(a)return this.recordStaticDrawStats(e,r),a;const s=this.getOrCreateDirectForwardBundle(e.draws,t,r,i);if(!s)return null;let o=this.materialPassStaticBundleCache.get(e);return o||(o=new Map,this.materialPassStaticBundleCache.set(e,o)),o.set(n,s),s}resolveSceneBindGroupForDraw(e,t){if(!(e.residentInstanceBinding&&this.state.device&&this.state.sceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.shadowComparisonSampler&&this.state.directionalShadowView&&this.state.linearClampSampler&&this.state.pointShadowArrayView&&this.state.spotShadowView&&e.residentInstanceBinding.buffer))return t;const r=e.residentInstanceBinding,i=r.buffer,n=r.colorBuffer??r.buffer;return i&&n?(r.sceneBindGroup&&r.sceneBindGroupVersion===this.state.residentSceneBindGroupVersion||(r.sceneBindGroup=this.state.device.createBindGroup("instanced-direct"===r.mode?{label:"renderer-resident-direct-scene-bind-group",layout:this.state.directSceneBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:1,resource:{buffer:this.state.lightBuffer}},{binding:2,resource:{buffer:i}},{binding:3,resource:{buffer:n}},{binding:4,resource:this.state.shadowComparisonSampler},{binding:5,resource:this.state.directionalShadowView},{binding:6,resource:this.state.linearClampSampler},{binding:7,resource:this.state.pointShadowArrayView},{binding:8,resource:this.state.spotShadowView},{binding:10,resource:this.state.spotLightMapView},{binding:11,resource:this.tiledPointLights.view}]}:{label:"renderer-resident-scene-bind-group",layout:this.state.sceneBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:1,resource:{buffer:this.state.lightBuffer}},{binding:2,resource:{buffer:i}},{binding:3,resource:this.state.shadowComparisonSampler},{binding:4,resource:this.state.directionalShadowView},{binding:5,resource:this.state.linearClampSampler},{binding:6,resource:this.state.pointShadowArrayView},{binding:7,resource:this.state.spotShadowView},{binding:9,resource:this.state.spotLightMapView},{binding:11,resource:this.tiledPointLights.view}]}),r.sceneBindGroupVersion=this.state.residentSceneBindGroupVersion),r.sceneBindGroup):t}resolveShadowBindGroupForDraw(e,t,r=this.state.shadowCameraBuffer){if(!(e.residentInstanceBinding&&this.state.device&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&r&&e.residentInstanceBinding.buffer))return t;const i=e.residentInstanceBinding,n=i.buffer,a=i.colorBuffer??i.buffer;if(!n||!a)return t;if(i.shadowBindGroupVersion!==this.state.residentShadowBindGroupVersion&&(i.shadowBindGroup=null,i.shadowBindGroups.clear(),i.shadowBindGroupVersion=this.state.residentShadowBindGroupVersion),r===this.state.shadowCameraBuffer&&i.shadowBindGroup)return i.shadowBindGroup;const s=i.shadowBindGroups.get(r);if(s)return s;const o=this.state.device.createBindGroup("instanced-direct"===i.mode?{label:"renderer-resident-direct-shadow-bind-group",layout:this.state.directShadowBindGroupLayout,entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:n}},{binding:2,resource:{buffer:a}}]}:{label:"renderer-resident-shadow-bind-group",layout:this.state.shadowBindGroupLayout,entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:n}}]});return i.shadowBindGroups.set(r,o),r===this.state.shadowCameraBuffer&&(i.shadowBindGroup=o),o}uploadDrawMetadata(e){if(!this.state.device||!this.state.visibilityParamsBuffer)return;if(0===e.length)return this.visibilityParamsUpload[0]=0,this.visibilityParamsUpload[1]=this.state.hizMipCount,this.visibilityParamsUpload[2]=0,this.visibilityParamsUpload[3]=0,this.state.device.queue.writeBuffer(this.state.visibilityParamsBuffer,0,this.visibilityParamsUpload,0,4),void(this.state.drawMetadataResource&&(this.state.drawMetadataResource.count=0));const t=e.length*M;this.drawMetadataUpload.length<t&&(this.drawMetadataUpload=new Float32Array(Math.max(t,2*this.drawMetadataUpload.length,768)));const r=5*e.length;this.indirectDrawUpload.length<r&&(this.indirectDrawUpload=new Uint32Array(Math.max(r,2*this.indirectDrawUpload.length,320)));const i=this.drawMetadataUpload,n=this.indirectDrawUpload;for(let t=0;t<e.length;t+=1){const r=e[t],a=t*M;i[a+0]=r.boundsCenter.x,i[a+1]=r.boundsCenter.y,i[a+2]=r.boundsCenter.z,i[a+3]=r.boundsRadius,i[a+4]=r.count,i[a+5]=r.start,i[a+6]=r.instanceStart,i[a+7]=r.instanceCount,i[a+8]=1,i[a+9]=0,i[a+10]=0,i[a+11]=0;const s=5*t;n[s+0]=r.count,n[s+1]=r.instanceCount,n[s+2]=r.start,n[s+3]=0,n[s+4]=r.instanceStart}const a=e.length;if(!(this.state.drawMetadataResource&&this.state.drawMetadataResource.capacity>=a)){this.state.drawMetadataResource?.metadataBuffer.destroy(),this.state.drawMetadataResource?.indirectBuffer.destroy(),this.state.drawMetadataResource?.postIndirectBuffer.destroy();const t=Math.max(64,1<<Math.ceil(Math.log2(a)));this.state.drawMetadataResource={count:e.length,capacity:t,metadataBuffer:this.state.device.createBuffer({label:"renderer-draw-metadata-buffer",size:t*M*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),indirectBuffer:this.state.device.createBuffer({label:"renderer-indirect-draw-buffer",size:5*t*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.INDIRECT|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC}),postIndirectBuffer:this.state.device.createBuffer({label:"renderer-post-indirect-draw-buffer",size:5*t*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.INDIRECT|GPUBufferUsage.COPY_DST})},this.state.visibilityBindGroup=null,this.state.visibilityBindGroupMetadataResource=null,this.clearIndirectBundleCache()}this.state.drawMetadataResource.count=e.length,this.state.device.queue.writeBuffer(this.state.drawMetadataResource.metadataBuffer,0,i,0,t),this.state.device.queue.writeBuffer(this.state.drawMetadataResource.indirectBuffer,0,n,0,r),this.visibilityParamsUpload[0]=e.length,this.visibilityParamsUpload[1]=this.state.hizMipCount,this.visibilityParamsUpload[2]=0,this.visibilityParamsUpload[3]=0,this.state.device.queue.writeBuffer(this.state.visibilityParamsBuffer,0,this.visibilityParamsUpload,0,4)}recordDraw(e,t){t.drawCallCount+=1,t.triangleCount+=Ti(e)}executeVisibilityPass(e,t){Gd.call(this,e,t)}executeStaticVisibilityPasses(e,t){zd.call(this,e,t)}getOrCreateStaticVisibilityBindGroup(e,t){return Rd.call(this,e,t)}executeDirectionalShadowPass(e,t,r,i){Ud.call(this,e,t,r,i)}executePointShadowPass(e,t,r,i){kd.call(this,e,t,r,i)}executeSpotShadowPass(e,t,r,i){Fd.call(this,e,t,r,i)}executeDepthPrepass(e,t,r,i){$d.call(this,e,t,r,i)}executeStaticDepthPrepass(e,t,r){Ed.call(this,e,t,r)}executeStaticTemporalDepthResolvePass(e){_d.call(this,e)}getOrCreateStaticDepthPrepassBundle(e,t){return Nd.call(this,e,t)}executeHiZPasses(e,t=!1,r=!1){qd.call(this,e,t,r)}getOrCreateStaticVisibleSceneBindGroup(e){if(!(this.state.device&&this.state.visibleSceneBindGroupLayout&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.shadowComparisonSampler&&this.state.directionalShadowView&&this.state.linearClampSampler&&this.state.pointShadowArrayView&&this.state.spotShadowView&&this.state.spotLightMapView))throw new Error("Renderer visible scene bind group resources are not initialized.");return e.visibleSceneBindGroup&&e.visibleSceneBindGroupVersion===this.state.residentSceneBindGroupVersion||(e.visibleSceneBindGroup=this.state.device.createBindGroup({label:`${e.label}-static-visible-scene-bind-group`,layout:this.state.visibleSceneBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:1,resource:{buffer:this.state.lightBuffer}},{binding:2,resource:{buffer:e.instanceBuffer}},{binding:3,resource:this.state.shadowComparisonSampler},{binding:4,resource:this.state.directionalShadowView},{binding:5,resource:this.state.linearClampSampler},{binding:6,resource:this.state.pointShadowArrayView},{binding:7,resource:this.state.spotShadowView},{binding:8,resource:{buffer:e.instanceVisibilityResource.visibleInstanceIndicesBuffer}},{binding:9,resource:this.state.spotLightMapView},{binding:11,resource:this.tiledPointLights.view}]}),e.visibleSceneBindGroupVersion=this.state.residentSceneBindGroupVersion),e.visibleSceneBindGroup}getOrCreateStaticVisibleDepthSceneBindGroup(e){if(!this.state.device||!this.state.visibleDepthSceneBindGroupLayout||!this.state.cameraBuffer)throw new Error("Renderer visible depth scene bind group resources are not initialized.");return e.visibleDepthSceneBindGroup&&e.visibleDepthSceneBindGroupVersion===this.state.residentSceneBindGroupVersion||(e.visibleDepthSceneBindGroup=this.state.device.createBindGroup({label:`${e.label}-static-visible-depth-scene-bind-group`,layout:this.state.visibleDepthSceneBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:2,resource:{buffer:e.instanceBuffer}},{binding:3,resource:{buffer:e.instanceVisibilityResource.visibleInstanceIndicesBuffer}}]}),e.visibleDepthSceneBindGroupVersion=this.state.residentSceneBindGroupVersion),e.visibleDepthSceneBindGroup}executeMaterialPass(e,t,r,i,n,a={}){if(!this.state.mainDepthView||0===t.length)return;const s=t.map(e=>this.getColorTargetFormat(e)),o=this.getColorFormatsId(s),l=t.map(e=>this.getColorTargetView(e)),c=this.sampleCount>1,u=c?t.map(e=>this.ensureMsaaColorTarget(e)):[],d=this.getColorTargetDimensions(t[0]),h=c?this.ensureMsaaDepthTarget(d.width,d.height):null,p=e.beginRenderPass({label:"renderer-material-pass",colorAttachments:t.map((e,t)=>({view:u[t]?.view??l[t],resolveTarget:u[t]?l[t]:void 0,clearValue:1===t?{r:.5,g:.5,b:1,a:1}:t>=2?{r:0,g:0,b:0,a:1}:{r:a.clearColor?.[0]??this.clearColor[0],g:a.clearColor?.[1]??this.clearColor[1],b:a.clearColor?.[2]??this.clearColor[2],a:a.clearColor?.[3]??this.clearColor[3]},loadOp:a.loadColor?"load":"clear",storeOp:u[t]?"discard":"store"})),depthStencilAttachment:{view:h?.view??this.state.mainDepthView,depthClearValue:1,depthLoadOp:h?"clear":a.loadDepth?"load":"clear",depthStoreOp:h?"discard":"store"}});let f=null,m=null,g=null,v=null,x=null;const w=e=>{e.sourceObject&&e.hasRenderCallbacks&&e.sourceObject.onBeforeRender(this,i.scene,i.camera,e.geometry,e.material,e.geometryGroup);const t=e.geometryResource;let a=e.material;const o=this.getMaterialResourceForDraw(e,s),l=this.resolveSceneBindGroupForDraw(e,r);if(f!==o.pipeline&&(f=o.pipeline,g=null,x=null,p.setPipeline(f)),g!==e.geometryKey&&(g=e.geometryKey,this.bindGeometryVertexBuffers(p,e.geometry,t,o.vertexAttributes,e.instanceStart,e.instanceCount,e.wireframe)),v!==l&&(v=l,p.setBindGroup(0,l)),m!==a){if(m=a,p.setBindGroup(1,o.bindGroup),!o.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");p.setBindGroup(3,this.createGraphTextureBindGroup(a,o.graphTextureBindGroupLayout))}o.usesSkinning&&e.skinning&&x!==e.skinning.bindGroup&&(x=e.skinning.bindGroup,p.setBindGroup(2,x)),e.indexed&&(e.wireframe?t.wireframeIndex:t.index)?p.drawIndexed(e.count,e.instanceCount,e.start,0,e.instanceStart):p.draw(e.count,e.instanceCount,e.start,e.instanceStart),this.recordDraw(e,n),e.sourceObject&&e.hasRenderCallbacks&&e.sourceObject.onAfterRender(this,i.scene,i.camera,e.geometry,e.material,e.geometryGroup)},b=a.drawStage??"all";if(a.objectFilter||a.overrideMaterial){const e=e=>{if(a.objectFilter){const t=e.sourceRanges?.filter(e=>a.objectFilter(e.sourceObject));if(null!=t&&t.length>0){const r="function"==typeof a.overrideMaterial?a.overrideMaterial(e.material,null!==e.skinning):a.overrideMaterial;for(const i of t)w({...e,sourceObject:i.sourceObject,instanceStart:i.instanceStart,instanceCount:i.instanceCount,material:r??e.material,sourceRanges:void 0});return}if(!a.objectFilter(e.sourceObject))return}const t="function"==typeof a.overrideMaterial?a.overrideMaterial(e.material,null!==e.skinning):a.overrideMaterial;w(t?{...e,material:t}:e)};if("late"!==b){for(const t of this.staticDrawSets)if(t.publicSet.enabled&&"opaque"===t.drawStage)for(const r of t.draws)e(r);for(const t of i.gpuOpaqueDraws)e(t);for(const t of i.directOpaqueDraws)e(t)}if("opaque"!==b)for(const t of i.transparentDraws)e(t);return void p.end()}if("late"!==b){for(const e of this.staticDrawSets){if(!e.publicSet.enabled||0===e.draws.length||"opaque"!==e.drawStage)continue;if(this.getHiZOcclusionCullingActive()&&e.lastVisibilityFrameToken===this.staticFrameToken){const t=this.getOrCreateStaticVisibleSceneBindGroup(e),r=this.getOrCreateStaticIndirectSubmissionStreams(e,t,s);for(const t of r){if(this.getMultiDrawIndirectActive()){if(p.setPipeline(t.materialResource.pipeline),this.bindGeometryVertexBuffers(p,t.geometry,t.geometryResource,t.materialResource.vertexAttributes,0,1,t.material.wireframe),p.setBindGroup(0,t.sceneBindGroup),p.setBindGroup(1,t.materialResource.bindGroup),!t.materialResource.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");p.setBindGroup(3,this.createGraphTextureBindGroup(t.material,t.materialResource.graphTextureBindGroupLayout)),p.multiDrawIndexedIndirect(e.drawMetadataResource.indirectBuffer,5*t.indirectStartIndex*Uint32Array.BYTES_PER_ELEMENT,t.indirectCount)}else this.renderBundleScratch[0]=this.getOrCreateIndirectForwardBundle(t,e.drawMetadataResource,e.indirectForwardBundleCache,`${e.label}-static-indirect-material-bundle`,s,!1,o),p.executeBundles(this.renderBundleScratch);n.drawCallCount+=t.drawCallCount,n.triangleCount+=t.triangleCount}continue}const t=this.getOrCreateStaticMaterialBundle(e,r,n,s);t&&(this.renderBundleScratch[0]=t,p.executeBundles(this.renderBundleScratch))}if(this.getHiZOcclusionCullingActive()&&this.state.drawMetadataResource){const e=this.indirectMaterialResourcesScratch;e.length=i.gpuOpaqueDraws.length;for(let t=0;t<i.gpuOpaqueDraws.length;t+=1)e[t]=this.getMaterialResourceForDraw(i.gpuOpaqueDraws[t],s);const t=this.buildIndirectSubmissionStreams(i.gpuOpaqueDraws,r,void 0,e);for(const e of t){const t=this.getOrCreateIndirectForwardBundle(e,this.state.drawMetadataResource,this.state.indirectForwardBundleCache,"renderer-indirect-material-bundle",s,!0,o);t?(this.renderBundleScratch[0]=t,p.executeBundles(this.renderBundleScratch)):this.submitIndirectStreamDirect(p,e,this.state.drawMetadataResource),n.drawCallCount+=e.drawCallCount,n.triangleCount+=e.triangleCount}}else{const e=hi(i.gpuOpaqueDraws)||i.gpuOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(i.gpuOpaqueDraws,r,n,s);if(e)this.renderBundleScratch[0]=e,p.executeBundles(this.renderBundleScratch);else for(const e of i.gpuOpaqueDraws)w(e)}const e=hi(i.directOpaqueDraws)||i.directOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(i.directOpaqueDraws,r,n,s);if(e)this.renderBundleScratch[0]=e,p.executeBundles(this.renderBundleScratch);else for(const e of i.directOpaqueDraws)w(e)}if("opaque"!==b)for(const e of i.transparentDraws)w(e);p.end()}executeForwardPass(e,t,r,i,n,a,s=!1,o="all",l=!1,c=this.sampleCount){Kd.call(this,e,t,r,i,n,a,s,o,l,c)}executeStaticForwardPass(e,t,r,i="all",n=this.sampleCount){Zd.call(this,e,t,r,i,n)}getOrCreateStaticDirectForwardBundle(e,t,r=this.sampleCount){return Yd.call(this,e,t,r)}refreshStaticDrawMaterialResources(e){Jd.call(this,e)}syncStaticVisibleMaterialBindingCaches(e){Xd.call(this,e)}recordStaticDrawStats(e,t){Qd.call(this,e,t)}hasEnabledStaticDrawSets(){return eh.call(this)}executePresentPass(e,t,r){th.call(this,e,t,r)}clearDirectionalShadow(e){rh.call(this,e)}clearPointShadow(e){ih.call(this,e)}clearSpotShadow(e){nh.call(this,e)}drawDepthLike(e,t,r,i){ah.call(this,e,t,r,i)}getGeometryResource(e){if(!this.state.device)throw new Error("Renderer is not initialized.");const t=this.geometryCache.get(e);if(!this.invokeObjectRenderCallbacks&&t&&t.lastValidatedExtractionVersion===this.extractionVersion)return t;if(t&&this.updateDynamicGeometryAttributes(e,t))return t.lastValidatedExtractionVersion=this.extractionVersion,t;if(t&&t.lastValidatedExtractionVersion===this.extractionVersion)return t;if(t&&function(e,t){if(t.indexVersion!==(e.index?.version??0)||t.drawRangeStart!==e.drawRange.start||t.drawRangeCount!==e.drawRange.count)return!1;if(t.groups.length!==e.groups.length)return!1;for(let r=0;r<t.groups.length;r+=1){const i=t.groups[r],n=e.groups[r];if(i.start!==n?.start||i.count!==n?.count||i.materialIndex!==(n?.materialIndex??0))return!1}for(let r=0;r<t.attributes.length;r+=1){const i=t.attributes[r],n=e.getAttribute(i.name);if(n?n!==i.source||Fr(n)!==i.version||n.itemSize!==i.itemSize||n.count!==i.count:0!==i.version||0!==i.itemSize||0!==i.count)return!1}return!0}(e,t))return t.lastValidatedExtractionVersion=this.extractionVersion,t;t&&(this.clearIndirectBundleCache(),this.retireGeometryResource(t));const r=e.getAttribute("position");if(!r)throw new Error("BufferGeometry is missing the required position attribute.");const i=r.count,n=Yr(r,i,3,[0,0,0]),a=Yr(e.getAttribute("normal"),i,3,[0,0,1]),s=Yr(e.getAttribute("uv"),i,2,[0,0]),o=Yr(e.getAttribute("color"),i,4,[1,1,1,1]),l=e.getAttribute("skinIndex"),c=e.getAttribute("skinWeight"),u=l?Xr(l,i,"uint32x4",[]):void 0,d=c?Xr(c,i,"float32x4",[]):void 0;let h=null,p=null;if(e.index){const t=e.index.array,r=t instanceof Uint32Array?t:new Uint16Array(t);p=t instanceof Uint32Array?"uint32":"uint16",h=Wr(this.state.device,r,GPUBufferUsage.INDEX,`${e.uuid}-index`)}const f={signature:$r(e),indexVersion:e.index?.version??0,drawRangeStart:e.drawRange.start,drawRangeCount:e.drawRange.count,vertexCount:i,attributes:["position","normal","uv","color",...l?["skinIndex"]:[],...c?["skinWeight"]:[]].map(t=>{const r=e.getAttribute(t);return{name:t,source:r,version:Fr(r),itemSize:r?.itemSize??0,count:r?.count??0}}),lastValidatedExtractionVersion:this.extractionVersion,groups:e.groups.map(e=>({start:e.start,count:e.count,materialIndex:e.materialIndex??0})),...this.createGeometryBuffers(e.uuid,n,a,s,o,u,d,e.index?.array),extraAttributeBuffers:new Map,extraAttributeBufferVersions:new Map,wireframeIndex:null,wireframeIndexFormat:null};return this.geometryCache.set(e,f),f}updateDynamicGeometryAttributes(e,t){if(!this.state.device)return!1;let r=!1;for(const i of t.attributes){const t=e.getAttribute(i.name),n=t?.itemSize??0,a=t?.count??0;if(n!==i.itemSize||a!==i.count)return!1;r||=t!==i.source||Fr(t)!==i.version}if(!r)return!1;if(t.indexVersion!==(e.index?.version??0)||t.drawRangeStart!==e.drawRange.start||t.drawRangeCount!==e.drawRange.count||t.groups.length!==e.groups.length)return!1;for(let r=0;r<t.groups.length;r++){const i=t.groups[r],n=e.groups[r];if(i.start!==n?.start||i.count!==n?.count||i.materialIndex!==(n?.materialIndex??0))return!1}const i={position:{buffer:t.position,format:"float32x3",defaults:[0,0,0]},normal:{buffer:t.normal,format:"float32x3",defaults:[0,0,1]},uv:{buffer:t.uv,format:"float32x2",defaults:[0,0]},color:{buffer:t.color,format:"float32x4",defaults:[1,1,1,1]},skinIndex:{buffer:t.skinIndex,format:"uint32x4",defaults:[0,0,0,0]},skinWeight:{buffer:t.skinWeight,format:"float32x4",defaults:[0,0,0,0]}};for(const r of t.attributes){const t=e.getAttribute(r.name),n=Fr(t),a=t!==r.source;if(!a&&n===r.version)continue;const s=i[r.name];if(!t||!s?.buffer)return!1;const o=Number(s.format.at(-1)),l=!a&&"updateRanges"in t&&t.updateRanges.length>0?t.updateRanges:[{start:0,count:t.count*t.itemSize}];for(const e of l){const r=Math.max(0,Math.floor(e.start/t.itemSize)),i=Math.min(t.count,Math.ceil((e.start+e.count)/t.itemSize));if(i<=r)continue;if(t instanceof qc&&!t.normalized&&t.itemSize===o&&("uint32x4"===s.format&&t.array instanceof Uint32Array||"uint32x4"!==s.format&&t.array instanceof Float32Array)){this.state.device.queue.writeBuffer(s.buffer,r*o*4,t.array.buffer,t.array.byteOffset+r*o*4,(i-r)*o*4);continue}const n="uint32x4"===s.format?new Uint32Array((i-r)*o):new Float32Array((i-r)*o);for(let e=r;e<i;e++){const i=(e-r)*o;for(let r=0;r<o;r++){const a=0===r?t.getX(e):1===r&&t.itemSize>1?t.getY(e):2===r&&t.itemSize>2?t.getZ(e):3===r&&t.itemSize>3?t.getW(e):void 0;n[i+r]=a??s.defaults[r]??0}}this.state.device.queue.writeBuffer(s.buffer,r*o*4,n)}"clearUpdateRanges"in t&&t.clearUpdateRanges(),r.version=n,r.source=t}return t.signature=$r(e),!0}getSkinnedGeometryResource(e){if(!this.state.device)throw new Error("Renderer is not initialized.");const t=e.geometry.getAttribute("skinIndex"),r=e.geometry.getAttribute("skinWeight"),i=e.geometry.getAttribute("position");if(!t||!r||!i)throw new Error("SkinnedMesh requires position, skinIndex, and skinWeight attributes.");if(0===e.skeleton.bones.length)throw new Error("SkinnedMesh requires a skeleton with at least one bone.");const n=this.getGeometryResource(e.geometry);let a=this.skinnedGeometryCache.get(e);if(!a||a.resource!==n||a.positionAttribute!==i||a.positionVersion!==Fr(i)||a.skinIndexAttribute!==t||a.skinIndexVersion!==Fr(t)||a.skinWeightAttribute!==r||a.skinWeightVersion!==Fr(r)||a.boneCount!==e.skeleton.bones.length||a.skinning.palette.skeleton!==e.skeleton){a&&a.skinning.bindUniformBuffer.destroy();const s=this.getSkinningPalette(e.skeleton),o=this.state.device.createBuffer({label:`${e.uuid}-skinning-bind-matrices`,size:32*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),l=new Float32Array(32);l.set(e.bindMatrix.elements,0),l.set(e.bindMatrixInverse.elements,16);const c={bindGroup:this.state.device.createBindGroup({label:`${e.uuid}-skinning-bind-group`,layout:this.state.skinningBindGroupLayout,entries:[{binding:0,resource:{buffer:s.matrixBuffer}},{binding:1,resource:{buffer:o}},{binding:2,resource:{buffer:s.previousMatrixBuffer}}]}),bindUniformBuffer:o,bindMatrices:l,palette:s,bindUniformDirty:!0},u={positionAttribute:i,positionVersion:Fr(i),skinIndexAttribute:t,skinIndexVersion:Fr(t),skinWeightAttribute:r,skinWeightVersion:Fr(r),boneCount:e.skeleton.bones.length,resource:n,skinning:c,boneBounds:this.createSkinningBoneBounds(e,i,t,r),localBoundsMin:new uu,localBoundsMax:new uu,localBoundsCenter:new uu,localBoundsRadius:1};a=u,this.skinnedGeometryCache.set(e,u)}if(!a)throw new Error("Skinned geometry cache entry could not be created.");return a}getSkinningPalette(e){const t=this.skinPaletteCache.get(e);if(t&&t.previousMatrices.length===16*e.bones.length)return t;if(!this.state.device||0===e.bones.length)throw new Error("A non-empty skeleton is required to create a GPU skinning palette.");const r=16*e.bones.length;t&&(t.matrixBuffer.destroy(),t.previousMatrixBuffer.destroy(),this.skinPaletteResources.delete(t)),e.boneMatrices.length<r&&(e.boneMatrices=new Float32Array(r)),this.skeletonPalettes.update(e);const i=new Float32Array(r);for(let t=0;t<r;t++)i[t]=e.boneMatrices[t];const n={skeleton:e,matrixBuffer:this.state.device.createBuffer({label:"renderer-skinning-bone-palette",size:r*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),previousMatrixBuffer:this.state.device.createBuffer({label:"renderer-skinning-previous-bone-palette",size:r*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),previousMatrices:i,dirty:!0,previousDirty:!0,previousNeedsAdvance:!1,lastRefreshExtractionVersion:-1};return this.skinPaletteCache.set(e,n),this.skinPaletteResources.add(n),n}refreshSkinningPalette(e){if(e.lastRefreshExtractionVersion===this.extractionVersion)return;e.lastRefreshExtractionVersion=this.extractionVersion;const t=this.skeletonPalettes.update(e.skeleton);e.dirty||=t,e.previousDirty||=t||e.previousNeedsAdvance,e.previousNeedsAdvance=t}refreshSkinningBindMatrices(e,t){const r=t.bindMatrices;let i=!1;for(let t=0;t<16;t+=1){const n=Math.fround(e.bindMatrix.elements[t]),a=Math.fround(e.bindMatrixInverse.elements[t]);r[t]===n&&r[t+16]===a||(i=!0),r[t]=n,r[t+16]=a}t.bindUniformDirty||=i}uploadSkinningPalette(e){if(this.state.device&&(e.previousDirty&&(this.state.device.queue.writeBuffer(e.previousMatrixBuffer,0,e.previousMatrices.buffer,e.previousMatrices.byteOffset,e.previousMatrices.byteLength),e.previousDirty=!1),e.dirty)){const t=e.skeleton.boneMatrices;this.state.device.queue.writeBuffer(e.matrixBuffer,0,t.buffer,t.byteOffset,16*e.skeleton.bones.length*Float32Array.BYTES_PER_ELEMENT);for(let r=0;r<e.previousMatrices.length;r++)e.previousMatrices[r]=t[r];e.dirty=!1}}uploadSkinningResources(e){this.state.device&&(this.uploadSkinningPalette(e.palette),e.bindUniformDirty&&(this.state.device.queue.writeBuffer(e.bindUniformBuffer,0,e.bindMatrices.buffer,e.bindMatrices.byteOffset,e.bindMatrices.byteLength),e.bindUniformDirty=!1))}createSkinningBoneBounds(e,t,r,i){const n=Array.from({length:e.skeleton.bones.length},()=>new uu(1/0,1/0,1/0)),a=Array.from({length:e.skeleton.bones.length},()=>new uu(-1/0,-1/0,-1/0));for(let e=0;e<t.count;e+=1){F.set(t.getX(e),t.getY(e),t.getZ(e));for(let t=0;t<4;t+=1){if(i.getComponent(e,t)<=0)continue;const s=Math.round(r.getComponent(e,t)),o=n[s],l=a[s];o&&l&&(o.min(F),l.max(F))}}return n.map((e,t)=>{if(!Number.isFinite(e.x))return null;const r=a[t],i=e.clone().add(r).multiplyScalar(.5);return{center:i,radius:r.distanceTo(i)}})}updateSkinnedBounds(e,t){const r=t.localBoundsMin,i=t.localBoundsMax,n=Mi(e.geometry);r.set(n.center.x-n.radius,n.center.y-n.radius,n.center.z-n.radius),i.set(n.center.x+n.radius,n.center.y+n.radius,n.center.z+n.radius);for(let n=0;n<t.boneBounds.length;n+=1){const a=t.boneBounds[n];if(!a)continue;const s=Bi(a.center,a.radius,e.bindMatrix,t.skinning.palette.skeleton.boneMatrices,16*n,e.bindMatrixInverse,F);r.min($.copy(F).addScalar(-s)),i.max($.copy(F).addScalar(s))}t.localBoundsCenter.copy(r).add(i).multiplyScalar(.5),t.localBoundsRadius=i.distanceTo(t.localBoundsCenter)}createGeometryBuffers(e,t,r,i,n,a,s,o,l=GPUBufferUsage.VERTEX,c=GPUBufferUsage.VERTEX){if(!this.state.device)throw new Error("Renderer is not initialized.");let u=null,d=null;if(o){const t=o instanceof Uint32Array?o:new Uint16Array(o);d=o instanceof Uint32Array?"uint32":"uint16",u=Wr(this.state.device,t,GPUBufferUsage.INDEX,`${e}-index`)}return{position:Wr(this.state.device,t,l|GPUBufferUsage.COPY_DST,`${e}-position`),normal:Wr(this.state.device,r,c|GPUBufferUsage.COPY_DST,`${e}-normal`),uv:Wr(this.state.device,i,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-uv`),color:Wr(this.state.device,n,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-color`),skinIndex:a?Wr(this.state.device,a,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-skin-index`):null,skinWeight:s?Wr(this.state.device,s,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-skin-weight`):null,index:u,indexFormat:d}}createVertexBufferLayouts(e){return this.getVertexAttributeGroups(e).map(e=>{let t=0;const r=e.map(e=>{const r={shaderLocation:e.shaderLocation,offset:t,format:e.format};return t+=4*Er(e.format),r});return{arrayStride:t,stepMode:e[0].stepMode??"vertex",attributes:r}})}getVertexAttributeGroups(e){const t=this.vertexAttributeGroupCache.get(e);if(t)return t;const r=this.state.device?.limits.maxVertexBuffers??8;if(e.length<=r){const t=e.map(e=>[e]);return this.vertexAttributeGroupCache.set(e,t),t}let i=e.length-r;const n=[],a=new Set;for(const t of["vertex","instance"]){if(0===i)break;const r=e.filter(e=>(e.stepMode??"vertex")===t),s=Math.min(r.length,i+1);if(s<2)continue;const o=r.slice(0,s);n.push(o);for(const e of o)a.add(e);i-=s-1}if(i>0)throw new Error(`Vertex attributes cannot be packed into the device's ${r} vertex-buffer slots.`);const s=[];for(const t of e){if(!a.has(t)){s.push([t]);continue}const e=n.find(e=>e[0]===t);e&&s.push(e)}return this.vertexAttributeGroupCache.set(e,s),s}getGeometryAttributeBufferKey(e){const t=this.vertexAttributeBufferKeyCache.get(e);if(void 0!==t)return t;const r=function(e){const t=e.defaultValue?Array.from(e.defaultValue).join(","):"";return`${e.name}:${e.format}:${e.stepMode??"vertex"}:${t}`}(e);return this.vertexAttributeBufferKeyCache.set(e,r),r}getGeometryAttributeGroupBufferKey(e){const t=this.vertexAttributeGroupBufferKeyCache.get(e);if(void 0!==t)return t;const r=e.map(e=>this.getGeometryAttributeBufferKey(e)).join("|");return this.vertexAttributeGroupBufferKeyCache.set(e,r),r}getMaterialVertexAttributes(e,t){let r=this.materialVertexAttributeCache.get(e);if(r&&r.version===e.version||(r={version:e.version,unskinned:e.vertexAttributes.slice()},this.materialVertexAttributeCache.set(e,r)),!t)return r.unskinned;if(r.skinned)return r.skinned;const i=r.unskinned.slice(),n=[{name:"skinIndex",shaderLocation:4,format:"uint32x4"},{name:"skinWeight",shaderLocation:5,format:"float32x4"}];for(const e of n){const t=i.find(t=>t.name===e.name);if(t){if(t.shaderLocation!==e.shaderLocation||t.format!==e.format)throw new Error(`Skinned material attribute "${e.name}" must use ${e.format} at location ${e.shaderLocation}.`);continue}const r=i.find(t=>t.shaderLocation===e.shaderLocation);if(r)throw new Error(`Skinned material requires location ${e.shaderLocation} for "${e.name}", but it is used by "${r.name}".`);i.push(e)}return r.skinned=i,r.skinned}getGeometryVertexBuffer(e,t,r,i=0,n=1){if(!this.state.device)throw new Error("Renderer is not initialized.");const a=this.getStandardVertexAttribute(r);if(a){const e=t[a];if(e)return e}const s=e.getAttribute(r.name),o="instance"===r.stepMode,l=o?Math.max(0,Math.trunc(i)):0;if(o&&!s)return this.getDefaultInstanceAttributeBuffer(r,l+Math.max(1,n));const c=Fr(s),u=this.geometryVertexBufferFastCache.get(t),d=u?.get(r),h=d?.get(l);if(h&&h.source===s&&h.version===c&&h.itemSize===(s?.itemSize??0)&&h.count===(s?.count??0))return h.buffer;const p=`${this.getGeometryAttributeBufferKey(r)}${o?`:instance-start=${l}`:""}`,f=s?`${c}:${s.itemSize}:${s.count}`:"default",m=t.extraAttributeBuffers.get(p);if(m&&h?.source===s&&t.extraAttributeBufferVersions.get(p)===f)return this.cacheGeometryVertexBufferFast(t,r,l,s,c,m),m;if(!s&&!r.defaultValue)throw new Error(`Geometry "${e.uuid}" is missing required vertex attribute "${r.name}".`);const g=Xr(s,o?l+Math.max(1,s?.count??1,n):t.vertexCount,r.format,r.defaultValue??[],o?l:0,h?.staging);if(m&&m.size>=Math.max(4,g.byteLength))return this.state.device.queue.writeBuffer(m,0,g.buffer,g.byteOffset,g.byteLength),t.extraAttributeBufferVersions.set(p,f),this.cacheGeometryVertexBufferFast(t,r,l,s,c,m,g),m;const v=Wr(this.state.device,g,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e.uuid}-${r.name}-${r.format}`);return m&&(this.clearIndirectBundleCache(),this.retiredGeometryBuffers.push(m)),t.extraAttributeBuffers.set(p,v),t.extraAttributeBufferVersions.set(p,f),this.cacheGeometryVertexBufferFast(t,r,l,s,c,v,g),v}cacheGeometryVertexBufferFast(e,t,r,i,n,a,s){let o=this.geometryVertexBufferFastCache.get(e);o||(o=new WeakMap,this.geometryVertexBufferFastCache.set(e,o));let l=o.get(t);l||(l=new Map,o.set(t,l));const c=i;l.set(r,{source:i,version:n,itemSize:c?.itemSize??0,count:c?.count??0,buffer:a,staging:s&&s.buffer!==(c?.array??c?.data?.array)?.buffer?s:void 0})}packedVertexGroups=new WeakMap;getInterleavedGeometryVertexBuffer(e,t,r,i,n){if(!this.state.device)throw new Error("Renderer is not initialized.");const a=r[0].stepMode??"vertex",s="instance"===a?Math.max(0,Math.trunc(i)):0;let o=this.packedVertexGroups.get(t);o||(o=new WeakMap,this.packedVertexGroups.set(t,o));let l=o.get(r);l||(l=new Map,o.set(r,l));let c=l.get(s);c||(c={key:`interleaved:${this.getGeometryAttributeGroupBufferKey(r)}:instance-start=${s}`,staging:new Ai(r)},l.set(s,c));const u=c.staging.update(e,t.vertexCount,s,n),d=t.extraAttributeBuffers.get(c.key);if(!u&&d)return d;const h=c.staging.data;if(d&&d.size>=Math.max(4,h.byteLength))return this.state.device.queue.writeBuffer(d,0,h.buffer,h.byteOffset,h.byteLength),d;const p=Wr(this.state.device,h,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e.uuid}-interleaved-${a}`);return d&&(this.clearIndirectBundleCache(),this.retiredGeometryBuffers.push(d)),t.extraAttributeBuffers.set(c.key,p),p}ensureWireframeIndex(e,t){if(t.wireframeIndex)return;if(!this.state.device)throw new Error("Renderer is not initialized.");const r=e.index?.array,i=r?.length??t.vertexCount,n=Math.floor(i/3),a=t.vertexCount>65535,s=a?new Uint32Array(6*n):new Uint16Array(6*n);for(let e=0;e<n;e+=1){const t=3*e,i=6*e,n=r?r[t]:t,a=r?r[t+1]:t+1,o=r?r[t+2]:t+2;s[i]=n,s[i+1]=a,s[i+2]=a,s[i+3]=o,s[i+4]=o,s[i+5]=n}t.wireframeIndexFormat=a?"uint32":"uint16",t.wireframeIndex=Wr(this.state.device,s,GPUBufferUsage.INDEX,`${e.uuid}-wireframe-index`)}bindGeometryVertexBuffers(e,t,r,i,n=0,a=1,s=!1){const o=this.prepareGeometryVertexBuffers(t,r,i,n,a);for(let t=0;t<o.length;t+=1)e.setVertexBuffer(t,o[t]);s&&r.wireframeIndex&&r.wireframeIndexFormat?e.setIndexBuffer(r.wireframeIndex,r.wireframeIndexFormat):r.index&&r.indexFormat&&e.setIndexBuffer(r.index,r.indexFormat)}prepareGeometryVertexBuffers(e,t,r,i,n){let a=this.preparedVertexBufferCache.get(t);a||(a=new WeakMap,this.preparedVertexBufferCache.set(t,a));let s=a.get(r);s||(s={instanced:r.some(e=>"instance"===e.stepMode),ranges:new Map},a.set(r,s));const o=s.instanced?Math.max(0,Math.trunc(i)):0,l=s.instanced?n:1;let c=s.ranges.get(o);if(!this.invokeObjectRenderCallbacks&&c&&c.extractionVersion===this.extractionVersion&&c.instanceCount===l&&c.instanceBufferSize===this.state.instanceBufferSize)return c.buffers;c||(c={extractionVersion:-1,instanceCount:l,instanceBufferSize:0,buffers:[]},s.ranges.set(o,c));let u=this.vertexBufferBindingPlanCache.get(r);u||(u=this.getVertexAttributeGroups(r).map(e=>({group:e,standardAttribute:1===e.length?this.getStandardVertexAttribute(e[0]):null})),this.vertexBufferBindingPlanCache.set(r,u));for(let r=0;r<u.length;r+=1){const{group:a,standardAttribute:s}=u[r],o=s?t[s]:null;c.buffers[r]=o??(1===a.length?this.getGeometryVertexBuffer(e,t,a[0],i,n):this.getInterleavedGeometryVertexBuffer(e,t,a,i,n))}return c.extractionVersion=this.extractionVersion,c.instanceCount=l,c.instanceBufferSize=this.state.instanceBufferSize,c.buffers}getStandardVertexAttribute(e){let t=this.standardVertexAttributeCache.get(e);return void 0!==t||(t="position"===e.name&&"float32x3"===e.format?"position":"normal"!==e.name||"float32x3"!==e.format||void 0!==e.defaultValue&&!Kr(e.defaultValue,zh)?"uv"!==e.name||"float32x2"!==e.format||void 0!==e.defaultValue&&!Kr(e.defaultValue,Lh)?"color"!==e.name||"float32x4"!==e.format||void 0!==e.defaultValue&&!Kr(e.defaultValue,Rh)?"skinIndex"===e.name&&"uint32x4"===e.format?"skinIndex":"skinWeight"===e.name&&"float32x4"===e.format?"skinWeight":null:"color":"uv":"normal",this.standardVertexAttributeCache.set(e,t)),t}prepareDrawGeometryVertexBuffers(e){for(let t=0;t<(e.customDepthMaterial?2:1);t++){const r=0===t?e.material:e.customDepthMaterial,i=this.getMaterialVertexAttributes(r,null!==e.skinning);this.prepareGeometryVertexBuffers(e.geometry,e.geometryResource,i,e.instanceStart,e.instanceCount)}}getDefaultInstanceAttributeBuffer(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=Math.max(1,t,Math.ceil(this.state.instanceBufferSize/(Float32Array.BYTES_PER_ELEMENT*C))),i=2**Math.ceil(Math.log2(r)),n=`${e.format}:${(e.defaultValue??[]).join(",")}`;let a=this.defaultInstanceAttributeBuffers.get(n);a||(a=new Map,this.defaultInstanceAttributeBuffers.set(n,a));const s=a.get(i);if(s)return s;const o=Wr(this.state.device,Xr(void 0,i,e.format,e.defaultValue??[]),GPUBufferUsage.VERTEX,`renderer-default-instance-${e.format}`);return a.set(i,o),o}getMeshExtractionCacheEntry(e,t,r,i,n,a){const s=this.meshExtractionCache.get(e),o=Array.isArray(t)?t:null,l=Array.isArray(t)?null:t;if(s&&s.geometryResource===a&&s.customDepthMaterial===n&&(null!==l&&s.material===l&&s.resolvedMaterial===r||null!==o&&null!==s.materials&&null!==s.resolvedMaterials&&Nr(s.materials,o)&&qr(s.resolvedMaterials,i)))return s;const c=null!==e.geometry.index,u=Mi(e.geometry),d=[];if(e.geometry.groups.length>0)for(const t of e.geometry.groups){const s=o?i[t.materialIndex??0]??i[0]:r;if(!s)continue;const l=Jr(e.geometry,c,t.start,t.count),u=li(s,e.geometry,c,t.start,l,n),h=oi(s),p=oi(e.geometry),f=n?oi(n):0;d.push({geometry:e.geometry,geometryKey:e.geometry,geometryResource:a,material:s,customDepthMaterial:n,residentInstanceBinding:null,sourceObject:e,frontFaceCW:e.matrixWorld.determinant()<0,usesBatching:!1,geometryGroup:t,batchKey:u,batchHash:ci(h,p,c,t.start,l,f),indexed:c,wireframe:s.wireframe&&"triangle-list"===s.primitiveTopology,start:t.start,count:l,transparent:s.transparent||s.requiresLatePass(),renderOrder:e.renderOrder,hasRenderCallbacks:this.hasRenderCallbacks(e),castShadow:e.castShadow,receiveShadow:e.receiveShadow,sortMaterialId:h,sortGeometryId:p,sortCustomDepthMaterialId:f})}else{const t=r??i?.[0]??null;if(t){const r=Qr(e.geometry,c),i=li(t,e.geometry,c,r.start,r.count,n),s=oi(t),o=oi(e.geometry),l=n?oi(n):0;d.push({geometry:e.geometry,geometryKey:e.geometry,geometryResource:a,material:t,customDepthMaterial:n,residentInstanceBinding:null,sourceObject:e,frontFaceCW:e.matrixWorld.determinant()<0,usesBatching:!1,geometryGroup:null,batchKey:i,batchHash:ci(s,o,c,r.start,r.count,l),indexed:c,wireframe:t.wireframe&&"triangle-list"===t.primitiveTopology,start:r.start,count:r.count,transparent:t.transparent||t.requiresLatePass(),renderOrder:e.renderOrder,hasRenderCallbacks:this.hasRenderCallbacks(e),castShadow:e.castShadow,receiveShadow:e.receiveShadow,sortMaterialId:s,sortGeometryId:o,sortCustomDepthMaterialId:l})}}const h={geometryResource:a,material:l,materials:o?o.slice():null,resolvedMaterial:r,resolvedMaterials:o?i.slice():null,customDepthMaterial:n,indexed:c,templates:d,localBoundsCenter:u.center.clone(),localBoundsRadius:u.radius};return this.meshExtractionCache.set(e,h),h}getInstancedMeshExtractionCacheEntry(e,t,r,i){const n=null!==e.geometry.index,a=Qr(e.geometry,n),s=Mi(e.geometry),o=this.instancedMeshExtractionCache.get(e);if(o&&o.geometryResource===i&&o.material===t&&o.customDepthMaterial===r&&o.indexed===n&&o.drawRangeStart===a.start&&o.drawRangeCount===a.count)return o.sourceMaterial=e.material,o.sourceMaterialVersion=e.material.version,o;o?.residentInstanceBinding?.buffer?.destroy(),o?.residentInstanceBinding?.colorBuffer?.destroy();const l=oi(t),c=oi(e.geometry),u=r?oi(r):0,d={geometryResource:i,sourceMesh:e,sourceMaterial:e.material,sourceMaterialVersion:e.material.version,material:t,customDepthMaterial:r,indexed:n,drawRangeStart:a.start,drawRangeCount:a.count,batchKey:li(t,e,n,a.start,a.count,r),batchHash:ci(l,c,n,a.start,a.count,u),sortMaterialId:l,sortGeometryId:c,sortCustomDepthMaterialId:u,localBoundsCenter:s.center.clone(),localBoundsRadius:s.radius,cachedInstanceData:new Li(1024),cachedBoundsMin:new uu,cachedBoundsMax:new uu,cachedDrawBoundsCenter:new uu,cachedDrawBoundsRadius:0,cachedMatrixWorld:new Float64Array(16),cachedInstanceMatrixVersion:-1,cachedInstanceColorVersion:-1,cachedCount:0,cachedDefaultColorData:null,residentInstanceBinding:{mode:"packed",buffer:null,colorBuffer:null,sceneBindGroup:null,shadowBindGroup:null,shadowBindGroups:new Map,sceneBindGroupVersion:0,shadowBindGroupVersion:0},residentBufferSize:0,residentColorBufferSize:0,residentBufferDirty:!1,residentColorBufferDirty:!1,cacheValid:!1};return this.instancedMeshExtractionCache.set(e,d),d}getBatchedMeshExtractionCacheEntry(e,t,r,i,n){const a=n._geometryCount??0,s=this.batchedMeshExtractionCache.get(e);if(s&&s.geometryResource===i&&s.material===t&&s.customDepthMaterial===r&&s.indexed===(null!==e.geometry.index)&&s.cachedGeometryCount===a)return s;s?.residentInstanceBinding?.buffer?.destroy(),s?.residentInstanceBinding?.colorBuffer?.destroy();const o=null!==e.geometry.index,l=new Array(a).fill(null),c=new Array(a).fill(null);for(let n=0;n<a;n+=1){const a=e.getGeometryRangeAt(n);if(!a||a.count<=0)continue;const s=Jr(e.geometry,o,a.start,a.count),u=li(t,e.geometry,o,a.start,s,r),d=oi(t),h=oi(e.geometry),p=r?oi(r):0,f=e.getBoundingSphereAt(n,k),m={geometry:e.geometry,geometryKey:e.geometry,geometryResource:i,material:t,customDepthMaterial:r,residentInstanceBinding:null,sourceObject:e,frontFaceCW:!1,usesBatching:!0,geometryGroup:null,batchKey:u,batchHash:ci(d,h,o,a.start,s,p),indexed:o,wireframe:t.wireframe&&"triangle-list"===t.primitiveTopology,start:a.start,count:s,transparent:t.transparent||t.requiresLatePass(),renderOrder:e.renderOrder,hasRenderCallbacks:this.hasRenderCallbacks(e),castShadow:e.castShadow,receiveShadow:e.receiveShadow,sortMaterialId:d,sortGeometryId:h,sortCustomDepthMaterialId:p,geometryId:n,localBoundsCenter:f?f.center.clone():new uu,localBoundsRadius:f?.radius??1};l[n]=m,c[n]={template:m,boundsMin:new uu,boundsMax:new uu,activeInFrame:!1,activeCount:0,instanceStart:0,writeOffset:0}}const u={geometryResource:i,material:t,customDepthMaterial:r,indexed:o,templates:l,groups:c,activeGroups:[],cachedInstanceData:new Li(1024),cachedDraws:[],cachedBoundsMin:new uu,cachedBoundsMax:new uu,cachedMatrixWorld:new Float64Array(16),geometryIdsSnapshot:new Int32Array(0),cachedMatricesVersion:-1,cachedColorsVersion:-1,cachedGeometryCount:a,cachedInstanceInfoLength:0,residentInstanceBinding:{mode:"packed",buffer:null,colorBuffer:null,sceneBindGroup:null,shadowBindGroup:null,shadowBindGroups:new Map,sceneBindGroupVersion:0,shadowBindGroupVersion:0},residentBufferSize:0,residentColorBufferSize:0,residentBufferDirty:!1,residentColorBufferDirty:!1,cacheValid:!1};return this.batchedMeshExtractionCache.set(e,u),u}batchedGeometryIdsMatchSnapshot(e,t){if(e.length!==t.length)return!1;for(let r=0;r<t.length;r+=1){const i=t[r];if((e[r]??-1)!==(i?.active&&i.visible?i.geometryIndex:-1))return!1}return!0}destroyGeometryResource(e){e.position.destroy(),e.normal.destroy(),e.uv.destroy(),e.color.destroy(),e.skinIndex?.destroy(),e.skinWeight?.destroy();for(const t of e.extraAttributeBuffers.values())t.destroy();e.extraAttributeBuffers.clear(),e.extraAttributeBufferVersions.clear(),e.index?.destroy(),e.wireframeIndex?.destroy()}retireGeometryResource(e){this.retiredGeometryResources.push(e)}releaseRetiredGeometryResourcesAfterSubmit(){const e=this.retiredGeometryResources.splice(0),t=this.retiredGeometryBuffers.splice(0);if(0!==e.length||0!==t.length)if(this.state.device)this.state.device.queue.onSubmittedWorkDone().then(()=>{for(const t of e)this.destroyGeometryResource(t);for(const e of t)e.destroy()},()=>{for(const t of e)this.destroyGeometryResource(t);for(const e of t)e.destroy()});else{for(const t of e)this.destroyGeometryResource(t);for(const e of t)e.destroy()}}destroyTextureResource(e){this.textureManager.destroyTextureResource(e)}createTextureSampler(e,t){return this.textureManager.createTextureSampler(e,t)}uploadDataTextureResource(e,t,r){this.textureManager.uploadDataTextureResource(e,t,r)}uploadCompressedTextureResource(e,t,r){this.textureManager.uploadCompressedTextureResource(e,t,r)}uploadExternalTextureResource(e,t,r){this.textureManager.uploadExternalTextureResource(e,t,r)}uploadTextureResource(e,t,r){this.textureManager.uploadTextureResource(e,t,r)}getTextureResource(e){return this.textureManager.getTextureResource(e)}updateMaterialUniformBuffer(e,t){if(!this.state.device||!t.uniformBuffer)return;const r=e.getUniformLayout();if(0===r.entries.length)return;let i=t.uniformValueHash;if(e.uniformValuesAutoUpdate){if(i=e.getUniformValueHash(),t.uniformValueHash===i)return}else if(t.uniformValuesAutoVersion===e.uniformValuesAutoVersion)return;const n=Wt(e.uniforms,r);!t.uniformBuffer||n.byteLength>t.uniformBuffer.size||(t.uniformValueHash=i,t.uniformValuesAutoVersion=e.uniformValuesAutoVersion,this.state.device.queue.writeBuffer(t.uniformBuffer,0,n))}materialResourceMatches(e,t,r,i=this.sampleCount){if(e.key!==r)return!1;if(e.materialVersion===t.version&&e.textureVersionHash===t.getTextureVersionHash()&&e.rendererSampleCount===i&&e.uniformBufferSize===t.getUniformLayout().byteLength)return!0;const n=qr(e.textures,t.getTexturesList())&&Kr(e.textureVersions,t.getTextureVersionsList())&&qr(e.storageBuffers,t.getStorageBufferList())&&e.rendererSampleCount===i&&e.uniformBufferSize===t.getUniformLayout().byteLength;return n&&(e.materialVersion=t.version,e.textureVersionHash=t.getTextureVersionHash()),n}destroyMaterialResource(e){e?.uniformBuffer?.destroy()}createMaterialBindGroupData(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const i=this.pipelineCompilationDiagnostics,n=i?performance.now():0,a=[],s=[],o=Array.from(e.getTexturesList()),l=Array.from(e.getTextureVersionsList()),c=e.getStorageBufferBindingList();let u=null;const d=i?performance.now():0;if(Object.keys(e.uniforms).length>0){const r=Wt(e.uniforms,e.getUniformLayout());u=this.state.device.createBuffer({label:`${t}-uniforms`,size:r.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.state.device.queue.writeBuffer(u,0,r),a.push({binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}),s.push({binding:0,resource:{buffer:u}})}i&&(i.cpuTotalsMs.uniformBuffer=(i.cpuTotalsMs.uniformBuffer??0)+performance.now()-d);for(const[t,n]of o.entries()){const o=1+2*t,l=i?performance.now():0,c=this.getTextureResource(n);if(i){const t=performance.now()-l;i.cpuTotalsMs.textureLookup=(i.cpuTotalsMs.textureLookup??0)+t,t>=1&&i.slowTextureLookups.push({material:e.name||e.uuid,texture:n.name||n.uuid,durationMs:t})}a.push({binding:o,visibility:r,sampler:{type:c.samplerBindingType}},{binding:o+1,visibility:r,texture:{sampleType:c.sampleType,viewDimension:c.viewDimension}}),s.push({binding:o,resource:c.sampler},{binding:o+1,resource:c.view})}const h=1+2*o.length,p=Array.from(e.getStorageBufferList());for(const[e,t]of c.entries()){const r=h+e;a.push({binding:r,visibility:Hr(t.visibility),buffer:{type:"read-only-storage"}}),s.push({binding:r,resource:{buffer:t.buffer}})}return i&&(i.cpuTotalsMs.bindGroupData=(i.cpuTotalsMs.bindGroupData??0)+performance.now()-n),{bindGroupLayoutEntries:a,bindGroupEntries:s,uniformBuffer:u,textures:o,textureVersions:l,storageBuffers:p}}createGraphTextureBindGroupLayout(e){if(!this.state.device)throw new Error("Renderer is not initialized.");const t=[];return Object.values(e.getGraphTextureInputs()).forEach((e,r)=>{t.push({binding:2*r,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,sampler:{type:e.sampler??("depth-2d"===e.dimension?"non-filtering":"filtering")}},{binding:2*r+1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,texture:{sampleType:e.sampleType??("depth-2d"===e.dimension?"depth":"float"),viewDimension:"3d"===e.dimension?"3d":"2d"}})}),this.state.device.createBindGroupLayout({label:`${e.uuid}-graph-textures-layout`,entries:t})}createGraphTextureBindGroup(e,t){if(!(this.state.device&&this.state.linearClampSampler&&this.state.nearestClampSampler&&this.state.shadowComparisonSampler))throw new Error("Renderer graph texture bindings are not initialized.");let r=this.graphTextureBindGroupCache.get(e);const i=r?.get(t);if(i&&i.materialVersion===e.version&&i.resourceVersion===this.graphTextureResourceVersion)return i.bindGroup;const n=[];Object.values(e.getGraphTextureInputs()).forEach((e,t)=>{const r="comparison"===e.sampler?this.state.shadowComparisonSampler:"non-filtering"===e.sampler||"depth-2d"===e.dimension?this.state.nearestClampSampler:"physicalTransmissionSnapshot"===e.resource?this.transmissionSampler:this.state.linearClampSampler,i="mainDepth"===e.resource?this.state.sceneDepthSnapshotView:this.getGraphTextureView(e.resource);n.push({binding:2*t,resource:r},{binding:2*t+1,resource:i})});const a=this.state.device.createBindGroup({label:`${e.uuid}-graph-textures`,layout:t,entries:n});return r||(r=new WeakMap,this.graphTextureBindGroupCache.set(e,r)),r.set(t,{materialVersion:e.version,resourceVersion:this.graphTextureResourceVersion,bindGroup:a}),a}getGraphTextureView(e){return"physicalTransmissionSnapshot"===e?this.transmissionSnapshotView:"mainDepth"===e?this.state.mainDepthView:"sceneColorSnapshot"===e?this.state.sceneColorSnapshotView:"sceneDepthSnapshot"===e?this.state.hizMipViews[0]:this.getColorTargetView(e)}compileDrawMaterials(e){const t=new Set;for(const r of e){const e=this.getDrawInstanceAccessMode(r),i=null!==r.skinning,n=this.drawUsesBatching(r),a=`${r.material.uuid}:${e}:receiveShadow=${r.receiveShadow?1:0}:skinning=${i?1:0}:batching=${n?1:0}`;t.has(a)||(r.materialResource=this.getMaterialResource(r.material,e,r.receiveShadow,void 0,i,n),t.add(a))}}async compileDrawMaterialsAsync(e,t=Bh,r=this.sampleCount,i=!0){const n=new Set,a=new Set,s=[],o=[];for(const l of e){const e=this.getDrawInstanceAccessMode(l);i&&l.residentInstanceBinding&&l.sourceObject instanceof eu&&o.push({...l,materialResource:null,residentInstanceBinding:{...l.residentInstanceBinding,mode:"packed"===e?"instanced-direct":"packed"}});const c=null!==l.skinning,u=this.drawUsesBatching(l),d=`${l.material.uuid}:${e}:receiveShadow=${l.receiveShadow?1:0}:skinning=${c?1:0}:batching=${u?1:0}`;if(n.has(d)||(s.push(this.getMaterialResourceAsync(l.material,e,l.receiveShadow,t,c,u,r).then(e=>(l.materialResource=e,e))),n.add(d)),l.customDepthMaterial){const t=`${l.customDepthMaterial.uuid}:${e}:skinning=${c?1:0}`;a.has(t)||(s.push(this.getDepthPassMaterialResourceAsyncForDraw(l.customDepthMaterial,"directionalShadow",l)),a.add(t))}if(null!==l.material.depthVertexShader||u){const t=null!==l.material.depthVertexShader?["prepass","directionalShadow","pointShadow"]:["prepass","directionalShadow"];for(const r of t){const t=`${l.material.uuid}:${r}:${e}:skinning=${c?1:0}:batching=${u?1:0}`;a.has(t)||(s.push(this.getDepthPassMaterialResourceAsyncForDraw(l.material,r,l)),a.add(t))}}}o.length>0&&s.push(this.compileDrawMaterialsAsync(o,t,r,!1)),await Promise.all(s)}async compileStaticDrawMaterialsAsync(e,t=this.sampleCount,r="all"){const i=[],n=new Set;for(const a of this.staticDrawSets)if(a.publicSet.enabled&&("all"===r||a.drawStage===r)){i.push(this.compileDrawMaterialsAsync(a.draws,e,t));for(const r of a.visibleMaterialBindings){const a=`${r.material.uuid}:receiveShadow=${r.receiveShadow?1:0}:batching=${r.usesBatching?1:0}`;n.has(a)||(n.add(a),i.push(this.getMaterialResourceAsync(r.material,"packed-visible",r.receiveShadow,e,!1,r.usesBatching,t)))}if(this.directionalShadowGpu.available)for(const e of a.draws){const t=e.customDepthMaterial??(null!==e.material.depthVertexShader?e.material:null);if(!t||t.vertexAttributes.some(e=>"instance"===e.stepMode))continue;const r=`shadow-visible:${t.uuid}:${this.drawUsesBatching(e)}:${gi(e)}`;n.has(r)||(n.add(r),i.push(this.getDepthPassMaterialResourceAsync(t,"directionalShadow","packed-visible",!1,this.drawUsesBatching(e),gi(e))))}}await Promise.all(i)}getDepthPassMaterialKey(e,t,r,i,n,a=!1){if(!this.state.device)throw new Error("Renderer is not initialized.");return`${e.getDepthProgramCacheKey("pointShadow"===t)}:${t}:instance=${r}:skinning=${i?1:0}:batching=${n?1:0}:frontFace=${a?"cw":"ccw"}:textures=${e.getTextureLayoutKey(this.state.device)}`}getForwardMaterialKey(e,t,r,i,n,a,s=!1,o=this.sampleCount){return`${e.customProgramCacheKey()}:instance=${t}:receiveShadow=${r?1:0}:skinning=${n?1:0}:batching=${a?1:0}:frontFace=${s?"cw":"ccw"}:textures=${e.getTextureLayoutKey(this.state.device)}:samples=${o}:targets=${i.join("|")}`}getInstanceAccessModeIndex(e){return"packed"===e?0:"packed-visible"===e?1:2}getForwardMaterialFastCacheIndex(e,t,r,i,n=!1){return this.getInstanceAccessModeIndex(e)|(t?4:0)|(r?8:0)|(i?16:0)|(n?32:0)}getDepthMaterialFastCacheIndex(e,t,r,i,n=!1){return("prepass"===e?0:"directionalShadow"===e?1:2)+3*this.getInstanceAccessModeIndex(t)+(r?9:0)+(i?18:0)+(n?36:0)}fastMaterialResourceMatches(e,t,r=this.sampleCount){return e.materialVersion===t.version&&e.textureVersionHash===t.getTextureVersionHash()&&e.rendererSampleCount===r}setForwardMaterialFastCache(e,t,r){let i=this.forwardMaterialFastCache.get(e);i||(i=[],this.forwardMaterialFastCache.set(e,i)),i[t]=r}getForwardMaterialTargetFastCacheKey(e,t){return 32*this.getColorFormatsId(e)+t}setForwardMaterialTargetFastCache(e,t,r){let i=this.forwardMaterialTargetFastCache.get(e);i||(i=new Map,this.forwardMaterialTargetFastCache.set(e,i)),i.set(t,r)}setForwardMaterialFrameCache(e,t,r){let i=this.forwardMaterialFrameCache.get(e);i||(i=[],this.forwardMaterialFrameCache.set(e,i)),i[t]={extractionVersion:this.extractionVersion,resource:r}}setDepthMaterialFastCache(e,t,r){let i=this.depthMaterialFastCache.get(e);i||(i=[],this.depthMaterialFastCache.set(e,i)),i[t]=r}getDrawInstanceAccessMode(e){return"instanced-direct"===e.residentInstanceBinding?.mode?"instanced-direct":"packed"}drawUsesBatching(e){return e.usesBatching}buildMaterialShaderCode(e,t,r,i,n=!1,a=!1){const s=this.pipelineCompilationDiagnostics,o=s?performance.now():0,l=fu(`${t}\n${r}`,this.createMaterialPreprocessorDefines(e,i,n,a),{sourceName:i}),c=i.includes("vertex")?function(e){let t=0,r=0,i=null;for(;;){const n=e.indexOf("@builtin",t);if(n<0)break;t=n+8;let a=t;for(;zu(e.charCodeAt(a));)a++;if("("!==e[a++])continue;for(;zu(e.charCodeAt(a));)a++;if(!e.startsWith("position",a))continue;for(a+=8;zu(e.charCodeAt(a));)a++;if(")"!==e[a++])continue;Lu.lastIndex=a;const s=Lu.exec(e);s&&(i??=[],i.push(e.slice(r,n),"@builtin(position) @invariant "),r=a+s[0].length,t=r)}return null===i?e:(i.push(e.slice(r)),i.join(""))}(l):l;return s&&(s.cpuTotalsMs.shaderPreprocess=(s.cpuTotalsMs.shaderPreprocess??0)+performance.now()-o),c}createMaterialPreprocessorDefines(e,t,r=!1,i=!1){const n={HIGH_PRECISION:!0,WEBGPU_RENDERER:!0,WGSL_SHADER_MATERIAL:!0,USE_BATCHING:i,USE_COLOR:!0,USE_COLOR_ALPHA:!0,NUM_DIR_LIGHTS:4,NUM_POINT_LIGHTS:y,NUM_SPOT_LIGHTS:S,NUM_DIR_LIGHT_SHADOWS:4,NUM_POINT_LIGHT_SHADOWS:y,NUM_SPOT_LIGHT_SHADOWS:S,NUM_CLIPPING_PLANES:0,UNION_CLIPPING_PLANES:0,USE_SKINNING:r,RENDERER_MOTION_VECTORS:!t.includes("shared-depth"),...this.createTexturePreprocessorDefines(e)};return e.side===Yc?n.DOUBLE_SIDED=!0:e.side===Hc&&(n.FLIP_SIDED=!0),!t.includes("receiveShadow=1")&&t.includes("receiveShadow=0")||(n.USE_SHADOWMAP=!0,n.SHADOWMAP_TYPE_PCF=!0),{...n,...e.defines,USE_BATCHING:i}}createTexturePreprocessorDefines(e){const t={},r={map:"USE_MAP",matcap:"USE_MATCAP",lightMap:"USE_LIGHTMAP",aoMap:"USE_AOMAP",bumpMap:"USE_BUMPMAP",normalMap:"USE_NORMALMAP",displacementMap:"USE_DISPLACEMENTMAP",emissiveMap:"USE_EMISSIVEMAP",anisotropyMap:"USE_ANISOTROPYMAP",clearcoatMap:"USE_CLEARCOATMAP",clearcoatRoughnessMap:"USE_CLEARCOAT_ROUGHNESSMAP",clearcoatNormalMap:"USE_CLEARCOAT_NORMALMAP",iridescenceMap:"USE_IRIDESCENCEMAP",iridescenceThicknessMap:"USE_IRIDESCENCE_THICKNESSMAP",specularMap:"USE_SPECULARMAP",specularColorMap:"USE_SPECULAR_COLORMAP",specularIntensityMap:"USE_SPECULAR_INTENSITYMAP",roughnessMap:"USE_ROUGHNESSMAP",metalnessMap:"USE_METALNESSMAP",alphaMap:"USE_ALPHAMAP",sheenColorMap:"USE_SHEEN_COLORMAP",sheenRoughnessMap:"USE_SHEEN_ROUGHNESSMAP",transmissionMap:"USE_TRANSMISSIONMAP",thicknessMap:"USE_THICKNESSMAP"};for(const[i,n]of Object.entries(r))e.textures[i]&&(t[n]=!0);return t}shouldInvalidateDrawMaterialResource(e,t,r,i,n){return!!e.materialResource&&(e.material!==t||e.receiveShadow!==r||e.usesBatching!==i||e.skinning!==n)}cachedDrawMaterialResourceMatches(e,t,r,i=this.sampleCount){const n=this.getDrawInstanceAccessMode(e),a=null!==e.skinning,s=this.drawUsesBatching(e),o=this.getColorFormatsId(r);return t.instanceAccessMode===n&&t.receiveShadow===e.receiveShadow&&t.useBatching===s&&t.frontFaceCW===gi(e)&&t.usesSkinning===a&&t.rendererSampleCount===i&&t.colorTargetFormatsId===o&&(this.drawMaterialResourceFrameValidation.get(t)===this.extractionVersion||(t.materialVersion===e.material.version&&t.textureVersionHash===e.material.getTextureVersionHash()||this.materialResourceMatches(t,e.material,t.key,i)))}getMaterialResourceForDraw(e,t=Bh,r=this.sampleCount){const i=e.materialResource;if(i&&this.cachedDrawMaterialResourceMatches(e,i,t,r))return this.drawMaterialResourceFrameValidation.get(i)!==this.extractionVersion&&(this.updateMaterialUniformBuffer(e.material,i),this.drawMaterialResourceFrameValidation.set(i,this.extractionVersion)),i;const n=this.getDrawInstanceAccessMode(e),a=null!==e.skinning,s=this.drawUsesBatching(e),o=this.getMaterialResource(e.material,n,e.receiveShadow,t,a,s,r,gi(e));return e.materialResource=o,this.drawMaterialResourceFrameValidation.set(o,this.extractionVersion),o}getMaterialResourceAsyncForDraw(e){return this.getMaterialResourceAsync(e.material,this.getDrawInstanceAccessMode(e),e.receiveShadow,void 0,null!==e.skinning,this.drawUsesBatching(e),this.sampleCount,gi(e))}resolveForwardMaterialResources(e){for(let t=0;t<e.length;t+=1){const r=e[t];r.materialResource=this.getMaterialResource(r.material,this.getDrawInstanceAccessMode(r),r.receiveShadow,void 0,null!==r.skinning,this.drawUsesBatching(r),this.sampleCount,gi(r))}}getDepthPassMaterialResourceForDraw(e,t,r,i){return this.getDepthPassMaterialResource(e,t,i??this.getDrawInstanceAccessMode(r),null!==r.skinning,this.drawUsesBatching(r),gi(r))}getDepthPassMaterialResourceAsyncForDraw(e,t,r){return this.getDepthPassMaterialResourceAsync(e,t,this.getDrawInstanceAccessMode(r),null!==r.skinning,this.drawUsesBatching(r),gi(r))}getOrCreateSharedDepthPipeline(e,t,i,n,a,s,o,l){if(!(this.state.device&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&this.state.skinningBindGroupLayout))throw new Error("Renderer is not initialized.");const c=this.sharedDepthPipelineCache.get(e);if(c)return c;const u=`${t.uuid}-shared-depth-${i}-${n}`;r(this.state.device,u+"-pipeline",{key:String(t.userData.pipelineOrigin?.assetId??t.userData.assetId??t.userData.pipelineOrigin?.sourceUuid??t.uuid)+":depth:"+i,material:{name:t.name,uuid:t.uuid,version:t.version,assetId:t.userData.assetId,assetName:t.userData.assetName,...t.userData.pipelineOrigin},variant:{instanceAccessMode:n,useSkinning:s,useBatching:o,passKind:i,frontFaceCW:l},defines:{...t.defines}});const d=this.state.device.createBindGroupLayout({label:`${u}-material-layout`,entries:a}),h="prepass"===i?"instanced-direct"===n?this.state.directSceneBindGroupLayout:this.state.sceneBindGroupLayout:"packed"!==n?this.state.directShadowBindGroupLayout:this.state.shadowBindGroupLayout,p=this.state.device.createPipelineLayout({label:`${u}-pipeline-layout`,bindGroupLayouts:[h,d,...s?[this.state.skinningBindGroupLayout]:[]]}),f=rd(t,"prepass"===i?"camera":"shadow",this.state.device,n,s),m=this.buildMaterialShaderCode(t,f,"pointShadow"===i?t.pointShadowVertexShader??t.vertexShader:t.depthVertexShader??t.vertexShader,`${u}-vertex`,s,o),g="pointShadow"===i?t.pointShadowFragmentShader:t.depthFragmentShader,v=g?this.buildMaterialShaderCode(t,f,g,`${u}-fragment`,s,o):null,x={bindGroupLayout:d,pipeline:this.state.device.createRenderPipeline({label:`${u}-pipeline`,layout:p,vertex:{module:this.state.device.createShaderModule({label:`${u}-vertex`,code:m}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,s))},...v?{fragment:{module:this.state.device.createShaderModule({label:`${u}-fragment`,code:v}),entryPoint:"fsMain",targets:"pointShadow"===i?[{format:"rgba16float"}]:[]}}:{},primitive:{topology:Th(t),cullMode:Ih(t,i,o),frontFace:l?"cw":"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",..."directionalShadow"===i?{depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}:{}}})};return this.sharedDepthPipelineCache.set(e,x),x}async getOrCreateSharedDepthPipelineAsync(e,t,i,n,a,s,o,l){if(!(this.state.device&&this.state.sceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&this.state.skinningBindGroupLayout))throw new Error("Renderer is not initialized.");const c=this.sharedDepthPipelineCache.get(e);if(c)return c;const u=this.sharedDepthPipelinePromiseCache.get(e);if(u)return u;const d=`${t.uuid}-shared-depth-${i}-${n}`;r(this.state.device,d+"-pipeline",{key:String(t.userData.pipelineOrigin?.assetId??t.userData.assetId??t.userData.pipelineOrigin?.sourceUuid??t.uuid)+":depth:"+i,material:{name:t.name,uuid:t.uuid,version:t.version,assetId:t.userData.assetId,assetName:t.userData.assetName,...t.userData.pipelineOrigin},variant:{instanceAccessMode:n,useSkinning:s,useBatching:o,passKind:i,frontFaceCW:l},defines:{...t.defines}});const h=(async()=>{const r=this.state.device.createBindGroupLayout({label:`${d}-material-layout`,entries:a}),c="prepass"===i?"instanced-direct"===n?this.state.directSceneBindGroupLayout:this.state.sceneBindGroupLayout:"packed"!==n?this.state.directShadowBindGroupLayout:this.state.shadowBindGroupLayout,u=this.state.device.createPipelineLayout({label:`${d}-pipeline-layout`,bindGroupLayouts:[c,r,...s?[this.state.skinningBindGroupLayout]:[]]}),h=rd(t,"prepass"===i?"camera":"shadow",this.state.device,n,s),p=this.buildMaterialShaderCode(t,h,"pointShadow"===i?t.pointShadowVertexShader??t.vertexShader:t.depthVertexShader??t.vertexShader,`${d}-vertex`,s,o),f="pointShadow"===i?t.pointShadowFragmentShader:t.depthFragmentShader,m=f?this.buildMaterialShaderCode(t,h,f,`${d}-fragment`,s,o):null,g={bindGroupLayout:r,pipeline:await Uh(this.state.device,{label:`${d}-pipeline`,layout:u,vertex:{module:this.state.device.createShaderModule({label:`${d}-vertex`,code:p}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,s))},...m?{fragment:{module:this.state.device.createShaderModule({label:`${d}-fragment`,code:m}),entryPoint:"fsMain",targets:"pointShadow"===i?[{format:"rgba16float"}]:[]}}:{},primitive:{topology:Th(t),cullMode:Ih(t,i,o),frontFace:l?"cw":"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",..."directionalShadow"===i?{depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}:{}}},this.pipelineCompilationDiagnostics,"depth",`${t.name||"unnamed"} [${t.uuid}] (${i}, ${n})`,p.length,m?.length??0)};return this.sharedDepthPipelineCache.set(e,g),this.sharedDepthPipelinePromiseCache.delete(e),g})();return this.sharedDepthPipelinePromiseCache.set(e,h),h}getOrCreateSharedForwardPipeline(e,t,i,n,a,s,o,l,c,u=this.sampleCount){if(!(this.state.device&&this.state.format&&this.state.sceneBindGroupLayout&&this.state.visibleSceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.skinningBindGroupLayout&&this.state.emptyBindGroupLayout))throw new Error("Renderer is not initialized.");const d=this.sharedForwardPipelineCache.get(e);if(d)return d;const h=`${t.uuid}-shared-forward-${i}-${u}-receiveShadow=${a?1:0}`;r(this.state.device,h+"-pipeline",{key:String(t.userData.pipelineOrigin?.assetId??t.userData.assetId??t.userData.pipelineOrigin?.sourceUuid??t.uuid)+":forward",material:{name:t.name,uuid:t.uuid,version:t.version,assetId:t.userData.assetId,assetName:t.userData.assetName,...t.userData.pipelineOrigin},variant:{instanceAccessMode:i,useSkinning:o,useBatching:l,receiveShadow:a,sampleCount:u,colorTargetFormats:s},defines:{...t.defines}});const p=this.state.device.createBindGroupLayout({label:`${h}-material-layout`,entries:n}),f=this.createGraphTextureBindGroupLayout(t),m=this.state.device.createPipelineLayout({label:`${h}-pipeline-layout`,bindGroupLayouts:["instanced-direct"===i?this.state.directSceneBindGroupLayout:"packed-visible"===i?this.state.visibleSceneBindGroupLayout:this.state.sceneBindGroupLayout,p,o?this.state.skinningBindGroupLayout:this.state.emptyBindGroupLayout,f]}),g=ed(t,this.state.device,i,a,o),v=this.buildMaterialShaderCode(t,g,t.vertexShader,`${h}-vertex`,o,l),x=this.buildMaterialShaderCode(t,g,t.fragmentShader,`${h}-fragment`,o,l),w={bindGroupLayout:p,graphTextureBindGroupLayout:f,pipeline:this.state.device.createRenderPipeline({label:`${h}-pipeline`,layout:m,vertex:{module:this.state.device.createShaderModule({label:`${h}-vertex`,code:v}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,o))},fragment:{module:this.state.device.createShaderModule({label:`${h}-fragment`,code:x}),entryPoint:"fsMain",targets:yh(x,s,wh(t))},primitive:{topology:Th(t),cullMode:Th(t).startsWith("triangle")&&t.side!==Yc?t.side===Hc?"front":"back":"none",frontFace:c?"cw":"ccw"},multisample:{count:u},depthStencil:{format:"depth32float",depthWriteEnabled:t.depthWrite,depthCompare:t.depthTest?"less-equal":"always"}})};return this.sharedForwardPipelineCache.set(e,w),w}async getOrCreateSharedForwardPipelineAsync(e,t,i,n,a,s,o,l,c,u=this.sampleCount){if(!(this.state.device&&this.state.format&&this.state.sceneBindGroupLayout&&this.state.visibleSceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.skinningBindGroupLayout&&this.state.emptyBindGroupLayout))throw new Error("Renderer is not initialized.");const d=this.sharedForwardPipelineCache.get(e);if(d)return d;const h=this.sharedForwardPipelinePromiseCache.get(e);if(h)return h;const p=`${t.uuid}-shared-forward-${i}-${u}-receiveShadow=${a?1:0}`;r(this.state.device,p+"-pipeline",{key:String(t.userData.pipelineOrigin?.assetId??t.userData.assetId??t.userData.pipelineOrigin?.sourceUuid??t.uuid)+":forward",material:{name:t.name,uuid:t.uuid,version:t.version,assetId:t.userData.assetId,assetName:t.userData.assetName,...t.userData.pipelineOrigin},variant:{instanceAccessMode:i,useSkinning:o,useBatching:l,receiveShadow:a,sampleCount:u,colorTargetFormats:s},defines:{...t.defines}});const f=(async()=>{const r=this.state.device.createBindGroupLayout({label:`${p}-material-layout`,entries:n}),d=this.createGraphTextureBindGroupLayout(t),h=this.state.device.createPipelineLayout({label:`${p}-pipeline-layout`,bindGroupLayouts:["instanced-direct"===i?this.state.directSceneBindGroupLayout:"packed-visible"===i?this.state.visibleSceneBindGroupLayout:this.state.sceneBindGroupLayout,r,o?this.state.skinningBindGroupLayout:this.state.emptyBindGroupLayout,d]}),f=ed(t,this.state.device,i,a,o),m=this.buildMaterialShaderCode(t,f,t.vertexShader,`${p}-vertex`,o,l),g=this.buildMaterialShaderCode(t,f,t.fragmentShader,`${p}-fragment`,o,l),v={bindGroupLayout:r,graphTextureBindGroupLayout:d,pipeline:await Uh(this.state.device,{label:`${p}-pipeline`,layout:h,vertex:{module:this.state.device.createShaderModule({label:`${p}-vertex`,code:m}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,o))},fragment:{module:this.state.device.createShaderModule({label:`${p}-fragment`,code:g}),entryPoint:"fsMain",targets:yh(g,s,wh(t))},primitive:{topology:Th(t),cullMode:Th(t).startsWith("triangle")&&t.side!==Yc?t.side===Hc?"front":"back":"none",frontFace:c?"cw":"ccw"},multisample:{count:u},depthStencil:{format:"depth32float",depthWriteEnabled:t.depthWrite,depthCompare:t.depthTest?"less-equal":"always"}},this.pipelineCompilationDiagnostics,"forward",`${t.name||"unnamed"} [${t.uuid}] (${i}, ${u}x)`,m.length,g.length)};return this.sharedForwardPipelineCache.set(e,v),this.sharedForwardPipelinePromiseCache.delete(e),v})();return this.sharedForwardPipelinePromiseCache.set(e,f),f}getDepthPassMaterialResource(e,t,r,i,n,a=!1){if(!(this.state.device&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&this.state.skinningBindGroupLayout))throw new Error("Renderer is not initialized.");if("prepass"===t&&null===e.depthVertexShader||"pointShadow"===t&&(null===e.pointShadowVertexShader||null===e.pointShadowFragmentShader))return null;const s=this.getDepthMaterialFastCacheIndex(t,r,i,n,a),o=this.depthMaterialFrameCache.get(e)?.[s];if(o?.extractionVersion===this.extractionVersion)return o.resource;const l=this.depthMaterialFastCache.get(e)?.[s];if(l&&this.fastMaterialResourceMatches(l,e))return this.updateMaterialUniformBuffer(e,l),this.setDepthMaterialFrameCache(e,s,l),l;const c="prepass"===t?this.depthPrepassMaterialCache:i?this.skinnedDirectionalShadowMaterialCache:"instanced-direct"===r?this.directionalShadowMaterialCacheDirect:this.directionalShadowMaterialCache,u=this.getDepthPassMaterialKey(e,t,r,i,n,a),d=c.get(e),h=d?.get(u);if(h&&this.materialResourceMatches(h,e,u))return this.setDepthMaterialFastCache(e,s,h),this.updateMaterialUniformBuffer(e,h),this.setDepthMaterialFrameCache(e,s,h),h;this.destroyMaterialResource(h),d&&d.delete(u);const{bindGroupLayoutEntries:p,bindGroupEntries:f,uniformBuffer:m,textures:g,textureVersions:v,storageBuffers:x}=this.createMaterialBindGroupData(e,`${e.uuid}-${t}-${r}-material`,GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT),w=this.getOrCreateSharedDepthPipeline(u,e,t,r,p,i,n,a),b=this.state.device.createBindGroup({label:`${e.uuid}-${t}-${r}-material-bind-group`,layout:w.bindGroupLayout,entries:f}),y={key:u,materialVersion:e.version,textureVersionHash:e.getTextureVersionHash(),rendererSampleCount:this.sampleCount,instanceAccessMode:r,receiveShadow:!0,useBatching:n,frontFaceCW:a,colorTargetFormatsId:0,pipeline:w.pipeline,graphTextureBindGroupLayout:w.graphTextureBindGroupLayout,bindGroup:b,uniformBuffer:m,uniformBufferSize:m?.size??0,uniformValueHash:e.uniformValuesAutoUpdate?e.getUniformValueHash():0,uniformValuesAutoVersion:e.uniformValuesAutoVersion,textures:g,textureVersions:v,storageBuffers:x,vertexAttributes:this.getMaterialVertexAttributes(e,i),usesSkinning:i};let S=c.get(e);return S||(S=new Map,c.set(e,S)),S.set(u,y),this.setDepthMaterialFastCache(e,s,y),this.setDepthMaterialFrameCache(e,s,y),y}setDepthMaterialFrameCache(e,t,r){let i=this.depthMaterialFrameCache.get(e);i||(i=[],this.depthMaterialFrameCache.set(e,i)),i[t]={extractionVersion:this.extractionVersion,resource:r}}async getDepthPassMaterialResourceAsync(e,t,r,i,n,a=!1){if(!(this.state.device&&this.state.sceneBindGroupLayout&&this.state.directSceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&this.state.skinningBindGroupLayout))throw new Error("Renderer is not initialized.");if("prepass"===t&&null===e.depthVertexShader||"pointShadow"===t&&(null===e.pointShadowVertexShader||null===e.pointShadowFragmentShader))return null;const s=this.getDepthMaterialFastCacheIndex(t,r,i,n,a),o=this.depthMaterialFastCache.get(e)?.[s];if(o&&this.fastMaterialResourceMatches(o,e))return this.updateMaterialUniformBuffer(e,o),o;const l="prepass"===t?this.depthPrepassMaterialCache:i?this.skinnedDirectionalShadowMaterialCache:"instanced-direct"===r?this.directionalShadowMaterialCacheDirect:this.directionalShadowMaterialCache,c=this.getDepthPassMaterialKey(e,t,r,i,n,a),u=l.get(e),d=u?.get(c);if(d&&this.materialResourceMatches(d,e,c))return this.setDepthMaterialFastCache(e,s,d),this.updateMaterialUniformBuffer(e,d),d;this.destroyMaterialResource(d),u&&u.delete(c);const{bindGroupLayoutEntries:h,bindGroupEntries:p,uniformBuffer:f,textures:m,textureVersions:g,storageBuffers:v}=this.createMaterialBindGroupData(e,`${e.uuid}-${t}-${r}-material`,GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT),x=await this.getOrCreateSharedDepthPipelineAsync(c,e,t,r,h,i,n,a),w=this.state.device.createBindGroup({label:`${e.uuid}-${t}-${r}-material-bind-group`,layout:x.bindGroupLayout,entries:p}),b={key:c,materialVersion:e.version,textureVersionHash:e.getTextureVersionHash(),rendererSampleCount:this.sampleCount,instanceAccessMode:r,receiveShadow:!0,useBatching:n,frontFaceCW:a,colorTargetFormatsId:0,pipeline:x.pipeline,graphTextureBindGroupLayout:x.graphTextureBindGroupLayout,bindGroup:w,uniformBuffer:f,uniformBufferSize:f?.size??0,uniformValueHash:e.uniformValuesAutoUpdate?e.getUniformValueHash():0,uniformValuesAutoVersion:e.uniformValuesAutoVersion,textures:m,textureVersions:g,storageBuffers:v,vertexAttributes:this.getMaterialVertexAttributes(e,i),usesSkinning:i};let y=l.get(e);return y||(y=new Map,l.set(e,y)),y.set(c,b),this.setDepthMaterialFastCache(e,s,b),b}getMaterialResource(e,t,r=!0,i,n=!1,a=!1,s=this.sampleCount,o=!1){if(!(this.state.device&&this.state.format&&this.state.sceneBindGroupLayout&&this.state.visibleSceneBindGroupLayout&&this.state.directSceneBindGroupLayout))throw new Error("Renderer is not initialized.");const l=n?r?this.skinnedMaterialCache:this.skinnedMaterialNoReceiveShadowCache:r?"instanced-direct"===t?this.materialCacheDirect:"packed-visible"===t?this.materialCacheVisible:this.materialCache:"instanced-direct"===t?this.materialNoReceiveShadowCacheDirect:"packed-visible"===t?this.materialNoReceiveShadowCacheVisible:this.materialNoReceiveShadowCache,c=i??Bh,u=void 0===i||1===i.length&&i[0]===D,d=this.getForwardMaterialFastCacheIndex(t,r,n,a,o),h=u?null:this.getForwardMaterialTargetFastCacheKey(c,d);if(u){const t=this.forwardMaterialFrameCache.get(e)?.[d];if(t?.extractionVersion===this.extractionVersion&&t.resource.rendererSampleCount===s)return t.resource;const r=this.forwardMaterialFastCache.get(e)?.[d];if(r&&this.fastMaterialResourceMatches(r,e,s))return this.updateMaterialUniformBuffer(e,r),this.setForwardMaterialFrameCache(e,d,r),r}else{const t=this.forwardMaterialTargetFastCache.get(e)?.get(h);if(t&&this.fastMaterialResourceMatches(t,e,s))return this.updateMaterialUniformBuffer(e,t),t}const p=this.getForwardMaterialKey(e,t,r,c,n,a,o,s),f=l.get(e),m=f?.get(p);if(m&&this.materialResourceMatches(m,e,p,s))return u?(this.setForwardMaterialFastCache(e,d,m),this.setForwardMaterialFrameCache(e,d,m)):this.setForwardMaterialTargetFastCache(e,h,m),this.updateMaterialUniformBuffer(e,m),m;this.destroyMaterialResource(m),f&&f.delete(p);const{bindGroupLayoutEntries:g,bindGroupEntries:v,uniformBuffer:x,textures:w,textureVersions:b,storageBuffers:y}=this.createMaterialBindGroupData(e,`${e.uuid}-${t}-material`,GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT),S=this.getOrCreateSharedForwardPipeline(p,e,t,g,r,c,n,a,o,s),C=this.state.device.createBindGroup({label:`${e.uuid}-${t}-material-bind-group`,layout:S.bindGroupLayout,entries:v}),M={key:p,materialVersion:e.version,textureVersionHash:e.getTextureVersionHash(),rendererSampleCount:s,instanceAccessMode:t,receiveShadow:r,useBatching:a,frontFaceCW:o,colorTargetFormatsId:this.getColorFormatsId(c),pipeline:S.pipeline,graphTextureBindGroupLayout:S.graphTextureBindGroupLayout,bindGroup:C,uniformBuffer:x,uniformBufferSize:x?.size??0,uniformValueHash:e.uniformValuesAutoUpdate?e.getUniformValueHash():0,uniformValuesAutoVersion:e.uniformValuesAutoVersion,textures:w,textureVersions:b,storageBuffers:y,vertexAttributes:this.getMaterialVertexAttributes(e,n),usesSkinning:n};let P=l.get(e);return P||(P=new Map,l.set(e,P)),P.set(p,M),u?(this.setForwardMaterialFastCache(e,d,M),this.setForwardMaterialFrameCache(e,d,M)):this.setForwardMaterialTargetFastCache(e,h,M),M}async getMaterialResourceAsync(e,t,r=!0,i,n=!1,a=!1,s=this.sampleCount,o=!1){if(!(this.state.device&&this.state.format&&this.state.sceneBindGroupLayout&&this.state.visibleSceneBindGroupLayout&&this.state.directSceneBindGroupLayout))throw new Error("Renderer is not initialized.");const l=n?r?this.skinnedMaterialCache:this.skinnedMaterialNoReceiveShadowCache:r?"instanced-direct"===t?this.materialCacheDirect:"packed-visible"===t?this.materialCacheVisible:this.materialCache:"instanced-direct"===t?this.materialNoReceiveShadowCacheDirect:"packed-visible"===t?this.materialNoReceiveShadowCacheVisible:this.materialNoReceiveShadowCache,c=i??Bh,u=void 0===i||1===i.length&&i[0]===D,d=this.getForwardMaterialFastCacheIndex(t,r,n,a,o);if(u){const t=this.forwardMaterialFrameCache.get(e)?.[d];if(t?.extractionVersion===this.extractionVersion&&t.resource.rendererSampleCount===s)return t.resource;const r=this.forwardMaterialFastCache.get(e)?.[d];if(r&&this.fastMaterialResourceMatches(r,e,s))return this.updateMaterialUniformBuffer(e,r),this.setForwardMaterialFrameCache(e,d,r),r}const h=this.getForwardMaterialKey(e,t,r,c,n,a,o,s),p=l.get(e),f=p?.get(h);if(f&&this.materialResourceMatches(f,e,h,s))return u&&(this.setForwardMaterialFastCache(e,d,f),this.setForwardMaterialFrameCache(e,d,f)),this.updateMaterialUniformBuffer(e,f),f;this.destroyMaterialResource(f),p&&p.delete(h);const{bindGroupLayoutEntries:m,bindGroupEntries:g,uniformBuffer:v,textures:x,textureVersions:w,storageBuffers:b}=this.createMaterialBindGroupData(e,`${e.uuid}-${t}-material`,GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT),y=await this.getOrCreateSharedForwardPipelineAsync(h,e,t,m,r,c,n,a,o,s),S=this.state.device.createBindGroup({label:`${e.uuid}-${t}-material-bind-group`,layout:y.bindGroupLayout,entries:g}),C={key:h,materialVersion:e.version,textureVersionHash:e.getTextureVersionHash(),rendererSampleCount:s,instanceAccessMode:t,receiveShadow:r,useBatching:a,frontFaceCW:o,colorTargetFormatsId:this.getColorFormatsId(c),pipeline:y.pipeline,graphTextureBindGroupLayout:y.graphTextureBindGroupLayout,bindGroup:S,uniformBuffer:v,uniformBufferSize:v?.size??0,uniformValueHash:e.uniformValuesAutoUpdate?e.getUniformValueHash():0,uniformValuesAutoVersion:e.uniformValuesAutoVersion,textures:x,textureVersions:w,storageBuffers:b,vertexAttributes:this.getMaterialVertexAttributes(e,n),usesSkinning:n};let M=l.get(e);return M||(M=new Map,l.set(e,M)),M.set(h,C),u&&(this.setForwardMaterialFastCache(e,d,C),this.setForwardMaterialFrameCache(e,d,C)),C}ensureTiledLightingSize(){this.tiledPointLights?.resize(this.state.width,this.state.height)&&(this.state.sharedSceneBindGroup=null,this.state.residentSceneBindGroupVersion+=1,this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches())}updateCameraUniforms(e,t){if(!this.state.device||!this.state.cameraBuffer)return;const r=this.cameraProjectionScratch.copy(e.projectionMatrix);0===this.projectionJitterPixels.x&&0===this.projectionJitterPixels.y||(r.elements[8]-=2*this.projectionJitterPixels.x/this.state.width,r.elements[9]-=2*this.projectionJitterPixels.y/this.state.height);const i=this.cameraViewProjScratch.copy(I).multiply(r).multiply(e.matrixWorldInverse);e.getWorldPosition(F);const n=this.cameraUniformScratch;n.set(i.elements,0),n[16]=F.x,n[17]=F.y,n[18]=F.z,n[19]=1,n[20]=this.state.width,n[21]=this.state.height,n[22]=this.state.pixelRatio,n[23]=this.state.frameTimeSeconds,n.set(e.matrixWorldInverse.elements,24),n.set(A.multiplyMatrices(I,r).elements,40),n[56]=e.near,n[57]=e.far,n[58]=1/Math.max(e.far-e.near,1e-4),n[59]=this.tiledLightingEnabled?1:0;const a=t.fog;null!=a?(n[60]=a.color.r,n[61]=a.color.g,n[62]=a.color.b,n[63]=1,"density"in a?(n[64]=0,n[65]=0,n[66]=a.density,n[67]=1):(n[64]=a.near,n[65]=a.far,n[66]=0,n[67]=0)):(n.fill(0,60,68),n[67]=-1);const s=this.motionVectorProjectionPending?this.motionVectorProjection:e.projectionMatrix,o=this.motionVectorCurrentViewProj.copy(I).multiply(s).multiply(e.matrixWorldInverse);n.set(o.elements,68),n.set((this.motionVectorHistoryValid?this.motionVectorPreviousViewProj:o).elements,84),n[100]=this.motionVectorHistoryValid?1:0,n[101]=this.state.width,n[102]=this.state.height,n[103]=0,this.motionVectorProjectionPending=!1,this.state.device.queue.writeBuffer(this.state.cameraBuffer,0,n,0,104)}updateTemporalVisibilityUniforms(e){if(!this.state.device||!this.state.temporalVisibilityBuffer)return;const t=yi(e,this.temporalVisibilityCurrentViewProj);e.getWorldPosition(this.temporalVisibilityCurrentCameraPosition);const r=this.temporalVisibilityUniformScratch;r.set(t.elements,0),r.set((this.state.temporalHiZHistoryValid?this.temporalVisibilityPreviousViewProj:t).elements,16),r[32]=this.temporalVisibilityCurrentCameraPosition.x,r[33]=this.temporalVisibilityCurrentCameraPosition.y,r[34]=this.temporalVisibilityCurrentCameraPosition.z,r[35]=1;const i=this.state.temporalHiZHistoryValid?this.temporalVisibilityPreviousCameraPosition:this.temporalVisibilityCurrentCameraPosition;r[36]=i.x,r[37]=i.y,r[38]=i.z,r[39]=1,r[40]=this.state.width,r[41]=this.state.height,r[42]=this.state.pixelRatio,r[43]=this.state.frameTimeSeconds,this.state.device.queue.writeBuffer(this.state.temporalVisibilityBuffer,0,r,0,44)}commitTemporalHiZHistory(){this.temporalVisibilityPreviousViewProj.copy(this.temporalVisibilityCurrentViewProj),this.temporalVisibilityPreviousCameraPosition.copy(this.temporalVisibilityCurrentCameraPosition),this.state.temporalHiZHistoryValid=!0,this.motionVectorPreviousViewProj.copy(this.motionVectorCurrentViewProj),this.motionVectorHistoryValid=!0}updateLightUniforms(e){if(!this.state.device||!this.state.lightBuffer)return;let t=17;for(const e of this.staticDrawSets)t=Math.imul(t,31)+2*e.id+Number(e.publicSet.enabled)|0;this.directionalShadowScheduler.prepare(e.lights.directionals,e.camera,this.csmCascadeRanges,this.csmCascadeCount,performance.now(),t);const r=this.lightUniformScratch;this.updateSpotLightMapAtlas(e.lights.spots),r.fill(0),r[0]=e.lights.ambient.x,r[1]=e.lights.ambient.y,r[2]=e.lights.ambient.z,r[3]=e.lights.ambient.w,r[4]=e.lights.directionals.length,r[5]=e.lights.points.length,r[6]=e.lights.spots.length,r[7]=Math.min(this.csmCascadeCount,e.lights.directionals.length);for(let e=0;e<this.csmCascadeCount;e+=1){const t=this.csmCascadeRanges[e],i=3976+4*e;r[i+0]=t.x,r[i+1]=t.y}const i=e.lights.hemisphere;null!=i&&(r[3992]=i.skyColor.x,r[3993]=i.skyColor.y,r[3994]=i.skyColor.z,r[3995]=i.intensity,r[3996]=i.groundColor.x,r[3997]=i.groundColor.y,r[3998]=i.groundColor.z,r[3999]=i.intensity,r[4e3]=i.direction.x,r[4001]=i.direction.y,r[4002]=i.direction.z,r[4003]=1);for(let t=0;t<e.lights.directionals.length;t+=1){const i=e.lights.directionals[t],n=this.directionalShadowCameras[t],a=8+4*t;r[a+0]=i.direction.x,r[a+1]=i.direction.y,r[a+2]=i.direction.z,r[a+3]=1;const s=24+4*t;r[s+0]=i.color.x,r[s+1]=i.color.y,r[s+2]=i.color.z,r[s+3]=i.intensity;const o=40+4*t;r[o+0]=i.shadowBias,r[o+1]=i.castShadow?1:0,r[o+2]=this.state.directionalShadowTextureSize,r[o+3]=i.shadowNormalBias;const l=56+4*t;r[l+0]=i.shadowRadius,r[l+1]=i.shadowIntensity;const c=i.shadowViewProjection??=new ru;r.set(yi(n,c).elements,72+16*t)}for(let t=0;t<e.lights.points.length;t+=1){const i=e.lights.points[t],n=136+4*t;r[n+0]=i.position.x,r[n+1]=i.position.y,r[n+2]=i.position.z,r[n+3]=i.range;const a=392+4*t;r[a+0]=i.color.x,r[a+1]=i.color.y,r[a+2]=i.color.z,r[a+3]=i.intensity;const s=648+4*t;r[s+0]=i.distance,r[s+1]=i.decay;const o=904+4*t;r[o+0]=i.shadowBias,r[o+1]=i.castShadow?1:0,r[o+2]=this.state.pointShadowTextureSize,r[o+3]=i.shadowNormalBias;const l=1160+4*t;r[l+0]=i.shadowRadius,r[l+1]=i.shadowIntensity,r[l+2]=i.shadowCameraNear,r[l+3]=i.shadowCameraFar}for(let t=0;t<e.lights.spots.length;t+=1){const i=e.lights.spots[t],n=1416+4*t;r[n+0]=i.position.x,r[n+1]=i.position.y,r[n+2]=i.position.z,r[n+3]=i.range;const a=1672+4*t;r[a+0]=i.direction.x,r[a+1]=i.direction.y,r[a+2]=i.direction.z,r[a+3]=Math.cos(i.angle);const s=1928+4*t;r[s+0]=i.color.x,r[s+1]=i.color.y,r[s+2]=i.color.z,r[s+3]=i.intensity;const o=2184+4*t;r[o+0]=i.shadowBias,r[o+1]=i.castShadow?1:0,r[o+2]=this.state.spotShadowTextureSize,r[o+3]=i.shadowNormalBias;const l=2440+4*t;r[l+0]=i.shadowRadius,r[l+1]=i.shadowIntensity;const c=2696+4*t;if(r[c+0]=i.range,r[c+1]=Math.cos(i.angle*(1-i.penumbra)),r[c+2]=i.decay,r[c+3]=null!=i.map?1:0,i.castShadow||null!=i.map){const e=this.spotShadowCameras[t];e.near=i.shadowCameraNear,e.far=i.shadowCameraFar,e.fov=i.shadowCameraFov,e.aspect=1,e.position.copy(i.position),$.copy(i.position).add(i.direction),e.lookAt($),e.updateMatrixWorld(!0),e.updateProjectionMatrix(),r.set(yi(e,this.shadowViewProjScratch).elements,2952+16*t)}}this.state.device.queue.writeBuffer(this.state.lightBuffer,0,r,0,L)}updateSpotLightMapAtlas(e){const t=this.state.device;if(null==t)return;const r=e.some(e=>null!=e.map),i=r?2048:1,n=r?i/8:1,a=r?e.map(e=>null==e.map?"-":`${e.map.uuid}:${e.map.version}`).join("|"):"fallback";if(null!=this.state.spotLightMapTexture&&i===this.spotLightMapAtlasSize&&a===this.spotLightMapAtlasSignature)return;if(null==this.state.spotLightMapTexture||i!==this.spotLightMapAtlasSize){const e=this.state.spotLightMapTexture,n=t.createTexture({label:r?"spot-light-map-atlas":"spot-light-map-fallback",size:{width:i,height:i},format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.COPY_DST});this.state.spotLightMapTexture=n,this.state.spotLightMapView=n.createView(),this.spotLightMapAtlasSize=i,e?.destroy(),this.state.sharedSceneBindGroup=null,this.state.residentSceneBindGroupVersion+=1,this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches()}if(!r)return t.queue.writeTexture({texture:this.state.spotLightMapTexture},new Uint8Array([255,255,255,255]),{},{width:1,height:1}),void(this.spotLightMapAtlasSignature=a);if(null==this.spotLightMapAtlasLayout||null==this.spotLightMapAtlasPipeline){this.spotLightMapAtlasLayout=t.createBindGroupLayout({label:"spot-light-map-atlas-layout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}}]});const e=t.createShaderModule({label:"spot-light-map-atlas-shader",code:"\n struct VertexOutput { @builtin(position) position: vec4<f32>, @location(0) uv: vec2<f32> };\n @vertex fn vertexMain(@builtin(vertex_index) index: u32) -> VertexOutput {\n let positions = array<vec2<f32>, 3>(vec2(-1.0, -1.0), vec2(3.0, -1.0), vec2(-1.0, 3.0));\n var output: VertexOutput;\n output.position = vec4(positions[index], 0.0, 1.0);\n output.uv = positions[index] * vec2(0.5, -0.5) + vec2(0.5);\n return output;\n }\n @group(0) @binding(0) var mapSampler: sampler;\n @group(0) @binding(1) var mapTexture: texture_2d<f32>;\n @fragment fn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {\n return textureSample(mapTexture, mapSampler, input.uv);\n }\n "});this.spotLightMapAtlasPipeline=t.createRenderPipeline({label:"spot-light-map-atlas-pipeline",layout:t.createPipelineLayout({bindGroupLayouts:[this.spotLightMapAtlasLayout]}),vertex:{module:e,entryPoint:"vertexMain"},fragment:{module:e,entryPoint:"fragmentMain",targets:[{format:"rgba8unorm"}]}})}const s=t.createCommandEncoder({label:"spot-light-map-atlas-upload"}),o=s.beginRenderPass({colorAttachments:[{view:this.state.spotLightMapView,clearValue:{r:1,g:1,b:1,a:1},loadOp:"clear",storeOp:"store"}]});o.setPipeline(this.spotLightMapAtlasPipeline);for(let r=0;r<e.length;r+=1){const i=e[r].map;if(null==i)continue;const a=this.getTextureResource(i),s=r%8*n,l=Math.floor(r/8)*n;o.setViewport(s,l,n,n,0,1),o.setScissorRect(s,l,n,n),o.setBindGroup(0,t.createBindGroup({layout:this.spotLightMapAtlasLayout,entries:[{binding:0,resource:this.state.linearClampSampler},{binding:1,resource:a.view}]})),o.draw(3)}o.end(),t.queue.submit([s.finish()]),this.spotLightMapAtlasSignature=a}writeShadowCameraBuffer(e,t,r,i,n,a=this.state.shadowCameraBuffer,s){if(!this.state.device||!a)return;const o=this.shadowCameraUniformScratch;o.set(e.elements,0),o[16]=t,o[17]=r,o[18]=i,o[19]=n,o[60]=this.state.frameTimeSeconds,o[61]=this.state.width,o[62]=this.state.height,o[63]=0,s&&(o.set(s.matrixWorldInverse.elements,20),o.set(s.projectionMatrix.elements,36),o[52]=s.position.x,o[53]=s.position.y,o[54]=s.position.z,o[55]=1,o[56]=s.near,o[57]=s.far,o[58]=0,o[59]=0),this.state.device.queue.writeBuffer(a,0,o,0,64)}};var Lh=[0,0],zh=[0,0,1],Rh=[1,1,1,1];async function Uh(e,t,r,i,n,a=0,s=0){if(null==e)throw new Error("WebGPU device is not initialized");const o=performance.now();try{return await j(e,t)}finally{r&&i&&n&&r.pipelines.push({kind:i,material:n,durationMs:performance.now()-o,vertexCodeLength:a,fragmentCodeLength:s})}}import{DataTexture as Ah,Matrix4 as kh,RepeatWrapping as Fh}from"three";var $h={off:{enabled:!1,temporal:{}},low:{enabled:!0,resolutionScale:.35,directions:2,steps:3,temporal:{historyWeight:.92,depthRejection:.1},denoise:{samples:4,radius:4}},medium:{enabled:!0,resolutionScale:.5,directions:2,steps:4,temporal:{historyWeight:.9,depthRejection:.08},denoise:{samples:8,radius:6}},high:{enabled:!0,resolutionScale:.5,directions:3,steps:5,temporal:{historyWeight:.88,depthRejection:.06},denoise:{samples:12,radius:8}}},Eh=class{options;noiseTexture=function(){const e=new Array(25).fill(0);let t=Math.floor(2.5),r=4;for(let i=1;i<=25;){-1===t&&5===r?(t=0,r=3):(5===r&&(r=0),t<0&&(t=4));const n=5*t+r;0===e[n]?(e[n]=i++,t-=1,r+=1):(t+=1,r-=2)}const i=new Uint8Array(100);for(let t=0;t<e.length;t+=1){const r=2*Math.PI*e[t]/e.length;i[4*t]=Math.round(255*(.5*Math.cos(r)+.5)),i[4*t+1]=Math.round(255*(.5*Math.sin(r)+.5)),i[4*t+2]=127,i[4*t+3]=255}const n=new Ah(i,5,5);return n.wrapS=Fh,n.wrapT=Fh,n.needsUpdate=!0,n}();gtaoPasses=new Map;temporalPasses=new Map;denoisePasses=new Map;compositePasses=new Map;writeIndex=0;frameIndex=0;historyValid=!1;constructor(e={}){this.options=qh(e)}get enabled(){return this.options.enabled}get temporalEnabled(){return!1!==this.options.temporal}setOptions(e){Object.assign(this.options,qh({...this.options,...e,denoise:e.denoise??this.options.denoise,temporal:e.temporal??this.options.temporal,targetPrefix:this.options.targetPrefix})),this.gtaoPasses.clear(),this.temporalPasses.clear(),this.denoisePasses.clear(),this.compositePasses.clear(),this.reset()}applyPreset(e){this.setOptions($h[e])}reset(){this.writeIndex=0,this.frameIndex=0,this.historyValid=!1}addPasses(e,t){const r=e.createColorTarget(`${this.options.targetPrefix}Raw`,{format:"r16float",scale:this.options.resolutionScale}),i=`${t.depth}:${t.normal}:${r}`;let n=this.gtaoPasses.get(i);n||(n=new Oh(t.depth,t.normal,r,this.noiseTexture,this.options),this.gtaoPasses.set(i,n));const a=!1!==this.options.temporal&&null!=t.velocity;n.frameIndex=a?this.frameIndex:0,e.addFullscreenPass(n);let s=r;if(a&&!1!==this.options.temporal&&null!=t.velocity){const i=e.createColorTarget(`${this.options.targetPrefix}TemporalA`,{format:"r16float",scale:this.options.resolutionScale}),n=e.createColorTarget(`${this.options.targetPrefix}TemporalB`,{format:"r16float",scale:this.options.resolutionScale}),a=e.createColorTarget(`${this.options.targetPrefix}TemporalDepthA`,{format:"r16float",scale:this.options.resolutionScale}),o=e.createColorTarget(`${this.options.targetPrefix}TemporalDepthB`,{format:"r16float",scale:this.options.resolutionScale}),l=0===this.writeIndex?n:i,c=0===this.writeIndex?i:n,u=0===this.writeIndex?o:a,d=0===this.writeIndex?a:o,h=`${r}:${t.depth}:${t.velocity}:${l}:${u}:${c}:${d}`;let p=this.temporalPasses.get(h);p||(p=new _h(r,t.depth,t.velocity,l,u,c,d,this.options.temporal,this),this.temporalPasses.set(h,p)),e.addFullscreenPass(p),s=c,this.writeIndex=1-this.writeIndex}if(a&&(this.frameIndex+=1),!1===this.options.denoise)return s;const o=e.createColorTarget(`${this.options.targetPrefix}Denoised`,{format:"r16float",scale:this.options.resolutionScale}),l=`${s}:${t.depth}:${t.normal}:${o}`;let c=this.denoisePasses.get(l);return c||(c=new jh(s,t.depth,t.normal,o,this.options.normalSpace,this.options.denoise),this.denoisePasses.set(l,c)),e.addFullscreenPass(c),o}addCompositePass(e,t,r,i={}){const n=i.output??e.createColorTarget(`${this.options.targetPrefix}Composite`,{format:"rgba16float"}),a=Math.max(0,i.intensity??this.options.intensity),s=Math.max(1e-4,i.power??this.options.power),o=`${t}:${r}:${n}:${a}:${s}`;let l=this.compositePasses.get(o);return l||(l=new Nh(t,r,n,a,s),this.compositePasses.set(o,l)),e.addFullscreenPass(l),n}dispose(){this.noiseTexture.dispose(),this.gtaoPasses.clear(),this.temporalPasses.clear(),this.denoisePasses.clear(),this.compositePasses.clear()}consumeHistoryValid(){const e=this.historyValid;return this.historyValid=!0,e}},Oh=class{constructor(e,t,r,i,n){this.options=n,this.inputs={sceneDepth:e,sceneNormal:t},this.outputs=r,this.textures={gtaoNoise:i},this.fragmentShader=function(e){const t="world"===e.normalSpace?"normalize(viewRotation() * decodedNormal)":"decodedNormal";return`\nconst PI = 3.14159265359;\nconst DIRECTIONS: i32 = ${e.directions};\nconst STEPS: i32 = ${e.steps};\n\nfn projectionMatrix() -> mat4x4<f32> {\n return mat4x4<f32>(fullscreenUniforms[0], fullscreenUniforms[1], fullscreenUniforms[2], fullscreenUniforms[3]);\n}\nfn inverseProjectionMatrix() -> mat4x4<f32> {\n return mat4x4<f32>(fullscreenUniforms[4], fullscreenUniforms[5], fullscreenUniforms[6], fullscreenUniforms[7]);\n}\nfn viewRotation() -> mat3x3<f32> {\n return mat3x3<f32>(fullscreenUniforms[8].xyz, fullscreenUniforms[9].xyz, fullscreenUniforms[10].xyz);\n}\nfn getViewPosition(uv: vec2<f32>, depth: f32) -> vec3<f32> {\n let clip = vec4<f32>(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, depth, 1.0);\n let view = inverseProjectionMatrix() * clip;\n return view.xyz / view.w;\n}\nfn projectViewPosition(position: vec3<f32>) -> vec2<f32> {\n let clip = projectionMatrix() * vec4<f32>(position, 1.0);\n let ndc = clip.xy / clip.w;\n return vec2<f32>(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);\n}\nfn loadDepth(uv: vec2<f32>, size: vec2<i32>) -> f32 {\n let pixel = clamp(vec2<i32>(uv * vec2<f32>(size)), vec2<i32>(0), size - vec2<i32>(1));\n return textureLoad(sceneDepthTexture, pixel, 0);\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let depthSize = vec2<i32>(textureDimensions(sceneDepthTexture));\n let pixel = clamp(vec2<i32>(input.uv * vec2<f32>(depthSize)), vec2<i32>(0), depthSize - vec2<i32>(1));\n let depth = textureLoad(sceneDepthTexture, pixel, 0);\n if (depth >= 1.0) { return vec4<f32>(1.0); }\n\n let viewPosition = getViewPosition(input.uv, depth);\n let decodedNormal = normalize(textureLoad(sceneNormalTexture, pixel, 0).rgb * 2.0 - vec3<f32>(1.0));\n let viewNormal = ${t};\n let viewDirection = normalize(-viewPosition);\n let radius = fullscreenUniforms[12].x;\n let thickness = fullscreenUniforms[12].y;\n let distanceExponent = fullscreenUniforms[12].z;\n let distanceFalloff = fullscreenUniforms[12].w;\n let noiseSize = vec2<f32>(textureDimensions(gtaoNoiseTexture));\n let noiseUv = input.uv * vec2<f32>(depthSize) / noiseSize;\n let noiseTexel = textureSampleLevel(gtaoNoiseTexture, gtaoNoiseSampler, noiseUv, 0.0);\n let baseTangent = normalize(noiseTexel.xy * 2.0 - vec2<f32>(1.0));\n let temporalAngle = f32(i32(fullscreenUniforms[13].x) & 7) * 2.39996323;\n let temporalRotation = mat2x2<f32>(\n vec2<f32>(cos(temporalAngle), sin(temporalAngle)),\n vec2<f32>(-sin(temporalAngle), cos(temporalAngle))\n );\n let rotatedTangent = temporalRotation * baseTangent;\n let tangent = vec3<f32>(rotatedTangent, 0.0);\n let bitangent = vec3<f32>(-tangent.y, tangent.x, 0.0);\n var ao = 0.0;\n\n for (var i = 0; i < DIRECTIONS; i += 1) {\n let angle = (f32(i) / f32(DIRECTIONS)) * PI;\n let sampleDirection = normalize(tangent * cos(angle) + bitangent * sin(angle));\n let sliceBitangent = normalize(cross(sampleDirection, viewDirection));\n let sliceTangent = cross(sliceBitangent, viewDirection);\n let normalInSlice = normalize(viewNormal - sliceBitangent * dot(viewNormal, sliceBitangent));\n let tangentToNormal = cross(normalInSlice, sliceBitangent);\n var cosHorizons = vec2<f32>(dot(viewDirection, tangentToNormal), dot(viewDirection, -tangentToNormal));\n for (var j = 0; j < STEPS; j += 1) {\n let distance = radius * pow(f32(j + 1) / f32(STEPS), distanceExponent);\n for (var side = 0; side < 2; side += 1) {\n let sign = select(-1.0, 1.0, side == 0);\n let sampleUv = projectViewPosition(viewPosition + sampleDirection * distance * sign);\n if (all(sampleUv >= vec2<f32>(0.0)) && all(sampleUv <= vec2<f32>(1.0))) {\n let sampleDepth = loadDepth(sampleUv, depthSize);\n if (sampleDepth < 1.0) {\n let viewDelta = getViewPosition(sampleUv, sampleDepth) - viewPosition;\n if (abs(viewDelta.z) < thickness) {\n let horizon = dot(viewDirection, normalize(viewDelta));\n let update = max(0.0, (horizon - cosHorizons[side]) * mix(1.0, 2.0 / f32(j + 2), distanceFalloff));\n cosHorizons[side] += update;\n }\n }\n }\n }\n }\n let sinHorizons = sqrt(max(vec2<f32>(0.0), vec2<f32>(1.0) - cosHorizons * cosHorizons));\n let nx = dot(normalInSlice, sliceTangent);\n let ny = dot(normalInSlice, viewDirection);\n let nxb = 0.5 * (acos(cosHorizons.y) - acos(cosHorizons.x) + sinHorizons.x * cosHorizons.x - sinHorizons.y * cosHorizons.y);\n let nyb = 0.5 * (2.0 - cosHorizons.x * cosHorizons.x - cosHorizons.y * cosHorizons.y);\n ao += nx * nxb + ny * nyb;\n }\n return vec4<f32>(vec3<f32>(clamp(ao / f32(DIRECTIONS), 0.0, 1.0)), 1.0);\n}\n`}(n)}options;name="GTAOPass";sampler="nearest";uniformBufferSize=224;inputs;outputs;textures;fragmentShader;uniforms=new Float32Array(this.uniformBufferSize/4);webGpuProjection=new kh;webGpuProjectionInverse=new kh;frameIndex=0;updateUniforms=e=>(this.webGpuProjection.copy(Wh).multiply(e.camera.projectionMatrix),this.webGpuProjectionInverse.copy(this.webGpuProjection).invert(),this.uniforms.set(this.webGpuProjection.elements,0),this.uniforms.set(this.webGpuProjectionInverse.elements,16),this.uniforms.set(e.camera.matrixWorldInverse.elements,32),this.uniforms.set([this.options.radius,this.options.thickness,this.options.distanceExponent,this.options.distanceFalloff],48),this.uniforms.set([this.frameIndex,0,0,0],52),this.uniforms)},_h=class{constructor(e,t,r,i,n,a,s,o,l){this.options=o,this.state=l,this.inputs={currentAo:e,sceneDepth:t,velocity:r,historyAo:i,historyDepth:n},this.outputs=[a,s]}options;state;name="GTAOTemporalPass";sampler="linear";uniformBufferSize=80;inputs;outputs;fragmentShader=Hh;uniforms=new Float32Array(this.uniformBufferSize/4);inverseProjection=new kh;updateUniforms=e=>(this.inverseProjection.copy(Wh).multiply(e.camera.projectionMatrix).invert(),this.uniforms.set(this.inverseProjection.elements,0),this.uniforms.set([this.options.historyWeight,this.options.depthRejection,this.options.neighborhoodClamp?1:0,this.state.consumeHistoryValid()?1:0],16),this.uniforms)},jh=class{constructor(e,t,r,i,n,a){this.options=a,this.inputs={aoInput:e,sceneDepth:t,sceneNormal:r},this.outputs=i,this.fragmentShader=function(e,t){const r="world"===e?"normalize(viewRotation() * decoded)":"decoded";return`\nconst PI = 3.14159265359;\nconst MAGIC_SQUARE: array<u32, 25> = array<u32, 25>(9u, 3u, 22u, 16u, 15u, 2u, 21u, 20u, 14u, 8u, 25u, 19u, 13u, 7u, 1u, 18u, 12u, 6u, 5u, 24u, 11u, 10u, 4u, 23u, 17u);\nconst POISSON_DISK: array<vec3<f32>, 16> = array<vec3<f32>, 16>(\n vec3<f32>(1.0, 0.0, 0.0), vec3<f32>(0.707106781, 0.707106781, 0.066666667), vec3<f32>(0.0, 1.0, 0.133333333), vec3<f32>(-0.707106781, 0.707106781, 0.2),\n vec3<f32>(-1.0, 0.0, 0.266666667), vec3<f32>(-0.707106781, -0.707106781, 0.333333333), vec3<f32>(0.0, -1.0, 0.4), vec3<f32>(0.707106781, -0.707106781, 0.466666667),\n vec3<f32>(1.0, 0.0, 0.533333333), vec3<f32>(0.707106781, 0.707106781, 0.6), vec3<f32>(0.0, 1.0, 0.666666667), vec3<f32>(-0.707106781, 0.707106781, 0.733333333),\n vec3<f32>(-1.0, 0.0, 0.8), vec3<f32>(-0.707106781, -0.707106781, 0.866666667), vec3<f32>(0.0, -1.0, 0.933333333), vec3<f32>(0.707106781, -0.707106781, 1.0));\nfn inverseProjectionMatrix() -> mat4x4<f32> { return mat4x4<f32>(fullscreenUniforms[0], fullscreenUniforms[1], fullscreenUniforms[2], fullscreenUniforms[3]); }\nfn viewRotation() -> mat3x3<f32> { return mat3x3<f32>(fullscreenUniforms[4].xyz, fullscreenUniforms[5].xyz, fullscreenUniforms[6].xyz); }\nfn viewPosition(pixel: vec2<i32>, depth: f32, size: vec2<i32>) -> vec3<f32> {\n let uv = (vec2<f32>(pixel) + vec2<f32>(0.5)) / vec2<f32>(size);\n let view = inverseProjectionMatrix() * vec4<f32>(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, depth, 1.0);\n return view.xyz / view.w;\n}\nfn viewNormal(pixel: vec2<i32>) -> vec3<f32> {\n let decoded = normalize(textureLoad(sceneNormalTexture, pixel, 0).rgb * 2.0 - vec3<f32>(1.0));\n return ${r};\n}\nfn magicSquareAngle(pixel: vec2<i32>) -> f32 { return f32(MAGIC_SQUARE[u32((pixel.y % 5) * 5 + pixel.x % 5)]) * (2.0 * PI / 25.0); }\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let aoSize = vec2<i32>(textureDimensions(aoInputTexture));\n let depthSize = vec2<i32>(textureDimensions(sceneDepthTexture));\n let pixel = clamp(vec2<i32>(input.position.xy), vec2<i32>(0), aoSize - vec2<i32>(1));\n let depthPixel = clamp(vec2<i32>(input.uv * vec2<f32>(depthSize)), vec2<i32>(0), depthSize - vec2<i32>(1));\n let depth = textureLoad(sceneDepthTexture, depthPixel, 0);\n if (depth >= 1.0) { return vec4<f32>(1.0); }\n let center = textureLoad(aoInputTexture, pixel, 0).r;\n let normal = viewNormal(depthPixel);\n let position = viewPosition(depthPixel, depth, depthSize);\n let radius = fullscreenUniforms[8].x;\n let depthPhi = fullscreenUniforms[8].y;\n let normalPhi = fullscreenUniforms[8].z;\n let lumaPhi = fullscreenUniforms[8].w;\n let angle = magicSquareAngle(pixel);\n let rotation = mat2x2<f32>(vec2<f32>(cos(angle), sin(angle)), vec2<f32>(-sin(angle), cos(angle)));\n var denoised = center;\n var totalWeight = 1.0;\n for (var i = 0; i < ${t}; i += 1) {\n let sampleIndex = (i * 16) / ${t};\n let sample = POISSON_DISK[sampleIndex];\n let samplePixel = vec2<i32>(round(vec2<f32>(pixel) + rotation * sample.xy * (1.0 + sample.z * (radius - 1.0))));\n if (all(samplePixel >= vec2<i32>(0)) && all(samplePixel < aoSize)) {\n let sampleUv = (vec2<f32>(samplePixel) + vec2<f32>(0.5)) / vec2<f32>(aoSize);\n let sampleDepthPixel = clamp(vec2<i32>(sampleUv * vec2<f32>(depthSize)), vec2<i32>(0), depthSize - vec2<i32>(1));\n let sampleDepth = textureLoad(sceneDepthTexture, sampleDepthPixel, 0);\n if (sampleDepth < 1.0) {\n let neighbor = textureLoad(aoInputTexture, samplePixel, 0).r;\n let sampleNormal = viewNormal(sampleDepthPixel);\n let samplePosition = viewPosition(sampleDepthPixel, sampleDepth, depthSize);\n let normalSimilarity = pow(max(dot(normal, sampleNormal), 0.0), normalPhi);\n let lumaSimilarity = max(1.0 - abs(neighbor - center) / lumaPhi, 0.0);\n let depthSimilarity = max(1.0 - abs(dot(position - samplePosition, normal)) / depthPhi, 0.0);\n let weight = normalSimilarity * lumaSimilarity * depthSimilarity;\n denoised += neighbor * weight;\n totalWeight += weight;\n }\n }\n }\n return vec4<f32>(vec3<f32>(denoised / totalWeight), 1.0);\n}\n`}(n,a.samples)}options;name="GTAODenoisePass";sampler="nearest";uniformBufferSize=144;inputs;outputs;fragmentShader;uniforms=new Float32Array(this.uniformBufferSize/4);webGpuProjectionInverse=new kh;updateUniforms=e=>(this.webGpuProjectionInverse.copy(Wh).multiply(e.camera.projectionMatrix).invert(),this.uniforms.set(this.webGpuProjectionInverse.elements,0),this.uniforms.set(e.camera.matrixWorldInverse.elements,16),this.uniforms.set([this.options.radius,this.options.depthPhi,this.options.normalPhi,this.options.lumaPhi],32),this.uniforms)},Nh=class{name="GTAOCompositePass";sampler="nearest";uniformBufferSize=16;inputs;outputs;uniforms;constructor(e,t,r,i,n){this.inputs={sceneColor:e,ambientOcclusion:t},this.outputs=r,this.uniforms=new Float32Array([i,n,0,0])}updateUniforms=()=>this.uniforms;fragmentShader="\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let color = textureLoad(sceneColorTexture, vec2<i32>(input.position.xy), 0);\n let aoSize = vec2<i32>(textureDimensions(ambientOcclusionTexture));\n let aoPixel = clamp(vec2<i32>(input.uv * vec2<f32>(aoSize)), vec2<i32>(0), aoSize - vec2<i32>(1));\n let ao = textureLoad(ambientOcclusionTexture, aoPixel, 0).r;\n let materialFlags = u32(round(color.a));\n let isAlphaTested = (materialFlags & 1u) != 0u;\n let visibility = select(mix(1.0, pow(clamp(ao, 0.0, 1.0), fullscreenUniforms[0].y), fullscreenUniforms[0].x), 1.0, isAlphaTested);\n return vec4<f32>(color.rgb * visibility, color.a);\n}\n"},Wh=(new kh).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);var Hh="\nstruct GTAOTemporalOutput {\n @location(0) ao: vec4<f32>,\n @location(1) depth: vec4<f32>,\n};\n\nfn inverseProjectionMatrix() -> mat4x4<f32> {\n return mat4x4<f32>(\n fullscreenUniforms[0], fullscreenUniforms[1],\n fullscreenUniforms[2], fullscreenUniforms[3]\n );\n}\n\nfn loadSceneDepth(uv: vec2<f32>) -> f32 {\n let size = vec2<i32>(textureDimensions(sceneDepthTexture));\n let pixel = clamp(\n vec2<i32>(uv * vec2<f32>(size)),\n vec2<i32>(0),\n size - vec2<i32>(1)\n );\n return textureLoad(sceneDepthTexture, pixel, 0);\n}\n\nfn linearViewDepth(uv: vec2<f32>, depth: f32) -> f32 {\n let clip = vec4<f32>(\n uv.x * 2.0 - 1.0,\n 1.0 - uv.y * 2.0,\n depth,\n 1.0\n );\n let view = inverseProjectionMatrix() * clip;\n return abs(view.z / max(abs(view.w), 1e-6));\n}\n\nfn loadVelocity(uv: vec2<f32>) -> vec2<f32> {\n let size = vec2<i32>(textureDimensions(velocityTexture));\n let pixel = clamp(\n vec2<i32>(uv * vec2<f32>(size)),\n vec2<i32>(0),\n size - vec2<i32>(1)\n );\n return textureLoad(velocityTexture, pixel, 0).xy;\n}\n\nfn loadCurrentAo(pixel: vec2<i32>, size: vec2<i32>) -> f32 {\n return textureLoad(\n currentAoTexture,\n clamp(pixel, vec2<i32>(0), size - vec2<i32>(1)),\n 0\n ).r;\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> GTAOTemporalOutput {\n let aoSize = vec2<i32>(textureDimensions(currentAoTexture));\n let pixel = clamp(\n vec2<i32>(input.position.xy),\n vec2<i32>(0),\n aoSize - vec2<i32>(1)\n );\n let currentAo = loadCurrentAo(pixel, aoSize);\n let currentDepthRaw = loadSceneDepth(input.uv);\n let currentDepth = linearViewDepth(input.uv, currentDepthRaw);\n let previousUv = input.uv - loadVelocity(input.uv);\n let inBounds =\n all(previousUv >= vec2<f32>(0.0)) &&\n all(previousUv <= vec2<f32>(1.0));\n let historySize = vec2<i32>(textureDimensions(historyDepthTexture));\n let historyPixel = clamp(\n vec2<i32>(previousUv * vec2<f32>(historySize)),\n vec2<i32>(0),\n historySize - vec2<i32>(1)\n );\n let previousDepth = textureLoad(historyDepthTexture, historyPixel, 0).r;\n let relativeDepthDifference =\n abs(previousDepth - currentDepth) / max(currentDepth, 1e-3);\n let historyAccepted =\n fullscreenUniforms[4].w > 0.5 &&\n inBounds &&\n currentDepthRaw < 1.0 &&\n relativeDepthDifference <= fullscreenUniforms[4].y;\n\n var historyAo = textureSampleLevel(\n historyAoTexture,\n fullscreenSampler,\n clamp(previousUv, vec2<f32>(0.0), vec2<f32>(1.0)),\n 0.0\n ).r;\n if (fullscreenUniforms[4].z > 0.5) {\n let left = loadCurrentAo(pixel + vec2<i32>(-1, 0), aoSize);\n let right = loadCurrentAo(pixel + vec2<i32>(1, 0), aoSize);\n let up = loadCurrentAo(pixel + vec2<i32>(0, -1), aoSize);\n let down = loadCurrentAo(pixel + vec2<i32>(0, 1), aoSize);\n let neighborhoodMin = min(currentAo, min(min(left, right), min(up, down)));\n let neighborhoodMax = max(currentAo, max(max(left, right), max(up, down)));\n historyAo = clamp(historyAo, neighborhoodMin, neighborhoodMax);\n }\n let historyWeight = select(\n 0.0,\n fullscreenUniforms[4].x,\n historyAccepted\n );\n let accumulated = mix(currentAo, historyAo, historyWeight);\n\n var output: GTAOTemporalOutput;\n output.ao = vec4<f32>(accumulated);\n output.depth = vec4<f32>(currentDepth);\n return output;\n}\n";function qh(e){return{intensity:Math.max(0,e.intensity??.6),power:Math.max(1e-4,e.power??1),enabled:e.enabled??!0,radius:Math.max(.001,e.radius??.25),resolutionScale:Zh(e.resolutionScale??1,.25,1),thickness:Math.max(.001,e.thickness??1),distanceExponent:Math.max(.01,e.distanceExponent??1),distanceFalloff:Zh(e.distanceFalloff??1,0,1),directions:Yh(e.directions??3,1,8),steps:Yh(e.steps??6,1,16),normalSpace:e.normalSpace??"world",targetPrefix:e.targetPrefix??"gtao",denoise:!1!==e.denoise&&{radius:Math.max(1,e.denoise?.radius??8),samples:Kh(e.denoise?.samples??16),depthPhi:Math.max(1e-4,e.denoise?.depthPhi??2),normalPhi:Math.max(1e-4,e.denoise?.normalPhi??3),lumaPhi:Math.max(1e-4,e.denoise?.lumaPhi??10)},temporal:!1!==e.temporal&&{historyWeight:Zh(e.temporal?.historyWeight??.9,0,.98),depthRejection:Zh(e.temporal?.depthRejection??.08,.001,1),neighborhoodClamp:e.temporal?.neighborhoodClamp??!0}}}function Kh(e){return e<=4?4:e<=8?8:e<=12?12:16}function Zh(e,t,r){return Math.min(r,Math.max(t,e))}function Yh(e,t,r){return Math.floor(Zh(e,t,r))}import{Matrix4 as Xh}from"three";var Jh=class{options;passes=new Map;constructor(e={}){var t,r,i;this.options={resolutionScale:ip(e.resolutionScale??.5,.25,1),maxDistance:Math.max(.01,e.maxDistance??50),thickness:Math.max(.001,e.thickness??.15),intensity:Math.max(0,e.intensity??.65),distanceAttenuation:e.distanceAttenuation??!0,maxRoughness:ip(e.maxRoughness??.8,.01,1),steps:(t=e.steps??2048,r=8,i=2048,Math.round(ip(t,r,i))),pixelStride:ip(e.pixelStride??1,1,4),normalSpace:e.normalSpace??"world",blur:e.blur??!0,blurRadius:ip(e.blurRadius??6,1,12),targetPrefix:e.targetPrefix??"ssr"}}addPasses(e,t){const r=e.createColorTarget(`${this.options.targetPrefix}Raw`,{format:"rgba16float",scale:this.options.resolutionScale}),i=`trace:${t.sceneColor}:${t.depth}:${t.normalRoughness}:${r}`;let n=this.passes.get(i);n||(n=new Qh(t,r,this.options),this.passes.set(i,n)),e.addFullscreenPass(n);let a=r;if(this.options.blur)for(let r=0;r<2;r++){const i=e.createColorTarget(`${this.options.targetPrefix}Blur${r}`,{format:"rgba16float",scale:this.options.resolutionScale}),n=`blur:${a}:${t.depth}:${t.normalRoughness}:${i}:${r}:${this.options.blurRadius}`;let s=this.passes.get(n);s||(s=new ep(a,t.depth,t.normalRoughness,i,r,this.options.blurRadius),this.passes.set(n,s)),e.addFullscreenPass(s),a=i}const s=e.createColorTarget(`${this.options.targetPrefix}Composite`,{format:"rgba16float"}),o=`composite:${t.sceneColor}:${a}:${s}`;let l=this.passes.get(o);return l||(l=new tp(t.sceneColor,a,s,this.options.intensity),this.passes.set(o,l)),e.addFullscreenPass(l),s}},Qh=class{constructor(e,t,r){this.options=r,this.inputs={sceneColor:e.sceneColor,sceneDepth:e.depth,normalRoughness:e.normalRoughness},this.outputs=t,this.fragmentShader=function(e){const t="world"===e.normalSpace?"normalize(viewRotation() * encodedNormal)":"encodedNormal",r=e.distanceAttenuation?"pow(clamp(1.0 - hitDistance / maxDistance, 0.0, 1.0), 2.0)":"1.0";return`\nconst STEPS: i32 = ${e.steps};\nfn projectionMatrix() -> mat4x4<f32> { return mat4x4<f32>(fullscreenUniforms[0], fullscreenUniforms[1], fullscreenUniforms[2], fullscreenUniforms[3]); }\nfn inverseProjectionMatrix() -> mat4x4<f32> { return mat4x4<f32>(fullscreenUniforms[4], fullscreenUniforms[5], fullscreenUniforms[6], fullscreenUniforms[7]); }\nfn viewRotation() -> mat3x3<f32> { return mat3x3<f32>(fullscreenUniforms[8].xyz, fullscreenUniforms[9].xyz, fullscreenUniforms[10].xyz); }\nfn viewPosition(uv: vec2<f32>, depth: f32) -> vec3<f32> {\n let p = inverseProjectionMatrix() * vec4<f32>(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, depth, 1.0);\n return p.xyz / p.w;\n}\nfn projectUv(position: vec3<f32>) -> vec2<f32> {\n let p = projectionMatrix() * vec4<f32>(position, 1.0);\n return vec2<f32>(p.x / p.w * 0.5 + 0.5, 0.5 - p.y / p.w * 0.5);\n}\nfn depthAt(uv: vec2<f32>) -> f32 {\n let size = vec2<i32>(textureDimensions(sceneDepthTexture));\n return textureLoad(sceneDepthTexture, clamp(vec2<i32>(uv * vec2<f32>(size)), vec2<i32>(0), size - vec2<i32>(1)), 0);\n}\nfn viewZFromDepth(depth: f32) -> f32 {\n let projection = projectionMatrix();\n return (projection[3].z - depth * projection[3].w)\n / (depth * projection[2].w - projection[2].z);\n}\nfn pointToLineDistanceSquared(point: vec3<f32>, start: vec3<f32>, end: vec3<f32>) -> f32 {\n let line = end - start;\n let perpendicular = cross(point - start, point - end);\n return dot(perpendicular, perpendicular) / max(dot(line, line), 0.0000001);\n}\nfn pointPlaneDistance(point: vec3<f32>, planePoint: vec3<f32>, planeNormal: vec3<f32>) -> f32 {\n return dot(point - planePoint, planeNormal);\n}\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let depth = depthAt(input.uv);\n if (depth >= 1.0) { return vec4<f32>(0.0); }\n let normalSize = vec2<i32>(textureDimensions(normalRoughnessTexture));\n let normalPixel = clamp(vec2<i32>(input.uv * vec2<f32>(normalSize)), vec2<i32>(0), normalSize - vec2<i32>(1));\n let material = textureLoad(normalRoughnessTexture, normalPixel, 0);\n let encodedNormal = normalize(material.rgb * 2.0 - vec3<f32>(1.0));\n let normal = ${t};\n let roughness = clamp(material.a, 0.0, 1.0);\n let maxRoughness = fullscreenUniforms[12].z;\n let reflectivity = 1.0 - roughness;\n if (roughness >= maxRoughness || reflectivity <= 0.0) { return vec4<f32>(0.0); }\n let origin = viewPosition(input.uv, depth);\n let incident = normalize(origin);\n let direction = normalize(reflect(incident, normal));\n let maxDistance = fullscreenUniforms[12].x;\n let thickness = fullscreenUniforms[12].y;\n let pixelStride = fullscreenUniforms[12].w;\n let near = fullscreenUniforms[13].x;\n let resolutionScale = fullscreenUniforms[13].z;\n let perspective = fullscreenUniforms[13].w > 0.5;\n let incidence = max(dot(-incident, normal), 0.001);\n let rayLength = maxDistance / incidence;\n var endpoint = origin + direction * rayLength;\n if (perspective && endpoint.z > -near && direction.z > 0.0) {\n endpoint = origin + direction * ((-near - origin.z) / direction.z);\n }\n let traceSize = vec2<f32>(textureDimensions(sceneDepthTexture)) * resolutionScale;\n let startPixel = input.position.xy;\n let endPixel = projectUv(endpoint) * traceSize;\n let pixelDelta = endPixel - startPixel;\n let totalSteps = max(abs(pixelDelta.x), abs(pixelDelta.y));\n if (totalSteps < 1.0) { return vec4<f32>(0.0); }\n let pixelStep = pixelDelta / totalSteps;\n let reciprocalOriginZ = 1.0 / origin.z;\n for (var i = 1; i <= STEPS; i += 1) {\n let traversedPixels = f32(i) * pixelStride;\n if (traversedPixels >= totalSteps) { break; }\n let samplePixel = startPixel + traversedPixels * pixelStep;\n if (any(samplePixel < vec2<f32>(0.0)) || any(samplePixel >= traceSize)) { break; }\n let sampleUv = samplePixel / traceSize;\n let sampleDepth = depthAt(sampleUv);\n if (sampleDepth < 1.0) {\n let progress = traversedPixels / totalSteps;\n let rayZ = select(\n mix(origin.z, endpoint.z, progress),\n 1.0 / mix(reciprocalOriginZ, 1.0 / endpoint.z, progress),\n perspective,\n );\n let sceneZ = viewZFromDepth(sampleDepth);\n if (rayZ <= sceneZ) {\n let scene = viewPosition(sampleUv, sampleDepth);\n let neighborUv = sampleUv + vec2<f32>(1.0 / traceSize.x, 0.0);\n let neighbor = viewPosition(neighborUv, sampleDepth);\n let minimumThickness = abs(neighbor.x - scene.x) * 3.0;\n let hitThickness = max(minimumThickness, thickness);\n if (pointToLineDistanceSquared(scene, origin, endpoint) <= hitThickness * hitThickness) {\n let hitPixel = clamp(vec2<i32>(sampleUv * vec2<f32>(normalSize)), vec2<i32>(0), normalSize - vec2<i32>(1));\n let hitEncodedNormal = normalize(textureLoad(normalRoughnessTexture, hitPixel, 0).rgb * 2.0 - vec3<f32>(1.0));\n let hitNormal = ${t.replace("encodedNormal","hitEncodedNormal")};\n if (dot(direction, hitNormal) < 0.0) {\n let hitDistance = pointPlaneDistance(scene, origin, normal);\n if (hitDistance > maxDistance) { break; }\n let distanceFade = ${r};\n let fresnel = (dot(incident, direction) + 1.0) * 0.5;\n let reflected = textureSampleLevel(sceneColorTexture, fullscreenSampler, sampleUv, 0.0).rgb;\n return vec4<f32>(reflected, reflectivity * distanceFade * fresnel);\n }\n }\n }\n }\n }\n return vec4<f32>(0.0);\n}`}(r)}options;name="SSRTracePass";sampler="linear";uniformBufferSize=224;inputs;outputs;fragmentShader;uniforms=new Float32Array(56);projection=new Xh;inverseProjection=new Xh;updateUniforms=e=>(this.projection.copy(rp).multiply(e.camera.projectionMatrix),this.inverseProjection.copy(this.projection).invert(),this.uniforms.set(this.projection.elements,0),this.uniforms.set(this.inverseProjection.elements,16),this.uniforms.set(e.camera.matrixWorldInverse.elements,32),this.uniforms.set([this.options.maxDistance,this.options.thickness,this.options.maxRoughness,this.options.pixelStride],48),this.uniforms.set([e.camera.near,e.camera.far,this.options.resolutionScale,"isPerspectiveCamera"in e.camera&&e.camera.isPerspectiveCamera?1:0],52),this.uniforms)},ep=class{name;sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms;constructor(e,t,r,i,n,a){this.name=0===n?"SSRBlurHorizontalPass":"SSRBlurVerticalPass",this.inputs={reflection:e,sceneDepth:t,normalRoughness:r},this.outputs=i,this.uniforms=new Float32Array([0===n?1:0,1===n?1:0,a,0])}updateUniforms=()=>this.uniforms;fragmentShader="\nconst MIN_BLUR = 0.02; // Helps reducing artifacts\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let reflectionSize = vec2<i32>(textureDimensions(reflectionTexture));\n let depthSize = vec2<i32>(textureDimensions(sceneDepthTexture));\n let p = clamp(vec2<i32>(input.position.xy), vec2<i32>(0), reflectionSize - vec2<i32>(1));\n let fullP = clamp(vec2<i32>(input.uv * vec2<f32>(depthSize)), vec2<i32>(0), depthSize - vec2<i32>(1));\n let centerDepth = textureLoad(sceneDepthTexture, fullP, 0);\n let centerMaterial = textureLoad(normalRoughnessTexture, fullP, 0);\n let centerNormal = normalize(centerMaterial.rgb * 2.0 - vec3<f32>(1.0));\n let blurAmount = smoothstep(0.03, 0.75, centerMaterial.a);\n // A tiny base radius antialiases trace silhouettes on perfect mirrors. The\n // outer Gaussian tap reaches blurRadius pixels on a fully rough receiver.\n let radiusPixels = mix(0.75, fullscreenUniforms[0].z, max(MIN_BLUR, blurAmount));\n let axis = fullscreenUniforms[0].xy;\n let tapSpacing = radiusPixels / 4.0;\n var premultiplied = vec3<f32>(0.0);\n var alphaSum = 0.0;\n var weightSum = 0.0;\n for (var i = -4; i <= 4; i += 1) {\n let fi = f32(i);\n let sampleUv = clamp(\n input.uv + axis * fi * tapSpacing / vec2<f32>(reflectionSize),\n vec2<f32>(0.0),\n vec2<f32>(1.0),\n );\n let sampleFullP = clamp(vec2<i32>(sampleUv * vec2<f32>(depthSize)), vec2<i32>(0), depthSize - vec2<i32>(1));\n let sampleDepth = textureLoad(sceneDepthTexture, sampleFullP, 0);\n let sampleNormal = normalize(textureLoad(normalRoughnessTexture, sampleFullP, 0).rgb * 2.0 - vec3<f32>(1.0));\n let geometryWeight = select(\n exp(-abs(sampleDepth - centerDepth) * 350.0) * pow(max(dot(centerNormal, sampleNormal), 0.0), 16.0),\n 1.0,\n i == 0,\n );\n let reflected = textureSampleLevel(reflectionTexture, fullscreenSampler, sampleUv, 0.0);\n let gaussianWeight = exp(-0.5 * fi * fi / 4.0);\n let weight = geometryWeight * gaussianWeight;\n premultiplied += reflected.rgb * reflected.a * weight;\n alphaSum += reflected.a * weight;\n weightSum += weight;\n }\n let alpha = alphaSum / max(weightSum, 0.0001);\n let color = select(vec3<f32>(0.0), premultiplied / max(alphaSum, 0.0001), alphaSum > 0.0001);\n return vec4<f32>(color, alpha);\n}"},tp=class{name="SSRCompositePass";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms;constructor(e,t,r,i){this.inputs={sceneColor:e,reflection:t},this.outputs=r,this.uniforms=new Float32Array([i,0,0,0])}updateUniforms=()=>this.uniforms;fragmentShader="\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let color = textureLoad(sceneColorTexture, vec2<i32>(input.position.xy), 0);\n let reflection = textureSampleLevel(reflectionTexture, fullscreenSampler, input.uv, 0.0);\n let reflectionWeight = clamp(reflection.a * fullscreenUniforms[0].x, 0.0, 1.0);\n return vec4<f32>(mix(color.rgb, reflection.rgb, reflectionWeight), color.a);\n}"};var rp=(new Xh).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);function ip(e,t,r){return Math.min(r,Math.max(t,e))}import{Matrix4 as np,Vector2 as ap}from"three";var sp=(new np).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),op=class{renderScale;sampleCount;minCurrentWeight;motionWeightScale;depthThreshold;relativeDepthThreshold;targetPrefix;writeIndex=0;historyValid=!1;frameIndex=0;renderWidth=1;renderHeight=1;outputWidth=1;outputHeight=1;jitter=new ap;unjitteredProjection=new np;previousJitterUv=new ap;currentJitterUv=new ap;previousViewProjection=new np;resolvePasses=new Map;constructor(e={}){this.renderScale=up(e.renderScale??1,.25,1),this.sampleCount=Math.max(1,Math.floor(e.sampleCount??32)),this.minCurrentWeight=up(e.minCurrentWeight??.06,0,1),this.motionWeightScale=Math.max(.001,e.motionWeightScale??24),this.depthThreshold=Math.max(0,e.depthThreshold??.001),this.relativeDepthThreshold=Math.max(0,e.relativeDepthThreshold??.002),this.targetPrefix=e.targetPrefix??"taa"}prepareCamera(e,t,r){this.setSize(t,r),e.updateProjectionMatrix(),this.unjitteredProjection.copy(e.projectionMatrix),this.jitter.set(cp(this.frameIndex%this.sampleCount+1,2)-.5,cp(this.frameIndex%this.sampleCount+1,3)-.5),this.currentJitterUv.set(this.jitter.x/this.renderWidth,-this.jitter.y/this.renderHeight),e.projectionMatrix.elements[8]-=2*this.jitter.x/this.renderWidth,e.projectionMatrix.elements[9]-=2*this.jitter.y/this.renderHeight,e.projectionMatrixInverse?.copy(e.projectionMatrix).invert()}finishCamera(e){e.projectionMatrix.copy(this.unjitteredProjection),e.projectionMatrixInverse?.copy(e.projectionMatrix).invert()}addPass(e,t,r=e.mainDepth,i){const n=e.createColorTarget(`${this.targetPrefix}HistoryColorA`,{format:"rgba16float",resolution:"presentation"}),a=e.createColorTarget(`${this.targetPrefix}HistoryColorB`,{format:"rgba16float",resolution:"presentation"}),s=e.createColorTarget(`${this.targetPrefix}HistoryDepthA`,{format:"r32float",resolution:"presentation"}),o=e.createColorTarget(`${this.targetPrefix}HistoryDepthB`,{format:"r32float",resolution:"presentation"}),l=0===this.writeIndex?a:n,c=0===this.writeIndex?n:a,u=0===this.writeIndex?o:s,d=0===this.writeIndex?s:o,h=`${t}:${r}:${i??"camera"}:${l}:${u}:${c}:${d}`;let p=this.resolvePasses.get(h);return p||(p=new lp(t,r,i,l,u,c,d,this),this.resolvePasses.set(h,p)),e.addFullscreenPass(p),this.writeIndex=1-this.writeIndex,this.frameIndex+=1,c}reset(){this.frameIndex=0,this.writeIndex=0,this.historyValid=!1,this.previousViewProjection.identity(),this.currentJitterUv.set(0,0),this.previousJitterUv.set(0,0)}setRenderScale(e){const t=up(e,.25,1);t!==this.renderScale&&(this.renderScale=t,this.renderWidth=Math.max(1,Math.floor(this.outputWidth*this.renderScale)),this.renderHeight=Math.max(1,Math.floor(this.outputHeight*this.renderScale)),this.reset())}setSize(e,t){const r=Math.max(1,Math.floor(e)),i=Math.max(1,Math.floor(t));r===this.outputWidth&&i===this.outputHeight||(this.outputWidth=r,this.outputHeight=i,this.renderWidth=Math.max(1,Math.floor(r*this.renderScale)),this.renderHeight=Math.max(1,Math.floor(i*this.renderScale)),this.reset())}updateResolveUniforms(e,t,r,i){t.copy(sp).multiply(i.camera.projectionMatrix).multiply(i.camera.matrixWorldInverse),r.copy(t).invert(),e.set(r.elements,0),e.set((this.historyValid?this.previousViewProjection:t).elements,16),e.set([i.presentationWidth,i.presentationHeight,this.historyValid?1:0,0],32),e.set([this.currentJitterUv.x,this.currentJitterUv.y,this.previousJitterUv.x,this.previousJitterUv.y],36),e.set([this.minCurrentWeight,this.motionWeightScale,this.depthThreshold,this.relativeDepthThreshold],40),this.previousViewProjection.copy(t),this.previousJitterUv.copy(this.currentJitterUv),this.historyValid=!0}},lp=class{constructor(e,t,r,i,n,a,s,o){var l;this.state=o,this.inputs=null==r?{currentColor:e,currentDepth:t,historyColor:i,historyDepth:n}:{currentColor:e,currentDepth:t,historyColor:i,historyDepth:n,velocity:r},this.outputs=[a,s],this.fragmentShader=`\nstruct TAAOutput {\n @location(0) color: vec4<f32>,\n @location(1) depth: vec4<f32>,\n};\n\nfn currentViewProjectionInverse() -> mat4x4<f32> {\n return mat4x4<f32>(fullscreenUniforms[0], fullscreenUniforms[1], fullscreenUniforms[2], fullscreenUniforms[3]);\n}\n\nfn previousViewProjection() -> mat4x4<f32> {\n return mat4x4<f32>(fullscreenUniforms[4], fullscreenUniforms[5], fullscreenUniforms[6], fullscreenUniforms[7]);\n}\n\nfn loadCurrentDepth(pixel: vec2<i32>, size: vec2<i32>) -> f32 {\n return textureLoad(currentDepthTexture, clamp(pixel, vec2<i32>(0), size - vec2<i32>(1)), 0);\n}\n\nfn loadCurrentColor(pixel: vec2<i32>, size: vec2<i32>) -> vec3<f32> {\n return textureLoad(currentColorTexture, clamp(pixel, vec2<i32>(0), size - vec2<i32>(1)), 0).rgb;\n}\n\nfn sampleCurrentColorBilinear(uv: vec2<f32>) -> vec3<f32> {\n let size = vec2<i32>(textureDimensions(currentColorTexture));\n let position = uv * vec2<f32>(size) - 0.5;\n let base = vec2<i32>(floor(position));\n let fraction = fract(position);\n let c00 = loadCurrentColor(base, size);\n let c10 = loadCurrentColor(base + vec2<i32>(1, 0), size);\n let c01 = loadCurrentColor(base + vec2<i32>(0, 1), size);\n let c11 = loadCurrentColor(base + vec2<i32>(1, 1), size);\n return mix(mix(c00, c10, fraction.x), mix(c01, c11, fraction.x), fraction.y);\n}\n\nfn sampleHistoryColorBilinear(uv: vec2<f32>) -> vec3<f32> {\n let size = vec2<i32>(textureDimensions(historyColorTexture));\n let position = uv * vec2<f32>(size) - 0.5;\n let base = vec2<i32>(floor(position));\n let fraction = fract(position);\n let maximum = size - vec2<i32>(1);\n let c00 = textureLoad(historyColorTexture, clamp(base, vec2<i32>(0), maximum), 0).rgb;\n let c10 = textureLoad(historyColorTexture, clamp(base + vec2<i32>(1, 0), vec2<i32>(0), maximum), 0).rgb;\n let c01 = textureLoad(historyColorTexture, clamp(base + vec2<i32>(0, 1), vec2<i32>(0), maximum), 0).rgb;\n let c11 = textureLoad(historyColorTexture, clamp(base + vec2<i32>(1, 1), vec2<i32>(0), maximum), 0).rgb;\n return mix(mix(c00, c10, fraction.x), mix(c01, c11, fraction.x), fraction.y);\n}\n\nfn sampleHistoryDepthNearest(uv: vec2<f32>) -> f32 {\n let size = vec2<i32>(textureDimensions(historyDepthTexture));\n let pixel = clamp(vec2<i32>(uv * vec2<f32>(size)), vec2<i32>(0), size - vec2<i32>(1));\n return textureLoad(historyDepthTexture, pixel, 0).r;\n}\n\nfn historyUvFor(currentUv: vec2<f32>, depth: f32) -> vec2<f32> {\n let clip = vec4<f32>(currentUv.x * 2.0 - 1.0, 1.0 - currentUv.y * 2.0, depth, 1.0);\n let worldH = currentViewProjectionInverse() * clip;\n let world = worldH / worldH.w;\n let previousClip = previousViewProjection() * world;\n let previousNdc = previousClip.xy / previousClip.w;\n let previousRasterUv = vec2<f32>(previousNdc.x * 0.5 + 0.5, 0.5 - previousNdc.y * 0.5);\n return previousRasterUv - fullscreenUniforms[9].zw;\n}\n${(l=null!=r)?"\nfn loadPackedVelocity(pixel: vec2<i32>, renderSize: vec2<i32>) -> vec4<f32> {\n let velocitySize = vec2<i32>(textureDimensions(velocityTexture));\n let velocityPixel = clamp(\n vec2<i32>((vec2<f32>(pixel) + 0.5) * vec2<f32>(velocitySize) / vec2<f32>(renderSize)),\n vec2<i32>(0),\n velocitySize - vec2<i32>(1)\n );\n return textureLoad(velocityTexture, velocityPixel, 0);\n}\n":""}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> TAAOutput {\n let renderSize = vec2<i32>(textureDimensions(currentDepthTexture));\n let outputSize = vec2<i32>(fullscreenUniforms[8].xy);\n let centerPixel = clamp(vec2<i32>(input.position.xy), vec2<i32>(0), outputSize - vec2<i32>(1));\n let centerUv = (vec2<f32>(centerPixel) + 0.5) / vec2<f32>(outputSize);\n let currentJitterUv = fullscreenUniforms[9].xy;\n let currentSampleUv = centerUv + currentJitterUv;\n let currentSamplePixel = clamp(vec2<i32>(currentSampleUv * vec2<f32>(renderSize)), vec2<i32>(0), renderSize - vec2<i32>(1));\n let centerDepth = loadCurrentDepth(currentSamplePixel, renderSize);\n\n var closestDepth = centerDepth;\n var closestPixel = currentSamplePixel;\n var mean = vec3<f32>(0.0);\n var meanSquared = vec3<f32>(0.0);\n for (var y = -1; y <= 1; y += 1) {\n for (var x = -1; x <= 1; x += 1) {\n let samplePixel = clamp(currentSamplePixel + vec2<i32>(x, y), vec2<i32>(0), renderSize - vec2<i32>(1));\n let sampleDepth = loadCurrentDepth(samplePixel, renderSize);\n if (sampleDepth < closestDepth) {\n closestDepth = sampleDepth;\n closestPixel = samplePixel;\n }\n let sampleColor = sampleCurrentColorBilinear(currentSampleUv + vec2<f32>(f32(x), f32(y)) / vec2<f32>(renderSize));\n mean += sampleColor;\n meanSquared += sampleColor * sampleColor;\n }\n }\n mean /= 9.0;\n let sigma = sqrt(max(meanSquared / 9.0 - mean * mean, vec3<f32>(0.0)));\n\n let currentColor = sampleCurrentColorBilinear(currentSampleUv);\n let closestUv = (vec2<f32>(closestPixel) + 0.5) / vec2<f32>(renderSize);\n let closestHistoryUv = historyUvFor(closestUv, closestDepth);\n let closestOutputUv = closestUv - currentJitterUv;\n let cameraHistoryUv = centerUv - (closestOutputUv - closestHistoryUv);\n${l?"\n // RG stores unjittered previous-to-current displacement in top-left-origin\n // UV units. History therefore lies opposite the velocity. Sampling at the\n // closest-depth pixel avoids borrowing background motion at silhouettes.\n let packedVelocity = loadPackedVelocity(closestPixel, renderSize);\n let rawVelocity = packedVelocity.xy;\n let finiteVelocity = all(rawVelocity == rawVelocity) && all(abs(rawVelocity) < vec2<f32>(2.0));\n // B=CameraOnly with exactly zero RG is the explicit fallback emitted by a\n // custom-position material that did not provide previous-frame deformation.\n let needsCameraFallback =\n abs(packedVelocity.z - 1.0) < 0.25 &&\n dot(rawVelocity, rawVelocity) < 1e-12;\n let historyUv = select(\n cameraHistoryUv,\n centerUv - rawVelocity,\n finiteVelocity && !needsCameraFallback\n );\n":"\n let historyUv = cameraHistoryUv;\n"}\n let validUv = all(historyUv >= vec2<f32>(0.0)) && all(historyUv <= vec2<f32>(1.0));\n let historyWasValid = fullscreenUniforms[8].z > 0.5;\n\n var validHistory = historyWasValid && validUv && centerDepth < 1.0;\n var historyColor = currentColor;\n if (validHistory) {\n historyColor = sampleHistoryColorBilinear(historyUv);\n let previousDepth = sampleHistoryDepthNearest(historyUv);\n let expectedPreviousDepth = previousViewProjection() *\n (currentViewProjectionInverse() * vec4<f32>(closestUv.x * 2.0 - 1.0, 1.0 - closestUv.y * 2.0, closestDepth, 1.0));\n let expectedDepth = expectedPreviousDepth.z / expectedPreviousDepth.w;\n let depthThreshold = fullscreenUniforms[10].z;\n let relativeDepthThreshold = fullscreenUniforms[10].w;\n validHistory = abs(previousDepth - expectedDepth) < max(depthThreshold, abs(expectedDepth) * relativeDepthThreshold);\n }\n\n let clippedHistory = clamp(historyColor, mean - sigma, mean + sigma);\n let motionPixels = length((centerUv - historyUv) * vec2<f32>(outputSize));\n let minCurrentWeight = fullscreenUniforms[10].x;\n let currentWeight = clamp(minCurrentWeight + motionPixels / fullscreenUniforms[10].y, minCurrentWeight, 1.0);\n let resolved = select(currentColor, mix(clippedHistory, currentColor, currentWeight), validHistory);\n\n var output: TAAOutput;\n output.color = vec4<f32>(resolved, 1.0);\n output.depth = vec4<f32>(centerDepth, 0.0, 0.0, 1.0);\n return output;\n}\n`}state;name="TemporalAAResolvePass";sampler="nearest";uniformBufferSize=176;inputs;outputs;fragmentShader;uniforms=new Float32Array(this.uniformBufferSize/4);currentViewProjection=new np;currentViewProjectionInverse=new np;updateUniforms=e=>(this.state.updateResolveUniforms(this.uniforms,this.currentViewProjection,this.currentViewProjectionInverse,e),this.uniforms)};function cp(e,t){let r=1,i=0;for(;e>0;)r/=t,i+=r*(e%t),e=Math.floor(e/t);return i}function up(e,t,r){return Math.min(r,Math.max(t,e))}var dp=class{contrastThreshold;relativeThreshold;subpixelBlending;targetPrefix;passes=new Map;constructor(e={}){this.contrastThreshold=Math.max(0,e.contrastThreshold??.0312),this.relativeThreshold=Math.max(0,e.relativeThreshold??.063),this.subpixelBlending=pp(e.subpixelBlending??.75,0,1),this.targetPrefix=e.targetPrefix??"fxaa"}addPass(e,t,r={}){const i=r.output??e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float",resolution:"presentation"}),n=`${t}:${i}`;let a=this.passes.get(n);return a||(a=new hp(t,i,this),this.passes.set(n,a)),e.addFullscreenPass(a),i}},hp=class{constructor(e,t,r){this.state=r,this.inputs={source:e},this.outputs=t}state;name="FXAAPass";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([Math.max(0,this.state.contrastThreshold),Math.max(0,this.state.relativeThreshold),pp(this.state.subpixelBlending,0,1),0]),this.uniforms);fragmentShader="\nconst EDGE_STEP_COUNT: i32 = 6;\nconst EDGE_GUESS: f32 = 8.0;\nconst EDGE_STEPS = array<f32, 6>(1.0, 1.5, 2.0, 2.0, 2.0, 4.0);\n\nstruct LuminanceData {\n m: f32,\n n: f32,\n e: f32,\n s: f32,\n w: f32,\n ne: f32,\n nw: f32,\n se: f32,\n sw: f32,\n highest: f32,\n lowest: f32,\n contrast: f32,\n};\n\nstruct EdgeData {\n isHorizontal: bool,\n pixelStep: f32,\n oppositeLuminance: f32,\n gradient: f32,\n};\n\nfn sampleColor(uv: vec2<f32>) -> vec4<f32> {\n return textureSampleLevel(sourceTexture, fullscreenSampler, uv, 0.0);\n}\n\nfn sampleLuminance(uv: vec2<f32>) -> f32 {\n // The renderer's intermediate buffers are linear. FXAA thresholds are tuned\n // for perceptual luminance, so sqrt is a cheap gamma approximation here.\n return sqrt(max(dot(sampleColor(uv).rgb, vec3<f32>(0.299, 0.587, 0.114)), 0.0));\n}\n\nfn offsetLuminance(uv: vec2<f32>, texel: vec2<f32>, offset: vec2<f32>) -> f32 {\n return sampleLuminance(uv + texel * offset);\n}\n\nfn sampleNeighborhood(uv: vec2<f32>, texel: vec2<f32>) -> LuminanceData {\n var l: LuminanceData;\n l.m = sampleLuminance(uv);\n l.n = offsetLuminance(uv, texel, vec2<f32>(0.0, -1.0));\n l.e = offsetLuminance(uv, texel, vec2<f32>(1.0, 0.0));\n l.s = offsetLuminance(uv, texel, vec2<f32>(0.0, 1.0));\n l.w = offsetLuminance(uv, texel, vec2<f32>(-1.0, 0.0));\n l.ne = offsetLuminance(uv, texel, vec2<f32>(1.0, -1.0));\n l.nw = offsetLuminance(uv, texel, vec2<f32>(-1.0, -1.0));\n l.se = offsetLuminance(uv, texel, vec2<f32>(1.0, 1.0));\n l.sw = offsetLuminance(uv, texel, vec2<f32>(-1.0, 1.0));\n l.highest = max(max(max(max(l.n, l.e), l.s), l.w), l.m);\n l.lowest = min(min(min(min(l.n, l.e), l.s), l.w), l.m);\n l.contrast = l.highest - l.lowest;\n return l;\n}\n\nfn pixelBlendFactor(l: LuminanceData) -> f32 {\n var filterAmount = 2.0 * (l.n + l.e + l.s + l.w);\n filterAmount += l.ne + l.nw + l.se + l.sw;\n filterAmount = abs(filterAmount / 12.0 - l.m);\n filterAmount = clamp(filterAmount / max(l.contrast, 1e-5), 0.0, 1.0);\n let blend = smoothstep(0.0, 1.0, filterAmount);\n return blend * blend * fullscreenUniforms[0].z;\n}\n\nfn determineEdge(texel: vec2<f32>, l: LuminanceData) -> EdgeData {\n let horizontal =\n abs(l.n + l.s - 2.0 * l.m) * 2.0 +\n abs(l.ne + l.se - 2.0 * l.e) +\n abs(l.nw + l.sw - 2.0 * l.w);\n let vertical =\n abs(l.e + l.w - 2.0 * l.m) * 2.0 +\n abs(l.ne + l.nw - 2.0 * l.n) +\n abs(l.se + l.sw - 2.0 * l.s);\n\n var edge: EdgeData;\n edge.isHorizontal = horizontal >= vertical;\n let positiveLuminance = select(l.e, l.n, edge.isHorizontal);\n let negativeLuminance = select(l.w, l.s, edge.isHorizontal);\n let positiveGradient = abs(positiveLuminance - l.m);\n let negativeGradient = abs(negativeLuminance - l.m);\n edge.pixelStep = select(texel.x, texel.y, edge.isHorizontal);\n if (positiveGradient < negativeGradient) {\n edge.pixelStep = -edge.pixelStep;\n edge.oppositeLuminance = negativeLuminance;\n edge.gradient = negativeGradient;\n } else {\n edge.oppositeLuminance = positiveLuminance;\n edge.gradient = positiveGradient;\n }\n return edge;\n}\n\nfn edgeBlendFactor(uv: vec2<f32>, texel: vec2<f32>, l: LuminanceData, edge: EdgeData) -> f32 {\n var edgeUv = uv;\n var edgeStep: vec2<f32>;\n if (edge.isHorizontal) {\n edgeUv.y += edge.pixelStep * 0.5;\n edgeStep = vec2<f32>(texel.x, 0.0);\n } else {\n edgeUv.x += edge.pixelStep * 0.5;\n edgeStep = vec2<f32>(0.0, texel.y);\n }\n\n let edgeLuminance = (l.m + edge.oppositeLuminance) * 0.5;\n let gradientThreshold = edge.gradient * 0.25;\n var positiveUv = edgeUv + edgeStep * EDGE_STEPS[0];\n var positiveDelta = sampleLuminance(positiveUv) - edgeLuminance;\n var positiveAtEnd = abs(positiveDelta) >= gradientThreshold;\n for (var i = 1; i < EDGE_STEP_COUNT; i += 1) {\n if (!positiveAtEnd) {\n positiveUv += edgeStep * EDGE_STEPS[i];\n positiveDelta = sampleLuminance(positiveUv) - edgeLuminance;\n positiveAtEnd = abs(positiveDelta) >= gradientThreshold;\n }\n }\n if (!positiveAtEnd) {\n positiveUv += edgeStep * EDGE_GUESS;\n }\n\n var negativeUv = edgeUv - edgeStep * EDGE_STEPS[0];\n var negativeDelta = sampleLuminance(negativeUv) - edgeLuminance;\n var negativeAtEnd = abs(negativeDelta) >= gradientThreshold;\n for (var i = 1; i < EDGE_STEP_COUNT; i += 1) {\n if (!negativeAtEnd) {\n negativeUv -= edgeStep * EDGE_STEPS[i];\n negativeDelta = sampleLuminance(negativeUv) - edgeLuminance;\n negativeAtEnd = abs(negativeDelta) >= gradientThreshold;\n }\n }\n if (!negativeAtEnd) {\n negativeUv -= edgeStep * EDGE_GUESS;\n }\n\n let positiveDistance = select(positiveUv.y - uv.y, positiveUv.x - uv.x, edge.isHorizontal);\n let negativeDistance = select(uv.y - negativeUv.y, uv.x - negativeUv.x, edge.isHorizontal);\n var shortestDistance = negativeDistance;\n var deltaSign = negativeDelta >= 0.0;\n if (positiveDistance <= negativeDistance) {\n shortestDistance = positiveDistance;\n deltaSign = positiveDelta >= 0.0;\n }\n if (deltaSign == (l.m - edgeLuminance >= 0.0)) {\n return 0.0;\n }\n return 0.5 - shortestDistance / max(positiveDistance + negativeDistance, 1e-5);\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let texel = 1.0 / vec2<f32>(textureDimensions(sourceTexture));\n let luminance = sampleNeighborhood(input.uv, texel);\n let threshold = max(fullscreenUniforms[0].x, fullscreenUniforms[0].y * luminance.highest);\n if (luminance.contrast < threshold) {\n return sampleColor(input.uv);\n }\n\n let edge = determineEdge(texel, luminance);\n let blend = max(pixelBlendFactor(luminance), edgeBlendFactor(input.uv, texel, luminance, edge));\n var sampleUv = input.uv;\n if (edge.isHorizontal) {\n sampleUv.y += edge.pixelStep * blend;\n } else {\n sampleUv.x += edge.pixelStep * blend;\n }\n return sampleColor(sampleUv);\n}\n"};function pp(e,t,r){return Math.min(r,Math.max(t,e))}import{ClampToEdgeWrapping as fp,DataTexture as mp,LinearFilter as gp,NoColorSpace as vp,RGFormat as xp,UnsignedByteType as wp}from"three";var bp={low:{searchSteps:4,diagonalSteps:0},medium:{searchSteps:8,diagonalSteps:0},high:{searchSteps:16,diagonalSteps:8},ultra:{searchSteps:32,diagonalSteps:16}},yp=class{threshold;localContrastAdaptation;edgeDetection;cornerRounding;sharpness;quality;targetPrefix;areaTexture;edgePasses=new Map;weightPasses=new Map;blendPasses=new Map;constructor(e={}){this.threshold=Math.max(0,e.threshold??.08),this.localContrastAdaptation=Math.max(0,e.localContrastAdaptation??.5),this.edgeDetection=e.edgeDetection??"color",this.cornerRounding=zp(e.cornerRounding??.25,0,1),this.sharpness=zp(e.sharpness??0,0,1),this.quality=bp[e.quality??"high"],this.targetPrefix=e.targetPrefix??"smaa",this.areaTexture=function(){const e=new mp(function(){if(Pp)return Pp;const e=new Uint8Array(25600),t=[[0,0],[3,0],[0,3],[3,3],[1,0],[4,0],[1,3],[4,3],[0,1],[3,1],[0,4],[3,4],[1,1],[4,1],[1,4],[4,4]],r=[[0,0],[1,0],[0,2],[1,2],[2,0],[3,0],[2,2],[3,2],[0,1],[1,1],[0,3],[1,3],[2,1],[3,1],[2,3],[3,3]];for(let i=0;i<16;i+=1){const[n,a]=t[i];for(let t=0;t<16;t+=1)for(let r=0;r<16;r+=1){Bp(e,16*n+r,16*a+t,Dp(i,r*r,t*t))}const[s,o]=r[i];for(let t=0;t<20;t+=1)for(let r=0;r<20;r+=1){Bp(e,80+20*s+r,20*o+t,Vp(i,r,t))}}return Pp=e,e}(),160,80,xp,wp);return e.name="SMAA-Area-Lookup",e.colorSpace=vp,e.minFilter=gp,e.magFilter=gp,e.wrapS=fp,e.wrapT=fp,e.generateMipmaps=!1,e.needsUpdate=!0,e}()}addPass(e,t,r={}){const i=e.createColorTarget(`${this.targetPrefix}Edges`,{format:"rg8unorm",resolution:"render"}),n=e.createColorTarget(`${this.targetPrefix}Weights`,{format:"rgba8unorm",resolution:"render"}),a=r.output??e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float",resolution:"render"}),s=`${t}:${i}`;let o=this.edgePasses.get(s);o||(o=new Sp(t,i,this),this.edgePasses.set(s,o));const l=`${i}:${n}`;let c=this.weightPasses.get(l);c||(c=new Cp(i,n,this.areaTexture,this),this.weightPasses.set(l,c));const u=`${t}:${n}:${a}`;let d=this.blendPasses.get(u);return d||(d=new Mp(t,n,a,this),this.blendPasses.set(u,d)),e.addFullscreenPass(o),e.addFullscreenPass(c),e.addFullscreenPass(d),a}dispose(){this.areaTexture.dispose()}get searchSteps(){return this.quality.searchSteps}get diagonalSteps(){return this.quality.diagonalSteps}},Sp=class{constructor(e,t,r){this.state=r,this.inputs={source:e},this.outputs=t}state;name="SMAAEdgeDetectionPass";sampler="nearest";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([Math.max(0,this.state.threshold),Math.max(0,this.state.localContrastAdaptation),"color"===this.state.edgeDetection?1:0,0]),this.uniforms);fragmentShader="\nfn loadColor(pixel: vec2<i32>, size: vec2<i32>) -> vec3<f32> {\n let color = textureLoad(sourceTexture, clamp(pixel, vec2<i32>(0), size - vec2<i32>(1)), 0).rgb;\n // Intermediate buffers are linear. This inexpensive transfer makes the\n // threshold perceptual and keeps black toon strokes from being missed.\n return sqrt(max(color, vec3<f32>(0.0)));\n}\n\nfn colorDelta(a: vec3<f32>, b: vec3<f32>) -> f32 {\n let difference = abs(a - b);\n let colorDelta = max(difference.r, max(difference.g, difference.b));\n let lumaDelta = abs(dot(a - b, vec3<f32>(0.299, 0.587, 0.114)));\n return select(lumaDelta, colorDelta, fullscreenUniforms[0].z > 0.5);\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let size = vec2<i32>(textureDimensions(sourceTexture));\n let pixel = clamp(vec2<i32>(input.position.xy), vec2<i32>(0), size - vec2<i32>(1));\n let center = loadColor(pixel, size);\n let leftColor = loadColor(pixel + vec2<i32>(-1, 0), size);\n let topColor = loadColor(pixel + vec2<i32>(0, -1), size);\n let left = colorDelta(center, leftColor);\n let top = colorDelta(center, topColor);\n let right = colorDelta(center, loadColor(pixel + vec2<i32>(1, 0), size));\n let bottom = colorDelta(center, loadColor(pixel + vec2<i32>(0, 1), size));\n let left2 = colorDelta(leftColor, loadColor(pixel + vec2<i32>(-2, 0), size));\n let top2 = colorDelta(topColor, loadColor(pixel + vec2<i32>(0, -2), size));\n let maximum = max(max(max(left, top), max(right, bottom)), max(left2, top2));\n let threshold = fullscreenUniforms[0].x;\n let adaptation = fullscreenUniforms[0].y * maximum;\n let westEdge = left >= threshold && left >= adaptation;\n let northEdge = top >= threshold && top >= adaptation;\n return vec4<f32>(\n select(0.0, 1.0, westEdge),\n select(0.0, 1.0, northEdge),\n 0.0,\n 0.0\n );\n}\n"},Cp=class{constructor(e,t,r,i){this.state=i,this.inputs={edges:e},this.outputs=t,this.textures={area:r}}state;name="SMAABlendingWeightPass";sampler="nearest";uniformBufferSize=16;inputs;outputs;textures;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([this.state.searchSteps,this.state.diagonalSteps,zp(this.state.cornerRounding,0,1),0]),this.uniforms);fragmentShader="\nconst MAX_SEARCH_STEPS: i32 = 32;\nconst MAX_DIAGONAL_STEPS: i32 = 16;\n\nfn edgeAt(pixel: vec2<i32>, size: vec2<i32>) -> vec2<f32> {\n if (any(pixel < vec2<i32>(0)) || any(pixel >= size)) {\n return vec2<f32>(0.0);\n }\n return textureLoad(edgesTexture, pixel, 0).rg;\n}\n\nfn areaOrthogonal(distance: vec2<f32>, e1: f32, e2: f32) -> vec2<f32> {\n let pattern = vec2<f32>(round(4.0 * vec2<f32>(e1, e2)));\n let texel = vec2<f32>(16.0) * pattern + sqrt(max(distance, vec2<f32>(0.0)));\n let uv = (texel + vec2<f32>(0.5)) / vec2<f32>(160.0, 80.0);\n return textureSampleLevel(areaTexture, areaSampler, uv, 0.0).rg;\n}\n\nfn areaDiagonal(distance: vec2<f32>, e: vec2<f32>) -> vec2<f32> {\n let pattern = round(e);\n let texel = vec2<f32>(80.0, 0.0) + vec2<f32>(20.0) * pattern + distance;\n let uv = (texel + vec2<f32>(0.5)) / vec2<f32>(160.0, 80.0);\n return textureSampleLevel(areaTexture, areaSampler, uv, 0.0).rg;\n}\n\nfn searchHorizontal(pixel: vec2<i32>, direction: i32, size: vec2<i32>) -> i32 {\n var distance = 0;\n let limit = i32(fullscreenUniforms[0].x);\n for (var step = 1; step <= MAX_SEARCH_STEPS; step += 1) {\n if (step > limit) { break; }\n let candidate = pixel + vec2<i32>(direction * step, 0);\n let edge = edgeAt(candidate, size);\n if (edge.g < 0.5 || (step > 1 && edge.r > 0.5)) { break; }\n distance = step;\n }\n return distance;\n}\n\nfn searchVertical(pixel: vec2<i32>, direction: i32, size: vec2<i32>) -> i32 {\n var distance = 0;\n let limit = i32(fullscreenUniforms[0].x);\n for (var step = 1; step <= MAX_SEARCH_STEPS; step += 1) {\n if (step > limit) { break; }\n let candidate = pixel + vec2<i32>(0, direction * step);\n let edge = edgeAt(candidate, size);\n if (edge.r < 0.5 || (step > 1 && edge.g > 0.5)) { break; }\n distance = step;\n }\n return distance;\n}\n\nfn horizontalCrossing(pixel: vec2<i32>, size: vec2<i32>) -> f32 {\n let near = edgeAt(pixel, size).r;\n let far = edgeAt(pixel + vec2<i32>(0, -1), size).r;\n return (3.0 * near + far) * 0.25;\n}\n\nfn verticalCrossing(pixel: vec2<i32>, size: vec2<i32>) -> f32 {\n let near = edgeAt(pixel, size).g;\n let far = edgeAt(pixel + vec2<i32>(-1, 0), size).g;\n return (3.0 * near + far) * 0.25;\n}\n\nfn attenuateHorizontalCorners(\n weights: vec2<f32>,\n leftPixel: vec2<i32>,\n rightPixel: vec2<i32>,\n leftDistance: i32,\n rightDistance: i32,\n size: vec2<i32>\n) -> vec2<f32> {\n let rounding = fullscreenUniforms[0].z;\n var result = weights;\n if (leftDistance <= rightDistance) {\n let extended = max(edgeAt(leftPixel + vec2<i32>(0, 1), size).r, edgeAt(leftPixel + vec2<i32>(0, -2), size).r);\n result *= clamp(vec2<f32>(rounding + 1.0 - extended), vec2<f32>(0.0), vec2<f32>(1.0));\n } else {\n let extended = max(edgeAt(rightPixel + vec2<i32>(1, 1), size).r, edgeAt(rightPixel + vec2<i32>(1, -2), size).r);\n result *= clamp(vec2<f32>(rounding + 1.0 - extended), vec2<f32>(0.0), vec2<f32>(1.0));\n }\n return result;\n}\n\nfn attenuateVerticalCorners(\n weights: vec2<f32>,\n topPixel: vec2<i32>,\n bottomPixel: vec2<i32>,\n topDistance: i32,\n bottomDistance: i32,\n size: vec2<i32>\n) -> vec2<f32> {\n let rounding = fullscreenUniforms[0].z;\n var result = weights;\n if (topDistance <= bottomDistance) {\n let extended = max(edgeAt(topPixel + vec2<i32>(1, 0), size).g, edgeAt(topPixel + vec2<i32>(-2, 0), size).g);\n result *= clamp(vec2<f32>(rounding + 1.0 - extended), vec2<f32>(0.0), vec2<f32>(1.0));\n } else {\n let extended = max(edgeAt(bottomPixel + vec2<i32>(1, 1), size).g, edgeAt(bottomPixel + vec2<i32>(-2, 1), size).g);\n result *= clamp(vec2<f32>(rounding + 1.0 - extended), vec2<f32>(0.0), vec2<f32>(1.0));\n }\n return result;\n}\n\nfn searchDiagonal(\n pixel: vec2<i32>,\n direction: vec2<i32>,\n size: vec2<i32>\n) -> vec2<f32> {\n var distance = 0;\n var lastEdge = vec2<f32>(0.0);\n let limit = i32(fullscreenUniforms[0].y);\n for (var step = 1; step <= MAX_DIAGONAL_STEPS; step += 1) {\n if (step > limit) { break; }\n let candidate = pixel + direction * step;\n let edge = edgeAt(candidate, size);\n let adjacent = edgeAt(candidate + vec2<i32>(1, 0), size).r;\n lastEdge = vec2<f32>(edge.g, adjacent);\n if (edge.g + adjacent < 1.5) { break; }\n distance = step;\n }\n return vec2<f32>(f32(distance), lastEdge.g);\n}\n\nfn diagonalWeights(pixel: vec2<i32>, edges: vec2<f32>, size: vec2<i32>) -> vec2<f32> {\n if (fullscreenUniforms[0].y < 1.0 || edges.g < 0.5) {\n return vec2<f32>(0.0);\n }\n var result = vec2<f32>(0.0);\n var negative = vec2<f32>(0.0);\n if (edges.r > 0.5) {\n negative = searchDiagonal(pixel, vec2<i32>(-1, 1), size);\n }\n let positive = searchDiagonal(pixel, vec2<i32>(1, -1), size);\n if (negative.x + positive.x >= 2.0) {\n let leftPixel = pixel + vec2<i32>(-i32(negative.x), i32(negative.x));\n let rightPixel = pixel + vec2<i32>(i32(positive.x), -i32(positive.x));\n let c1 = edgeAt(leftPixel + vec2<i32>(-1, 0), size).g;\n let c2 = edgeAt(leftPixel, size).r;\n let c3 = edgeAt(rightPixel + vec2<i32>(1, 0), size).g;\n let c4 = edgeAt(rightPixel + vec2<i32>(1, -1), size).r;\n result += areaDiagonal(vec2<f32>(negative.x, positive.x), vec2<f32>(2.0 * c1 + c2, 2.0 * c3 + c4));\n }\n\n let negativeOpposite = searchDiagonal(pixel, vec2<i32>(-1, -1), size);\n var positiveOpposite = vec2<f32>(0.0);\n if (edgeAt(pixel + vec2<i32>(1, 0), size).r > 0.5) {\n positiveOpposite = searchDiagonal(pixel, vec2<i32>(1, 1), size);\n }\n if (negativeOpposite.x + positiveOpposite.x >= 2.0) {\n let leftPixel = pixel + vec2<i32>(-i32(negativeOpposite.x), -i32(negativeOpposite.x));\n let rightPixel = pixel + vec2<i32>(i32(positiveOpposite.x), i32(positiveOpposite.x));\n let c1 = edgeAt(leftPixel + vec2<i32>(-1, 0), size).g;\n let c2 = edgeAt(leftPixel + vec2<i32>(0, -1), size).r;\n let rightEdges = edgeAt(rightPixel + vec2<i32>(1, 0), size);\n result += areaDiagonal(\n vec2<f32>(negativeOpposite.x, positiveOpposite.x),\n vec2<f32>(2.0 * c1 + c2, 2.0 * rightEdges.g + rightEdges.r)\n ).gr;\n }\n return result;\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let size = vec2<i32>(textureDimensions(edgesTexture));\n let pixel = clamp(vec2<i32>(input.position.xy), vec2<i32>(0), size - vec2<i32>(1));\n let edges = edgeAt(pixel, size);\n var weights = vec4<f32>(0.0);\n\n if (edges.g > 0.5) {\n let diagonal = diagonalWeights(pixel, edges, size);\n if (dot(diagonal, vec2<f32>(1.0)) > 1e-5) {\n weights.r = diagonal.x;\n weights.g = diagonal.y;\n } else {\n let leftDistance = searchHorizontal(pixel, -1, size);\n let rightDistance = searchHorizontal(pixel, 1, size);\n let leftPixel = pixel + vec2<i32>(-leftDistance, 0);\n let rightPixel = pixel + vec2<i32>(rightDistance, 0);\n let e1 = horizontalCrossing(leftPixel, size);\n let e2 = horizontalCrossing(rightPixel + vec2<i32>(1, 0), size);\n let area = areaOrthogonal(vec2<f32>(f32(leftDistance), f32(rightDistance)), e1, e2);\n let a = attenuateHorizontalCorners(area, leftPixel, rightPixel, leftDistance, rightDistance, size);\n weights.r = a.x;\n weights.g = a.y;\n }\n }\n\n if (edges.r > 0.5) {\n let topDistance = searchVertical(pixel, -1, size);\n let bottomDistance = searchVertical(pixel, 1, size);\n let topPixel = pixel + vec2<i32>(0, -topDistance);\n let bottomPixel = pixel + vec2<i32>(0, bottomDistance);\n let e1 = verticalCrossing(topPixel, size);\n let e2 = verticalCrossing(bottomPixel + vec2<i32>(0, 1), size);\n let area = areaOrthogonal(vec2<f32>(f32(topDistance), f32(bottomDistance)), e1, e2);\n let a = attenuateVerticalCorners(area, topPixel, bottomPixel, topDistance, bottomDistance, size);\n weights.b = a.x;\n weights.a = a.y;\n }\n\n return weights;\n}\n"},Mp=class{constructor(e,t,r,i){this.state=i,this.inputs={source:e,weights:t},this.outputs=r}state;name="SMAANeighborhoodBlendPass";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([zp(this.state.sharpness,0,1),0,0,0]),this.uniforms);fragmentShader="\nfn loadSource(pixel: vec2<i32>, size: vec2<i32>) -> vec4<f32> {\n return textureLoad(sourceTexture, clamp(pixel, vec2<i32>(0), size - vec2<i32>(1)), 0);\n}\n\nfn loadWeights(pixel: vec2<i32>, size: vec2<i32>) -> vec4<f32> {\n return textureLoad(weightsTexture, clamp(pixel, vec2<i32>(0), size - vec2<i32>(1)), 0);\n}\n\nfn sharpen(center: vec3<f32>, pixel: vec2<i32>, size: vec2<i32>, edgeAmount: f32) -> vec3<f32> {\n let strength = fullscreenUniforms[0].x * (1.0 - clamp(edgeAmount * 2.0, 0.0, 1.0));\n if (strength <= 1e-5) { return center; }\n let left = loadSource(pixel + vec2<i32>(-1, 0), size).rgb;\n let right = loadSource(pixel + vec2<i32>(1, 0), size).rgb;\n let top = loadSource(pixel + vec2<i32>(0, -1), size).rgb;\n let bottom = loadSource(pixel + vec2<i32>(0, 1), size).rgb;\n let minimum = min(center, min(min(left, right), min(top, bottom)));\n let maximum = max(center, max(max(left, right), max(top, bottom)));\n let average = (left + right + top + bottom) * 0.25;\n let contrast = max(maximum.r - minimum.r, max(maximum.g - minimum.g, maximum.b - minimum.b));\n let adaptive = strength * (1.0 - clamp(contrast, 0.0, 1.0)) * 0.5;\n return clamp(center + (center - average) * adaptive, minimum, maximum);\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let size = vec2<i32>(textureDimensions(sourceTexture));\n let pixel = clamp(vec2<i32>(input.position.xy), vec2<i32>(0), size - vec2<i32>(1));\n let center = loadSource(pixel, size);\n let current = loadWeights(pixel, size);\n\n // SMAA stores right/bottom weights in adjacent texels and left/top weights\n // in the current texel. Preserve that exact channel convention.\n let right = loadWeights(pixel + vec2<i32>(1, 0), size).a;\n let bottom = loadWeights(pixel + vec2<i32>(0, 1), size).g;\n let left = current.b;\n let top = current.r;\n let edgeAmount = max(max(right, bottom), max(left, top));\n\n var color = center;\n if (edgeAmount > 1e-5) {\n let texel = 1.0 / vec2<f32>(size);\n if (max(right, left) > max(bottom, top)) {\n let total = max(right + left, 1e-5);\n let rightColor = textureSampleLevel(\n sourceTexture,\n fullscreenSampler,\n input.uv + vec2<f32>(right * texel.x, 0.0),\n 0.0\n );\n let leftColor = textureSampleLevel(\n sourceTexture,\n fullscreenSampler,\n input.uv - vec2<f32>(left * texel.x, 0.0),\n 0.0\n );\n color = (rightColor * right + leftColor * left) / total;\n } else {\n let total = max(bottom + top, 1e-5);\n let bottomColor = textureSampleLevel(\n sourceTexture,\n fullscreenSampler,\n input.uv + vec2<f32>(0.0, bottom * texel.y),\n 0.0\n );\n let topColor = textureSampleLevel(\n sourceTexture,\n fullscreenSampler,\n input.uv - vec2<f32>(0.0, top * texel.y),\n 0.0\n );\n color = (bottomColor * bottom + topColor * top) / total;\n }\n }\n\n color = vec4<f32>(sharpen(color.rgb, pixel, size, edgeAmount), color.a);\n return color;\n}\n"};var Pp=null;function Bp(e,t,r,i){const n=2*(160*r+t);e[n]=Math.floor(255*zp(i[0],0,1)),e[n+1]=Math.floor(255*zp(i[1],0,1))}function Dp(e,t,r){const i=t+r+1,n=.5,a=-.5,s=()=>Tp([0,a],[i/2,0],t),o=()=>Tp([i/2,0],[i,a],t);switch(e){case 0:case 5:case 10:case 15:default:return[0,0];case 1:return t<=r?s():[0,0];case 2:return t>=r?o():[0,0];case 3:return Ip(i,s(),o());case 4:return t<=r?Tp([0,n],[i/2,0],t):[0,0];case 6:case 14:case 7:return Tp([0,n],[i,a],t);case 8:return t>=r?Tp([i/2,0],[i,n],t):[0,0];case 9:case 11:case 13:return Tp([0,a],[i,n],t);case 12:return Ip(i,Tp([0,n],[i/2,0],t),Tp([i/2,0],[i,n],t))}}function Tp(e,t,r){const i=t[0]-e[0],n=t[1]-e[1];if(Math.abs(i)<1e-6)return[0,0];const a=r,s=r+1,o=e[1]+n*(a-e[0])/i,l=e[1]+n*(s-e[0])/i;if(!(a>=e[0]&&a<t[0]||s>e[0]&&s<=t[0]))return[0,0];if(Math.sign(o)===Math.sign(l)||Math.abs(o)<1e-4||Math.abs(l)<1e-4){const e=.5*(o+l);return e<0?[-e,0]:[0,e]}const c=-e[1]*i/n+e[0],u=c-Math.floor(c),d=c>e[0]?o*u*.5:0,h=c<t[0]?l*(1-u)*.5:0;return(Math.abs(d)>Math.abs(h)?d:-h)<0?[Math.abs(d),Math.abs(h)]:[Math.abs(h),Math.abs(d)]}function Ip(e,t,r){const i=e=>[.5*Math.sqrt(2*e[0]),.5*Math.sqrt(2*e[1])],n=zp(e/32,0,1),a=i(t),s=i(r);return[Lp(a[0],t[0],n)+Lp(s[0],r[0],n),Lp(a[1],t[1],n)+Lp(s[1],r[1],n)]}function Vp(e,t,r){const i=t+r+1,[n,a]=[[0,0],[1,0],[0,2],[1,2],[2,0],[3,0],[2,2],[3,2],[0,1],[1,1],[0,3],[1,3],[2,1],[3,1],[2,3],[3,3]][e],s=(e,r)=>function(e,t,r){const i=30;let n=0,a=0;if(e[0]===t[0]&&e[1]===t[1])return[0,1];const s=.5*(e[0]+t[0]),o=.5*(e[1]+t[1]),l=t[1]-e[1],c=e[0]-t[0],u=(e,t)=>l*(e-s)+c*(t-o)>0;for(let e=0;e<i;e+=1)for(let t=0;t<i;t+=1){const s=t/(i-1),o=e/(i-1);u(1+r+s,r+o)&&(n+=1),u(1+r+s,1+r+o)&&(a+=1)}const d=i*i;return[1-n/d,a/d]}(n>0?[e[0],e[1]]:e,a>0?[r[0],r[1]]:r,t),o=(e,t)=>s([1,e],[1+i,t+i]);switch(e){case 0:return Gp(o(1,1),o(0,0));case 1:return Gp(s([1,0],[i,i]),o(0,0));case 2:return Gp(s([0,0],[1+i,i]),o(0,0));case 3:return o(0,0);case 4:return Gp(s([1,1],[i,i]),s([1,1],[1+i,i]));case 5:return Gp(s([1,1],[i,i]),o(0,0));case 6:return s([1,1],[1+i,i]);case 7:return Gp(s([1,1],[1+i,i]),o(0,0));case 8:return Gp(s([0,0],[1+i,1+i]),s([1,0],[1+i,1+i]));case 9:return s([1,0],[1+i,1+i]);case 10:return Gp(s([0,0],[1+i,1+i]),o(0,0));case 11:return Gp(s([1,0],[1+i,1+i]),o(0,0));case 12:return s([1,1],[1+i,1+i]);case 13:return Gp(s([1,1],[1+i,1+i]),s([1,0],[1+i,1+i]));case 14:return Gp(s([1,1],[1+i,1+i]),s([1,1],[1+i,i]));case 15:return Gp(s([1,1],[1+i,1+i]),o(0,0));default:return[0,0]}}function Gp(e,t){return[.5*(e[0]+t[0]),.5*(e[1]+t[1])]}function Lp(e,t,r){return e+(t-e)*r}function zp(e,t,r){return Math.min(r,Math.max(t,e))}var Rp=class{strength;threshold;knee;radius;levels;targetPrefix;passes=new Map;constructor(e={}){var t,r,i;this.strength=Math.max(0,e.strength??.9),this.threshold=Math.max(0,e.threshold??1),this.knee=Math.max(1e-4,e.knee??.1),this.radius=Fp(e.radius??.2,0,1),this.levels=(t=e.levels??5,r=1,i=5,Math.floor(Fp(t,r,i))),this.targetPrefix=e.targetPrefix??"bloom"}addPass(e,t,r={}){const i=[];let n=t;for(let t=0;t<this.levels;t+=1){const r=1/2**(t+1),a=e.createColorTarget(`${this.targetPrefix}Horizontal${t}`,{format:"rgba16float",scale:r}),s=e.createColorTarget(`${this.targetPrefix}Vertical${t}`,{format:"rgba16float",scale:r}),o=n,l=`h:${t}:${o}:${a}`;let c=this.passes.get(l);c||(c=0===t?new Up(o,a,this):new Ap(`BloomDownsampleHorizontal${t}`,o,a,!0,t),this.passes.set(l,c)),e.addFullscreenPass(c);const u=`v:${t}:${a}:${s}`;let d=this.passes.get(u);d||(d=new Ap(`BloomVertical${t}`,a,s,!1,t),this.passes.set(u,d)),e.addFullscreenPass(d),i.push(s),n=s}const a=r.output??e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"}),s=Object.fromEntries(i.map((e,t)=>[`blur${t}`,e])),o=`composite:${t}:${i.join(":")}:${a}`;let l=this.passes.get(o);return l||(l=new kp(t,s,a,this,this.levels),this.passes.set(o,l)),e.addFullscreenPass(l),a}},Up=class{constructor(e,t,r){this.state=r,this.inputs={source:e},this.outputs=t}state;name="BloomThresholdHorizontal";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([this.state.threshold,this.state.knee,0,0]),this.uniforms);fragmentShader="\nfn bright(color: vec3<f32>) -> vec3<f32> {\n let brightness = dot(color, vec3<f32>(0.2126, 0.7152, 0.0722));\n let threshold = fullscreenUniforms[0].x;\n let knee = fullscreenUniforms[0].y;\n let soft = clamp(brightness - threshold + knee, 0.0, 2.0 * knee);\n let contribution = max(brightness - threshold, soft * soft / (4.0 * knee));\n return color * contribution / max(brightness, 0.0001);\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let texel = 1.0 / vec2<f32>(textureDimensions(sourceTexture));\n let center = bright(textureSample(sourceTexture, fullscreenSampler, input.uv).rgb) * 0.227027;\n let a = bright(textureSample(sourceTexture, fullscreenSampler, input.uv + vec2<f32>(1.384615 * texel.x, 0.0)).rgb);\n let b = bright(textureSample(sourceTexture, fullscreenSampler, input.uv - vec2<f32>(1.384615 * texel.x, 0.0)).rgb);\n let c = bright(textureSample(sourceTexture, fullscreenSampler, input.uv + vec2<f32>(3.230769 * texel.x, 0.0)).rgb);\n let d = bright(textureSample(sourceTexture, fullscreenSampler, input.uv - vec2<f32>(3.230769 * texel.x, 0.0)).rgb);\n return vec4<f32>(center + (a + b) * 0.316216 + (c + d) * 0.070270, 1.0);\n}"},Ap=class{constructor(e,t,r,i,n){this.name=e,this.inputs={source:t},this.outputs=r;const a=i?"vec2<f32>(texel.x, 0.0)":"vec2<f32>(0.0, texel.y)",s=(1+.35*n).toFixed(2);this.fragmentShader=`\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let texel = 1.0 / vec2<f32>(textureDimensions(sourceTexture));\n let axis = ${a} * ${s};\n var color = textureSample(sourceTexture, fullscreenSampler, input.uv).rgb * 0.227027;\n color += textureSample(sourceTexture, fullscreenSampler, input.uv + axis * 1.384615).rgb * 0.316216;\n color += textureSample(sourceTexture, fullscreenSampler, input.uv - axis * 1.384615).rgb * 0.316216;\n color += textureSample(sourceTexture, fullscreenSampler, input.uv + axis * 3.230769).rgb * 0.070270;\n color += textureSample(sourceTexture, fullscreenSampler, input.uv - axis * 3.230769).rgb * 0.070270;\n return vec4<f32>(color, 1.0);\n}`}name;sampler="linear";inputs;outputs;fragmentShader},kp=class{constructor(e,t,r,i,n){this.state=i,this.inputs={source:e,...t},this.outputs=r;const a=[1,.8,.6,.4,.2],s=Array.from({length:n},(e,t)=>`bloom += textureSample(blur${t}Texture, fullscreenSampler, input.uv).rgb * mix(${a[t].toFixed(1)}, ${(1.2-a[t]).toFixed(1)}, radius);`).join("\n ");this.fragmentShader=`\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let scene = textureSample(sourceTexture, fullscreenSampler, input.uv);\n let radius = fullscreenUniforms[0].y;\n var bloom = vec3<f32>(0.0);\n ${s}\n return vec4<f32>(scene.rgb + bloom * fullscreenUniforms[0].x, scene.a);\n}`}state;name="BloomComposite";sampler="linear";uniformBufferSize=32;inputs;outputs;uniforms=new Float32Array(8);updateUniforms=()=>(this.uniforms.set([this.state.strength,Fp(this.state.radius,0,1),0,0]),this.uniforms);fragmentShader};function Fp(e,t,r){return Math.min(r,Math.max(t,e))}var $p=[1,1,1],Ep=[0,0,0],Op=class{options;passes=new Map;targetPrefix;constructor(e={}){this.options=e,this.targetPrefix=e.targetPrefix??"colorGrading"}addPass(e,t){if(!1===this.options.enabled)return t;const r=e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"}),i=`${t}:${r}`;let n=this.passes.get(i);return n||(n=new _p(t,r,this.options),this.passes.set(i,n)),e.addFullscreenPass(n),r}},_p=class{constructor(e,t,r){this.state=r,this.inputs={source:e},this.outputs=t}state;name="ColorGrading";sampler="linear";uniformBufferSize=384;inputs;outputs;uniforms=new Float32Array(this.uniformBufferSize/4);updateUniforms=()=>{const e=[],t=(t,r)=>e.push(...t??r,0),r=e=>{t(e?.saturation,$p),t(e?.contrast,$p),t(e?.gamma,$p),t(e?.gain,$p),t(e?.offset,Ep)};return t(this.state.whiteBalance,$p),t(this.state.tint,$p),r(this.state),r(this.state.shadows),r(this.state.midtones),r(this.state.highlights),e.push(this.state.exposure??1,{none:0,linear:1,reinhard:2,cineon:3,aces:4,agx:5,neutral:6}[this.state.toneMapping??"none"],Math.max(0,this.state.vignetteIntensity??0),Math.min(1,Math.max(0,this.state.tintIntensity??0)),this.state.shadowsMax??.09,this.state.highlightsMin??.5,!1===this.state.enabled?0:1,0),this.uniforms.fill(0),this.uniforms.set(e),this.uniforms};fragmentShader="\nfn grade(color: vec3<f32>, s: vec3<f32>, c: vec3<f32>, g: vec3<f32>, gain: vec3<f32>, offset: vec3<f32>) -> vec3<f32> {\n let luma = dot(color, vec3<f32>(0.2126, 0.7152, 0.0722));\n var result = mix(vec3<f32>(luma), color, s);\n result = (result - vec3<f32>(0.18)) * c + vec3<f32>(0.18);\n result = pow(max(result, vec3<f32>(0.0)), vec3<f32>(1.0) / max(g, vec3<f32>(0.0001)));\n return max(result * gain + offset, vec3<f32>(0.0));\n}\nfn aces(x: vec3<f32>) -> vec3<f32> { return clamp((x * (2.51*x + vec3<f32>(0.03))) / (x * (2.43*x + vec3<f32>(0.59)) + vec3<f32>(0.14)), vec3<f32>(0.0), vec3<f32>(1.0)); }\nfn tonemap(x: vec3<f32>, mode: i32) -> vec3<f32> {\n if (mode == 1) { return clamp(x, vec3<f32>(0.0), vec3<f32>(1.0)); }\n if (mode == 2) { return x / (vec3<f32>(1.0) + x); }\n if (mode == 3) { let y=max(vec3<f32>(0.0),x-vec3<f32>(0.004)); return pow((y*(6.2*y+vec3<f32>(0.5)))/(y*(6.2*y+vec3<f32>(1.7))+vec3<f32>(0.06)),vec3<f32>(2.2)); }\n if (mode == 4) { return aces(x); }\n if (mode == 5) { return clamp((x * (x + vec3<f32>(0.0245786)) - vec3<f32>(0.000090537)) / (x * (0.983729*x + vec3<f32>(0.432951)) + vec3<f32>(0.238081)), vec3<f32>(0.0), vec3<f32>(1.0)); }\n if (mode == 6) { return clamp(x / (max(max(x.r,x.g),x.b) + 1.0), vec3<f32>(0.0), vec3<f32>(1.0)); }\n return x;\n}\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let source = textureSample(sourceTexture, fullscreenSampler, input.uv);\n if (fullscreenUniforms[23].z < 0.5) { return source; }\n var color = source.rgb * fullscreenUniforms[0].xyz;\n color = mix(color, color * fullscreenUniforms[1].xyz, fullscreenUniforms[22].w);\n let lum = clamp(dot(color, vec3<f32>(0.2126,0.7152,0.0722)), 0.0, 1.0);\n let shadowLimit = clamp(fullscreenUniforms[23].x, 0.0, 0.98);\n let highlightLimit = clamp(max(fullscreenUniforms[23].y, shadowLimit + 0.02), 0.02, 1.0);\n let sw = 1.0 - smoothstep(shadowLimit, min(1.0, shadowLimit + 0.05), lum);\n let hw = smoothstep(max(0.0, highlightLimit - 0.05), highlightLimit, lum);\n let mw = clamp(1.0-sw-hw, 0.0, 1.0);\n var s=fullscreenUniforms[2].xyz; var c=fullscreenUniforms[3].xyz; var g=fullscreenUniforms[4].xyz; var gn=fullscreenUniforms[5].xyz; var o=fullscreenUniforms[6].xyz;\n s*=mix(vec3<f32>(1),fullscreenUniforms[7].xyz,sw)*mix(vec3<f32>(1),fullscreenUniforms[12].xyz,mw)*mix(vec3<f32>(1),fullscreenUniforms[17].xyz,hw);\n c*=mix(vec3<f32>(1),fullscreenUniforms[8].xyz,sw)*mix(vec3<f32>(1),fullscreenUniforms[13].xyz,mw)*mix(vec3<f32>(1),fullscreenUniforms[18].xyz,hw);\n g*=mix(vec3<f32>(1),fullscreenUniforms[9].xyz,sw)*mix(vec3<f32>(1),fullscreenUniforms[14].xyz,mw)*mix(vec3<f32>(1),fullscreenUniforms[19].xyz,hw);\n gn*=mix(vec3<f32>(1),fullscreenUniforms[10].xyz,sw)*mix(vec3<f32>(1),fullscreenUniforms[15].xyz,mw)*mix(vec3<f32>(1),fullscreenUniforms[20].xyz,hw);\n o+=fullscreenUniforms[11].xyz*sw+fullscreenUniforms[16].xyz*mw+fullscreenUniforms[21].xyz*hw;\n color=grade(color,s,c,g,gn,o);\n color=tonemap(color*fullscreenUniforms[22].x,i32(fullscreenUniforms[22].y));\n let d=distance(input.uv,vec2<f32>(0.5));\n color*=smoothstep(0.8,0.1598,d*(fullscreenUniforms[22].z+0.2));\n return vec4<f32>(color,source.a);\n}"};import{Matrix4 as jp}from"three";var Np=class{options;passes=new Map;targetPrefix;constructor(e={}){this.options=e,this.targetPrefix=e.targetPrefix??"depthOfField"}addPass(e,t,r){if(!1===this.options.enabled)return t;const i=e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"}),n=`${t}:${r}:${i}`;let a=this.passes.get(n);return a||(a=new Wp(t,r,i,this.options),this.passes.set(n,a)),e.addFullscreenPass(a),i}},Wp=class{constructor(e,t,r,i){this.state=i,this.inputs={source:e,sceneDepth:t},this.outputs=r}state;name="DepthOfField";sampler="linear";uniformBufferSize=80;inputs;outputs;uniforms=new Float32Array(20);inverseProjection=new jp;updateUniforms=e=>(this.inverseProjection.copy(Hp).multiply(e.camera.projectionMatrix).invert(),this.uniforms.set(this.inverseProjection.elements,0),this.uniforms.set([this.state.focus??10,this.state.aperture??2e-4,this.state.maxBlur??.01,!1===this.state.enabled?0:1],16),this.uniforms);fragmentShader="\nfn viewDistance(uv:vec2<f32>,depth:f32)->f32 { let clip=vec4<f32>(uv*vec2<f32>(2,-2)+vec2<f32>(-1,1),depth,1); let view=mat4x4<f32>(fullscreenUniforms[0],fullscreenUniforms[1],fullscreenUniforms[2],fullscreenUniforms[3])*clip; return abs(view.z/view.w); }\n@fragment fn fsMain(input:FullscreenVertexOutput)->@location(0) vec4<f32>{\n let center=textureSample(sourceTexture,fullscreenSampler,input.uv); if(fullscreenUniforms[4].w<0.5){return center;}\n let px=vec2<f32>(1)/vec2<f32>(textureDimensions(sourceTexture)); let depth=textureLoad(sceneDepthTexture,vec2<i32>(input.position.xy),0);\n let blur=clamp(abs(viewDistance(input.uv,depth)-fullscreenUniforms[4].x)*fullscreenUniforms[4].y,0,fullscreenUniforms[4].z);\n var color=center.rgb*0.2; color+=textureSample(sourceTexture,fullscreenSampler,input.uv+vec2<f32>( blur,0)*px*400).rgb*0.1; color+=textureSample(sourceTexture,fullscreenSampler,input.uv-vec2<f32>( blur,0)*px*400).rgb*0.1;\n color+=textureSample(sourceTexture,fullscreenSampler,input.uv+vec2<f32>(0, blur)*px*400).rgb*0.1; color+=textureSample(sourceTexture,fullscreenSampler,input.uv-vec2<f32>(0, blur)*px*400).rgb*0.1;\n color+=textureSample(sourceTexture,fullscreenSampler,input.uv+vec2<f32>( blur, blur)*px*280).rgb*0.1; color+=textureSample(sourceTexture,fullscreenSampler,input.uv+vec2<f32>(-blur, blur)*px*280).rgb*0.1; color+=textureSample(sourceTexture,fullscreenSampler,input.uv+vec2<f32>( blur,-blur)*px*280).rgb*0.1; color+=textureSample(sourceTexture,fullscreenSampler,input.uv-vec2<f32>( blur, blur)*px*280).rgb*0.1;\n return vec4<f32>(color,center.a); }"},Hp=(new jp).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);import{Matrix4 as qp,Vector2 as Kp,Vector3 as Zp}from"three";var Yp=(new qp).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),Xp=(e=>(e[e.Disabled=0]="Disabled",e[e.CameraOnly=1]="CameraOnly",e[e.ObjectAndCamera=2]="ObjectAndCamera",e[e.ForceObjectBlur=3]="ForceObjectBlur",e))(Xp||{}),Jp={off:{enabled:!1,sampleCount:0},low:{enabled:!0,sampleCount:4,shutterScale:.65,maxBlurPixels:10,cameraBlurScale:.08,objectBlurScale:.8,depthRejectionStrength:28,velocityThresholdPixels:.75,dilation:!1},medium:{enabled:!0,sampleCount:8,shutterScale:.75,maxBlurPixels:18,cameraBlurScale:.1,objectBlurScale:1,depthRejectionStrength:24,velocityThresholdPixels:.6,dilation:!0},high:{enabled:!0,sampleCount:12,shutterScale:.85,maxBlurPixels:24,cameraBlurScale:.12,objectBlurScale:1.1,depthRejectionStrength:20,velocityThresholdPixels:.45,dilation:!0}},Qp=class{options;targetPrefix;currentViewProjection=new qp;currentInverseViewProjection=new qp;currentInverseProjection=new qp;previousViewProjection=new qp;pendingViewProjection=new qp;previousProjection=new qp;previousCameraWorld=new qp;previousCameraPosition=new Zp;currentCameraPosition=new Zp;currentJitterUv=new Kp;historyValid=!1;pendingCamera=!1;width=1;height=1;timeSeconds=0;frameDuration=1/60;previousTimeSeconds=Number.NaN;nextOverrideId=1;overrides=[];passes=new Map;constructor(e={}){this.options={enabled:e.enabled??!0,sampleCount:tf(e.sampleCount??8),shutterScale:rf(e.shutterScale??.75,0,4),maxBlurPixels:rf(e.maxBlurPixels??18,0,128),cameraBlurScale:rf(e.cameraBlurScale??.1,0,4),objectBlurScale:rf(e.objectBlurScale??1,0,8),depthRejectionStrength:rf(e.depthRejectionStrength??24,0,200),velocityThresholdPixels:rf(e.velocityThresholdPixels??.6,0,16),dilation:e.dilation??!0,debugVelocity:e.debugVelocity??!1,targetFrameRate:rf(e.targetFrameRate??60,15,240),maxFrameTime:rf(e.maxFrameTime??.1,1/240,1),cameraCutDistance:rf(e.cameraCutDistance??8,0,1e3),cameraCutRotationThreshold:rf(e.cameraCutRotationThreshold??.75,0,2),projectionCutThreshold:rf(e.projectionCutThreshold??.25,0,4)},this.targetPrefix=e.targetPrefix??"motionBlur"}applyPreset(e){Object.assign(this.options,Jp[e]),this.options.sampleCount=tf(this.options.sampleCount)}prepareCamera(e,t,r,i){t===this.width&&r===this.height||(this.width=Math.max(1,t),this.height=Math.max(1,r),this.reset());const n=i-this.previousTimeSeconds;Number.isFinite(n)&&n>0&&(this.frameDuration=Math.min(n,this.options.maxFrameTime),n>this.options.maxFrameTime&&this.reset()),this.previousTimeSeconds=i,this.timeSeconds=i,this.pruneOverrides(),e.getWorldPosition(this.currentCameraPosition),this.historyValid&&(this.currentCameraPosition.distanceTo(this.previousCameraPosition)>this.options.cameraCutDistance||function(e,t){let r=0;const i=[0,1,2,4,5,6,8,9,10];for(const n of i)r=Math.max(r,Math.abs(e.elements[n]-t.elements[n]));return r}(e.matrixWorld,this.previousCameraWorld)>this.options.cameraCutRotationThreshold||function(e,t){let r=0;for(let i=0;i<16;i+=1)r=Math.max(r,Math.abs(e.elements[i]-t.elements[i]));return r}(e.projectionMatrix,this.previousProjection)>this.options.projectionCutThreshold)&&this.reset(),this.pendingViewProjection.copy(Yp).multiply(e.projectionMatrix).multiply(e.matrixWorldInverse),this.currentViewProjection.copy(this.pendingViewProjection),this.currentInverseViewProjection.copy(this.currentViewProjection).invert(),this.currentInverseProjection.copy(Yp).multiply(e.projectionMatrix).invert(),this.historyValid||this.previousViewProjection.copy(this.currentViewProjection),this.pendingCamera=!0,this.previousProjection.copy(e.projectionMatrix),this.previousCameraWorld.copy(e.matrixWorld),this.previousCameraPosition.copy(this.currentCameraPosition)}commitCamera(){this.pendingCamera&&(this.previousViewProjection.copy(this.pendingViewProjection),this.historyValid=!0,this.pendingCamera=!1)}setJitterUv(e,t){this.currentJitterUv.set(Number.isFinite(e)?e:0,Number.isFinite(t)?t:0)}reset(){this.historyValid=!1,this.pendingCamera=!1}requiresRendererHistoryReset(){return!this.historyValid}pushOverride(e){const t=this.nextOverrideId++,r=Math.max(0,e.duration);return this.overrides.push({id:t,startTime:this.timeSeconds,endTime:this.timeSeconds+r,options:e}),{id:t,cancel:()=>{const e=this.overrides.findIndex(e=>e.id===t);e>=0&&this.overrides.splice(e,1)}}}addPass(e,t,r,i=e.mainDepth){const n=this.getResolvedSettings();if(!n.enabled||0===n.sampleCount)return t;const a=e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"}),s=tf(n.sampleCount),o=`${t}:${r}:${i}:${a}:${s}`;let l=this.passes.get(o);return l||(l=new ef(t,r,i,a,s,this),this.passes.set(o,l)),l.settings=n,e.addFullscreenPass(l),a}dispose(){this.passes.clear(),this.overrides.length=0}getTemporalMatrices(){return{currentInverseViewProjection:this.currentInverseViewProjection,currentInverseProjection:this.currentInverseProjection,previousViewProjection:this.previousViewProjection}}getFrameDuration(){return this.frameDuration}getJitterUv(){return this.currentJitterUv}pruneOverrides(){for(let e=this.overrides.length-1;e>=0;e-=1)this.overrides[e].endTime<=this.timeSeconds&&this.overrides.splice(e,1)}getResolvedSettings(){const e={...this.options};for(const t of this.overrides){const r=t.options;null!=r.enabled&&(e.enabled||=r.enabled),null!=r.sampleCount&&(e.sampleCount=Math.max(e.sampleCount,tf(r.sampleCount))),null!=r.shutterScale&&(e.shutterScale=Math.max(e.shutterScale,r.shutterScale)),null!=r.maxBlurPixels&&(e.maxBlurPixels=Math.max(e.maxBlurPixels,r.maxBlurPixels)),null!=r.cameraBlurScale&&(e.cameraBlurScale=Math.max(e.cameraBlurScale,r.cameraBlurScale)),null!=r.objectBlurScale&&(e.objectBlurScale=Math.max(e.objectBlurScale,r.objectBlurScale)),null!=r.dilation&&(e.dilation||=r.dilation),null!=r.debugVelocity&&(e.debugVelocity||=r.debugVelocity)}return e}},ef=class{constructor(e,t,r,i,n,a){this.state=a,this.name=`MotionBlurResolve${n}`,this.inputs={source:e,velocity:t,depth:r},this.outputs=i,this.settings=a.options,this.fragmentShader=function(e){return`\nfn currentInverseViewProjection() -> mat4x4<f32> {\n return mat4x4<f32>(\n fullscreenUniforms[0], fullscreenUniforms[1],\n fullscreenUniforms[2], fullscreenUniforms[3]\n );\n}\n\nfn previousViewProjection() -> mat4x4<f32> {\n return mat4x4<f32>(\n fullscreenUniforms[4], fullscreenUniforms[5],\n fullscreenUniforms[6], fullscreenUniforms[7]\n );\n}\n\nfn currentInverseProjection() -> mat4x4<f32> {\n return mat4x4<f32>(\n fullscreenUniforms[8], fullscreenUniforms[9],\n fullscreenUniforms[10], fullscreenUniforms[11]\n );\n}\n\nfn uvToNdc(uv: vec2<f32>, depth: f32) -> vec4<f32> {\n let unjitteredUv = uv - fullscreenUniforms[14].xy;\n return vec4<f32>(\n unjitteredUv.x * 2.0 - 1.0,\n (0.5 - unjitteredUv.y) * 2.0,\n depth,\n 1.0\n );\n}\n\nfn viewDepth(uv: vec2<f32>, depth: f32) -> f32 {\n let view = currentInverseProjection() * uvToNdc(uv, depth);\n return abs(view.z / max(abs(view.w), 1e-6));\n}\n\nfn depthAt(uv: vec2<f32>) -> f32 {\n let dimensions = vec2<i32>(textureDimensions(depthTexture));\n let pixel = clamp(\n vec2<i32>(uv * vec2<f32>(dimensions)),\n vec2<i32>(0),\n dimensions - vec2<i32>(1)\n );\n return textureLoad(depthTexture, pixel, 0);\n}\n\nfn cameraVelocity(uv: vec2<f32>, depth: f32) -> vec2<f32> {\n let worldH = currentInverseViewProjection() * uvToNdc(uv, depth);\n let world = worldH / max(abs(worldH.w), 1e-6);\n let previousClip = previousViewProjection() * world;\n let previousNdc = previousClip.xy / max(abs(previousClip.w), 1e-6);\n let previousUv = previousNdc * vec2<f32>(0.5, -0.5) + vec2<f32>(0.5);\n return (uv - fullscreenUniforms[14].xy) - previousUv;\n}\n\nfn scaledVelocity(uv: vec2<f32>, packed: vec4<f32>, depth: f32) -> vec2<f32> {\n let camera = cameraVelocity(uv, depth);\n let objectRelative = packed.xy - camera;\n let mode = i32(round(packed.z));\n if (mode == 0) { return vec2<f32>(0.0); }\n if (mode == 1) {\n return camera * fullscreenUniforms[12].z;\n }\n let forceScale = select(1.0, 1.35, mode == 3);\n return camera * fullscreenUniforms[12].z +\n objectRelative * fullscreenUniforms[12].w * packed.w * forceScale;\n}\n\nfn chooseDilatedVelocity(\n uv: vec2<f32>,\n centerDepthRaw: f32,\n texel: vec2<f32>\n) -> vec2<f32> {\n let centerPacked = textureSampleLevel(velocityTexture, fullscreenSampler, uv, 0.0);\n var best = scaledVelocity(uv, centerPacked, centerDepthRaw);\n if (fullscreenUniforms[13].z < 0.5) { return best; }\n let centerDepth = viewDepth(uv, centerDepthRaw);\n for (var y = -1; y <= 1; y += 1) {\n for (var x = -1; x <= 1; x += 1) {\n let sampleUv = clamp(uv + vec2<f32>(f32(x), f32(y)) * texel, vec2<f32>(0.0), vec2<f32>(1.0));\n let sampleDepthRaw = depthAt(sampleUv);\n let sampleDepth = viewDepth(sampleUv, sampleDepthRaw);\n let depthSimilarity = abs(sampleDepth - centerDepth) / max(centerDepth, 1e-3);\n if (depthSimilarity < 0.025 || sampleDepth <= centerDepth) {\n let candidatePacked = textureSampleLevel(velocityTexture, fullscreenSampler, sampleUv, 0.0);\n let candidate = scaledVelocity(sampleUv, candidatePacked, sampleDepthRaw);\n if (dot(candidate, candidate) > dot(best, best)) { best = candidate; }\n }\n }\n }\n return best;\n}\n\n@fragment\nfn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let centerColor = textureSampleLevel(sourceTexture, fullscreenSampler, input.uv, 0.0);\n let dimensions = vec2<f32>(textureDimensions(sourceTexture));\n let texel = 1.0 / dimensions;\n let centerDepthRaw = depthAt(input.uv);\n let centerDepth = viewDepth(input.uv, centerDepthRaw);\n var blurUv = chooseDilatedVelocity(input.uv, centerDepthRaw, texel) * fullscreenUniforms[12].x;\n let velocityPixels = length(blurUv * dimensions);\n\n if (fullscreenUniforms[13].w > 0.5) {\n let debugMagnitude = clamp(\n velocityPixels / max(fullscreenUniforms[12].y, 1.0),\n 0.0,\n 1.0\n );\n // Black means stationary. Moving pixels become brighter; R/G retain the\n // signed horizontal/vertical mapping around 0.5 and B shows magnitude.\n let directionColor = vec3<f32>(\n 0.5 + 0.5 * clamp(blurUv.x * 32.0, -1.0, 1.0),\n 0.5 + 0.5 * clamp(blurUv.y * 32.0, -1.0, 1.0),\n 1.0\n ) * debugMagnitude;\n return vec4<f32>(directionColor, 1.0);\n }\n\n let threshold = fullscreenUniforms[13].y;\n if (velocityPixels <= threshold) { return centerColor; }\n let maxBlurUv = fullscreenUniforms[12].y / max(dimensions.x, dimensions.y);\n let blurLength = length(blurUv);\n if (blurLength > maxBlurUv) { blurUv *= maxBlurUv / blurLength; }\n\n let activeSamples = clamp(\n i32(ceil(velocityPixels / max(threshold, 0.25))),\n 2,\n ${e}\n );\n var accumulated = centerColor;\n var totalWeight = 1.0;\n for (var sampleIndex = 0; sampleIndex < ${e}; sampleIndex += 1) {\n if (sampleIndex >= activeSamples) { continue; }\n let t = (f32(sampleIndex) + 0.5) / f32(activeSamples);\n let sampleUv = clamp(\n input.uv + mix(-0.5, 0.5, t) * blurUv,\n vec2<f32>(0.0),\n vec2<f32>(1.0)\n );\n let sampleDepthRaw = depthAt(sampleUv);\n let sampleDepth = viewDepth(sampleUv, sampleDepthRaw);\n let relativeDifference = abs(sampleDepth - centerDepth) / max(centerDepth, 1e-3);\n let depthWeight = exp(-relativeDifference * fullscreenUniforms[13].x);\n let sampleColor = textureSampleLevel(sourceTexture, fullscreenSampler, sampleUv, 0.0);\n accumulated += sampleColor * depthWeight;\n totalWeight += depthWeight;\n }\n return accumulated / max(totalWeight, 1e-4);\n}\n`}(n)}state;name;sampler="linear";uniformBufferSize=256;inputs;outputs;fragmentShader;settings;uniforms=new Float32Array(64);updateUniforms=()=>{const e=this.state.getTemporalMatrices();this.uniforms.set(e.currentInverseViewProjection.elements,0),this.uniforms.set(e.previousViewProjection.elements,16),this.uniforms.set(e.currentInverseProjection.elements,32);const t=1/this.settings.targetFrameRate/Math.max(this.state.getFrameDuration(),.001);this.uniforms.set([this.settings.shutterScale*t,this.settings.maxBlurPixels,this.settings.cameraBlurScale,this.settings.objectBlurScale,this.settings.depthRejectionStrength,this.settings.velocityThresholdPixels,this.settings.dilation?1:0,this.settings.debugVelocity?1:0],48);const r=this.state.getJitterUv();return this.uniforms[56]=r.x,this.uniforms[57]=r.y,this.uniforms}};function tf(e){return e<=0?0:e<=4?4:e<=8?8:e<=12?12:16}function rf(e,t,r){return Math.min(r,Math.max(t,e))}var nf=class{enabled;visibleEdgeColor;edgeStrength;edgeThickness;edgeSoftness;selectedObjects=new Set;selectedInstances=[];targetPrefix;maskMaterial;skinnedMaskMaterial;instanceMaskMaterials=new Map;passes=new Map;constructor(e={}){this.enabled=e.enabled??!0,this.visibleEdgeColor=[...e.visibleEdgeColor??[1,1,1]],this.edgeStrength=Math.max(0,e.edgeStrength??5),this.edgeThickness=Math.max(0,e.edgeThickness??.6),this.edgeSoftness=Math.max(0,e.edgeSoftness??.6),this.targetPrefix=e.targetPrefix??"outline",this.maskMaterial=af(!1),this.skinnedMaskMaterial=af(!0)}setSelectedObjects(e){this.selectedObjects.clear();for(const t of e)this.selectedObjects.add(t)}setSelectedInstances(e){this.selectedInstances.length=0;for(const t of e)Number.isInteger(t.instanceIndex)&&t.instanceIndex>=0&&this.selectedInstances.push(t)}addPass(e,t){if(!this.enabled||0===this.selectedObjects.size&&0===this.selectedInstances.length)return t;const r=e.createColorTarget(`${this.targetPrefix}Mask`,{format:"rgba8unorm"}),i=this.selectedObjects;e.addMaterialPass({name:"OutlineMask",outputs:r,clearColor:[0,0,0,0],loadDepth:!0,objectFilter:e=>null!==e&&function(e,t){for(let r=e;null!==r;r=r.parent)if(t.has(r))return!0;return!1}(e,i),overrideMaterial:(e,t)=>t?this.skinnedMaskMaterial:this.maskMaterial});for(let t=0;t<this.selectedInstances.length;t+=1){const i=this.selectedInstances[t];let n=this.instanceMaskMaterials.get(i.instanceIndex);n||(n=[af(!1,i.instanceIndex),af(!0,i.instanceIndex)],this.instanceMaskMaterials.set(i.instanceIndex,n)),e.addMaterialPass({name:`OutlineInstanceMask${t}-${i.instanceIndex}`,outputs:r,loadColor:!0,loadDepth:!0,objectFilter:e=>e===i.object,overrideMaterial:(e,t)=>t?n[1]:n[0]})}const n=e.createColorTarget(`${this.targetPrefix}Edge`,{format:"rgba16float"}),a=e.createColorTarget(`${this.targetPrefix}BlurHorizontal`,{format:"rgba16float"}),s=e.createColorTarget(`${this.targetPrefix}Blurred`,{format:"rgba16float"}),o=e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"});return this.addCachedPass(e,`edge:${r}:${n}`,()=>new sf(r,n,this)),this.addCachedPass(e,`blur-h:${n}:${a}`,()=>new of("OutlineBlurHorizontal",n,a,!0,this)),this.addCachedPass(e,`blur-v:${a}:${s}`,()=>new of("OutlineBlurVertical",a,s,!1,this)),this.addCachedPass(e,`composite:${t}:${s}:${o}`,()=>new lf(t,s,o,this)),o}addCachedPass(e,t,r){let i=this.passes.get(t);i||(i=r(),this.passes.set(t,i)),e.addFullscreenPass(i)}dispose(){this.maskMaterial.dispose(),this.skinnedMaskMaterial.dispose();for(const e of this.instanceMaskMaterials.values())e[0].dispose(),e[1].dispose();this.instanceMaskMaterials.clear(),this.passes.clear()}};function af(e,t=-1){return new Ir({vertexShader:`\nstruct VertexInput {\n @location(0) position: vec3<f32>,${e?"\n @location(4) skinIndex: vec4<u32>,\n @location(5) skinWeight: vec4<f32>,":""}\n @builtin(instance_index) instanceIndex: u32,\n};\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @interpolate(flat) @location(0) batchingId: u32,\n};\n@vertex fn vsMain(input: VertexInput) -> VertexOutput {\n return VertexOutput(\n rendererClipPosition(${e?"rendererSkinPosition(input.position, input.skinIndex, input.skinWeight)":"input.position"}, input.instanceIndex),\n rendererBatchingId(input.instanceIndex)\n );\n}`,fragmentShader:"\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @interpolate(flat) @location(0) batchingId: u32,\n};\n@fragment fn fsMain(input: VertexOutput) -> @location(0) vec4<f32> {\n if (materialUniforms.selectedInstance >= 0.0 &&\n input.batchingId != u32(materialUniforms.selectedInstance)) { discard; }\n return vec4(1.0);\n}",uniforms:{selectedInstance:t},depthWrite:!1,depthTest:!1})}var sf=class{constructor(e,t,r){this.state=r,this.inputs={mask:e},this.outputs=t}state;name="OutlineEdge";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([this.state.edgeThickness,0,0,0]),this.uniforms);fragmentShader="\n@fragment fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let texel = 1.0 / vec2<f32>(textureDimensions(maskTexture));\n let radius = max(fullscreenUniforms[0].x, 0.5);\n let center = textureSample(maskTexture, fullscreenSampler, input.uv).r;\n let diagonalRadius = radius * 0.70710678;\n var around = 0.0;\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv + vec2(texel.x * radius, 0.0)).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv - vec2(texel.x * radius, 0.0)).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv + vec2(0.0, texel.y * radius)).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv - vec2(0.0, texel.y * radius)).r);\n let diagonalOffset = texel * diagonalRadius;\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv + diagonalOffset).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv - diagonalOffset).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv + vec2(diagonalOffset.x, -diagonalOffset.y)).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv + vec2(-diagonalOffset.x, diagonalOffset.y)).r);\n let edge = clamp(around - center, 0.0, 1.0);\n return vec4(edge, edge, edge, 1.0);\n}"},of=class{constructor(e,t,r,i,n){this.name=e,this.horizontal=i,this.state=n,this.inputs={source:t},this.outputs=r}name;horizontal;state;sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([this.state.edgeSoftness,this.horizontal?1:0,0,0]),this.uniforms);fragmentShader="\n@fragment fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let texel = 1.0 / vec2<f32>(textureDimensions(sourceTexture));\n let spread = max(fullscreenUniforms[0].x, 0.01);\n let axis = mix(vec2<f32>(0.0, texel.y), vec2<f32>(texel.x, 0.0), fullscreenUniforms[0].y) * spread;\n var value = textureSample(sourceTexture, fullscreenSampler, input.uv).r * 0.227027;\n value += textureSample(sourceTexture, fullscreenSampler, input.uv + axis * 1.384615).r * 0.316216;\n value += textureSample(sourceTexture, fullscreenSampler, input.uv - axis * 1.384615).r * 0.316216;\n value += textureSample(sourceTexture, fullscreenSampler, input.uv + axis * 3.230769).r * 0.070270;\n value += textureSample(sourceTexture, fullscreenSampler, input.uv - axis * 3.230769).r * 0.070270;\n return vec4(value, value, value, 1.0);\n}"},lf=class{constructor(e,t,r,i){this.state=i,this.inputs={source:e,edge:t},this.outputs=r}state;name="OutlineComposite";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms=new Float32Array(4);updateUniforms=()=>(this.uniforms.set([this.state.visibleEdgeColor[0],this.state.visibleEdgeColor[1],this.state.visibleEdgeColor[2],this.state.edgeStrength]),this.uniforms);fragmentShader="\n@fragment fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let scene = textureSample(sourceTexture, fullscreenSampler, input.uv);\n let edge = textureSample(edgeTexture, fullscreenSampler, input.uv).r;\n let color = fullscreenUniforms[0].rgb * fullscreenUniforms[0].a;\n return vec4(scene.rgb + color * edge, scene.a);\n}"};import{AmbientLight as cf,BackSide as uf,Bone as df,BatchedMesh as hf,BoxGeometry as pf,BufferAttribute as ff,BufferGeometry as mf,CanvasTexture as gf,Color as vf,CompressedArrayTexture as xf,CompressedArrayTexture as wf,CompressedCubeTexture as bf,CompressedTexture as yf,CubeTexture as Sf,Data3DTexture as Cf,DataArrayTexture as Mf,DataTexture as Pf,DepthTexture as Bf,DirectionalLight as Df,DoubleSide as Tf,FrontSide as If,Group as Vf,HemisphereLight as Gf,InstancedMesh as Lf,MathUtils as zf,Matrix4 as Rf,Mesh as Uf,Object3D as Af,OrthographicCamera as kf,PerspectiveCamera as Ff,PlaneGeometry as $f,PointLight as Ef,RepeatWrapping as Of,Scene as _f,Skeleton as jf,SkinnedMesh as Nf,SphereGeometry as Wf,SpotLight as Hf,Texture as qf,Vector2 as Kf,Vector3 as Zf,Vector4 as Yf}from"three";export{cf as AmbientLight,uf as BackSide,hf as BatchedMesh,Rp as BloomEffect,df as Bone,pf as BoxGeometry,ff as BufferAttribute,mf as BufferGeometry,gf as CanvasTexture,vf as Color,Op as ColorGradingEffect,xf as CompressedArrayTexture,bf as CompressedCubeTexture,yf as CompressedTexture,wf as CompressedTextureArray,W as ComputeKernel,Sf as CubeTexture,Tr as DEFAULT_WGSL_VERTEX_ATTRIBUTES,Cf as Data3DTexture,Mf as DataArrayTexture,Pf as DataTexture,Np as DepthOfFieldEffect,Bf as DepthTexture,Df as DirectionalLight,Tf as DoubleSide,dp as FXAAEffect,cr as FrameGraphBuilder,If as FrontSide,Eh as GTAOEffect,$h as GTAO_PRESETS,Vf as Group,Gf as HemisphereLight,Lf as InstancedMesh,Jp as MOTION_BLUR_PRESETS,zf as MathUtils,Rf as Matrix4,Uf as Mesh,Qp as MotionBlurEffect,Xp as MotionBlurMode,Af as Object3D,kf as OrthographicCamera,nf as OutlineEffect,Ff as PerspectiveCamera,$f as PlaneGeometry,Ef as PointLight,Ru as RenderGraph,Of as RepeatWrapping,D as SCENE_COLOR_FORMAT,yp as SMAAEffect,Jh as SSREffect,_f as Scene,jf as Skeleton,Nf as SkinnedMesh,Wf as SphereGeometry,Hf as SpotLight,op as TemporalAAEffect,qf as Texture,xe as VOLUMETRIC_FOG_MATERIAL_WGSL,re as VOLUMETRIC_FOG_PRESETS,Kf as Vector2,Zf as Vector3,Yf as Vector4,de as VolumetricFogEffect,te as VolumetricFogVolumeObject,Ir as WGSLShaderMaterial,Nu as WebGpuPMREMGenerator,Gh as WebGpuRenderer,td as buildParticleLightingShaderHeader,we as configureVolumetricFogMaterial,N as createComputePipelineAsync,j as createRenderPipelineAsync,r as registerPipelineDiagnosticOrigin,g as resolveDetailCulling,p as setObjectDetailCulling,t as setPipelineDiagnosticLoading};