@hology/webgpu-renderer 0.1.23 → 0.1.24
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.d.ts +380 -178
- package/dist/index.js +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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])}const n=(console.groupCollapsed??console.info).bind(console),a=(console.table??console.info).bind(console);n("[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:")))}),a([...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 s=u(r);a(s.map(({variants:e,...t})=>t)),console.info("GPU VFX variant report (copy this array)",s);const o=u(r,!1);a(o.map(({variants:e,...t})=>t)),console.info("Material variant report (copy this array)",o),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)}function d(e,t){e.userData.detailCulling=t}var h=Object.freeze({minScreenSize:10,maxDistance:0,shadowMinScreenSize:2,shadowMaxDistance:0}),p=[];function f(e,t){let r=!!t;for(let t=e;t&&!r;t=t.parent)r=!!t.userData.detailCulling;if(!r)return h;let i=!0,{minScreenSize:n,maxDistance:a,shadowMinScreenSize:s,shadowMaxDistance:o}=h,l=!0;const c=e=>{e&&(i=e.enabled??i,n=e.minScreenSize??n,a=e.maxDistance??a,l=e.shadow?.enabled??l,s=e.shadow?.minScreenSize??s,o=e.shadow?.maxDistance??o)};c(t),p.length=0;for(let t=e;t;t=t.parent)p.push(t);for(let e=p.length-1;e>=0;e--)c(p[e].userData.detailCulling);const u=e=>Number.isFinite(e)&&e>0?e:0;return{minScreenSize:i?u(n):0,maxDistance:u(a),shadowMinScreenSize:l?u(s):0,shadowMaxDistance:u(o)}}function m(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}function g(e,t,r,i,n){const a=e.boundsCenter,s=e.boundsRadius;if(e.maxDistance>0&&a.distanceTo(n)-s>e.maxDistance)return!1;if(e.minScreenSize<=0)return!0;const o=t.elements,l=a.x,c=a.y,u=a.z,d=Math.hypot(o[3],o[7],o[11]),h=o[3]*l+o[7]*c+o[11]*u+o[15]-s*d;if(h<=1e-4)return!0;const p=Math.hypot(o[0],o[4],o[8]),f=Math.hypot(o[1],o[5],o[9]),m=(Math.abs(o[0]*l+o[4]*c+o[8]*u+o[12])+s*p)/h,g=(Math.abs(o[1]*l+o[5]*c+o[9]*u+o[13])+s*f)/h;return e.maxMemberRadius*Math.max((p+m*d)*r,(f+g*d)*i)/h>=.85*e.minScreenSize}import{Matrix4 as v,Sphere as x,Vector3 as w}from"three";var b=64,y=64,S=40,C=12,M=new Float32Array(S),P=new Float32Array([1,1,1,1]),B="rgba16float",D="rgba8unorm",T=(new v).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),I=[new w(0,-1,0),new w(0,-1,0),new w(0,0,1),new w(0,0,-1),new w(0,-1,0),new w(0,-1,0)],V=[new w(1,0,0),new w(-1,0,0),new w(0,1,0),new w(0,-1,0),new w(0,0,1),new w(0,0,-1)],L=4004,G=[{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"}],z=new v,U=new v,A=(new v,new v,new x),k=new w,F=new w,$=new w,E=(new w,new w,new w,new w,new WeakMap);async function O(e,t){const r=E.get(e)??Promise.resolve();let i;const n=new Promise(e=>{i=e});E.set(e,r.catch(()=>{}).then(()=>n)),await r.catch(()=>{});try{return await new Promise(e=>requestAnimationFrame(()=>e())),t()}finally{i()}}function _(e,t){return i(e,t),"function"==typeof e.createRenderPipelineAsync?e.createRenderPipelineAsync(t):O(e,()=>e.createRenderPipeline(t))}function j(e,t){return i(e,t),"function"==typeof e.createComputePipelineAsync?e.createComputePipelineAsync(t):O(e,()=>e.createComputePipeline(t))}var N=class e{layout;pipeline;static async createAsync(t,r){const{pipelineDescriptor:i}=W(t,r),n=await j(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}=W(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 W(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 H,DirectionalLight as q,Matrix4 as K,Object3D as Z,PointLight as Y,Scene as X,SpotLight as J,Vector3 as Q}from"three";var ee=class extends Z{constructor(e){super(),this.volume=e}volume;isFogVolumeObject=!0},te={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}}},re=20,ie=16,ne=(new K).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),ae=new Q,se=new Q,oe=new Q,le={label:"VolumetricFogFroxelPass"};function ce(e,t,r,i,n,a){e[t]=r,e[t+1]=i,e[t+2]=n,e[t+3]=a}var ue=class{constructor(e=new X,t={}){this.scene=e,this.options=de(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*re);const r=this.options.maxDirectionalLights+this.options.maxPointLights+this.options.maxSpotLights;this.lightData=new Float32Array(r*ie),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 q&&e.layers.test(t.layers)&&!this.collectedDirectionals.includes(e)?this.collectedDirectionals.push(e):e instanceof Y&&e.layers.test(t.layers)?this.collectedPoints.push(e):e instanceof J&&e.layers.test(t.layers)&&this.collectedSpots.push(e)};executeFroxelPass=e=>{this.executeFroxels(e)};projectionInverse=new K;viewProjectionInverse=new K;previousTemporalViewProjection=new K;previousFroxelViewProjection=new K;previousFroxelCameraPosition=new Q;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=de({...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(te[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 he(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 pe(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 me(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 ge(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 fe(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(ne).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),ce(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(se);let n=r+.01;for(let e=0;e<this.volumeCount;e++){const t=e*re,r=this.volumeData[t]-se.x,i=this.volumeData[t+1]-se.y,a=this.volumeData[t+2]-se.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*re+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(ne).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,ce(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,ce(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(se),ce(this.uniforms,32,se.x,se.y,se.z,Math.max(e.camera.far-r,1e-4)),ce(this.uniforms,36,this.options.scatteringIntensity,this.options.spatialJitter?1:0,0,0),this.uniforms.set((this.froxelHistoryValid?this.previousFroxelViewProjection:this.projectionInverse).elements,40),ce(this.uniforms,56,this.previousFroxelCameraPosition.x,this.previousFroxelCameraPosition.y,this.previousFroxelCameraPosition.z,this.froxelHistoryValid&&!1!==this.options.temporal?1:0),ce(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*re*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*ie*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(le);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*re);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)*ie);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(se);let a=0;for(let t=0;t<e.length;t+=1){const s=e[t],o=Number(s instanceof Z?s.userData?.volumetricIntensity??0:s.volumetricIntensity);if(!Number.isFinite(o)||o<=0)continue;const l=s instanceof Z?s.getWorldPosition(ae):s.position,c=se.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*re;t.object.getWorldPosition(ae),t.object.getWorldScale(oe),ce(this.volumeData,r,ae.x,ae.y,ae.z,5*Math.max(oe.x,oe.y,oe.z)),ce(this.volumeData,r+4,t.albedo.r,t.albedo.g,t.albedo.b,Math.max(0,t.baseDensity)),ce(this.volumeData,r+8,t.heightFalloff,t.heightOffset,t.startDistance??3,-Math.max(-.99,Math.min(.99,t.scatteringDistribution))),ce(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*ie;t.getWorldPosition(ae),t.target.getWorldPosition(se),se.sub(ae).normalize(),ce(this.lightData,r,se.x,se.y,se.z,0);const i=t.intensity*(t.userData?.volumetricIntensity??1);ce(this.lightData,r+4,t.color.r*i,t.color.g*i,t.color.b*i,0)}writeExtractedDirectional(e,t){const r=e*ie;ce(this.lightData,r,t.direction.x,t.direction.y,t.direction.z,0);const i=t.intensity*t.volumetricIntensity;ce(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*ie;t.getWorldPosition(ae),ce(this.lightData,i,ae.x,ae.y,ae.z,Math.max(.001,t.distance||this.options.maxDistance));const n=t.intensity*(t.userData?.volumetricIntensity??1);ce(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*ie;ce(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;ce(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*ie;t.getWorldPosition(ae),t.target.getWorldPosition(se),se.sub(ae).normalize(),ce(this.lightData,i,ae.x,ae.y,ae.z,Math.max(.001,t.distance||this.options.maxDistance));const n=t.intensity*(t.userData?.volumetricIntensity??1);ce(this.lightData,i+4,t.color.r*n,t.color.g*n,t.color.b*n,Math.max(0,t.decay)),ce(this.lightData,i+8,se.x,se.y,se.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*ie;ce(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;ce(this.lightData,i+4,t.color.x*n,t.color.y*n,t.color.z*n,Math.max(0,t.decay)),ce(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:we.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 de(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 H(.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 he=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=be;data=new Float32Array(20);inverseProjection=new K;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(ne).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),ce(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)},pe=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=ye;data=new Float32Array(20);inverseProjection=new K;frameIndex=0;setFrameIndex(e){this.frameIndex=e}updateUniforms=e=>(this.inverseProjection.copy(ne).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),ce(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,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 K;currentViewProjectionInverse=new K;updateUniforms=e=>(this.state.updateTemporalUniforms(this.uniforms,this.currentViewProjection,this.currentViewProjectionInverse,this.temporal,e),ce(this.uniforms,36,e.camera.position.x,e.camera.position.y,e.camera.position.z,e.camera.far),this.uniforms)},me=class{name;sampler="linear";uniformBufferSize=80;inputs;outputs;fragmentShader;data=new Float32Array(20);inverseProjection=new K;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(ne).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),this.data)},ge=class{name="VolumetricFogBlurCompositePass";sampler="linear";uniformBufferSize=64;inputs;inputDimensions={};outputs;fragmentShader;data=new Float32Array(16);inverseProjection=new K;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?Se:Ce}updateUniforms=e=>(this.inverseProjection.copy(ne).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements),this.data)},ve="\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 xe(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 we="\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}",be="\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}",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 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 Se="\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}",Ce="\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 Me,DepthFormat as Pe,DepthStencilFormat as Be,FloatType as De,HalfFloatType as Te,IntType as Ie,RED_GREEN_RGTC2_Format as Ve,RED_RGTC1_Format as Le,RGBA_ASTC_10x10_Format as Ge,RGBA_ASTC_10x5_Format as Re,RGBA_ASTC_10x6_Format as ze,RGBA_ASTC_10x8_Format as Ue,RGBA_ASTC_12x10_Format as Ae,RGBA_ASTC_12x12_Format as ke,RGBA_ASTC_4x4_Format as Fe,RGBA_ASTC_5x4_Format as $e,RGBA_ASTC_5x5_Format as Ee,RGBA_ASTC_6x5_Format as Oe,RGBA_ASTC_6x6_Format as _e,RGBA_ASTC_8x5_Format as je,RGBA_ASTC_8x6_Format as Ne,RGBA_ASTC_8x8_Format as We,RGBA_BPTC_Format as He,RGBA_ETC2_EAC_Format as qe,RGBA_S3TC_DXT1_Format as Ke,RGBA_S3TC_DXT3_Format as Ze,RGBA_S3TC_DXT5_Format as Ye,RGBAFormat as Xe,RGBAIntegerFormat as Je,RGFormat as Qe,RGIntegerFormat as et,RGB_ETC1_Format as tt,RGB_ETC2_Format as rt,RGB_S3TC_DXT1_Format as it,RGBFormat as nt,RedFormat as at,RedIntegerFormat as st,ShortType as ot,SIGNED_RED_GREEN_RGTC2_Format as lt,SIGNED_RED_RGTC1_Format as ct,SRGBColorSpace as ut,UnsignedByteType as dt,UnsignedInt248Type as ht,UnsignedInt5999Type as pt,UnsignedIntType as ft,UnsignedShortType as mt}from"three";function gt(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 vt(e,t){const r=gt(e,t);return[r.format,r.textureDimension,r.viewDimension,r.sampleType,r.samplerBindingType,r.width,r.height,r.depthOrArrayLayers,r.mipLevelCount].join(":")}function xt(e){const t=yt(e,bt(e,void 0,!1));return[Ct(Pt(e),t),"comparison"===St(e,t)?"sampler_comparison":"sampler"].join(":")}function wt(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}}function bt(e,t,r=!0){const i=e.format,n=e.type,a=e.colorSpace===ut;let s=null;if(Bt(e))switch(i){case it:case Ke:s=a?"bc1-rgba-unorm-srgb":"bc1-rgba-unorm";break;case Ze:s=a?"bc2-rgba-unorm-srgb":"bc2-rgba-unorm";break;case Ye:s=a?"bc3-rgba-unorm-srgb":"bc3-rgba-unorm";break;case Le:s="bc4-r-unorm";break;case ct:s="bc4-r-snorm";break;case Ve:s="bc5-rg-unorm";break;case lt:s="bc5-rg-snorm";break;case He:s=a?"bc7-rgba-unorm-srgb":"bc7-rgba-unorm";break;case rt:case tt:s=a?"etc2-rgb8unorm-srgb":"etc2-rgb8unorm";break;case qe:s=a?"etc2-rgba8unorm-srgb":"etc2-rgba8unorm";break;case Fe:s=a?"astc-4x4-unorm-srgb":"astc-4x4-unorm";break;case $e:s=a?"astc-5x4-unorm-srgb":"astc-5x4-unorm";break;case Ee:s=a?"astc-5x5-unorm-srgb":"astc-5x5-unorm";break;case Oe:s=a?"astc-6x5-unorm-srgb":"astc-6x5-unorm";break;case _e:s=a?"astc-6x6-unorm-srgb":"astc-6x6-unorm";break;case je:s=a?"astc-8x5-unorm-srgb":"astc-8x5-unorm";break;case Ne:s=a?"astc-8x6-unorm-srgb":"astc-8x6-unorm";break;case We:s=a?"astc-8x8-unorm-srgb":"astc-8x8-unorm";break;case Re:s=a?"astc-10x5-unorm-srgb":"astc-10x5-unorm";break;case ze:s=a?"astc-10x6-unorm-srgb":"astc-10x6-unorm";break;case Ue:s=a?"astc-10x8-unorm-srgb":"astc-10x8-unorm";break;case Ge:s=a?"astc-10x10-unorm-srgb":"astc-10x10-unorm";break;case Ae:s=a?"astc-12x10-unorm-srgb":"astc-12x10-unorm";break;case ke:s=a?"astc-12x12-unorm-srgb":"astc-12x12-unorm";break;case Xe:s=a?"rgba8unorm-srgb":"rgba8unorm"}else switch(i){case Xe:switch(n){case Me:s="rgba8snorm";break;case ot:s="rgba16sint";break;case mt:s="rgba16uint";break;case ft:s="rgba32uint";break;case Ie:s="rgba32sint";break;case dt:s=a?"rgba8unorm-srgb":"rgba8unorm";break;case Te:s="rgba16float";break;case De:s="rgba32float"}break;case nt:switch(n){case pt:s="rgb9e5ufloat";break;case 35899:s="rg11b10ufloat"}break;case at:switch(n){case Me:s="r8snorm";break;case ot:s="r16sint";break;case mt:s="r16uint";break;case ft:s="r32uint";break;case Ie:s="r32sint";break;case dt:s="r8unorm";break;case Te:s="r16float";break;case De:s="r32float"}break;case Qe:switch(n){case Me:s="rg8snorm";break;case ot:s="rg16sint";break;case mt:s="rg16uint";break;case ft:s="rg32uint";break;case Ie:s="rg32sint";break;case dt:s="rg8unorm";break;case Te:s="rg16float";break;case De:s="rg32float"}break;case Pe:switch(n){case mt:s="depth16unorm";break;case ft:s="depth24plus";break;case De:s="depth32float"}break;case Be:switch(n){case ht:s="depth24plus-stencil8";break;case De:Dt("depth32float-stencil8",t,e,"DepthTexture with DepthStencilFormat + FloatType"),s="depth32float-stencil8"}break;case st:switch(n){case Ie:s="r32sint";break;case ft:s="r32uint"}break;case et:switch(n){case Ie:s="rg32sint";break;case ft:s="rg32uint"}break;case Je:switch(n){case Ie:s="rgba32sint";break;case ft: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===Ie)return"sint";if(e.type===ft)return"uint";if(e.type===De&&!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 Lt,Vector2 as Gt,Vector3 as Rt,Vector4 as zt}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 Lt)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 Gt||e instanceof Rt||e instanceof zt){if(0===t)return e.x;if(1===t)return e.y;if(2===t&&(e instanceof Rt||e instanceof zt))return e.z;if(3===t&&e instanceof zt)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 Lt?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 Gt?[e.x,e.y]:e instanceof Rt?[e.x,e.y,e.z]:e instanceof zt?[e.x,e.y,e.z,e.w]:e instanceof Vt||e instanceof Lt?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])=>vt(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])=>gt(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])=>vt(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])=>gt(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=Rr(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=Lr(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=Rr(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=Lr(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:Gr(t.value)}])),this.textures={...e.textures},this.sceneTextures={...e.sceneTextures},this.graphTextures={...e.graphTextures},this.storageBuffers={...e.storageBuffers},this.vertexAttributes=Lr(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}:${xt(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=gt(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 Lr(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 Gr(e){return Array.isArray(e)?Array.from(e):"number"==typeof e||"boolean"==typeof e?e:e.clone()}function Rr(e,t){const r=Ur(t)?t:null,i=null!==r&&"value"in r?r.value:t;if(function(e){return zr(e,"isTexture")}(i))return{kind:"texture",texture:i};if(!function(e){return"number"==typeof e||"boolean"==typeof e||Array.isArray(e)||zr(e,"isColor")||zr(e,"isVector2")||zr(e,"isVector3")||zr(e,"isVector4")||zr(e,"isMatrix3")||zr(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(zr(t,"isColor"))return"vec3<f32>";if(zr(t,"isVector2"))return"vec2<f32>";if(zr(t,"isVector3"))return"vec3<f32>";if(zr(t,"isVector4"))return"vec4<f32>";if(zr(t,"isMatrix3"))return"mat3x3<f32>";if(zr(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 zr(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(U.multiplyMatrices(T,e.projectionMatrix),e.matrixWorldInverse)}function Si(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];return Ci(t,0,s-i,u-o,f-d,x-m),Ci(t,4,s+i,u+o,f+d,x+m),Ci(t,8,s+n,u+l,f+h,x+g),Ci(t,12,s-n,u-l,f-h,x-g),Ci(t,16,s-a,u-c,f-p,x-v),Ci(t,20,a,c,p,v),t}function Ci(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 Mi(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 Pi(e){return null===e.boundingSphere&&e.computeBoundingSphere(),e.boundingSphere?{center:e.boundingSphere.center.clone(),radius:e.boundingSphere.radius}:{center:new Br,radius:1}}function Bi(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 Di(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],L=y*o[4]+S*o[5]+C*o[6],G=y*o[8]+S*o[9]+C*o[10],R=M*o[0]+P*o[1]+B*o[2],z=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]*R,k=l[0]*T+l[4]*L+l[8]*z,F=l[0]*I+l[4]*G+l[8]*U,$=l[1]*D+l[5]*V+l[9]*R,E=l[1]*T+l[5]*L+l[9]*z,O=l[1]*I+l[5]*G+l[9]*U,_=l[2]*D+l[6]*V+l[10]*R,j=l[2]*T+l[6]*L+l[10]*z,N=l[2]*I+l[6]*G+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 Ti(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 Ii(e){return Math.floor(Math.max(0,e.count)/3)*Math.max(0,e.instanceCount)}function Vi(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 Li(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,source:null},this.palettes.set(e,r)),e.boneMatrices.length<t&&(e.boneMatrices=new Float32Array(t)),r.published!==e.boneMatrices&&(r.source=e.boneMatrices.length===t?e.boneMatrices:new Float32Array(e.boneMatrices.buffer,e.boneMatrices.byteOffset,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],L=s[13],G=s[2],R=s[6],z=s[10],U=s[14],A=s[3],k=s[7],F=s[11],$=s[15];n[o]=l*M+c*T+u*G+d*A,n[o+4]=l*P+c*I+u*R+d*k,n[o+8]=l*B+c*V+u*z+d*F,n[o+12]=l*D+c*L+u*U+d*$,n[o+1]=h*M+p*T+f*G+m*A,n[o+5]=h*P+p*I+f*R+m*k,n[o+9]=h*B+p*V+f*z+m*F,n[o+13]=h*D+p*L+f*U+m*$,n[o+2]=g*M+v*T+x*G+w*A,n[o+6]=g*P+v*I+x*R+w*k,n[o+10]=g*B+v*V+x*z+w*F,n[o+14]=g*D+v*L+x*U+w*$,n[o+3]=b*M+y*T+S*G+C*A,n[o+7]=b*P+y*I+S*R+C*k,n[o+11]=b*B+y*V+S*z+C*F,n[o+15]=b*D+y*L+S*U+C*$}t&&null!==e.boneTexture&&(e.boneTexture.needsUpdate=!0)}(e,!1);let i=!1;for(let n=0;n<t;n++)if(r.values[n]!==e.boneMatrices[n]){i=!0;break}return i&&r.values.set(r.source),!i&&r.published===e.boneMatrices||null===e.boneTexture||(e.boneTexture.needsUpdate=!0),r.published=e.boneMatrices,i}},Ri=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/S}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+S);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+=S,u}appendRange(e,t,r){if(r<=0)return;const i=t*S,n=i+r*S;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*S;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 Ri;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 Ui,InterleavedBufferAttribute as Ai}from"three";var ki=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 Ai,u=t&&!t.normalized&&(c?t.getComponent===Ai.prototype.getComponent:t.getComponent===Ui.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{Color as Fi,CompressedArrayTexture as $i,Matrix3 as Ei,Matrix4 as Oi,Vector2 as _i,Vector3 as ji,Vector4 as Ni}from"three";import{Color as Wi,Matrix3 as Hi,Matrix4 as qi}from"three";function Ki(e){return!0===e.isWgslCompiler}function Zi(e){return!0===e.isWgslFragmentCompiler}function Yi(e){return e instanceof sn?e:new on(e)}function Xi(e){return e instanceof dn||e instanceof Sn?new Gn(e):e instanceof Ln?e:new Rn(e)}function Ji(e){return e instanceof Ln?new pn(e):e instanceof dn?e:new hn(e)}function Qi(e){return e instanceof Ln||e instanceof dn?new Mn(e):e instanceof Sn?e:new Cn(e)}var en={level:0};function tn(e){return Number.isInteger(e)?e+".":e.toString()}var rn=class{scopeLevel=en.level};function nn(e,t,r,i,n){if(Ki(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 Rn&&t instanceof Rn&&void 0!==e.number&&void 0!==t.number){return{out:`${tn(e.number-t.number)}`}}const a=`${i}_op_${n.variable()}`;return{chunk:`${i} ${a} = ${n.get(e)} ${r} ${n.get(t)};`,out:a}}function an(e,t,r,i){const n=`${r}_op_${i.variable()}`,a=`${t}${i.get(e)}`;return{chunk:Ki(i)?i.local(r,n,a):`${r} ${n} = ${a};`,out:n}}var sn=class extends rn{static typeName="bool";isBoolean(){return!0}and(e){return new cn(this,Yi(e))}or(e){return new un(this,Yi(e))}},on=class extends sn{bool;constructor(e){super(),this.bool=e}isBoolean(){return!0}compile(e){return{out:`${this.bool}`}}},ln=class extends sn{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return nn(this.a,this.b,this.op,"bool",e)}},cn=class extends ln{constructor(e,t){super(e,t,"&&")}},un=class extends ln{constructor(e,t){super(e,t,"||")}},dn=class extends rn{static typeName="int";isInt(){return!0}add(e){return new vn(this,Ji(e))}subtract(e){return new xn(this,Ji(e))}multiply(e){return new bn(this,Ji(e))}divide(e){return new wn(this,Ji(e))}gt(e){return new qs(this,Ji(e))}lt(e){return new Ks(this,Ji(e))}gte(e){return new Zs(this,Ji(e))}lte(e){return new Ys(this,Ji(e))}equals(e){return to(this,Ji(e))}notEquals(e){return ro(this,Ji(e))}mod(e){return new yn(this,Ji(e))}bitAnd(e){return new fn(this,Ji(e),"&")}bitOr(e){return new fn(this,Ji(e),"|")}bitXor(e){return new fn(this,Ji(e),"^")}bitNot(){return new gn(this,"~")}shiftLeft(e){return new mn(this,Qi(e),"<<")}shiftRight(e){return new mn(this,Qi(e),">>")}},hn=class extends dn{number;constructor(e){super(),this.number=e}compile(e){return{out:`${Math.floor(this.number)}`}}},pn=class extends dn{number;constructor(e){super(),this.number=e}compile(e){return Ki(e)?{out:`i32(${e.get(this.number)})`}:{out:`int(${e.get(this.number)})`}}},fn=class extends dn{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return nn(this.a,this.b,this.op,"int",e)}},mn=class extends dn{value;amount;op;constructor(e,t,r){super(),this.value=e,this.amount=t,this.op=r}compile(e){return nn(this.value,this.amount,this.op,"int",e)}},gn=class extends dn{value;op;constructor(e,t){super(),this.value=e,this.op=t}compile(e){return an(this.value,this.op,"int",e)}},vn=class extends fn{constructor(e,t){super(e,t,"+")}},xn=class extends fn{constructor(e,t){super(e,t,"-")}},wn=class extends fn{constructor(e,t){super(e,t,"/")}},bn=class extends fn{constructor(e,t){super(e,t,"*")}},yn=class extends fn{constructor(e,t){super(e,t,"%")}},Sn=class extends rn{static typeName="int";isuInt(){return!0}add(e){return new Dn(this,Qi(e))}subtract(e){return new Tn(this,Qi(e))}multiply(e){return new Vn(this,Qi(e))}divide(e){return new In(this,Qi(e))}gt(e){return new Xs(this,Qi(e))}lt(e){return new Js(this,Qi(e))}gte(e){return new Qs(this,Qi(e))}lte(e){return new eo(this,Qi(e))}equals(e){return to(this,Qi(e))}notEquals(e){return ro(this,Qi(e))}bitAnd(e){return new Pn(this,Qi(e),"&")}bitOr(e){return new Pn(this,Qi(e),"|")}bitXor(e){return new Pn(this,Qi(e),"^")}bitNot(){return new Bn(this,"~")}shiftLeft(e){return new Pn(this,Qi(e),"<<")}shiftRight(e){return new Pn(this,Qi(e),">>")}},Cn=class extends Sn{number;constructor(e){super(),this.number=e}compile(e){return Ki(e)?{out:`${Math.floor(this.number)}u`}:{out:`${Math.floor(this.number)}`}}},Mn=class extends Sn{number;constructor(e){super(),this.number=e}compile(e){return Ki(e)?{out:`u32(${e.get(this.number)})`}:{out:`uint(${e.get(this.number)})`}}},Pn=class extends Sn{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return nn(this.a,this.b,this.op,"uint",e)}},Bn=class extends Sn{value;op;constructor(e,t){super(),this.value=e,this.op=t}compile(e){return an(this.value,this.op,"uint",e)}},Dn=class extends Pn{constructor(e,t){super(e,t,"+")}},Tn=class extends Pn{constructor(e,t){super(e,t,"-")}},In=class extends Pn{constructor(e,t){super(e,t,"/")}},Vn=class extends Pn{constructor(e,t){super(e,t,"*")}},Ln=class extends rn{static typeName="float";isFloat(){return!0}add(e){return new Un(this,Xi(e))}subtract(e){return new An(this,Xi(e))}divide(e){return new kn(this,Xi(e))}multiply(e){return new Fn(this,Xi(e))}multiplyVec2(e){return new Xn(this,e)}multiplyVec3(e){return new Ma(this,e)}multiplyVec4(e){return new $a(this,e)}gt(e){return new js(this,Xi(e))}lt(e){return new Ns(this,Xi(e))}gte(e){if(this instanceof Rn&&e instanceof Rn&&void 0!==this.number&&void 0!==e.number){const t=this.number>=e.number;return new on(t)}return new Ws(this,Xi(e))}lte(e){return new Hs(this,Xi(e))}equals(e){return to(this,Xi(e))}notEquals(e){return ro(this,Xi(e))}},Gn=class extends Ln{number;constructor(e){super(),this.number=e}compile(e){return Ki(e)?{out:`f32(${e.get(this.number)})`}:{out:`float(${e.get(this.number)})`}}},Rn=class extends Ln{number;constructor(e){super(),this.number=e}compile(e){if(Ki(e))return{out:e.floatLiteral(this.number)};return{out:`${tn(this.number)}`}}},zn=class extends Ln{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return nn(this.a,this.b,this.op,"float",e)}},Un=class extends zn{constructor(e,t){super(e,t,"+")}},An=class extends zn{constructor(e,t){super(e,t,"-")}},kn=class extends zn{constructor(e,t){super(e,t,"/")}},Fn=class extends zn{constructor(e,t){super(e,t,"*")}},$n=class extends rn{static typeName="vec2";isVec2(){return!0}get x(){return Es(this)}get y(){return Os(this)}get yx(){return new On(Os(this),Es(this))}subtractScalar(e){return new Hn(this,Xi(e))}subtract(e){return new Nn(this,e)}addScalar(e){return new Wn(this,Xi(e))}add(e){return new jn(this,e)}divideScalar(e){return new Kn(this,Xi(e))}divide(e){return new Zn(this,e)}multiplyScalar(e){return new qn(this,Xi(e))}multiply(e){return new Yn(this,e)}multiplyMat(e){return new ns(this,e)}equals(e){return to(this,e)}notEquals(e){return ro(this,e)}},En=class extends $n{vec;constructor(e){super(),this.vec=e}compile(e){const t=e.variable();if(Ki(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(${tn(this.vec.x)},${tn(this.vec.y)});`,out:`vec2_${t}`}}},On=class extends $n{_x;_y;constructor(e,t){super(),this._x=e,this._y=t}compile(e){const t=e.variable();if(Ki(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}`}}},_n=class extends $n{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return nn(this.a,this.b,this.op,"vec2",e)}},jn=class extends _n{constructor(e,t){super(e,t,"+")}},Nn=class extends _n{constructor(e,t){super(e,t,"-")}},Wn=class extends _n{constructor(e,t){super(e,t,"+")}},Hn=class extends _n{constructor(e,t){super(e,t,"-")}},qn=class extends _n{constructor(e,t){super(e,t,"*")}},Kn=class extends _n{constructor(e,t){super(e,t,"/")}},Zn=class extends _n{constructor(e,t){super(e,t,"/")}},Yn=class extends _n{constructor(e,t){super(e,t,"*")}},Xn=class extends _n{constructor(e,t){super(e,t,"*")}},Jn=class extends rn{static typeName="ivec2";isiVec2(){return!0}get x(){return new Fs(this,"x")}get y(){return new Fs(this,"y")}subtractScalar(e){return new aa(this,Ji(e))}subtract(e){return new ia(this,e)}addScalar(e){return new na(this,Ji(e))}add(e){return new ra(this,e)}divideScalar(e){return new oa(this,Ji(e))}divide(e){return new la(this,e)}multiplyScalar(e){return new sa(this,Ji(e))}multiply(e){return new ca(this,e)}multiplyMat(e){return new Ea(this,e)}equals(e){return to(this,e)}notEquals(e){return ro(this,e)}},Qn=class extends Jn{vec;constructor(e){super(),this.vec=e}compile(e){const t=e.variable();if(Ki(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(${tn(this.vec.x)},${tn(this.vec.y)});`,out:`vec2_${t}`}}},ea=class extends Jn{_x;_y;constructor(e,t){super(),this._x=e,this._y=t}compile(e){return Ki(e)?{out:e.construct("ivec2",[e.get(this._x),e.get(this._y)])}:{out:`ivec2(${e.get(this._x)},${e.get(this._y)})`}}},ta=class extends Jn{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return nn(this.a,this.b,this.op,"ivec2",e)}},ra=class extends ta{constructor(e,t){super(e,t,"+")}},ia=class extends ta{constructor(e,t){super(e,t,"-")}},na=class extends ta{constructor(e,t){super(e,t,"+")}},aa=class extends ta{constructor(e,t){super(e,t,"-")}},sa=class extends ta{constructor(e,t){super(e,t,"*")}},oa=class extends ta{constructor(e,t){super(e,t,"/")}},la=class extends ta{constructor(e,t){super(e,t,"/")}},ca=class extends ta{constructor(e,t){super(e,t,"*")}},ua=class extends rn{static typeName="vec3";isVec3(){return!0}get x(){return Es(this)}get y(){return Os(this)}get z(){return _s(this)}get xy(){return new fa(this,"xy")}get xz(){return new fa(this,"xz")}get yz(){return new fa(this,"yz")}get zx(){return new fa(this,"zx")}get rgb(){return new Rs(this)}rgba(e){return this.rgb.rgba(e)}subtractScalar(e){return new wa(this,Xi(e))}subtract(e){return new va(this,e)}addScalar(e){return new xa(this,Xi(e))}add(e){return new ga(this,e)}divideScalar(e){return new ya(this,Xi(e))}divide(e){return new Sa(this,e)}multiplyScalar(e){return new ba(this,Xi(e))}multiply(e){return new Ca(this,e)}multiplyMat(e){return new gs(this,e)}equals(e){return to(this,e)}notEquals(e){return ro(this,e)}},da=class extends ua{vec;constructor(e){super(),this.vec=e}compile(e){const t=e.variable();if(Ki(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(${tn(this.vec.x)},${tn(this.vec.y)},${tn(this.vec.z)});`,out:`vec3_${t}`}}},ha=class extends ua{_x;_y;_z;constructor(e,t,r){super(),this._x=e,this._y=t,this._z=r}compile(e){const t=e.variable();if(Ki(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}`}}},pa=class extends ua{source;swizzle;constructor(e,t="xyz"){super(),this.source=e,this.swizzle=t}compile(e){return{out:`${e.get(this.source)}.${this.swizzle}`}}},fa=class extends $n{source;swizzle;constructor(e,t="xy"){super(),this.source=e,this.swizzle=t}compile(e){return{out:`${e.get(this.source)}.${this.swizzle}`}}},ma=class extends ua{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return nn(this.a,this.b,this.op,"vec3",e)}},ga=class extends ma{constructor(e,t){super(e,t,"+")}},va=class extends ma{constructor(e,t){super(e,t,"-")}},xa=class extends ma{constructor(e,t){super(e,t,"+")}},wa=class extends ma{constructor(e,t){super(e,t,"-")}},ba=class extends ma{constructor(e,t){super(e,t,"*")}},ya=class extends ma{constructor(e,t){super(e,t,"/")}},Sa=class extends ma{constructor(e,t){super(e,t,"/")}},Ca=class extends ma{constructor(e,t){super(e,t,"*")}},Ma=class extends ma{constructor(e,t){super(e,t,"*")}},Pa=class extends rn{static typeName="vec4";isVec4(){return!0}get x(){return Es(this)}get y(){return Os(this)}get z(){return _s(this)}get w(){return new ks(this,"w")}get xy(){return new fa(this,"xy")}get xz(){return new fa(this,"xz")}get yz(){return new fa(this,"yz")}get zx(){return new fa(this,"zx")}get zw(){return new fa(this,"zw")}get xyz(){return new pa(this,"xyz")}get rgb(){return new Gs(this.x,this.y,this.z)}get rgba(){return new zs(this)}subtractScalar(e){return new za(this,Xi(e))}subtract(e){return new Ga(this,e)}addScalar(e){return new Ra(this,Xi(e))}add(e){return new La(this,e)}divideScalar(e){return new Aa(this,Xi(e))}divide(e){return new ka(this,e)}multiplyScalar(e){return new Ua(this,Xi(e))}multiply(e){return new Fa(this,e)}multiplyMat(e){return new Ds(this,e)}equals(e){return to(this,e)}notEquals(e){return ro(this,e)}},Ba=class extends Pa{vec;constructor(e){super(),this.vec=e}compile(e){const t=e.variable();if(Ki(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(${tn(this.vec.x)},${tn(this.vec.y)},${tn(this.vec.z)},${tn(this.vec.w)});`,out:`vec4_${t}`}}},Da=class extends Pa{_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(Ki(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}`}}},Ta=class extends Pa{_xyz;_w;constructor(e,t){super(),this._xyz=e,this._w=t}compile(e){const t=e.variable();if(Ki(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}`}}},Ia=class extends Pa{_xy;_zw;constructor(e,t){super(),this._xy=e,this._zw=t}compile(e){const t=e.variable();if(Ki(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}`}}},Va=class extends Pa{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return nn(this.a,this.b,this.op,"vec4",e)}},La=class extends Va{constructor(e,t){super(e,t,"+")}},Ga=class extends Va{constructor(e,t){super(e,t,"-")}},Ra=class extends Va{constructor(e,t){super(e,t,"+")}},za=class extends Va{constructor(e,t){super(e,t,"-")}},Ua=class extends Va{constructor(e,t){super(e,t,"*")}},Aa=class extends Va{constructor(e,t){super(e,t,"/")}},ka=class extends Va{constructor(e,t){super(e,t,"/")}},Fa=class extends Va{constructor(e,t){super(e,t,"*")}},$a=class extends Va{constructor(e,t){super(e,t,"*")}},Ea=class extends ta{constructor(e,t){super(e,t,"*")}},Oa=class extends rn{static typeName="uvec4";isuVec4(){return!0}get x(){return new $s(this,"x")}get y(){return new $s(this,"y")}get z(){return new $s(this,"z")}get w(){return new $s(this,"w")}subtractScalar(e){return new Ha(this,Qi(e))}subtract(e){return new Na(this,e)}addScalar(e){return new Wa(this,Qi(e))}add(e){return new ja(this,e)}divideScalar(e){return new Ka(this,Qi(e))}divide(e){return new Za(this,e)}multiplyScalar(e){return new qa(this,Qi(e))}multiply(e){return new Ya(this,e)}equals(e){return to(this,e)}notEquals(e){return ro(this,e)}},_a=class extends Oa{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return nn(this.a,this.b,this.op,"ivec2",e)}},ja=class extends _a{constructor(e,t){super(e,t,"+")}},Na=class extends _a{constructor(e,t){super(e,t,"-")}},Wa=class extends _a{constructor(e,t){super(e,t,"+")}},Ha=class extends _a{constructor(e,t){super(e,t,"-")}},qa=class extends _a{constructor(e,t){super(e,t,"*")}},Ka=class extends _a{constructor(e,t){super(e,t,"/")}},Za=class extends _a{constructor(e,t){super(e,t,"/")}},Ya=class extends _a{constructor(e,t){super(e,t,"*")}},Xa=class extends rn{static typeName="mat2";isMat2(){return!0}col(e){return new lo(this,e)}add(e){return new Qa(this,e)}subtract(e){return new es(this,e)}divideScalar(e){return new rs(this,Xi(e))}multiplyScalar(e){return new is(this,e)}multiplyVec(e){return new as(this,e)}multiply(e){return new ts(this,e)}equals(e){return to(this,e)}notEquals(e){return ro(this,e)}},Ja=class extends Xa{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return nn(this.a,this.b,this.op,"mat2",e)}},Qa=class extends Ja{constructor(e,t){super(e,t,"+")}},es=class extends Ja{constructor(e,t){super(e,t,"-")}},ts=class extends Ja{constructor(e,t){super(e,t,"*")}},rs=class extends Ja{constructor(e,t){super(e,t,"*")}},is=class extends Ja{constructor(e,t){super(e,t,"*")}},ns=class extends _n{constructor(e,t){super(e,t,"*")}},as=class extends _n{constructor(e,t){super(e,t,"*")}},ss=class extends rn{static typeName="mat3";isMat3(){return!0}col(e){return new co(this,e)}add(e){return new ds(this,e)}subtract(e){return new hs(this,e)}divideScalar(e){return new fs(this,Xi(e))}multiplyScalar(e){return new ms(this,e)}multiplyVec(e){return new vs(this,e)}multiply(e){return new ps(this,e)}equals(e){return to(this,e)}notEquals(e){return ro(this,e)}},os=class extends ss{mat;constructor(e){super(),this.mat=e}compile(e){return{out:`mat3(${e.get(this.mat)})`}}},ls=class extends ss{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 Hi||"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:Ki(e)?e.local("mat3",t,e.construct("mat3",r.map(t=>e.floatLiteral(t)))):`mat3 ${t} = mat3(${r.map(tn).join(",")});`,out:t}}},cs=class extends ss{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 Ki(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 )`}}},us=class extends ss{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return nn(this.a,this.b,this.op,"mat3",e)}},ds=class extends us{constructor(e,t){super(e,t,"+")}},hs=class extends us{constructor(e,t){super(e,t,"-")}},ps=class extends us{constructor(e,t){super(e,t,"*")}},fs=class extends us{constructor(e,t){super(e,t,"*")}},ms=class extends us{constructor(e,t){super(e,t,"*")}},gs=class extends ma{constructor(e,t){super(e,t,"*")}},vs=class extends ma{constructor(e,t){super(e,t,"*")}},xs=class extends rn{static typeName="mat4";isMat4(){return!0}col(e){return new uo(this,e)}add(e){return new Ss(this,e)}subtract(e){return new Cs(this,e)}divideScalar(e){return new Ps(this,Xi(e))}multiplyScalar(e){return new Bs(this,Xi(e))}multiplyVec(e){return new Ts(this,e)}multiply(e){return new Ms(this,e)}equals(e){return to(this,e)}notEquals(e){return ro(this,e)}},ws=class extends xs{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 Ki(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 ${tn(this.a1)},${tn(this.b1)},${tn(this.c1)},${tn(this.d1)},\n ${tn(this.a2)},${tn(this.b2)},${tn(this.c2)},${tn(this.d2)},\n ${tn(this.a3)},${tn(this.b3)},${tn(this.c3)},${tn(this.d3)},\n ${tn(this.a4)},${tn(this.b4)},${tn(this.c4)},${tn(this.d4)}\n );`,out:r};if((i=this.a1)instanceof qi||"object"==typeof i&&null!=i&&!0===i.isMatrix4&&"function"==typeof i.toArray){if(Ki(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=>tn(e)).join(",")});`,out:r}}throw new Error("Invalid parameters to Matrix4");var i}},bs=class extends xs{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(Ki(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}`}}},ys=class extends xs{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return nn(this.a,this.b,this.op,"mat4",e)}},Ss=class extends ys{constructor(e,t){super(e,t,"+")}},Cs=class extends ys{constructor(e,t){super(e,t,"-")}},Ms=class extends ys{constructor(e,t){super(e,t,"*")}},Ps=class extends ys{constructor(e,t){super(e,t,"/")}},Bs=class extends ys{constructor(e,t){super(e,t,"*")}},Ds=class extends Va{constructor(e,t){super(e,t,"*")}},Ts=class extends Va{constructor(e,t){super(e,t,"*")}},Is=class extends Pa{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}},Vs=class extends ua{isRgb(){return!0}get r(){return this.x}get g(){return this.y}get b(){return this.z}rgba(e){return new As(this,Xi(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}},Ls=class extends Is{_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(Ki(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}`}}},Gs=class extends Vs{_r;_g;_b;constructor(e,t,r){super(),this._r=e,this._g=t,this._b=r}compile(e){const t=e.variable();if(Ki(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}`}}},Rs=class extends Vs{vec;constructor(e){super(),this.vec=e}compile(e){return{out:`${e.get(this.vec)}`}}},zs=class extends Is{vec;constructor(e){super(),this.vec=e}compile(e){return{out:`${e.get(this.vec)}`}}},Us=class extends Vs{color;constructor(e){super(),this.color=e}compile(e){const t=new Wi(this.color),r=e.variable();if(Ki(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(${tn(t.r)},${tn(t.g)},${tn(t.b)});`,out:`vec3_${r}`}}},As=class extends Is{_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(Ki(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}`}}},ks=class extends Ln{vec;component;constructor(e,t){super(),this.vec=e,this.component=t}compile(e){return{out:`${e.get(this.vec)}.${this.component}`}}},Fs=class extends dn{vec;component;constructor(e,t){super(),this.vec=e,this.component=t}compile(e){return{out:`${e.get(this.vec)}.${this.component}`}}},$s=class extends Sn{vec;component;constructor(e,t){super(),this.vec=e,this.component=t}compile(e){return{out:`${e.get(this.vec)}.${this.component}`}}};function Es(e){return new ks(e,"x")}function Os(e){return new ks(e,"y")}function _s(e){return new ks(e,"z")}var js=class extends sn{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 sn{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 sn{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 sn{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 sn{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 sn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} < ${e.get(this.b)}`}}},Zs=class extends sn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} >= ${e.get(this.b)}`}}},Ys=class extends sn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} <= ${e.get(this.b)}`}}},Xs=class extends sn{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 sn{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 sn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} >= ${e.get(this.b)}`}}},eo=class extends sn{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 to(e,t){return new class extends sn{compile(r){return{out:`${r.get(e)} == ${r.get(t)}`}}}}function ro(e,t){return new class extends sn{compile(r){return{out:`${r.get(e)} != ${r.get(t)}`}}}}var io=class extends rn{static get typeName(){return"sampler2D"}sample(e,t){return new so(this,e,t)}sampleGrad(e,t,r){return new oo(this,e,t,r)}},no=class extends rn{static typeName="usampler2D";sample(e,t){return new ao(this,e,t)}},ao=class extends Oa{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}`}}},so=class extends Is{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(Ki(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=Zi(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}`}}},oo=class extends Is{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(Ki(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}`}}},lo=class extends $n{mat;i;constructor(e,t){super(),this.mat=e,this.i=t}compile(e){return{out:`${e.get(this.mat)}[${this.i}]`}}},co=class extends ua{mat;i;constructor(e,t){super(),this.mat=e,this.i=t}compile(e){return{out:`${e.get(this.mat)}[${this.i}]`}}},uo=class extends Pa{mat;i;constructor(e,t){super(),this.mat=e,this.i=t}compile(e){return{out:`${e.get(this.mat)}[${this.i}]`}}};var ho=class extends Pa{name;constructor(e){super(),this.name=e}compile(e){return e instanceof Lo||Zi(e)?e.defineVarying("vec4",this):function(e,t,r){return Zi(e)?e.defineBuiltinVarying(r,t):Ki(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")}},po=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)}},fo=class extends sn{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 po(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)}},mo=class extends Ln{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 po(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)}},go=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 po(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)}},vo=class extends io{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new po(t):void 0}get value(){return this.currentValue}set value(e){this.currentValue=e,null!=this.binding&&(this.binding.value=e)}compile(e){return Ki(e)?e.defineTexture(this.name,this.value):e.defineUniform("sampler2D",this.name,this.value,this.ifdef,this.binding)}},xo=class extends ua{a;isVarying=!0;constructor(e){super(),this.a=e}compile(e){if(e instanceof Lo||Zi(e))return e.defineVarying("vec3",this.a);throw new Error("A varying can not be defined as input to another varying.")}},wo=class extends Pa{a;isVarying=!0;constructor(e){super(),this.a=e}compile(e){if(e instanceof Lo||Zi(e))return e.defineVarying("vec4",this.a);throw new Error("A varying can not be defined as input to another varying.")}};function bo(e){return new ko(e)}function yo(e){return e.multiplyScalar(Xi(-1))}function So(e,t,r){if((e instanceof Ln||"number"==typeof e)&&(t instanceof Ln||"number"==typeof t))return new Gs(Xi(e),Xi(t),Xi(r??0)).divideScalar(255);if((i=e)instanceof Fi||!0===i?.isColor||"number"==typeof e||"string"==typeof e)return new Us(e);var i;throw"Unsupported arguments to construct RGB"}function Co(e,t){return e instanceof _i?new Qn(e):new ea(Ji(e),Ji(null!=t?t:e))}function Mo(e,t){if(e instanceof ua||e instanceof Pa)return e.xy;if(("number"==typeof e||e instanceof Ln)&&("number"==typeof t||t instanceof Ln||null==t))return new On(Xi(e),Xi(t??e));if("number"==typeof e){if(t instanceof Ln)return new On(Xi(e),Xi(t));if("number"==typeof t||null==t)return new En(new _i(e,null!=t?t:e))}else if(e instanceof _i)return new En(e);if(e instanceof ji||e instanceof Ni)return new En(new _i(e.x,e.y));if(e instanceof Ln)return new On(Xi(e),Xi(null!=t?t:e));throw new Error("Invalid arguments for vec2")}function Po(e,t,r){if((e instanceof Ln||"number"==typeof e)&&void 0===t)return new ha(Xi(e),Xi(e),Xi(e));if(e instanceof ua)return e;if(e instanceof Pa)return e.xyz;if(("number"==typeof e||e instanceof Ln)&&("number"==typeof t||t instanceof Ln)&&("number"==typeof r||r instanceof Ln))return new ha(Xi(e),Xi(t),Xi(r));if(e instanceof ji||e instanceof Ni)return new da(e);throw new Error("Invalid arguments for vec3")}function Bo(e,t,r,i){if((e instanceof Ln||"number"==typeof e)&&void 0===t)return new Da(Xi(e),Xi(e),Xi(e),Xi(e));if(e instanceof ua)return new Ta(e,Xi(t));if(Io(e)&&Io(t)&&Io(r)&&Io(i))return new Da(Xi(e),Xi(t),Xi(r),Xi(i));if(e instanceof $n){if(t instanceof $n)return new Ia(e,t)}else if(e instanceof Ni)return new Ba(e);throw"Unsupported combination of inputs"}function Do(e,t,r){if(e instanceof Ei)return new ls(e);if("number"==typeof e&&void 0===t)return new ls(e,e,e,e,e,e,e,e,e);if(e instanceof ua&&t instanceof ua&&r instanceof ua)return new cs(e.x,e.y,e.z,t.x,t.y,t.z,r.x,r.y,r.z);if(e instanceof xs)return new os(e);throw"Unsupported combination of inputs"}function To(e,t,r,i){if(e instanceof Oi)return new ws(e);if("number"==typeof e&&void 0===t)return new ws(e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e);if(e instanceof Pa&&t instanceof Pa&&r instanceof Pa&&i instanceof Pa)return new bs(e,t,r,i);throw"Unsupported combination of inputs"}function Io(e){return"number"==typeof e||e instanceof Ln}var Vo=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=[]){en.level,this.scopeLevelChunkIndex[en.level]=this.chunks.length-1,en.level++,en.level;const r=this.getCachedOuts(en.level);for(const e of t){const t=this.cachedOuts.get(e);null!=t&&r.set(e,t)}null==this.chunkBuffers[en.level]&&(this.chunkBuffers[en.level]=[]),this.chunkBuffers[en.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(en.level).clear(),0===en.level)throw"stop scope only after entering";const t=this.getScopeChunks(en.level);this.chunkBuffers[en.level].pop(),en.level--;const r=this.getScopeChunks(en.level);r.push(...t),r.push(e),en.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?en.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(en.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 po&&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 `}},Lo=class extends Vo{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=en.level;en.level=0;const a=this.vertexCompiler.get(t);en.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=en.level;en.level=0;const i=this.vertexCompiler.get(Ji(r));en.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}},Go=/^\s*(?:(\w+)) (?=\w+)/g,Ro=/^\s*(?:(\w+)) (?=(\w+))/g,zo=class extends dn{compile(e){return Ki(e)?{out:e.currentLoopIndex()}:{out:"UNROLLED_LOOP_INDEX"}}},Uo=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(Ji(this.limit)),capacity:this.limit}}compileElement(e,t){return`${e.get(this)}[${e.get(t)}]`}get(e){const t=this,r=Ji(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;en.level++;const r=new zo,i=e(t.get(r),r);en.level--;const n=i.constructor;return new class extends n{compile(e){if(Ki(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&&Zi(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(Ji(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(Ji(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(Ro))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(Go,"")}),e.chunks[l-1]=e.chunks[l-1].replace("//VARIABLES",u),{out:`loop_sum_${r}`}}}}map(t){const r=this;en.level++;const i=new zo,n=t(r.get(i),i),a=n.constructor;return en.level--,new class extends e{type=a;limit=r.limit;compile(e){if(Ki(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(Ji(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(Ro))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(Go,"")}),e.chunks[l-1]=e.chunks[l-1].replace("//VARIABLES",u),{out:`loop_map_${t}`}}}}};var Ao=class e extends Uo{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(Ki(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(Ji(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(Ki(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)}},ko=class e extends Uo{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)}},Fo=class extends dn{expr;constructor(e){super(),this.expr=e}compile(e){if(Ki(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}}},$o=class extends ua{expr;constructor(e){super(),this.expr=e}compile(e){return Ki(e)?_o(e,"vec3",this.expr):{out:this.expr}}},Eo=class extends Pa{expr;constructor(e){super(),this.expr=e}compile(e){return Ki(e)?_o(e,"vec4",this.expr):{out:this.expr}}},Oo=class extends xs{expr;constructor(e){super(),this.expr=e}compile(e){if(Ki(e))switch(this.expr){case"modelMatrix":return jo(e,"rendererModelMatrix");case"modelViewMatrix":return jo(e,"rendererModelViewMatrix");case"projectionMatrix":return{out:"rendererProjectionMatrix()"};case"viewMatrix":return{out:"rendererViewMatrix()"};case"instanceMatrix":case"vertexTransform":return{out:Wo};default:throw No("mat4",this.expr)}return{out:this.expr}}};function _o(e,t,r){if("instanceColor"===r&&("vec3"===t||"vec4"===t)){if(Zi(e))return e.defineVarying(t,"vec3"===t?new $o(r):new Eo(r));const i="rendererObjectColor(input.instanceIndex)";return{out:"vec3"===t?`${i}.xyz`:i}}if("uv"===r||"position"===r||"normal"===r||"color"===r)return Zi(e)?e.defineBuiltinVarying(t,r):{out:`input.${r}`};if("cameraPosition"===r&&"vec3"===t)return{out:"rendererCameraPosition()"};if(Zi(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 No(t,r)}function jo(e,t){if(Zi(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 No(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 Wo="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 Ho,Vector3 as qo}from"three";var Ko=new ws((new Ho).identity()),Zo={tangent:new ho("tangent"),position:new $o("position"),normal:new $o("normal"),uv:new class extends $n{expr;constructor(e){super(),this.expr=e}compile(e){return Ki(e)?_o(e,"vec2",this.expr):{out:this.expr}}}("uv"),color:new ho("color").rgba},Yo=(new xo(Zo.position),new xo(Zo.normal),new class extends $n{a;isVarying=!0;constructor(e){super(),this.a=e}compile(e){if(e instanceof Lo||Zi(e))return e.defineVarying("vec2",this.a);throw new Error("A varying can not be defined as input to another varying.")}}(Zo.uv),{instanceMatrix:new class extends xs{compile(e){if(Ki(e))return{out:e.get(Ko)};const t=e.variable();return{chunk:`\n mat4 instanceMatrixOpt_${t} = ${e.get(Ko)};\n #ifdef USE_INSTANCING\n instanceMatrixOpt_${t} = instanceMatrix;\n #endif\n `,out:`instanceMatrixOpt_${t}`}}},modelMatrix:new Oo("modelMatrix"),modelViewMatrix:new Oo("modelViewMatrix"),projectionMatrix:new Oo("projectionMatrix"),viewMatrix:new Oo("viewMatrix"),normalMatrix:new class extends ss{expr;constructor(e){super(),this.expr=e}compile(e){if(Ki(e)){if("normalMatrix"===this.expr)return jo(e,"rendererNormalMatrix");throw No("mat3",this.expr)}return{out:this.expr}}}("normalMatrix"),cameraPosition:new $o("cameraPosition")});new Eo("projectionMatrix * modelViewMatrix * vec4( position , 1.0 )");function Xo(e,t){const r=Object.getPrototypeOf(t).constructor;return new class extends r{compile(i){const n=i.variable(),a=`out_${e}_${n}`;if(Ki(i)){const n=ll(e,1,r.typeName),s=function(e,t){if("inverse"!==e)return;switch(t){case"mat2":return cl;case"mat3":return ul;case"mat4":return dl;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 Jo(e){return Xo("transpose",e)}function Qo(e){return ol(Ln,"length",e)}function el(e){return Xo("normalize",e)}function tl(e){return Xo("exp2",e)}function rl(e){return Xo("sqrt",e)}function il(e){return Xo("inversesqrt",e)}function nl(e){return Xo("abs",e)}function al(e){return Xo("dFdx",e)}function sl(e){return Xo("dFdy",e)}function ol(e,t,...r){return new class extends e{compile(i){const n=r.map(e=>i.get("number"==typeof e?Xi(e):e)),a=i.variable(),s=`out_${t}_${a}`;if(Ki(i)){const a="mod"===t?`(${n[0]} - ${n[1]} * floor(${n[0]} / ${n[1]}))`:`${ll(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 ll(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 cl="\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",ul="\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",dl="\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 hl(e,t,r){return ol(e instanceof Is?Is:e instanceof Vs?Vs:e instanceof Pa?Pa:e instanceof ua?ua:e instanceof $n?$n:Ln,"mix",e,t,r)}function pl(e,t,r){return ol(Object.getPrototypeOf(r).constructor,"smoothstep",e,t,r)}function fl(e,t){return ol(Object.getPrototypeOf(e).constructor,"pow",e,t)}function ml(e,t){return ol(Object.getPrototypeOf(e).constructor,"max",e,t)}function gl(e,t){return ol(Object.getPrototypeOf(e).constructor,"min",e,t)}function vl(e,t){return ol(Ln,"dot",e,t)}function xl(e,t){return ol(Object.getPrototypeOf(e).constructor,"cross",e,t)}function wl(e,t){return new yl(e,Ji(t))}function bl(e,t,r){return e instanceof io?new Sl(e,t,Ji(r)):new Cl(e,t,Ji(r))}var yl=class extends Jn{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 Ki(e)?{chunk:e.local("ivec2",t,`vec2<i32>(textureDimensions(${r}Texture, ${i}))`),out:t}:{chunk:`ivec2 ${t} = textureSize(${r}, ${i});`,out:t}}},Sl=class extends Is{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 Ki(e)?{chunk:e.local("vec4",t,`textureLoad(${r}Texture, ${i}, ${n})`),out:t}:{chunk:`vec4 ${t} = texelFetch(${r}, ${i}, ${n});`,out:t}}},Cl=class extends Oa{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 Ki(e)?{chunk:e.local("uvec4",t,`textureLoad(${r}Texture, ${i}, ${n})`),out:t}:{chunk:`uvec4 ${t} = texelFetch(${r}, ${i}, ${n});`,out:t}}};function Ml(e){return t=e,r=Xi(0),i=Xi(1),ol(Object.getPrototypeOf(t).constructor,"clamp",t,r,i);var t,r,i}var Pl=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}},Bl=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}},Dl=class extends Vo{externalBindings;textureBindings;vertexAttributeBindings;getMain(){return this.chunks.join("\n")}isWgslCompiler=!0;wgslDefinitions=[];uniqueWgslDefinitions=new Set;loopIndices=[];vertexAttributes=new Map;rendererVertexPosition="input.position";rendererVertexNormal="input.normal";constructor(e={},t=new Pl,r=new Bl(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=Tl(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=Tl(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=Tl(i);return this.textureSampleTypes.set(n,!0===r.isDepthTexture?"depth":"float"),{out:n}}getTextureSampleType(e){return this.textureSampleTypes.get(e)??"float"}};function Tl(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}var Il=/\b(?:(?:attribute|varying|uniform|texture2D|gl_Position|#if|#ifdef|#endif|float\s*\(|vec[234]\s*\(|mat[234]\s*\()\b|(?:float|vec[234])\s+[A-Za-z_]\w*\s*=)/;function Vl(e){if(Il.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 Ll=0,Gl=new WeakMap;function Rl(e,t,r){const i=Object.entries(e),n="tsg_function_"+ ++Ll,a={},s=[];let o=!1;const l=t.typeName;for(const[e,t]of i){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))throw new Error(`Invalid shader function parameter name "${e}".`);if(!zl(t.typeName))throw new Error(`Shader functions do not support parameter type "${t.typeName}".`)}if(!zl(l))throw new Error(`Shader functions do not support return type "${l}".`);const c=t;class u extends c{inputs;constructor(e){super(),this.inputs=e}compile(e){const c=Ki(e);for(const u of(e=>{const c=e?1:0,u=s[c];if(null!=u)return u;if(o)throw new Error("Recursive shader functions are not supported.");o=!0;const d=en.level;en.level=0;try{const o=e?new Dl:void 0,u=o??new Vo;Gl.set(u,a);const d=Object.create(null),h=i.map(([e,t],r)=>{const i=`arg${r}`,n=t;return d[e]=new class extends n{compile(e){if(Gl.get(e)!==a)throw new Error("Shader function parameters cannot escape their function body.");return{out:i}}},o?`${i}: ${o.type(t.typeName)}`:`${t.typeName} ${i}`}),p=r(d);if(!(p instanceof t))throw new Error("Shader function body returned an incompatible node type.");const f=u.get(p);if(Object.keys(u.uniformTypes).length||Object.keys(u.uniforms).length||o&&(Object.keys(o.textures).length||Object.keys(o.sceneTextures).length||Object.keys(o.graphTextures).length||o.getVertexAttributes().length||u.pars.length)||!e&&u.pars.some(e=>/^\s*(?:uniform|attribute|varying)\s+/m.test(e))||Object.keys(u.outputs).length)throw new Error("Shader functions require explicit parameters, not captured resource bindings.");const m=u.getMain(),g=o?o.getWgslDefinitions():u.pars;if(e){Vl(m),Vl(f);for(const e of g)Vl(e)}const v=o?`fn ${n}(${h.join(", ")}) -> ${o.type(l)} {\n${m}\nreturn ${f};\n}`:`${l} ${n}(${h.join(", ")}) {\n${m}\nreturn ${f};\n}`,x=[...g,v];return s[c]=x,x}finally{en.level=d,o=!1}})(c))Ki(e)?e.addWgslDefinition(u):e.addDefinition(u);const u=i.map(([t,r])=>{const i=this.inputs[t];if(!(i instanceof r))throw new Error(`Incompatible shader function argument "${t}".`);return e.get(i)}),d=`function_result_${e.variable()}`,h=`${n}(${u.join(", ")})`;return{out:d,chunk:Ki(e)?e.local(l,d,h):`${l} ${d} = ${h};`}}}return e=>new u({...e})}function zl(e){return/^(?:bool|float|int|uint|[iu]?vec[234]|mat[234])$/.test(e)}var Ul=class extends Ln{vec;component;constructor(e,t){super(),this.vec=e,this.component=t}compile(e){return{out:`${e.get(this.vec)}.${this.component}`}}};var Al=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 `}},kl=new class extends dn{compile(e){return Ki(e)?{out:"i32(rendererCsmCascadeCount())"}:{out:"CSM_CASCADES"}}},Fl=(new Ao("lightProbe",ua,9),new Ao("pointLights",class extends Al{static typeName="PointLight";position=this.get(ua,"position");color=this.get(Vs,"color");distance=this.get(Ln,"distance");decay=this.get(Ln,"decay")},new Fo("NUM_POINT_LIGHTS")),new Ao("spotLights",class extends Al{static typeName="SpotLight";position=this.get(ua,"position");direction=this.get(ua,"direction");color=this.get(Vs,"color");distance=this.get(Ln,"distance");decay=this.get(Ln,"decay");coneCos=this.get(Ln,"coneCos");penumbraCos=this.get(Ln,"penumbraCos")},new Fo("NUM_SPOT_LIGHTS")),new Ao("hemisphereLights",class extends Al{static typeName="HemisphereLight";direction=this.get(ua,"direction");skyColor=this.get(Vs,"skyColor");groundColor=this.get(Vs,"groundColor")},new Fo("NUM_HEMI_LIGHTS")),new Ao("directionalLights",class extends Al{static typeName="DirectionalLight";direction=this.get(ua,"direction");color=this.get(Vs,"color")},new Fo("NUM_DIR_LIGHTS")),new Ao("rectAreaLights",class extends Al{static typeName="RectAreaLight";color=this.get(Vs,"color");position=this.get(ua,"position");halfWidth=this.get(ua,"halfWidth");halfHeight=this.get(ua,"halfHeight")},new Fo("NUM_RECT_AREA_LIGHTS")),new vo("ltc_1"),new vo("ltc_2"),new class extends ua{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new po(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 fo("receiveShadow"),new Ao("pointLightShadows",class extends Al{static typeName="PointLightShadow";shadowBias=this.get(Ln,"shadowBias");shadowNormalBias=this.get(Ln,"shadowNormalBias");shadowRadius=this.get(Ln,"shadowRadius");shadowMapSize=this.get($n,"shadowMapSize");shadowCameraNear=this.get(Ln,"shadowCameraNear");shadowCameraFar=this.get(Ln,"shadowCameraFar")},new Fo("NUM_POINT_LIGHT_SHADOWS"))),$l=(new Ao("pointShadowMap",io,new Fo("NUM_POINT_LIGHT_SHADOWS")),new Ao("pointShadowMatrix",xs,new Fo("NUM_POINT_LIGHT_SHADOWS"))),El=new Ao("directionalLightShadows",class extends Al{static typeName="DirectionalLightShadow";shadowBias=this.get(Ln,"shadowBias");shadowNormalBias=this.get(Ln,"shadowNormalBias");shadowRadius=this.get(Ln,"shadowRadius");shadowMapSize=this.get($n,"shadowMapSize")},new Fo("NUM_DIR_LIGHT_SHADOWS")),Ol=(new Ao("directionalShadowMap",io,new Fo("NUM_DIR_LIGHT_SHADOWS")),new Ao("directionalShadowMatrix",xs,new Fo("NUM_DIR_LIGHT_SHADOWS"))),_l=new Ao("spotLightShadows",class extends Al{static typeName="SpotLightShadow";shadowBias=this.get(Ln,"shadowBias");shadowNormalBias=this.get(Ln,"shadowNormalBias");shadowRadius=this.get(Ln,"shadowRadius");shadowMapSize=this.get($n,"shadowMapSize")},new Fo("NUM_SPOT_LIGHT_SHADOWS")),jl=(new Ao("spotShadowMap",io,new Fo("NUM_SPOT_LIGHT_SHADOWS")),new Ao("spotShadowMatrix",xs,new Fo("NUM_SPOT_LIGHT_SHADOWS")));new Ao("CSM_cascades",$n,kl);import*as Nl from"three";import{ShaderMaterial as Wl,UniformsUtils as Hl}from"three";function ql(e,t,r,i){return new class extends e{compile(n){if(t instanceof on&&void 0!==t.bool)return t.bool?{out:n.get(r)}:{out:n.get(i)};const a=`select_out_${n.variable()}`;return Ki(n)?{chunk:n.local(e.typeName,a,`select(${n.get(i)}, ${n.get(r)}, ${n.get(t)})`),out:a}:{chunk:`${e.typeName} ${a}; if (${n.get(t)}) { ${a} = ${n.get(r)}; } else { ${a} = ${n.get(i)}; }`,out:a}}}}var Kl=(e,t,r)=>{if(t instanceof sn&&r instanceof sn)return ql(sn,e,t,r);if(t instanceof Ln&&r instanceof Ln)return ql(Ln,e,t,r);if(t instanceof $n&&r instanceof $n)return ql($n,e,t,r);if(t instanceof ua&&r instanceof ua)return ql(ua,e,t,r);if(t instanceof Pa&&r instanceof Pa)return ql(Pa,e,t,r);if(t instanceof Xa&&r instanceof Xa)return ql(Xa,e,t,r);if(t instanceof ss&&r instanceof ss)return ql(ss,e,t,r);if(t instanceof xs&&r instanceof xs)return ql(xs,e,t,r);throw new Error("Can not select on type of "+t+" and "+r)};function Zl(e,t,r){return new class extends Object.getPrototypeOf(t).constructor{compile(i){if(Ki(i))return{out:i.get(t)};const n=`select_out_${i.variable()}`,a=t.constructor.typeName,s=i.forceAppend;i.forceAppend=!0;const o=en.level;en.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 `),en.level=o,i.forceAppend=s,{out:n}}}}var Yl=new vo("batchingTexture",void 0,"USE_BATCHING"),Xl=new class extends no{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new po(t):void 0}get value(){return this.currentValue}set value(e){this.currentValue=e,null!=this.binding&&(this.binding.value=e)}compile(e){return Ki(e)?e.defineTexture(this.name,this.value):e.defineUniform("usampler2D",this.name,this.value,this.ifdef,this.binding)}}("batchingIdTexture",void 0,"USE_BATCHING"),Jl=(new vo("batchingColorTexture",void 0,"USE_BATCHING"),class extends Ln{drawId;constructor(e){super(),this.drawId=e}compile(e){if(Ki(e))return{out:`f32(${e.get(this.drawId)})`};const t=wl(Xl,0).x,r=this.drawId.mod(t),i=this.drawId.divide(t);return{out:e.get(Xi(bl(Xl,Co(r,i),0).x))}}}),Ql=new class extends dn{compile(e){return Ki(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 ec=function(e){const t=wl(Yl,0).x,r=Ji(e).multiply(4),i=r.mod(t),n=r.divide(t);return To(bl(Yl,Co(i,n),0),bl(Yl,Co(i.add(1),n),0),bl(Yl,Co(i.add(2),n),0),bl(Yl,Co(i.add(3),n),0))}(new Jl(Ql)),tc=new go("bindMatrix",void 0,"USE_SKINNING"),rc=new go("bindMatrixInverse",void 0,"USE_SKINNING"),ic=new vo("boneTexture",void 0,"USE_SKINNING"),nc=class extends xs{index;constructor(e){super(),this.index=e}compile(e){if(Ki(e))throw new Error("WebGPU skinning must use the renderer-owned skinning path.");const t=`tsgSkinningBoneMatrix(${e.get(ic)}, ${e.get(this.index)})`,r=`bone_matrix_${e.variable()}`;return{out:r,pars:"\nmat4 tsgSkinningBoneMatrix(sampler2D bones, float index) {\n int size = textureSize(bones, 0).x;\n int j = int(index) * 4;\n int x = j % size;\n int y = j / size;\n return mat4(\n texelFetch(bones, ivec2(x, y), 0),\n texelFetch(bones, ivec2(x + 1, y), 0),\n texelFetch(bones, ivec2(x + 2, y), 0),\n texelFetch(bones, ivec2(x + 3, y), 0)\n );\n}",chunk:`mat4 ${r} = ${t};`}}},ac=new Eo("skinIndex"),sc=new Eo("skinWeight"),oc=new nc(ac.x),lc=new nc(ac.y),cc=new nc(ac.z),uc=new nc(ac.w),dc=Bo(0,0,0,0),hc={boneX:xs,boneY:xs,boneZ:xs,boneW:xs,weights:Pa,bind:xs,inverseBind:xs},pc={boneX:oc,boneY:lc,boneZ:cc,boneW:uc,weights:sc,bind:tc,inverseBind:rc},fc=Rl(hc,xs,e=>{let t=To(dc,dc,dc,dc);return t=t.add(e.boneX.multiplyScalar(e.weights.x)),t=t.add(e.boneY.multiplyScalar(e.weights.y)),t=t.add(e.boneZ.multiplyScalar(e.weights.z)),t=t.add(e.boneW.multiplyScalar(e.weights.w)),e.inverseBind.multiply(t).multiply(e.bind)})(pc);var mc=Rl({...hc,position:Pa},Pa,e=>{const t=e.bind.multiplyVec(e.position),r=dc.add(e.boneX.multiplyVec(t).multiplyScalar(e.weights.x)).add(e.boneY.multiplyVec(t).multiplyScalar(e.weights.y)).add(e.boneZ.multiplyVec(t).multiplyScalar(e.weights.z)).add(e.boneW.multiplyVec(t).multiplyScalar(e.weights.w));return e.inverseBind.multiplyVec(r)}),gc=new Oo("vertexTransform"),vc=Yo.instanceMatrix.multiplyVec(gc.multiplyVec(Sc(Zo.position)));vc=Zl("USE_SKINNING",vc,e=>{return t=e,mc({...pc,position:t});var t}),vc=Zl("USE_BATCHING",vc,e=>ec.multiplyVec(e));var xc,wc=Yo.modelViewMatrix.multiplyVec(vc),bc={position:vc,mvPosition:wc,worldPosition:Yo.modelMatrix.multiplyVec(vc).xyz,normal:el(Yo.normalMatrix.multiplyVec(Jo((xc=gc,Xo("inverse",xc))).multiplyVec(Sc(Zl("USE_INSTANCING",Zl("USE_BATCHING",Zl("USE_SKINNING",Zo.normal,e=>{return t=Zo.normal,fc.multiplyVec(Bo(t,0)).xyz;var t}),e=>{const t=Do(ec);return t.multiplyVec(e.divide(Po(vl(t.col(0),t.col(0)),vl(t.col(1),t.col(1)),vl(t.col(2),t.col(2)))))}),e=>{const t=Do(new Oo("instanceMatrix"));return t.multiplyVec(e.divide(Po(vl(t.col(0),t.col(0)),vl(t.col(1),t.col(1)),vl(t.col(2),t.col(2)))))}),1)).xyz)),viewDir:el(yo(wc.xyz))},yc={position:new wo(bc.position),mvPosition:new wo(bc.mvPosition),normal:el(new xo(bc.normal)),worldPosition:new xo(bc.worldPosition),viewDir:new xo(bc.viewDir)};function Sc(e,t=1){return new Da(new Ul(e,"x"),function(e){return new Ul(e,"y")}(e),function(e){return new Ul(e,"z")}(e),new Rn(t))}new ws(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),function(e,t=1){if(e instanceof ua)return new Ls(e.x,e.y,e.z,Xi(t));if(e instanceof Pa)return new Ls(e.x,e.y,e.z,null!=t?Xi(t):e.w);const r=new Fi(e);new Ls(Xi(r.r),Xi(r.g),Xi(r.b),Xi(t))}(0);var Cc=new mo("cameraNear"),Mc=new mo("shadowFar");new fo("receiveShadow",!1),Xi(1e-6);Rl({lightDistance:Ln,cutoffDistance:Ln,decayExponent:Ln},Ln,e=>function(e,t,r){const i=Xi(1).divide(ml(fl(e,r),Xi(.01)));return Kl(t.gt(Xi(0)),i.multiply(fl(Ml(Xi(1).subtract(fl(e.divide(t),Xi(4)))),Xi(2))),i)}(e.lightDistance,e.cutoffDistance,e.decayExponent));var Pc=Xi(.3183098861837907),Bc=yc.mvPosition.z.multiply(Xi(-1)).divide(Mc.subtract(Cc)),Dc=bc.mvPosition.z.multiply(Xi(-1)).divide(Mc.subtract(Cc)),Tc=class extends Ln{glslDepth;fragment;constructor(e,t){super(),this.glslDepth=e,this.fragment=t}compile(e){if(Ki(e)){return{out:`-(rendererCamera.view * vec4<f32>(${this.fragment&&Zi(e)?"input.worldPosition":`rendererWorldPosition(${e.getRendererVertexPosition()}, input.instanceIndex).xyz`}, 1.0)).z / max(rendererCameraFar() - rendererCameraNear(), 0.0001)`}}return{out:e.get(this.glslDepth)}}};new Tc(Bc,!0),new Tc(Dc,!1),Xi(1);import{Matrix3 as Ic}from"three";var Vc=Xi(1),Lc=Xi(-2),Gc=Xi(.8),Rc=Xi(-1),zc=Xi(.4),Uc=Xi(2),Ac=Xi(.305),kc=Xi(3),Fc=Xi(.21),$c=Xi(4);function Ec(e){return Kl(e.gte(Gc),Vc.subtract(e).multiply(Rc.subtract(Lc)).divide(Vc.subtract(Gc)).add(Lc),Kl(e.gte(zc),Gc.subtract(e).multiply(Uc.subtract(Rc)).divide(Gc.subtract(zc)).add(Rc),Kl(e.gte(Ac),zc.subtract(e).multiply(kc.subtract(Uc)).divide(zc.subtract(Ac)).add(Uc),Kl(e.gte(Fc),Ac.subtract(e).multiply($c.subtract(kc)).divide(Ac.subtract(Fc)).add(kc),Xi(-2).multiply(function(e){return Xo("log2",e)}(Xi(1.16).multiply(e)))))))}Rl({roughness:Ln},Ln,({roughness:e})=>Ec(e));function Oc(e,t){const r=vl(e,t),i=Xi(.8543985).add(Xi(.4965155).add(Xi(.0145206).multiply(nl(r))).multiply(nl(r))),n=Xi(3.417594).add(Xi(4.1616724).add(nl(r)).multiply(nl(r))),a=i.divide(n),s=Kl(r.gt(0),a,Xi(.5).multiply(il(ml(Xi(1).subtract(r.multiply(r)),Xi(1e-7)))).subtract(a));return xl(e,t).multiplyScalar(s)}function _c(e,t,r,i,n){const a=xl(n[1].subtract(n[0]),n[3].subtract(n[0])),s=el(t.subtract(e.multiplyScalar(vl(t,e)))),o=yo(xl(e,s)),l=i.multiply(Jo(Do(s,o,e))),c=n.map(e=>l.multiplyVec(e.subtract(r))).map(e=>el(e));let u=Oc(c[0],c[1]);u=u.add(Oc(c[1],c[2])),u=u.add(Oc(c[2],c[3])),u=u.add(Oc(c[3],c[0]));const d=function(e){const t=Qo(e);return ml(t.multiply(t).add(e.z).divide(t.add(1)),Xi(0))}(u);return Kl(vl(a,r.subtract(n[0])).lt(0),Xi(0),d)}Rl({normal:ua,view:ua,roughness:Ln},$n,e=>function(e,t,r){const i=Xi(64),n=i.subtract(1).divide(i),a=Xi(.5).divide(i),s=Ml(vl(e,t));return Mo(r,rl(Xi(1).subtract(s))).multiplyScalar(n).addScalar(a)}(e.normal,e.view,e.roughness)),Rl({normal:ua,view:ua,position:ua,inverse:ss,corner0:ua,corner1:ua,corner2:ua,corner3:ua},Ln,e=>_c(e.normal,e.view,e.position,e.inverse,[e.corner0,e.corner1,e.corner2,e.corner3]));import{Color as jc,ColorManagement as Nc,HalfFloatType as Wc,LinearMipmapLinearFilter as Hc,NoToneMapping as qc,UnsignedByteType as Kc,Vector2 as Zc,WebGLRenderTarget as Yc}from"three";Xc=Po(Qo(Yo.modelMatrix.col(0).xyz),Qo(Yo.modelMatrix.col(1).xyz),Qo(Yo.modelMatrix.col(2).xyz)),new class extends Object.getPrototypeOf(Xc).constructor{compile(e){if(e instanceof Lo||Zi(e))return e.defineVarying(Xc.constructor.typeName,Xc);throw new Error("A varying can not be defined as input to another varying.")}},Po(0,0,0);var Xc,Jc=Po(1,1,1),Qc=Xi(1),eu=Xi(0),tu=Xi(1e-6);function ru(e){return e.multiplyScalar(il(ml(vl(e,e),tu)))}new mo("envMapIntensity",1),new class extends ss{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new po(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 Ic),new vo("envMap"),Rl({viewDir:ua,normal:ua,roughness:Ln},ua,({viewDir:e,normal:t,roughness:r})=>ru(hl(function(e,t){return ol(Object.getPrototypeOf(e).constructor,"reflect",e,t)}(yo(e),t),t,r.multiply(r))));var iu=Yo.modelMatrix.multiplyVec(bc.position),nu=ru(Bo(bc.normal,0).multiplyMat(Yo.viewMatrix).xyz),au=Fl.map((e,t)=>{const r=iu.add(Bo(nu.multiplyScalar(e.shadowNormalBias),0));return $l.get(t).multiplyVec(r)}),su=(bo(au),_l.map((e,t)=>{const r=iu.add(Bo(nu.multiplyScalar(e.shadowNormalBias),0));return jl.get(t).multiplyVec(r)})),ou=(bo(su),El.map((e,t)=>{const r=iu.add(Bo(nu.multiplyScalar(e.shadowNormalBias),0));return Ol.get(t).multiplyVec(r)}));bo(ou);function lu(e){return e.multiply(e)}function cu(e,t,r,i,n){const a=ru(e.add(t)),s=Ml(vl(r,e)),o=Ml(vl(r,t)),l=function(e,t){const r=lu(e),i=Qc.divide(r),n=lu(t),a=ml(Qc.subtract(n),Xi(.0078125));return Xi(2).add(i).multiply(fl(a,i.multiply(.5))).divide(Xi(2*Math.PI))}(n,Ml(vl(r,a))),c=function(e,t){return Ml(Qc.divide(Xi(4).multiply(t.add(e).subtract(t.multiply(e)))))}(o,s);return i.multiplyScalar(l.multiply(c))}Rl({lightDir:ua,viewDir:ua,normal:ua,sheenColor:ua,sheenRoughness:Ln},ua,e=>cu(e.lightDir,e.viewDir,e.normal,e.sheenColor,e.sheenRoughness));function uu(e,t,r){const i=Ml(vl(e,t)),n=lu(r),a=Kl(r.lt(.25),Xi(-339.2).multiply(n).add(Xi(161.4).multiply(r)).subtract(Xi(25.9)),Xi(-8.48).multiply(n).add(Xi(14.3).multiply(r)).subtract(Xi(9.95))),s=Kl(r.lt(.25),Xi(44).multiply(n).subtract(Xi(23.7).multiply(r)).add(Xi(3.26)),Xi(1.97).multiply(n).subtract(Xi(3.27).multiply(r)).add(Xi(.72))),o=function(e){return Xo("exp",e)}(a.multiply(i).add(s)).add(Kl(r.lt(.25),eu,Xi(.1).multiply(r.subtract(.25))));return Ml(o.multiply(Pc))}Rl({normal:ua,viewDir:ua,roughness:Ln},Ln,e=>uu(e.normal,e.viewDir,e.roughness));Rl({eyePos:ua,surfNorm:ua,uv:$n},ss,e=>function(e,t,r){const i=Po(al(e.x),al(e.y),al(e.z)),n=Po(sl(e.x),sl(e.y),sl(e.z)),a=al(r),s=sl(r),o=t,l=xl(n,o),c=xl(o,i),u=l.multiplyScalar(a.x).add(c.multiplyScalar(s.x)),d=l.multiplyScalar(a.y).add(c.multiplyScalar(s.y)),h=ml(vl(u,u),vl(d,d)),p=Kl(h.equals(eu),eu,il(h));return Do(u.multiplyScalar(p),d.multiplyScalar(p),o)}(e.eyePos,e.surfNorm,e.uv));function du(e,t,r,i){const n=i.specularColor,a=i.specularF90,s=lu(i.roughness),o=ru(e.add(t)),l=Ml(vl(r,e)),c=Ml(vl(r,t)),u=Ml(vl(r,o)),d=function(e,t,r){const i=tl(Xi(-5.55473).multiply(r).subtract(Xi(6.98316)).multiply(r));return e.multiplyScalar(Qc.subtract(i)).addScalar(t.multiply(i))}(n,a,Ml(vl(t,o))),h=i.iridescence&&i.iridescenceFresnel?hl(d,i.iridescenceFresnel,i.iridescence):d;let p=function(e,t,r){const i=lu(e),n=Qc.subtract(i),a=t.multiply(rl(n.multiply(lu(r)).add(i))),s=r.multiply(rl(n.multiply(lu(t)).add(i)));return Xi(.5).divide(ml(a.add(s),tu))}(s,l,c),f=function(e,t){const r=lu(e),i=lu(t).multiply(r.subtract(Qc)).add(Qc);return Pc.multiply(r).divide(lu(i))}(s,u);if(null!=i.anisotropy&&null!=i.alphaT&&null!=i.anisotropyT&&null!=i.anisotropyB){const r=vl(i.anisotropyT,e),n=vl(i.anisotropyT,t),a=vl(i.anisotropyT,o),d=vl(i.anisotropyB,e),h=vl(i.anisotropyB,t),m=vl(i.anisotropyB,o);p=function(e,t,r,i,n,a,s,o){const l=o.multiply(Qo(Po(e.multiply(r),t.multiply(i),s))),c=s.multiply(Qo(Po(e.multiply(n),t.multiply(a),o)));return Ml(Xi(.5).divide(l.add(c)))}(i.alphaT,s,n,h,r,d,c,l),f=function(e,t,r,i,n){const a=e.multiply(t),s=Po(t.multiply(i),e.multiply(n),a.multiply(r)),o=vl(s,s),l=a.divide(o);return Pc.multiply(a).multiply(lu(l))}(i.alphaT,s,u,a,m)}return h.multiplyScalar(p.multiply(f))}var hu={lightDir:ua,viewDir:ua,normal:ua,f0:ua,f90:Ln,roughness:Ln,iridescence:Ln,iridescenceFresnel:ua,anisotropy:Ln,alphaT:Ln,anisotropyT:ua,anisotropyB:ua},pu=([0,1,2,3].map(e=>Rl(hu,ua,t=>du(t.lightDir,t.viewDir,t.normal,{specularColor:t.f0,specularF90:t.f90,roughness:t.roughness,iridescence:1&e?t.iridescence:void 0,iridescenceFresnel:1&e?t.iridescenceFresnel:void 0,anisotropy:2&e?t.anisotropy:null,alphaT:2&e?t.alphaT:null,anisotropyT:2&e?t.anisotropyT:null,anisotropyB:2&e?t.anisotropyB:null}))),Rl({viewDir:ua,normal:ua,roughness:Ln,bitangent:ua,anisotropy:Ln},ua,({viewDir:e,normal:t,roughness:r,bitangent:i,anisotropy:n})=>{let a=xl(i,e);return a=ru(xl(a,i)),a=ru(hl(a,t,lu(lu(Qc.subtract(n.multiply(Qc.subtract(r))))))),a}),Po(1),Po(1),So(0),So(0),yc.normal,Mo(1,0),Rl({geometricNormal:ua,roughnessFactor:Ln},Ln,({geometricNormal:e,roughnessFactor:t})=>{const r=ml(nl(al(e)),nl(sl(e))),i=ml(ml(r.x,r.y),r.z);return gl(ml(t,Xi(.0525)).add(i),Qc)}),Bo(-1,-.0275,-.572,.022)),fu=Bo(1,.0425,1.04,-.04);Rl({normal:ua,viewDir:ua,roughness:Ln},$n,e=>function(e,t,r){const i=Ml(vl(e,t)),n=r.multiplyVec4(pu).add(fu),a=gl(n.x.multiply(n.x),tl(Xi(-9.28).multiply(i))).multiply(n.x).add(n.y);return Mo(-1.04,1.04).multiplyScalar(a).add(Mo(n.z,n.w))}(e.normal,e.viewDir,e.roughness)),Rl({Fr:ua,singleScatter:ua,Ems:Ln},ua,({Fr:e,singleScatter:t,Ems:r})=>{const i=e.add(Jc.subtract(e).multiplyScalar(.047619));return t.multiply(i).divide(Jc.subtract(r.multiplyVec3(i))).multiplyScalar(r)}),new class extends ua{glslValue;constructor(e){super(),this.glslValue=e}compile(e){return Ki(e)?Zi(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)}}}(yc.normal);import{Matrix3 as mu}from"three";var gu=Xi(1),vu=Xi(0),xu=Xi(1e-6);function wu(e){return e.multiply(e)}Rl({outgoingLight:ua,diffuseColor:ua,eyeBrightness:Ln,eyeIrisColor:ua,irisMask:Ln,eyeLowerLightMask:Ln,eyeIrisGlow:Ln,eyeHighlightColor:ua,eyeHighlightMask:Ln,eyeHighlightStrength:Ln,eyeMask:Ln},ua,e=>{const t=e.outgoingLight.multiplyScalar(.35).add(e.diffuseColor.multiplyScalar(e.eyeBrightness.multiply(.65))),r=e.eyeIrisColor.multiplyScalar(e.irisMask.multiply(e.eyeLowerLightMask).multiply(e.eyeIrisGlow)),i=e.eyeHighlightColor.multiplyScalar(e.eyeHighlightMask.multiply(e.eyeHighlightStrength));return hl(e.outgoingLight,t,e.eyeMask).add(r).add(i)}),Rl({dotNV:Ln,rimPower:Ln,rimThreshold:Ln,rimSoftness:Ln,rimColor:ua,rimMask:Ln,rimStrength:Ln},ua,e=>{const t=fl(gu.subtract(e.dotNV),e.rimPower),r=pl(e.rimThreshold.subtract(e.rimSoftness),e.rimThreshold.add(e.rimSoftness),t);return e.rimColor.multiplyScalar(r.multiply(e.rimMask).multiply(e.rimStrength))});var bu=Rl({lightDirection:ua,normal:ua,viewDir:ua,alpha2:Ln,dotNV:Ln,specularThreshold:Ln,specularSoftness:Ln,specularToonness:Ln,specularIntensity:Ln},ua,e=>{const t=el(e.lightDirection.add(e.viewDir)),r=Ml(vl(e.normal,e.lightDirection)),i=Ml(vl(e.normal,t)),n=Ml(vl(e.viewDir,t)),a=wu(i).multiply(e.alpha2.subtract(gu)).add(gu),s=Xi(Pc).multiply(e.alpha2).divide(ml(wu(a),xu)),o=Xi(.5).divide(ml(r.multiply(rl(gu.subtract(e.alpha2).multiply(wu(e.dotNV)).add(e.alpha2))).add(e.dotNV.multiply(rl(gu.subtract(e.alpha2).multiply(wu(r)).add(e.alpha2)))),xu)),l=tl(Xi(-5.55473).multiply(n).subtract(6.98316).multiply(n)),c=Po(.04).multiplyScalar(gu.subtract(l)).addScalar(l),u=c.multiplyScalar(s.multiply(o).multiply(r)),d=ml(ml(u.x,u.y),u.z),h=pl(e.specularThreshold.subtract(e.specularSoftness),e.specularThreshold.add(e.specularSoftness),d);return hl(u,c.multiplyScalar(h),e.specularToonness).multiplyScalar(e.specularIntensity)});Yo.modelMatrix.multiplyVec(bc.position),el(Bo(bc.normal,0).multiplyMat(Yo.viewMatrix).xyz),Rl({lightDirection:ua,normal:ua,viewDir:ua,fw:Ln,skinShadowTint:ua,rim:ua,alpha2:Ln,dotNV:Ln,backscatterPower:Ln,backscatterStrength:Ln,diffuseColor:ua,faceMask:Ln,faceShadow:Ln,faceShadowOffset:Ln,faceShadowSoftness:Ln,faceShadowStrength:Ln,shadowSoftness:Ln,shadowThreshold:Ln,skinMask:Ln,subsurfaceColor:ua,subsurfaceStrength:Ln,subsurfaceWrap:Ln,thickness:Ln,specularThreshold:Ln,specularSoftness:Ln,specularToonness:Ln,specularIntensity:Ln},ua,e=>{const t=vl(e.normal,e.lightDirection),r=Ml(t.add(e.subsurfaceWrap).divide(gu.add(e.subsurfaceWrap))),i=hl(t,r,e.skinMask),n=hl(pl(e.shadowThreshold.subtract(e.shadowSoftness).subtract(e.fw),e.shadowThreshold.add(e.shadowSoftness).add(e.fw),i),pl(e.faceShadow.subtract(e.faceShadowSoftness),e.faceShadow.add(e.faceShadowSoftness),t.multiply(.5).add(.5).add(e.faceShadowOffset)),e.faceMask.multiply(e.faceShadowStrength)),a=hl(e.diffuseColor.multiply(e.skinShadowTint),e.diffuseColor,n).multiplyScalar(Pc),s=ml(r.subtract(Ml(t)),vu).multiply(e.skinMask).multiply(e.subsurfaceStrength),o=fl(Ml(vl(e.viewDir,yo(e.lightDirection))),e.backscatterPower).multiply(Ml(vu.subtract(t))).multiply(e.skinMask).multiply(e.thickness).multiply(e.subsurfaceStrength).multiply(e.backscatterStrength);return a.add(bu({lightDirection:e.lightDirection,normal:e.normal,viewDir:e.viewDir,alpha2:e.alpha2,dotNV:e.dotNV,specularThreshold:e.specularThreshold,specularSoftness:e.specularSoftness,specularToonness:e.specularToonness,specularIntensity:e.specularIntensity})).add(e.subsurfaceColor.multiplyScalar(s)).add(e.subsurfaceColor.multiplyScalar(o)).add(e.rim.multiplyScalar(pl(Xi(-.25),Xi(.25),t)))}),So(0),So(0),Xi(1),yc.normal,So(8950960),So(16740429),So(9424895),So(16777215),So(12179967);Rl({eyePos:ua,surfNorm:ua,mapN:ua,faceDirection:Ln,uv:$n},ua,e=>function(e,t,r,i,n){const a=Po(al(e.x),al(e.y),al(e.z)),s=Po(sl(e.x),sl(e.y),sl(e.z)),o=al(n),l=sl(n),c=t,u=xl(s,c),d=xl(c,a),h=u.multiplyScalar(o.x).add(d.multiplyScalar(l.x)),p=u.multiplyScalar(o.y).add(d.multiplyScalar(l.y)),f=ml(vl(h,h),vl(p,p)),m=Xi(0),g=Kl(f.equals(m),m,i.multiply(il(f)));return el(h.multiplyScalar(r.x.multiply(g)).add(p.multiplyScalar(r.y.multiply(g))).add(c.multiplyScalar(r.z)))}(e.eyePos,e.surfNorm,e.mapN,e.faceDirection,e.uv));var yu={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}))`}}};yu.arrays.pointLights;var Su=255/256,Cu=[1,256,65536,16777216],Mu=[Su,1/Cu[1]],Pu=(Mo(Mu[0],Mu[1]),[Su/Cu[0],Su/Cu[1],1/Cu[2]]),Bu=(Po(Pu[0],Pu[1],Pu[2]),[Su/Cu[0],Su/Cu[1],Su/Cu[2],1/Cu[3]]),Du=(Bo(Bu[0],Bu[1],Bu[2],Bu[3]),class extends Ln{constructor(e){super(),this.name=e}name;compile(){return{out:this.name}}}),Tu=new Du("radius"),Iu=new Du("scale"),Vu=new Du("threshold"),Lu=new Du("boundary"),Gu=new Du("maxDistance"),Ru=new Du("distanceSquared"),zu=Gu.add(Tu),Uu=function(e){const t=new Dl,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 Vl(i),Vl(n),{expression:r,statements:i,definitions:n}}(Vu.lte(0).or(Tu.multiply(Iu).gte(Vu.multiply(Lu))).and(Gu.lte(0).or(Ru.lte(zu.multiply(zu))))),Au=`\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${`${Uu.definitions}\nfn shadowDetailVisible(radius: f32, scale: f32, threshold: f32, boundary: f32,\n maxDistance: f32, distanceSquared: f32) -> bool {\n ${Uu.statements}\n return ${Uu.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`,ku="\n// Roughly eight f32 ULPs near depth 1. A 0.001 bias spans hundreds of\n// world units at distance with conventional perspective depth.\nconst OCCLUSION_DEPTH_BIAS: f32 = 0.000001;\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 nearestW = clip.w - radius * length(rowW);\n if (nearestW <= 0.0001) { return 0.0; }\n let depth = clip.z / clip.w;\n // For any sphere offset u, depth(u) - depth(center) equals\n // dot(rowZ - depth * rowW, u) / (clip.w + dot(rowW, u)).\n // Bound that difference, preserving the correlation of clip Z and W.\n // Independently minimizing Z and maximizing W grossly underestimates\n // distant depths and makes hidden buildings pass the occlusion test.\n let depthRadius = radius * length(rowZ - depth * rowW) / nearestW;\n return max(0.0, depth - depthRadius);\n}\n",Fu=`\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\n${ku}\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 + OCCLUSION_DEPTH_BIAS;\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`,$u=`\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\n${ku}\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 + OCCLUSION_DEPTH_BIAS;\n}\n\nfn cullInstance(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// Only sets fitting in one workgroup may use fused clear/cull/build.\nstruct CompactIndirectArgs {\n indexCount: u32,\n instanceCount: u32,\n firstIndex: u32,\n baseVertex: i32,\n firstInstance: u32,\n};\n@group(0) @binding(10) var<storage, read_write> compactIndirectArgs: array<CompactIndirectArgs>;\n@group(0) @binding(11) var<storage, read_write> compactPostIndirectArgs: array<CompactIndirectArgs>;\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let compact = (visibilityParams.flags & 8u) != 0u;\n let postpass = (visibilityParams.flags & 4u) != 0u;\n let index = globalId.x;\n if (compact && !postpass) {\n if (index < visibilityParams.drawCount) {\n atomicStore(&visibleCounts[index], 0u);\n atomicStore(&postVisibleCounts[index], 0u);\n }\n if (index < visibilityParams.instanceCount) {\n atomicStore(&visibleInstanceMask[index], atomicLoad(&visibleInstanceMask[index]) & 4u);\n }\n }\n if (compact) { storageBarrier(); }\n cullInstance(globalId);\n if (compact) {\n storageBarrier();\n if (index < visibilityParams.drawCount) {\n let primaryCount = atomicLoad(&visibleCounts[index]);\n let postCount = atomicLoad(&postVisibleCounts[index]);\n compactIndirectArgs[index].instanceCount = primaryCount + postCount;\n if (postpass) {\n compactPostIndirectArgs[index].instanceCount = postCount;\n compactPostIndirectArgs[index].firstInstance = compactIndirectArgs[index].firstInstance + primaryCount;\n }\n }\n }\n}\n`,Eu="\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",Ou="\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",_u="\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",ju="\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",Nu=`\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${ju}\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`,Wu=`\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${ju}\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`,Hu=`\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${ju}\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`,qu="\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 Ku(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 Zu=Ku(!1),Yu=Ku(!0),Xu=class{enabled=!0;available=!1;sets=new Map;device=null;layout=null;clear=null;cull=null;pipeline=null;frame=0;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=Au,n=Eu.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([N.createAsync(e,{label:"directional-shadow-clear",code:i,entryPoint:"clear",bindGroupLayoutEntries:r}),N.createAsync(e,{label:"directional-shadow-cull",code:i,bindGroupLayoutEntries:r}),_(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={materials:[],depthDrawIndices:[],materialVersion:0,preparedFrame:-1,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},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)}beginFrame(){this.frame++}prepareCascade(e,t,r,i){for(let t=0;t<6;t++){const r=e.planes[t],i=4*t;this.paramData[i]=r.normal.x,this.paramData[i+1]=r.normal.y,this.paramData[i+2]=r.normal.z,this.paramData[i+3]=r.constant}this.paramData[24]=r.x,this.paramData[25]=r.y,this.paramData[26]=r.z,this.paramData[28]=Math.max(Math.abs(t.projectionMatrix.elements[0]),Math.abs(t.projectionMatrix.elements[5]))*i}prepareSet(e,t,r){if(r.preparedFrame===this.frame)return;if(-1===r.preparedFrame){for(let e=0;e<t.draws.length;e++){const i=t.draws[e],n=i.detailCulling,a=this.eligible(i)?1:0,s=4*e;r.eligibility[e]=a,a&&(r.eligibleDrawCount++,i.castShadow&&(r.triangleCount+=Ii(i)),(i.customDepthMaterial||null!==i.material.depthVertexShader)&&r.depthDrawIndices.push(e)),r.policyData[s]=n.shadowMinScreenSize,r.policyData[s+1]=n.shadowMaxDistance,r.policyData[s+2]=i.castShadow?1:0,r.policyData[s+3]=a,r.materials[e]=null}this.device.queue.writeBuffer(r.policies,0,r.policyData)}let i=!1;for(const n of r.depthDrawIndices){const a=t.draws[n],s=a.customDepthMaterial??a.material,o=e.getDepthPassMaterialResourceForDraw(s,"directionalShadow",a,"packed-visible");r.materials[n]!==o&&(i=!0),r.materials[n]=o}i&&r.materialVersion++,r.preparedFrame=this.frame}prepare(e,t,r,i,n){if(!this.enabled||!this.available||r.instanceCount>64*this.device.limits.maxComputeWorkgroupsPerDimension)return null;const a=this.getSet(r);this.prepareSet(e,r,a);let s=a.layers.get(i);if(!s){const e=GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,t=this.buffer(`${r.label}-shadow-cull-params`,128,GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST),n=this.buffer(`${r.label}-shadow-indirect`,a.commands.byteLength,e|GPUBufferUsage.INDIRECT),o=this.buffer(`${r.label}-shadow-indices`,4*r.instanceCount,e),l=this.buffer(`${r.label}-shadow-history`,4*r.instanceCount,e);this.device.queue.writeBuffer(n,0,a.commands);const c=[t,r.instanceVisibilityResource.instanceMetadataBuffer,a.policies,n,o,l].map((e,t)=>({binding:t,resource:{buffer:e}}));s={params:t,indirect:n,indices:o,history:l,clearGroup:this.clear.createBindGroup(this.device,c),cullGroup:this.cull.createBindGroup(this.device,c),shadowGroup:this.device.createBindGroup({layout:this.layout,entries:[{binding:0,resource:{buffer:i}},{binding:1,resource:{buffer:r.instanceBuffer}},{binding:2,resource:{buffer:o}}]}),bundle:null,materials:[],eligibilityVersion:-1,materialVersion:-1,bundles:[],materialCacheKey:`directional-shadow-gpu-${a.layers.size}`},a.layers.set(i,s),r.depthMaterialResources.set(s.materialCacheKey,s.materials)}this.paramInts[29]=r.instanceCount,this.paramInts[30]=r.draws.length,this.device.queue.writeBuffer(s.params,0,this.paramData);const o=s.materialVersion!==a.materialVersion;if(o){for(let e=0;e<a.materials.length;e++)s.materials[e]=a.materials[e];s.materialVersion=a.materialVersion}s.bundle&&s.eligibilityVersion===a.eligibilityVersion&&!o||this.buildBundle(e,r,a,s);const l=n??t.beginComputePass({label:`${r.label}-directional-shadow-selection`});return l.setPipeline(this.clear.pipeline),l.setBindGroup(0,s.clearGroup),l.dispatchWorkgroups(Math.ceil(r.draws.length/64)),l.setPipeline(this.cull.pipeline),l.setBindGroup(0,s.cullGroup),l.dispatchWorkgroups(Math.ceil(r.instanceCount/64)),n||l.end(),a.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??G,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}},Ju=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}},Qu=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 j(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 ed,BackSide as td,BufferAttribute as rd,BufferGeometry as id,Color as nd,DoubleSide as ad,FrontSide as sd,InstancedBufferAttribute as od,InstancedBufferGeometry as ld,InstancedMesh as cd,MultiplyBlending as ud,Matrix4 as dd,Mesh as hd,OrthographicCamera as pd,PerspectiveCamera as fd,SkinnedMesh as md,Sphere as gd,SubtractiveBlending as vd,Vector2 as xd,Vector3 as wd,Vector4 as bd,ShaderMaterial as yd}from"three";var Sd=/^[A-Za-z_][A-Za-z0-9_]*$/;function Cd(e,t={},r={}){const i=function(e){const t=new Map;for(const[r,i]of Object.entries(e))Sd.test(r)&&!1!==i&&null!=i&&t.set(r,{name:r,parameters:null,body:Md(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=Pd(t),c=Dd(a);if(!r){s.push(c?Id(t,i,n):"");continue}const{name:u,rest:d}=r;switch(u){case"define":if(c){const t=Bd(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&&kd(d,i);a.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),s.push("");break}case"elif":{const t=Td(a,l,e+1,u);if(t.elseSeen)throw new Error(`${l}:${e+1}: #elif after #else`);const r=t.parentActive&&!t.branchTaken&&kd(d,i);t.active=r,t.branchTaken=t.branchTaken||r,s.push("");break}case"else":{const t=Td(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":Td(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 Md(e){return"boolean"==typeof e?e?"1":"0":String(e)}function Pd(e){const t=/^\s*#\s*([A-Za-z_][A-Za-z0-9_]*)(.*)$/.exec(e);return t?{name:t[1],rest:t[2]??""}:null}function Bd(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=Ad(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(!Sd.test(e))throw new Error(`${r}:${i}: invalid macro parameter "${e}"`);return t.set(a,{name:a,parameters:o,body:$d(s.slice(e+1)).trim()||"1"}),a}return t.set(a,{name:a,parameters:null,body:$d(s).trim()||"1"}),a}function Dd(e){for(const t of e)if(!t.active)return!1;return!0}function Td(e,t,r,i){const n=e[e.length-1];if(!n)throw new Error(`${t}:${r}: #${i} without matching #if`);return n}function Id(e,t,r){let i=e;for(let e=0;e<8;e+=1){const e=i;if(i=Ld(i,r),i=Vd(i,t),i===e)return i}return i}function Vd(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 Ld(e,t){if(0===t.size||!e.includes("("))return e;let r=e;for(const e of t.values())null!==e.parameters&&(r=Gd(r,e));return r}function Gd(e,t){let r="",i=0;for(;i<e.length;){const n=Rd(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=Ad(e,a);if(s<0){r+=e.slice(i);break}const o=Ud(e.slice(a+1,s));r+=e.slice(i,n),r+=zd(t,o),i=s+1}return r}function Rd(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 zd(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${Ed(n)}\\b`,"g"),a)}return r}function Ud(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 Ad(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 kd(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}($d(e));return 0!==new Fd(r,t).parseExpression()}var Fd=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 $d(e){const t=e.indexOf("//");return t>=0?e.slice(0,t):e}function Ed(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Od=/(?!\s*@invariant)\s+(?=(?:[A-Za-z_]\w*\s*:|vec4(?:\s*<\s*f32\s*>|f)\b))/y;function _d(e){return 32===e||9===e||10===e||13===e}var jd=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 Nd,HalfFloatType as Wd,LinearFilter as Hd,LinearSRGBColorSpace as qd,RGBAFormat as Kd,Texture as Zd}from"three";var Yd=[.125,.215,.35,.446,.526,.582],Xd=20,Jd=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]]}(),Qd=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=eh(r,this.equirectBindGroupLayout,ih,"pmrem-equirectangular"),this.blurPipeline=eh(r,this.blurBindGroupLayout,nh.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<Yd.length;e+=1)t.push({mip:4-e-1,size:16,sigma:Yd[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=th(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=Jd[(n.length-e-1)%Jd.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 Zd;return v.image={width:a,height:s},v.name="PMREM.cubeUv",v.mapping=Nd,v.format=Kd,v.type=Wd,v.colorSpace=qd,v.minFilter=Hd,v.magFilter=Hd,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(Xd);let i=0;for(let n=0;n<Xd;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=th(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,Xd).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 eh(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 th(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 rh="\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",ih=`${rh}\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`,nh=`${rh}\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 ah(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}function sh(e,t){const r=Object.entries(e.uniforms).map(([e,t])=>` ${ah(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=ah(e),s=gt(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=ah(e);return`@group(1) @binding(${a+r}) var<storage, read> ${i}: ${t.type};`}).join("\n")}`}function oh(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 lh(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 ch(e,t,r="packed",i=!0,n=!1,a){const s="particle"!==r&&!e.transparent&&!e.requiresLatePass(),o=sh(e,t),l=function(e){return Object.entries(e.getGraphTextureInputs()).map(([e,t],r)=>{const i=ah(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${oh("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${lh(n)}\n${o}\n${l}\n`}function uh(e=!0,t){return ch({uniforms:{},textures:{},storageBuffers:{},getGraphTextureInputs:()=>({})},void 0,"particle",e,!1,t)}function dh(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=sh(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${oh("camera"===t?"rendererCamera":"shadowCamera")}\n${lh(n)}\n${s}\n`}var hh=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)}},ph=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()}},fh=new WeakMap,mh=new WeakMap,gh=new WeakSet;function vh(e){fh.get(e)?.dispose(),fh.delete(e)}function xh(e,t){gh.has(t)||((!e.latestFrameProfile||t.profile.frameIndex>=e.latestFrameProfile.frameIndex)&&(e.latestFrameProfile=yh(t.profile)),(t.pendingGpuRead||t.pendingVisibilityRead)&&Promise.all([t.pendingGpuRead?wh(t.profile,t.pendingGpuRead):Promise.resolve(),t.pendingVisibilityRead?bh(t.profile,t.pendingVisibilityRead):Promise.resolve()]).then(()=>{if(mh.get(t)!==fh.get(e))return;const r=yh(t.profile);(!e.latestFrameProfile||r.frameIndex>=e.latestFrameProfile.frameIndex)&&(e.latestFrameProfile=r),(!e.latestCompletedFrameProfile||r.frameIndex>=e.latestCompletedFrameProfile.frameIndex)&&(e.latestCompletedFrameProfile=r)}))}async function wh(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 bh(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 yh(e){return{...e,cpuPhases:{...e.cpuPhases},passes:e.passes.map(e=>({...e})),visibility:e.visibility?{...e.visibility}:null}}import{Frustum as Sh,Matrix4 as Ch,Sphere as Mh}from"three";function Ph(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 Bh=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}},Dh=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}},Th=new WeakMap;function Ih(e){if(e.transparent)return!0;let t=Th.get(e);return void 0===t&&(t=e.alphaTest>0||/\bdiscard\b/.test(e.fragmentShader),Th.set(e,t)),t}function Vh(e){for(const t of e)if(t.customDepthMaterial||null!==t.skinning||t.material.vertexAttributes.some(e=>"instance"===e.stepMode)||null===t.material.depthVertexShader&&(Ih(t.material)||t.wireframe||!t.material.primitiveTopology.startsWith("triangle")))return!1;return!0}var Lh=new WeakMap,Gh={drawCallCount:0,triangleCount:0},Rh=new Sh,zh=new Ch,Uh=new Sh,Ah=new Ch,kh=new Mh,Fh=new WeakMap,$h=new WeakMap,Eh=k.clone();function Oh(e,t,r,i,n=0){let a=Fh.get(e);a||(a=new WeakMap,Fh.set(e,a));let s=a.get(t);s||(s={pool:[],draws:[],key:new Dh},a.set(t,s));if(!s.key.update(Ah,r,e.draws,Eh)&&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=$h.get(e);d||(d=new WeakMap,$h.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(kh.center.copy(t.boundsCenter),kh.radius=t.boundsRadius,Uh.intersectsSphere(kh))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=Ph(c,8*e,Uh,u,n.shadowMinScreenSize,n.shadowMaxDistance,0!==h[e],Eh),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 _h(e){return e.usesBatching}function jh(e){return!e.wireframe&&e.material.primitiveTopology.startsWith("triangle")}function Nh(e,t){return"pointShadow"===t?null!==e.material.pointShadowVertexShader&&null!==e.material.pointShadowFragmentShader:null!==e.material.depthVertexShader}function Wh(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()}function Hh(e){return e.instanceVisibilityResource.instanceCount<=64&&e.drawMetadataResource.count<=64}var qh=new WeakMap;function Kh(e,t){if(!(this.state.staticVisibilityClearKernel&&this.state.staticVisibilityCullKernel&&this.state.staticVisibilityIndirectBuildKernel&&this.getHiZOcclusionCullingActive()&&this.state.device))return;let r=qh.get(this);r||(r=[],qh.set(this,r)),r.length=0;for(const e of this.getCameraStaticDrawSets()){if(!e.publicSet.enabled||!this.isStaticDrawSetCameraVisible(e)||e.cpuVisibility||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)|(Hh(e)?8:0);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||Hh(e)||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;let i=!1;for(const e of r)if(!Hh(e)){i=!0;break}if("prepass"===t&&i){const t=e.beginComputePass({label:"static-temporal-visibility-clear-pass"});t.setPipeline(this.state.staticVisibilityClearKernel.pipeline);for(const e of r)Hh(e)||(t.setBindGroup(0,e.visibilityClearBindGroup),t.dispatchWorkgroups(Math.ceil(Math.max(e.drawMetadataResource.count,e.instanceVisibilityResource.instanceCount)/64)));t.end()}const n=e.beginComputePass({label:`static-temporal-visibility-${t}-cull-pass`});n.setPipeline(this.state.staticVisibilityCullKernel.pipeline);for(const e of r)n.setBindGroup(0,"prepass"===t?e.visibilityBindGroup:e.postVisibilityBindGroup),n.dispatchWorkgroups(Math.ceil(e.instanceVisibilityResource.instanceCount/64));n.end();const a=i?e.beginComputePass({label:`static-temporal-visibility-${t}-indirect-build-pass`}):null;a?.setPipeline(this.state.staticVisibilityIndirectBuildKernel.pipeline);for(const e of r)!Hh(e)&&a&&(a.setBindGroup(0,"prepass"===t?e.visibilityIndirectBuildBindGroup:e.postVisibilityIndirectBuildBindGroup),a.dispatchWorkgroups(Math.ceil(e.drawMetadataResource.count/64))),"prepass"===t?e.lastPreVisibilityFrameToken=this.staticFrameToken:e.lastVisibilityFrameToken=this.staticFrameToken;a?.end(),r.length=0}function Zh(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}},{binding:10,resource:{buffer:e.drawMetadataResource.indirectBuffer}},{binding:11,resource:{buffer:e.drawMetadataResource.postIndirectBuffer}}],`${e.label}-temporal-visibility-${t}-bind-group`);return"prepass"===t?e.visibilityBindGroup=i:e.postVisibilityBindGroup=i,e.visibilityBindGroupHizVersion=this.hizResourceVersion,i}function Yh(e,t,r,i){if(!this.state.shadowDepthPipeline||0===this.state.directionalShadowLayerViews.length)return void this.clearDirectionalShadow(e);this.directionalShadowGpu.beginFrame();let n=!1;r.camera.getWorldPosition(Eh);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),Uh.setFromProjectionMatrix(Ah.multiplyMatrices(o.projectionMatrix,o.matrixWorldInverse));const l=this.queryStaticShadowResources(Uh),c=this.getShadowCameraBuffer(t);this.writeShadowCameraBuffer(yi(o,this.shadowViewProjScratch),0,0,0,1,c,o);const u=this.getSharedShadowBindGroupForCameraBuffer(c);let d;this.directionalShadowGpu.prepareCascade(Uh,o,Eh,this.state.directionalShadowTextureSize);for(const r of l)r.publicSet.enabled&&0!==r.draws.length&&"late"!==r.drawStage&&(kh.center.copy(r.spatialBounds.boundsCenter),kh.radius=r.spatialBounds.boundsRadius,Uh.intersectsSphere(kh)&&(!d&&this.directionalShadowGpu.enabled&&this.directionalShadowGpu.available&&(d=e.beginComputePass({label:`renderer-directional-shadow-selection-${t}`})),this.directionalShadowGpu.prepare(this,e,r,c,d)));d?.end();const h=e.beginRenderPass({label:`renderer-directional-shadow-pass-${t}`,colorAttachments:[],depthStencilAttachment:{view:s,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});h.setPipeline(this.state.shadowDepthPipeline),h.setBindGroup(0,u),this.drawDepthLike(h,r.shadowDraws??[...r.gpuOpaqueDraws,...r.directOpaqueDraws],i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:u,shadowCameraBuffer:c,passKind:"directionalShadow",customDepthMode:"use"});for(const e of l){if(!e.publicSet.enabled||0===e.draws.length||"late"===e.drawStage)continue;if(kh.center.copy(e.spatialBounds.boundsCenter),kh.radius=e.spatialBounds.boundsRadius,!Uh.intersectsSphere(kh))continue;const t=this.directionalShadowGpu.submit(h,e,c,i)?this.directionalShadowGpu.sets.get(e):void 0;t?.eligibleDrawCount!==e.draws.length&&Xh.call(this,h,e,o,Oh.call(this,e,o,this.state.directionalShadowTextureSize,t?.eligibility,t?.eligibilityVersion),u,c,i)}h.end(),this.directionalShadowScheduler.commit(t)}n||this.clearDirectionalShadow(e)}function Xh(e,t,r,i,n,a,s){let o=Lh.get(t);o||(o=new WeakMap,Lh.set(t,o));let l=o.get(r);l||(l=new Bh,o.set(r,l)),l.draws.length=0,l.directDraws.length=0;let c=0;for(const e of i)e.customDepthMaterial||Nh(e,"directionalShadow")||e.hasRenderCallbacks||e.skinning||!e.indexed||e.wireframe||!jh(e)||"packed"!==this.getDrawInstanceAccessMode(e)?l.directDraws.push(e):(l.draws.push(e),c+=Ii(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});Gh.drawCallCount=0,Gh.triangleCount=0,yp.call(this,e,l.draws,Gh,{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),Gh.drawCallCount=0,Gh.triangleCount=0,yp.call(this,e,l.draws,Gh,{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 Jh(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),k.copy(a.position).add(V[n]),o.up.copy(I[n]),o.lookAt(k),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"}),ep.call(this,u,o,c,l,"pointShadow",this.state.pointShadowPipeline,this.state.pointShadowPipelineDirect,i),u.end()}}}n||this.clearPointShadow(e)}function Qh(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),k.copy(a.position).add(a.direction),o.lookAt(k),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"}),ep.call(this,u,o,c,l,"directionalShadow",this.state.shadowDepthPipeline,this.state.shadowDepthPipelineDirect,i),u.end()}n||this.clearSpotShadow(e)}function ep(e,t,r,i,n,a,s,o){Rh.setFromProjectionMatrix(zh.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse));const l=this.renderBundleScratch;l.length=0;for(const e of this.queryStaticShadowResources(Rh))for(const t of e.shadowChunks)kh.center.copy(t.boundsCenter),kh.radius=t.boundsRadius,Rh.intersectsSphere(kh)&&(l.push(lp.call(this,e,r,i,n,a,s,t)),o.drawCallCount+=t.drawCallCount,o.triangleCount+=t.triangleCount);l.length&&e.executeBundles(l),l.length=0}function tp(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 rp(e,t,r){const i=this.renderBundleScratch;i.length=0;for(const e of this.getCameraStaticDrawSets()){if(!e.publicSet.enabled||!this.isStaticDrawSetCameraVisible(e)||0===e.draws.length||"late"===e.drawStage)continue;if(this.getHiZOcclusionCullingActive()&&e.lastPreVisibilityFrameToken===this.staticFrameToken&&ap(e)){const t=this.getOrCreateStaticVisibleDepthSceneBindGroup(e);i.push(ip.call(this,e,t))}else i.push(this.getOrCreateStaticDepthPrepassBundle(e,t));this.recordStaticDrawStats(e,r)}i.length&&e.executeBundles(i),i.length=0}function ip(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}),o=op.call(this,e,"prepass","packed-visible");s.setBindGroup(0,t);let l=null,c=null,u=null;for(let t=0;t<e.draws.length;t+=1){const i=e.draws[t],n=o[t];if(i.customDepthMaterial||!n&&(Nh(i,"prepass")||Ih(i.material)||!jh(i)))continue;const a=n?.pipeline??this.state.depthPrepassPipelineVisible;l!==a&&(l=a,u=null,c=null,s.setPipeline(a)),n&&c!==n.bindGroup&&(c=n.bindGroup,s.setBindGroup(1,c)),u!==i.geometryKey&&(u=i.geometryKey,this.bindGeometryVertexBuffers(s,i.geometry,i.geometryResource,n?.vertexAttributes??G,0,1,i.wireframe)),s.drawIndexedIndirect(r,5*t*Uint32Array.BYTES_PER_ELEMENT)}const d=s.finish({label:a});return e.indirectDepthPrepassBundles[i]={sceneBindGroup:t,indirectBuffer:r,bundle:d},d}function np(e){if(this.sampleCount<=1||!this.state.mainDepthView||!this.getHiZOcclusionCullingActive())return;let t=null;const r=this.renderBundleScratch;r.length=0;for(const i of this.getCameraStaticDrawSets()){if(!i.publicSet.enabled||!this.isStaticDrawSetCameraVisible(i)||0===i.draws.length||"late"===i.drawStage||i.lastVisibilityFrameToken!==this.staticFrameToken||!ap(i))continue;t||(t=e.beginRenderPass({label:"renderer-static-temporal-depth-resolve",colorAttachments:[],depthStencilAttachment:{view:this.state.mainDepthView,depthLoadOp:"load",depthStoreOp:"store"}}));const n=this.getOrCreateStaticVisibleDepthSceneBindGroup(i);r.push(ip.call(this,i,n,i.drawMetadataResource.postIndirectBuffer,"postpass"))}r.length&&t.executeBundles(r),r.length=0,t?.end()}function ap(e){return e.temporalDepthSupported??Vh(e.draws)}function sp(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=op.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&&(Ih(r.material)||!jh(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??G,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 op(e,t,r){const i=r?`${t}:${r}`:t,n=e.depthMaterialResources.get(i);if(n)return n;const a=e.draws.map(e=>{const i=Nh(e,t);if(e.customDepthMaterial||!i)return null;return this.getDepthPassMaterialResourceForDraw(e.material,t,e,r)});return e.depthMaterialResources.set(i,a),a}function lp(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=op.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??G,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 cp(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 up(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,[B],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 dp(e,t,r,i="all",n=this.sampleCount){const a=this.renderBundleScratch;a.length=0;for(const s of this.getCameraStaticDrawSets())if(s.publicSet.enabled&&this.isStaticDrawSetCameraVisible(s)&&0!==s.draws.length&&("all"===i||s.drawStage===i)){if("opaque"===s.drawStage&&this.getHiZOcclusionCullingActive()&&s.lastVisibilityFrameToken===this.staticFrameToken){const t=this.getOrCreateStaticVisibleSceneBindGroup(s),i=this.getOrCreateStaticIndirectSubmissionStreams(s,t);for(const t of i)if(this.getMultiDrawIndirectActive()){if(a.length&&(e.executeBundles(a),a.length=0),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(s.drawMetadataResource.indirectBuffer,5*t.indirectStartIndex*Uint32Array.BYTES_PER_ELEMENT,t.indirectCount),r.drawCallCount+=t.drawCallCount,r.triangleCount+=t.triangleCount}else a.push(this.getOrCreateIndirectForwardBundle(t,s.drawMetadataResource,s.indirectForwardBundleCache,`${s.label}-static-indirect-forward-bundle`)),r.drawCallCount+=t.drawCallCount,r.triangleCount+=t.triangleCount;continue}a.push(this.getOrCreateStaticDirectForwardBundle(s,t,n)),this.recordStaticDrawStats(s,r)}a.length&&e.executeBundles(a),a.length=0}function hp(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:[B],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,_h(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 pp(e){for(const t of e.visibleMaterialBindings){const r=t.drawIndices[0];t.resource=e.draws[r]?.materialResource??e.visibleDrawMaterialResources[r]??null}}function fp(e){for(const t of e)t.materialResource=this.getMaterialResource(t.material,this.getDrawInstanceAccessMode(t),t.receiveShadow,void 0,null!==t.skinning,_h(t))}function mp(e,t){t.drawCallCount+=e.drawCallCount,t.triangleCount+=e.triangleCount}function gp(){return this.getCameraStaticDrawSets().some(e=>e.publicSet.enabled&&this.isStaticDrawSetCameraVisible(e)&&!e.cpuVisibility&&"opaque"===e.drawStage&&e.draws.length>0)}function vp(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 xp(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 wp(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 bp(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 yp(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(kh.center.copy(c.boundsCenter),kh.radius=c.boundsRadius,!Uh.intersectsSphere(kh))continue;const e=c.detailCulling??f(c.sourceObject);if(!c.staticLocalBoundsCenter&&!m(c.boundsCenter,c.boundsRadius,Ah,this.state.directionalShadowTextureSize,this.state.directionalShadowTextureSize,Eh,.85*e.shadowMinScreenSize,e.shadowMaxDistance))continue}if("prepass"!==i.passKind&&!c.castShadow)continue;if("prepass"===i.passKind&&null===c.material.depthVertexShader&&Ih(c.material))continue;if("skip"===i.customDepthMode&&c.customDepthMaterial)continue;const t=Nh(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&&!jh(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 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??h)&&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??(h?R:G),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)}}import{Box3 as Sp,Mesh as Cp,Sphere as Mp}from"three";import{Vector3 as Pp}from"three";var Bp=class{entries=[];pending=[];root=null;stack=[];stateStack=[];retired=0;add(e,t){const r={...t,boundsCenter:t.boundsCenter.clone(),value:e,active:!0};return this.pending.push(r),r}remove(e){e.active&&(e.active=!1,this.retired++)}clear(){this.entries.length=this.pending.length=this.stack.length=this.stateStack.length=0,this.root=null,this.retired=0}prepareQuery(){if(!this.root||this.pending.length+this.retired>Math.max(128,this.entries.length/4)){this.entries=this.entries.filter(e=>e.active);for(const e of this.pending)e.active&&this.entries.push(e);this.pending.length=0,this.retired=0,this.root=this.entries.length?this.build(0,this.entries.length):null}}query(e,t){if(!this.entries.length&&!this.pending.length)return;this.prepareQuery();const r=this.stack;for(r.length=0,this.root&&r.push(this.root);r.length;){const i=r.pop();if(e(i))if(i.left&&i.right)r.push(i.left,i.right);else for(let r=i.start;r<i.end;r++){const i=this.entries[r];i.active&&e(i)&&t(i.value)}}for(const r of this.pending)r.active&&e(r)&&t(r.value)}queryWithState(e,t,r){if(!this.entries.length&&!this.pending.length)return;this.prepareQuery();const i=this.stack,n=this.stateStack;for(i.length=n.length=0,this.root&&(i.push(this.root),n.push(r));i.length;){const r=i.pop(),a=e(r,n.pop());if(!(a<0))if(r.left&&r.right)i.push(r.left,r.right),n.push(a,a);else for(let i=r.start;i<r.end;i++){const r=this.entries[i];r.active&&e(r,a)>=0&&t(r.value)}}for(const i of this.pending)i.active&&e(i,r)>=0&&t(i.value)}build(e,t){let r=1/0,i=1/0,n=1/0,a=-1/0,s=-1/0,o=-1/0,l=0,c=1/0,u=0,d=!1,h=!1;for(let p=e;p<t;p++){const e=this.entries[p],t=e.boundsCenter,f=e.boundsRadius;r=Math.min(r,t.x-f),a=Math.max(a,t.x+f),i=Math.min(i,t.y-f),s=Math.max(s,t.y+f),n=Math.min(n,t.z-f),o=Math.max(o,t.z+f),l=Math.max(l,e.maxMemberRadius),c=Math.min(c,e.minScreenSize),d||=0===e.maxDistance,u=Math.max(u,e.maxDistance),h||=e.castShadow}const p=new Pp((r+a)/2,(i+s)/2,(n+o)/2),f={start:e,end:t,boundsCenter:p,boundsRadius:Math.hypot(a-p.x,s-p.y,o-p.z),maxMemberRadius:l,minScreenSize:c,maxDistance:d?0:u,castShadow:h,left:null,right:null};if(t-e>16){const l=a-r>=s-i&&a-r>=o-n?"x":s-i>=o-n?"y":"z",c=this.entries.slice(e,t).sort((e,t)=>e.boundsCenter[l]-t.boundsCenter[l]);for(let t=0;t<c.length;t++)this.entries[e+t]=c[t];const u=e+t>>>1;f.left=this.build(e,u),f.right=this.build(u,t)}return f}},Dp=class{index=new Bp;roots=new Set;children=new Map;invalidateChildren=e=>{e.target&&this.children.delete(e.target)};observed=new Set;indexedParents=new Map;registrations=new Set;registrationByRoot=new Map;meshSnapshots=new WeakMap;traversals=new WeakMap;getMeshSnapshot(e){return this.meshSnapshots.get(e)}queryScene=null;queryVisit=null;visitRoot=e=>{let t=e;for(;t&&t!==this.queryScene;t=t.parent)if(!t.visible)return;t===this.queryScene&&t?.visible&&this.queryVisit(e)};register(e){let t;this.registrationByRoot.get(e)?.dispose();let r=!1,i=!1,n=null;const a=new Set,s=[],o=()=>l(),l=()=>{if(t&&this.index.remove(t),t=void 0,this.roots.delete(e),this.traversals.delete(e),n){this.children.delete(n);const e=this.indexedParents.get(n)-1;e>0?this.indexedParents.set(n,e):(this.indexedParents.delete(n),this.observed.delete(n),n.removeEventListener("childadded",this.invalidateChildren),n.removeEventListener("childremoved",this.invalidateChildren)),n=null}for(const e of a)e.removeEventListener("childadded",o),e.removeEventListener("childremoved",o);a.clear();for(const e of s)this.meshSnapshots.delete(e);if(s.length=0,r||i)return;let l=!0,c=0,u=1/0,d=0,h=!1,p=!1;const m=new Sp,g=new Mp,v=new Sp;if(e.updateWorldMatrix(!0,!0),e.traverse(e=>{if(a.add(e),e.addEventListener("childadded",o),e.addEventListener("childremoved",o),e.isFogVolumeObject&&(l=!1),!(e instanceof Cp))return void("Group"!==e.type&&"Object3D"!==e.type&&(l=!1));(e.isSkinnedMesh||e.isInstancedMesh||e.isBatchedMesh||!e.frustumCulled||e.morphTargetInfluences?.length)&&(l=!1);const t=f(e);e.geometry.boundingSphere||e.geometry.computeBoundingSphere(),e.geometry.boundingSphere?(g.copy(e.geometry.boundingSphere).applyMatrix4(e.matrixWorld),m.union(g.getBoundingBox(v))):l=!1,u=Math.min(u,t.minScreenSize),h||=0===t.maxDistance,p||=e.castShadow,d=Math.max(d,t.maxDistance),c++}),!l||!c)return;if(m.getBoundingSphere(g),!Number.isFinite(g.radius)||!Number.isFinite(g.center.lengthSq()))return;for(const e of a)e instanceof Cp&&(g.copy(e.geometry.boundingSphere).applyMatrix4(e.matrixWorld),this.meshSnapshots.set(e,{boundsCenter:g.center.clone(),boundsRadius:g.radius,frontFaceCW:e.matrixWorld.determinant()<0,detailCulling:f(e)}),s.push(e));m.getBoundingSphere(g),this.roots.add(e);const x=Array.from(a),w=new Uint32Array(x.length),b=new Uint8Array(x.length),y=[];for(let e=0;e<x.length;e++){for(;y.length&&x[y[y.length-1]]!==x[e].parent;)w[y.pop()]=e;b[e]=x[e]instanceof Cp?1:0,y.push(e)}for(;y.length;)w[y.pop()]=x.length;this.traversals.set(e,{objects:x,subtreeEnds:w,meshes:b}),n=e.parent,n&&(this.indexedParents.set(n,(this.indexedParents.get(n)??0)+1),this.children.delete(n)),t=this.index.add(e,{boundsCenter:g.center,boundsRadius:g.radius,maxMemberRadius:g.radius,minScreenSize:u,maxDistance:h?0:d,castShadow:p})},c=()=>l();e.addEventListener("added",c),e.addEventListener("removed",c),l();const u={update:()=>{i||l()},setEditing:e=>{i||e===r||(r=e,l())},dispose:()=>{i||(i=!0,l(),e.removeEventListener("added",c),e.removeEventListener("removed",c),this.registrations.delete(u),this.registrationByRoot.delete(e))}};return this.registrations.add(u),this.registrationByRoot.set(e,u),u}traversalChildren(e){if(!this.indexedParents.has(e))return e.children;let t=this.children.get(e);return t||(t=e.children.filter(e=>!this.roots.has(e)),this.children.set(e,t),this.observed.has(e)||(this.observed.add(e),e.addEventListener("childadded",this.invalidateChildren),e.addEventListener("childremoved",this.invalidateChildren))),t}visitMeshes(e,t,r){const i=this.traversals.get(e);if(!i)return;const{objects:n,subtreeEnds:a,meshes:s}=i;for(let e=0;e<n.length;){const i=n[e];!i.visible||r&&!r(i)?e=a[e]:(s[e]&&t(i),e++)}}query(e,t,r){this.queryScene=e,this.queryVisit=r;try{this.index.query(t,this.visitRoot)}finally{this.queryScene=null,this.queryVisit=null}}queryWithState(e,t,r,i){this.queryScene=e,this.queryVisit=r;try{this.index.queryWithState(t,this.visitRoot,i)}finally{this.queryScene=null,this.queryVisit=null}}dispose(){for(const e of this.registrations)e.dispose();for(const e of this.observed)e.removeEventListener("childadded",this.invalidateChildren),e.removeEventListener("childremoved",this.invalidateChildren);this.observed.clear(),this.indexedParents.clear(),this.children.clear(),this.roots.clear(),this.index.clear()}};import{Matrix4 as Tp,OrthographicCamera as Ip,Vector3 as Vp}from"three";var Lp=(e,t)=>void 0!==e&&Number.isFinite(e)&&e>0?e:t,Gp=class{constructor(e){this.cameras=e,this.layers=e.map(()=>({valid:!1,source:null,direction:new Vp,rangeX:0,rangeY:0,nextUpdateMs:0,lastUpdateMs:-1/0,candidate:new Ip}))}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 Tp;previousPosition=new Vp;viewerPosition=new Vp;corner=new Vp;viewerValid=!1;revision=-1;timeMs=0;setOptions(e){this.settings={enabled:e.enabled??!1,maxUpdateHz:Lp(e.maxUpdateHz,60),cascadeUpdateHz:(e.cascadeUpdateHz?.length?e.cascadeUpdateHz:[60,30,15,7.5]).map(e=>Lp(e,60)),maxUpdatesPerFrame:Math.max(1,Math.floor(Lp(e.maxUpdatesPerFrame,2))),coverageMargin:Number.isFinite(e.coverageMargin)?Math.max(0,Math.min(.5,e.coverageMargin)):.05,teleportDistance:Lp(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{Sphere as Rp,Vector3 as zp}from"three";function Up(e,t){return e.id-t.id}function Ap(e){return`${Math.floor(e.x/32)}:${Math.floor(e.y/32)}:${Math.floor(e.z/32)}`}function kp(e,t){if(!t)return[e];const r=new Map;for(const t of e){const e=Ap(t.boundsCenter);let i=r.get(e);i||(i=[],r.set(e,i)),i.push(t)}return[...r.values()]}var Fp=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;revision=0;spatialIndex=new Bp;spatialEntries=new Map;cameraCandidates=[];shadowCandidates=[];shadowFrustum=null;shadowSphere=new Rp;testShadow=e=>!!e.castShadow&&(this.shadowSphere.center.copy(e.boundsCenter),this.shadowSphere.radius=e.boundsRadius,this.shadowFrustum.intersectsSphere(this.shadowSphere));collectShadow=e=>{e.publicSet.enabled&&"late"!==e.drawStage&&this.shadowCandidates.push(e)};markCameraVisible=e=>{e.publicSet.enabled&&(e.cameraVisible=!0,this.cameraCandidates.push(e))};updateCameraVisibility(e){for(const e of this.cameraCandidates)e.cameraVisible=!1;this.cameraCandidates.length=0,this.spatialIndex.query(e,this.markCameraVisible),this.cameraCandidates.sort(Up)}queryShadowResources(e){return this.shadowCandidates.length=0,this.shadowFrustum=e,this.spatialIndex.query(this.testShadow,this.collectShadow),this.shadowFrustum=null,this.shadowCandidates}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 Ri(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 c=new Map;if(!(s.instanceCount>=512&&!a.some(e=>e.transparent)))return this.createResource(r,a,s,l);let u=1/0,d=1/0,h=1/0;for(const e of a)u=Math.min(u,e.boundsCenter.x),d=Math.min(d,e.boundsCenter.y),h=Math.min(h,e.boundsCenter.z);for(const e of a){const t=e.boundsCenter,r=`${Math.floor((t.x-u)/256)}:${Math.floor((t.y-d)/256)}:${Math.floor((t.z-h)/256)}`;let i=c.get(r);i||c.set(r,i=[]),i.push(e)}if(c.size<=1)return this.createResource(r,a,s,l);const p=[];try{for(const[e,t]of c)p.push(this.createResource(`${r}-${e}`,t,s,0===p.length?l:new Map))}catch(e){for(const e of p)e.dispose();if(!p.length)for(const e of l.values())e.dispose();throw e}let f=!0,m=!1;return{label:r,get enabled(){return f},set enabled(e){f=e;for(const t of p)t.enabled=e},get drawCount(){return p.reduce((e,t)=>e+t.drawCount,0)},get instanceCount(){return p.reduce((e,t)=>e+t.instanceCount,0)},dispose(){if(!m){m=!0;for(const e of p)e.dispose()}}}}createResource(e,t,r,i){if(!this.state.device)throw new Error("Renderer is not initialized.");const{draws:n,instanceData:a}=this.mergeStaticDraws(t,r),s=n.some(e=>e.transparent),o=n.some(e=>!e.transparent);if(s&&o)throw new Error(`StaticDrawSet "${e}" cannot mix opaque and late materials; register them as separate sets.`);const l=this.createVisibleMaterialBindings(n),c=this.createShadowChunks(n),u=Math.max(4,a.byteLength),d=this.state.device.createBuffer({label:`${e}-static-instance-buffer`,size:256*Math.ceil(u/256),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});a.floatLength>0?this.state.device.queue.writeBuffer(d,0,a.rawData.buffer,0,a.byteLength):this.state.device.queue.writeBuffer(d,0,M,0,S);const h={mode:"packed",buffer:d,colorBuffer:null,sceneBindGroup:null,shadowBindGroup:null,shadowBindGroups:new Map,sceneBindGroupVersion:0,shadowBindGroupVersion:0};for(const e of n)e.residentInstanceBinding=h;const p=this.createStaticDrawMetadataResource(e,n),f=this.createStaticInstanceVisibilityResource(e,n,a),m=new zp(1/0,1/0,1/0),g=new zp(-1/0,-1/0,-1/0);let v=0,x=1/0,w=0,b=!1;const y=f.metadata;for(let e=0;e<a.instanceCount;e++){const t=8*e,r=y[t+3];k.set(y[t],y[t+1],y[t+2]),Ti(m,g,k,r),v=Math.max(v,r),x=Math.min(x,y[t+6]),b||=0===y[t+7],w=Math.max(w,y[t+7])}const C=(new zp).addVectors(m,g).multiplyScalar(.5),P={boundsCenter:C,boundsRadius:C.distanceTo(g),maxMemberRadius:v,minScreenSize:x,maxDistance:b?0:w,castShadow:n.some(e=>e.castShadow)},B=new Uint32Array([n.length,this.state.hizMipCount,a.instanceCount,0]),D=this.state.device.createBuffer({label:`${e}-visibility-params-buffer`,size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),T=new Uint32Array([n.length,this.state.hizMipCount,a.instanceCount,0]),I=this.state.device.createBuffer({label:`${e}-post-visibility-params-buffer`,size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});this.state.device.queue.writeBuffer(D,0,B,0,4),this.state.device.queue.writeBuffer(I,0,T,0,4);const V={temporalDepthSupported:Vh(n),spatialBounds:P,cpuVisibility:!s&&1===n.length&&1===a.instanceCount,cameraVisible:!1,cameraDetailVisible:!1,id:this.nextStaticDrawSetId++,label:e,publicSet:null,ownedMaterials:[...i.values()],draws:n,shadowChunks:c,drawStage:s?"late":"opaque",drawCallCount:n.length,triangleCount:n.reduce((e,t)=>e+Math.floor(Math.max(0,t.count)/3)*Math.max(0,t.instanceCount),0),instanceCount:a.instanceCount,instanceBuffer:d,residentInstanceBinding:h,drawMetadataResource:p,instanceVisibilityResource:f,visibilityParamsBuffer:D,visibilityParamsUpload:B,postVisibilityParamsBuffer:I,postVisibilityParamsUpload:T,visibilityBindGroup:null,postVisibilityBindGroup:null,visibilityClearBindGroup:null,visibilityIndirectBuildBindGroup:null,postVisibilityIndirectBuildBindGroup:null,visibleSceneBindGroup:null,visibleSceneBindGroupVersion:0,visibleDepthSceneBindGroup:null,visibleDepthSceneBindGroupVersion:0,visibleMaterialBindings:l,visibleDrawMaterialResources:new Array(n.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};let L=!0;const G=this,R={label:e,get enabled(){return L},set enabled(e){L!==e&&(L=e,G.revision++)},get drawCount(){return V.draws.length},get instanceCount(){return V.instanceCount},dispose:()=>{this.disposeStaticDrawSetResource(V)}};return V.publicSet=R,this.staticDrawSets.push(V),this.revision++,a.instanceCount>0&&this.spatialEntries.set(V,this.spatialIndex.add(V,P)),R}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=Ap(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 zp(.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(ui);const r=[],i=e.reduce((e,t)=>e+t.instanceCount*S,0),n=new Ri(Math.max(1024,i));for(let i=0;i<e.length;){const a=e[i],s=n.instanceCount;n.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=i+1;for(;f<e.length&&mi(a,e[f]);){const r=e[f];n.appendRange(t,r.instanceStart,r.instanceCount),o+=r.instanceCount;const i=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;i<l&&(l=i),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),i=f}return{draws:r,instanceData:n}}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(Li(e))return void n(e,"custom depth materials are not supported by StaticDrawSet v1");const s=this.getGeometryResource(e.geometry),o=Pi(e.geometry),l=k.copy(o.center).applyMatrix4(e.matrixWorld),c=o.radius*Bi(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(Li(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=Pi(e.geometry),c=this.getGeometryResource(e.geometry),u=[];for(let t=0;t<e.count;t+=1){e.getMatrixAt(t,z),U.multiplyMatrices(e.matrixWorld,z);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=$.copy(l.center).applyMatrix4(U),o=l.radius*Bi(U);u.push({matrix:new Float32Array(U.elements),color0:r,color1:i,color2:n,color3:a,batchingId:t,boundsCenter:s.clone(),boundsRadius:o})}for(const i of kp(u,!s.transparent&&!s.requiresLatePass())){const n=k.set(1/0,1/0,1/0),a=F.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),Ti(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(Li(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,A),a={geometryId:t,start:r.start,count:i,localBoundsCenter:n?n.center.clone():new zp,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(z,p,16*t):e.getMatrixAt(t,z),U.multiplyMatrices(e.matrixWorld,z);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=$.copy(i.localBoundsCenter).applyMatrix4(U),u=i.localBoundsRadius*Bi(U);i.instances.push({matrix:new Float32Array(U.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 kp(i.instances,!s.transparent&&!s.requiresLatePass())){const a=k.set(1/0,1/0,1/0),o=F.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),Ti(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,m,g=!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:f(this.activeObject,this.activeDetailDefaults),frontFaceCW:g,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 zp(c,u,d),boundsRadius:h,sortDepth:0,transparentSortGroup:0,transparentSortOrder:0,staticLocalBoundsCenter:p.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*C),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*C;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*C*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??Pi(i.geometry).center,a=i.staticLocalBoundsRadius??Pi(i.geometry).radius;for(let t=0;t<i.instanceCount;t+=1){const l=i.instanceStart+t,c=l*S,u=8*l;z.fromArray(r.rawData,c);const d=k.copy(n).applyMatrix4(z),h=a*Bi(z);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;const r=this.spatialEntries.get(e);r&&this.spatialIndex.remove(r),this.spatialEntries.delete(e),e.disposeDirectionalGpuShadows?.(),this.staticDrawSets.splice(t,1);const i=this.cameraCandidates.indexOf(e);i>=0&&this.cameraCandidates.splice(i,1),this.shadowCandidates.length=0,e.cameraVisible=!1,this.revision++;const n=new Set;for(const t of e.draws)t.materialResource&&n.add(t.materialResource);for(const t of e.visibleMaterialBindings)t.resource&&n.add(t.resource);for(const t of e.visibleDrawMaterialResources)t&&n.add(t);for(const t of e.depthMaterialResources.values())for(const e of t)e&&n.add(e);for(const e of n)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()}};import{RGBAFormat as $p}from"three";function Ep(e,t,r,i){const n=new Uint8Array(e.buffer,e.byteOffset,e.byteLength),a=new Uint8Array(n.byteLength);for(let e=0;e<i;e++){const i=e*t*r;for(let e=0;e<r;e++){const s=i+e*t;a.set(n.subarray(s,s+t),i+(r-e-1)*t)}}return a}var Op=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=wt(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 a=0;a<n.length;a+=1){const s=n[a];if(!s?.data)continue;const o=s.width??Math.max(1,r.width>>a),l=s.height??Math.max(1,r.height>>a),c=s.depth??r.depthOrArrayLayers;this.state.device.queue.writeTexture({texture:t,mipLevel:a},ii(e.flipY?Ep(s.data,o*i,l,c):s.data),{bytesPerRow:o*i,rowsPerImage:l},{width:o,height:l,depthOrArrayLayers:c})}return}const a=e.image;a?.data&&this.state.device.queue.writeTexture({texture:t},e.flipY?Ep(a.data,r.width*i,r.height,r.depthOrArrayLayers):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.");let 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&&e.format===$p){const e=wt(r.format);null!==e&&(i={width:1,height:1,byteLength:e})}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: ${_p(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: ${_p(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=gt(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 _p(e){return e instanceof Error?e.message:String(e)}function jp(e){if(e.transparent)switch(e.blending){case ed:return{color:{srcFactor:"src-alpha",dstFactor:"one",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one",operation:"add"}};case vd:return{color:{srcFactor:"zero",dstFactor:"one-minus-src",operation:"subtract"},alpha:{srcFactor:"one",dstFactor:"one",operation:"subtract"}};case ud: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 Np(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 Wp(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=Np(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=Np(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 Hp(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 qp(e){const t=Number(e.userData.motionBlurScale??1);return Number.isFinite(t)?Math.max(0,Math.min(t,8)):1}var Kp="chromium-experimental-multi-draw-indirect";function Zp(e,t){return Number(t.castShadow)-Number(e.castShadow)}var Yp=[B],Xp=[{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 Jp(e){return e.wireframe&&"triangle-list"===e.primitiveTopology?"line-list":e.primitiveTopology}function Qp(e,t,r){if(!Jp(e).startsWith("triangle"))return"none";if("directionalShadow"===t){if(r&&null===e.shadowSide)return"none";const t=e.shadowSide??(e.side===td?sd:e.side===ad?ad:td);return t===ad?"none":t===td?"front":"back"}return e.side===ad?"none":e.side===td?"front":"back"}function ef(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 tf=class{pipelineCompilationDiagnostics;canvas;clearColor;powerPreference;shadowMapSize;directionalShadowsEnabled=!0;spotShadowMapSize;pointShadowMapSize;fallbackMaterial;materialResolver;toonOutlineMaterialCache=new WeakMap;fallbackSkinnedMaterial;invokeObjectRenderCallbacks;sampleCount;renderScale;hiZOcclusionCullingEnabled;frameHiZOcclusionCullingNeeded=!0;multiDrawIndirectEnabled;dynamicBatchingEnabled;multiDrawIndirectSupported=!1;tiledPointLights=null;tiledLightingEnabled;transientPointLightsScratch=[];transientPointScoresScratch=new Float64Array(16);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;defaultVertexAttributeBuffers=new Map;textureManager=new Op(this.state,this.textureCache);renderGraph=new jd;nativePostSubmit;presentationOverlay;presentationOverlayContext={device:null,encoder:null,targetView:null,targetFormat:"bgra8unorm",presentationWidth:1,presentationHeight:1};directionalShadowCameras=Array.from({length:4},()=>new pd(-10,10,10,-10,.1,80));directionalShadowScheduler=new Gp(this.directionalShadowCameras);directionalShadowGpu=new Xu;directionalShadowSubmissionStats={bundleHits:0,bundleBuilds:0,selectionHits:0,selections:0};pointShadowCameras=Array.from({length:4},()=>V.map(()=>new fd(90,1,.1,25)));spotShadowCameras=Array.from({length:4},()=>new fd(60,1,.5,500));colorTargetCache=new Map;msaaColorTargetCache=new Map;msaaDepthTargetCache=new Map;sourceInstanceDataScratch=new Ri(4096);opaqueInstanceDataScratch=new Ri(4096);finalInstanceDataScratch=new Ri(4096);residentInstanceUploadsScratch=[];gpuOpaqueDrawsScratch=[];directOpaqueDrawsScratch=[];stagedOpaqueDrawsScratch=[];residentOpaqueDrawsScratch=[];retiredGeometryResources=[];retiredGeometryBuffers=[];vertexAttributeBufferKeyCache=new WeakMap;standardVertexAttributeCache=new WeakMap;geometryVertexBufferFastCache=new WeakMap;vertexAttributeGroupCache=new WeakMap;materialVertexAttributeCache=new WeakMap;sharedVertexAttributeLayouts=new Map;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([[B,1]]);nextColorFormatsId=2;renderBundleScratch=[];indirectMaterialResourcesScratch=[];directBundleDrawStatsScratch={drawCallCount:0,triangleCount:0};sortedOpaqueBatchesScratch=[];opaqueBatchPool=[];opaqueBatchPoolCount=0;drawCallPool=[];drawCallPoolCount=0;staticDrawSets=[];materialPassStaticBundleCache=new WeakMap;staticDrawSetManager=new Fp(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 bd;extractedHemisphereScratch=this.createExtractedHemisphereLightScratch();extractedBoundsMinScratch=new wd;extractedBoundsMaxScratch=new wd;extractedDirectionalLightsScratch=Array.from({length:4},()=>this.createExtractedDirectionalLightScratch());extractedPointLightsScratch=Array.from({length:b},()=>this.createExtractedPointLightScratch());extractedSpotLightsScratch=Array.from({length:y},()=>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 xd);csmCascadeCount=0;csmCascadeLights=[];shadowCameraUniformScratch=new Float32Array(64);cameraViewProjScratch=new dd;cameraProjectionScratch=new dd;projectionJitterPixels=new xd;temporalVisibilityCurrentViewProj=new dd;temporalVisibilityPreviousViewProj=new dd;motionVectorProjection=new dd;motionVectorCurrentViewProj=new dd;motionVectorPreviousViewProj=new dd;motionVectorProjectionPending=!1;motionVectorHistoryValid=!1;motionVectorHistoryGeneration=1;lastMotionVectorTimeSeconds=Number.NaN;objectMotionHistory=new WeakMap;cameraFrustumPlanesScratch=new Float32Array(24);objectTraversalStackScratch=[];staticSceneSpatialIndex=new Dp;staticMeshDraws=new WeakMap;spatialShadowPlanes=Array.from({length:4},()=>new Float32Array(24));spatialShadowCount=0;spatialLocalShadowSpheres=new Float64Array(512);spatialLocalShadowCount=0;spatialShadowMatrix=new dd;spatialIncludeOffscreen=!1;spatialCameraLayers=0;testSpatialCamera=e=>Mi(this.cameraFrustumPlanesScratch,e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius)&&g(e,this.cameraViewProjScratch,this.state.width,this.state.height,this.transparentSortCameraPositionScratch);testSpatialScene=(e,t)=>{if(this.spatialIncludeOffscreen)return 0;if(64!==t){if((t=function(e,t,r,i,n,a){for(let s=0,o=1;s<6;s++,o<<=1){if(!(a&o))continue;const l=4*s,c=e[l]*t+e[l+1]*r+e[l+2]*i+e[l+3];if(c<-n)return-1;c>=n&&(a&=~o)}return a}(this.cameraFrustumPlanesScratch,e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius,t))>=0&&g(e,this.cameraViewProjScratch,this.state.width,this.state.height,this.transparentSortCameraPositionScratch))return t;t=64}return e.castShadow&&this.isSpatialShadowSphereVisible(e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius)?t:-1};filterSpatialCaptureObject=e=>!1!==this.sceneCaptureOptions?.objectFilter?.(e)&&!1!==e.userData.sceneCapture;pushSpatialRoot=e=>{this.objectTraversalStackScratch.push(e)};collectSpatialMesh=e=>{0!==(e.layers.mask&this.spatialCameraLayers)&&(this.extractingCaster=e.castShadow,this.collectMesh(e,this.sourceInstanceDataScratch,this.updateExtractedBoundsFromMatrixScratch,this.spatialIncludeOffscreen?this.isSphereVisibleForCompilationScratch:this.isSpatialSphereVisible))};isSpatialSphereVisible=(e,t,r,i,n)=>!n||Mi(this.cameraFrustumPlanesScratch,e,t,r,i)||this.extractingCaster&&this.isSpatialShadowSphereVisible(e,t,r,i);isSpatialShadowSphereVisible(e,t,r,i){for(let n=0;n<this.spatialShadowCount;n++)if(Mi(this.spatialShadowPlanes[n],e,t,r,i))return!0;for(let n=0;n<this.spatialLocalShadowCount;n++){const a=4*n,s=this.spatialLocalShadowSpheres,o=e-s[a],l=t-s[a+1],c=r-s[a+2],u=i+s[a+3];if(o*o+l*l+c*c<=u*u)return!0}return!1}collectSpatialRoot=e=>{if(null!==this.sceneCaptureOptions)for(let t=e;t;t=t.parent)if(!1===this.sceneCaptureOptions.objectFilter?.(t)||!1===t.userData.sceneCapture)return;this.staticSceneSpatialIndex.visitMeshes(e,this.collectSpatialMesh,null===this.sceneCaptureOptions?void 0:this.filterSpatialCaptureObject)};shadowDrawsScratch=[];extractingCaster=!1;cameraDetailHistory=new WeakMap;isSphereVisibleScratch=(e,t,r,i,n)=>this.extractingCaster||!n||Mi(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 wd;transparentSortCameraForwardScratch=new wd;temporalVisibilityCurrentCameraPosition=new wd;temporalVisibilityPreviousCameraPosition=new wd;shadowViewProjScratch=new dd;extractionVersion=0;motionHistoryExtractionVersion=0;sceneCaptureOptions=null;sceneCaptureDisposers=new Set;captureMotionHistory={matrix:new Float32Array(16),generation:0,lastExtractionVersion:-1,valid:!1};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 wd,target:new wd,direction:new wd,color:new wd,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 wd(0,1,0),skyColor:new wd,groundColor:new wd,intensity:0}}createExtractedPointLightScratch(){return{sourceLight:null,position:new wd,color:new wd,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 wd,direction:new wd(0,-1,0),color:new wd,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 Ju;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:Xp}),this.invokeObjectRenderCallbacks=e.invokeObjectRenderCallbacks??!0,this.state.directionalShadowTextureSize=this.shadowMapSize,this.state.pointShadowTextureSize=this.pointShadowMapSize,this.state.spotShadowTextureSize=this.shadowMapSize,this.sampleCount=Vi(e.sampleCount),this.renderScale=ef(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 yd)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 nd(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:ad,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 nd(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(Kp)&&i.push(Kp);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(Kp),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(Qu.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|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|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"}}]}),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(N.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(N.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(N.createAsync(this.state.device,{label:"renderer-visibility-cull",code:Fu,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(N.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(N.createAsync(this.state.device,{label:"renderer-static-visibility-cull",code:$u,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"}},{binding:10,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:11,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}).then(e=>{this.state.staticVisibilityCullKernel=e})),u.push(N.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 N(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||vh(this.state)}getRenderGraphProfilingEnabled(){return this.renderGraphProfilingEnabled}getTimestampQuerySupported(){return this.timestampQuerySupported}getSampleCount(){return this.sampleCount}setSampleCount(e){const t=Vi(e);t!==this.sampleCount&&(this.sampleCount=t,this.destroyMsaaResources(),this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches())}setRenderScale(e){const t=ef(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&&this.frameHiZOcclusionCullingNeeded}isStaticDrawSetCameraVisible(e){return null!==this.sceneCaptureOptions||e.cameraVisible}getCameraStaticDrawSets(){return null!==this.sceneCaptureOptions||this.spatialIncludeOffscreen?this.staticDrawSets:this.staticDrawSetManager.cameraCandidates}queryStaticShadowResources(e){return this.staticDrawSetManager.queryShadowResources(e)}updateVisibilityWorkload(e){this.staticDrawSetManager.updateCameraVisibility(this.testSpatialCamera);let t=e.gpuOpaqueDraws.length>=64;for(const e of this.staticDrawSetManager.cameraCandidates){if(!e.publicSet.enabled||"opaque"!==e.drawStage)continue;if(!e.cpuVisibility){t||=e.cameraVisible;continue}const r=e.draws[0],i=r.detailCulling;e.cameraDetailVisible=m(r.boundsCenter,r.boundsRadius,this.cameraViewProjScratch,this.state.width,this.state.height,this.transparentSortCameraPositionScratch,(i?.minScreenSize??0)*(e.cameraDetailVisible?.85:1.15),i?.maxDistance??0),e.cameraVisible=e.cameraDetailVisible&&Mi(this.cameraFrustumPlanesScratch,r.boundsCenter.x,r.boundsCenter.y,r.boundsCenter.z,r.boundsRadius)}t!==this.frameHiZOcclusionCullingNeeded&&(this.state.temporalHiZHistoryValid=!1),this.frameHiZOcclusionCullingNeeded=t}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:B,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:D,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:B,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)}createSceneCapture(e,t=512,r=t){const i=this.state.device;if(!i||!this.state.initialized)throw new Error("Renderer is not initialized.");const n=e?.getContext("webgpu");if(e&&!n)throw new Error("The capture canvas does not provide WebGPU.");t=Math.max(1,Math.floor(t)),r=Math.max(1,Math.floor(r)),e&&(e.width=t,e.height=r),n?.configure({device:i,format:this.state.format,alphaMode:"premultiplied"});const a=n?void 0:i.createTexture({label:"scene-capture-output",size:[t,r],format:this.state.format,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),s=a?.createView(),o=i.createTexture({label:"scene-capture-color",size:[t,r],format:B,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),l=i.createTexture({label:"scene-capture-depth",size:[t,r],format:"depth32float",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),c={colorView:o.createView(),depthView:l.createView(),width:t,height:r};let u=!1;const d=()=>{u||(u=!0,n?.unconfigure(),a?.destroy(),o.destroy(),l.destroy(),this.sceneCaptureDisposers.delete(d))};return this.sceneCaptureDisposers.add(d),{textureView:s,capture:(e,t,r={})=>{if(u||this.sceneCaptureOptions)throw new Error("Scene capture is unavailable.");this.sceneCaptureOptions=r;try{e.matrixWorldAutoUpdate&&e.updateMatrixWorld(),t.updateWorldMatrix(!0,!1);const a=this.extractScene(e,t);this.uploadInstanceData(a.instanceData),this.uploadResidentInstanceData(a.residentInstanceUploads),this.updateCameraUniforms(t,e,c),this.updateLightUniforms(a);const o=i.createCommandEncoder({label:"scene-capture-encoder"});this.executeMaterialPass(o,["sceneColor"],this.getSharedSceneBindGroup(),a,{drawCallCount:0,triangleCount:0},{clearColor:r.clearColor,objectFilter:e=>r.objectFilter?.(e)??!0},c);const l=s??n.getCurrentTexture().createView();r.postProcess?r.postProcess({device:i,encoder:o,colorView:c.colorView,depthView:c.depthView,sampler:this.state.linearClampSampler,targetView:l,targetFormat:this.state.format,width:c.width,height:c.height,camera:t}):this.executePresentPass(o,c.colorView,l),i.queue.submit([o.finish()]),this.releaseRetiredGeometryResourcesAfterSubmit()}finally{this.sceneCaptureOptions=null}},dispose:d}}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 Qd({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)}registerStaticSpatialObject(e){return this.staticSceneSpatialIndex.register(e)}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);this.updateVisibilityWorkload(s);for(const e of s.gpuOpaqueDraws)this.prepareDrawGeometryVertexBuffers(e,!0);for(const e of s.directOpaqueDraws)this.prepareDrawGeometryVertexBuffers(e,!0);for(const e of s.transparentDraws)this.prepareDrawGeometryVertexBuffers(e,!0);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=fh.get(e);a&&a.device===e.device||(a?.dispose(),a=new ph(e.device),fh.set(e,a));const s=a,o={frameIndex:e.frameIndex+=1,renderWidth:e.width,renderHeight:e.height,presentationWidth:e.presentationWidth,presentationHeight:e.presentationHeight,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 gh.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(!gh.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=yh(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=yh(o)}}},h={profile:o,observer:d,pendingVisibilityRead:null,get pendingGpuRead(){return l},set pendingGpuRead(e){l=e}};return mh.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.getCameraStaticDrawSets())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(gh.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=mh.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&&xh(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&&xh(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(){this.sharedVertexAttributeLayouts.clear(),this.staticSceneSpatialIndex.dispose();for(const e of this.sceneCaptureDisposers)e();vh(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.defaultVertexAttributeBuffers.values())for(const t of e.values())t.destroy();this.defaultVertexAttributeBuffers.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(_(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(_(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(_(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(_(this.state.device,{label:"renderer-skinned-depth-prepass-pipeline",layout:n,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-depth-prepass-module",code:Nu}),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(_(this.state.device,{label:"renderer-directional-shadow-pipeline",layout:a,vertex:{module:this.state.device.createShaderModule({label:"renderer-directional-shadow-module",code:Eu}),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(_(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(_(this.state.device,{label:"renderer-skinned-directional-shadow-pipeline",layout:o,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-directional-shadow-module",code:Wu}),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(_(this.state.device,{label:"renderer-point-shadow-pipeline",layout:a,vertex:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-module",code:Ou}),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:Ou}),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(_(this.state.device,{label:"renderer-point-shadow-direct-pipeline",layout:s,vertex:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-direct-module",code:_u}),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:_u}),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(_(this.state.device,{label:"renderer-skinned-point-shadow-pipeline",layout:o,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-point-shadow-module",code:Hu}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(R)},fragment:{module:this.state.device.createShaderModule({label:"renderer-skinned-point-shadow-fragment-module",code:Hu}),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(_(this.state.device,{label:"renderer-present-pipeline",layout:l,vertex:{module:this.state.device.createShaderModule({label:"renderer-present-module",code:qu}),entryPoint:"vsMain"},fragment:{module:this.state.device.createShaderModule({label:"renderer-present-fragment-module",code:qu}),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:Zu});e.push(_(this.state.device,{label:"renderer-scene-color-snapshot-pipeline",layout:l,vertex:{module:c,entryPoint:"vsMain"},fragment:{module:c,entryPoint:"fsMain",targets:[{format:D}]},primitive:{topology:"triangle-list"}}).then(e=>{this.state.sceneColorSnapshotPipeline=e}));const u=this.state.device.createShaderModule({label:"physical-transmission-snapshot-module",code:Yu});e.push(_(this.state.device,{label:"physical-transmission-snapshot-pipeline",layout:l,vertex:{module:u,entryPoint:"vsMain"},fragment:{module:u,entryPoint:"fsMain",targets:[{format:B}]},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:B,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??B,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??B,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 B;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 hh("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:B,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 hh("DirectionalShadowPass",()=>{this.executeDirectionalShadowPass(t,i,s,o)},{writes:["directionalShadow"]}))},addPointShadowPass:()=>{s.lights.points.some(e=>e.castShadow)&&e.addPass(new hh("PointShadowPass",()=>{this.executePointShadowPass(t,i,s,o)},{writes:["pointShadow"]}))},addSpotShadowPass:()=>{s.lights.spots.some(e=>e.castShadow)&&e.addPass(new hh("SpotShadowPass",()=>{this.executeSpotShadowPass(t,i,s,o)},{writes:["spotShadow"]}))},addDepthPrepass:()=>{d=!0,this.getHiZOcclusionCullingActive()&&this.hasEnabledStaticDrawSets()&&e.addPass(new hh("TemporalStaticVisibilityPrepass",()=>{this.executeStaticVisibilityPasses(t,"prepass")},{reads:["hiz"],writes:["staticIndirectArgs"]})),e.addPass(new hh("DepthPrepass",()=>{this.executeDepthPrepass(t,r,s,o)},{writes:["mainDepth"]}))},addHiZPasses:()=>{this.getHiZOcclusionCullingActive()&&e.addPass(new hh("HiZPasses",()=>{this.executeHiZPasses(t)},{reads:["mainDepth"],writes:["hiz"]}))},addVisibilityPass:()=>{this.getHiZOcclusionCullingActive()&&(n||this.hasEnabledStaticDrawSets())&&(e.addPass(new hh("VisibilityPass",()=>{n&&this.executeVisibilityPass(t,n),this.executeStaticVisibilityPasses(t,"postpass")},{reads:["hiz"],writes:["indirectArgs","staticIndirectArgs"]})),this.sampleCount>1&&this.hasEnabledStaticDrawSets()&&e.addPass(new hh("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 hh("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 hh("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 hh("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 hh("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 hh("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.getCameraStaticDrawSets().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)!==B)throw new Error("Scene texture snapshots currently require a full-resolution rgba16float source.");e.addPass(new hh("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.getCameraStaticDrawSets().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 hh("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 hh("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 hh(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 hh(t.name,()=>{t.execute(f)},{reads:t.reads,writes:t.writes,dependsOn:t.dependsOn}))},addPresentPass:(r="sceneColor")=>{e.addPass(new hh("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=this.createDrawCall(),this.drawCallPool[e]=t),t}createDrawCall(){return{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 wd,boundsRadius:0,sortDepth:0,transparentSortGroup:0,transparentSortOrder:0}}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 wd,boundsMax:new wd},this.opaqueBatchPool[e]=t),t}populateDrawCall(e,t,r,i,n,a,s,o,l){const c=t.wireframe;c&&this.ensureWireframeIndex(t.geometry,t.geometryResource);const u=t.sourceObject?Boolean(t.sourceObject.receiveShadow):t.receiveShadow;return this.shouldInvalidateDrawMaterialResource(e,t.material,u,t.usesBatching,null)&&(e.materialResource=null),e.geometry=t.geometry,e.geometryKey=c?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=l?.detailCulling??f(t.sourceObject),e.frontFaceCW=l?.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=c||t.indexed,e.wireframe=c,e.start=c?2*t.start:t.start,e.count=c?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=u,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,m,g,v,x,w,b,y,S,C,M,P,B,D,T,I=null){const V=!0===o?.isBatchedMesh,L=n.wireframe&&"triangle-list"===n.primitiveTopology;return L&&this.ensureWireframeIndex(t,i),this.shouldInvalidateDrawMaterialResource(e,n,w,V,I)&&(e.materialResource=null),e.geometry=t,e.geometryKey=L?i.wireframeIndex:r,e.geometryResource=i,e.material=n,e.customDepthMaterial=a,e.residentInstanceBinding=s,e.sourceObject=o,e.cameraDetailRejected=void 0,e.detailCulling=f(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=L||d,e.wireframe=L,e.start=L?2*h:h,e.count=L?2*p:p,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=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=f(e.sourceObject),e.cameraDetailRejected=null===this.sceneCaptureOptions&&!m(k.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&&null===this.sceneCaptureOptions&&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?Xp:[{name:"position",shaderLocation:0,format:"float32x3"},{name:"normal",shaderLocation:1,format:"float32x3",defaultValue:[0,0,1]}],uniforms:{outlineThickness:r.thickness??.003,outlineColor:(new nd).fromArray(r.color??[0,0,0]),outlineAlpha:r.alpha??e.opacity},side:td,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=e.transparent||(this.getToonOutlineParameters(t)?.alpha??t.opacity)<1||r.requiresLatePass(),n=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,i,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.pushDraw(n)}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)}}selectTransientPointLight(e,t){if(!(e.intensity>0&&e.distance>0))return;if(k.setFromMatrixPosition(e.matrixWorld),!Mi(this.cameraFrustumPlanesScratch,k.x,k.y,k.z,e.distance))return;const r=e.intensity*e.distance*e.distance/Math.max(1,k.distanceToSquared(t));if(!Number.isFinite(r))return;const i=this.transientPointLightsScratch,n=this.transientPointScoresScratch;let a=0;for(;a<i.length&&(n[a]>r||n[a]===r&&i[a].id<e.id);)a++;if(a>=n.length)return;for(let e=Math.min(i.length,n.length-1);e>a;e--)i[e]=i[e-1],n[e]=n[e-1];i[a]=e,n[a]=r}extractPointLight(e,t){const r=e.shadow,i=r.camera;k.setFromMatrixPosition(e.matrixWorld);const n=e.distance>0?e.distance:Math.max(i.far,25);if(!Mi(this.cameraFrustumPlanesScratch,k.x,k.y,k.z,n))return;const a=this.extractedPointLightsScratch[t.length];a.sourceLight=e,a.position.copy(k),a.color.set(e.color.r,e.color.g,e.color.b),a.intensity=e.intensity,a.volumetricIntensity=e.userData?.volumetricIntensity??0,a.distance=e.distance,a.range=n,a.decay=e.decay,a.castShadow=e.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=e.distance>0?e.distance:i.far,t.push(a)}extractScene(e,t,r=!1){this.extractionVersion+=1,null===this.sceneCaptureOptions&&(this.motionHistoryExtractionVersion+=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.dynamicBatchingEnabled?this.finalInstanceDataScratch:a;this.finalInstanceDataScratch.reset();const h=this.extractedAmbientScratch;h.set(0,0,0,0);let p=null;const g=this.activeDirectionalLightsScratch,v=this.activePointLightsScratch,x=this.activeSpotLightsScratch,w=this.fogVolumeObjectsScratch;g.length=0,v.length=0,this.transientPointLightsScratch.length=0,x.length=0,w.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),Si(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(;;){if(0===T.length){for(const e of this.transientPointLightsScratch){if(v.length>=b)break;this.extractPointLight(e,v)}if(this.csmCascadeLights.length>0&&g.sort((e,t)=>{const r=e.sourceLight?this.csmCascadeLights.indexOf(e.sourceLight):-1,i=t.sourceLight?this.csmCascadeLights.indexOf(t.sourceLight):-1;return(r<0?4:r)-(i<0?4:i)}),!r&&null===this.sceneCaptureOptions){const e=this.staticDrawSetManager.revision;this.directionalShadowScheduler.prepare(g,t,this.csmCascadeRanges,this.csmCascadeCount,performance.now(),e)}if(this.spatialShadowCount=0,this.spatialLocalShadowCount=0,null===this.sceneCaptureOptions)for(let e=0;e<g.length;e++)g[e].castShadow&&Si(yi(this.directionalShadowCameras[e],this.spatialShadowMatrix),this.spatialShadowPlanes[this.spatialShadowCount++]);for(const e of v){if(!e.castShadow)continue;const t=4*this.spatialLocalShadowCount++,r=this.spatialLocalShadowSpheres;r[t]=e.position.x,r[t+1]=e.position.y,r[t+2]=e.position.z,r[t+3]=e.shadowCameraFar*Math.sqrt(3)}for(const e of x){if(!e.castShadow)continue;const t=4*this.spatialLocalShadowCount++,r=this.spatialLocalShadowSpheres;r[t]=e.position.x,r[t+1]=e.position.y,r[t+2]=e.position.z;const i=Math.tan(e.shadowCameraFov*Math.PI/360);r[t+3]=e.shadowCameraFar*Math.sqrt(1+2*i*i)}for(this.spatialIncludeOffscreen=r,this.spatialCameraLayers=t.layers.mask,this.staticSceneSpatialIndex.queryWithState(e,this.testSpatialScene,this.pushSpatialRoot,63);T.length;)this.collectSpatialRoot(T.pop());break}const i=T.pop();if(this.extractingCaster=i.castShadow,!i.visible)continue;if(!1===this.sceneCaptureOptions?.objectFilter?.(i))continue;if(null!==this.sceneCaptureOptions&&!1===i.userData.sceneCapture)continue;if(i.isBone){const e=this.staticSceneSpatialIndex.traversalChildren(i);for(let t=e.length-1;t>=0;t--)T.push(e[t]);continue}const n=0!==(i.layers.mask&t.layers.mask);if(!0===i.isFogVolumeObject&&null!=i.volume)w.push(i);else if(i.isAmbientLight){if(n){const e=i;h.x+=e.color.r*e.intensity,h.y+=e.color.g*e.intensity,h.z+=e.color.b*e.intensity,h.w=1}}else if(i.isHemisphereLight){if(n&&null==p){const e=i,t=this.extractedHemisphereScratch;k.setFromMatrixPosition(e.matrixWorld),t.direction.copy(k),t.direction.lengthSq()<=1e-10?t.direction.set(0,1,0):t.direction.normalize(),t.skyColor.set(e.color.r,e.color.g,e.color.b),t.groundColor.set(e.groundColor.r,e.groundColor.g,e.groundColor.b),t.intensity=e.intensity,p=t}}else if(i.isDirectionalLight){if(n&&g.length<4&&!this.hasExtractedDirectionalLight(g,i)){const e=i,t=e.shadow,r=t.camera,n=this.extractedDirectionalLightsScratch[g.length];n.sourceLight=e,e.target.matrixWorldAutoUpdate&&e.target.updateMatrixWorld(!0),k.setFromMatrixPosition(e.matrixWorld),F.setFromMatrixPosition(e.target.matrixWorld),n.position.copy(k),n.target.copy(F),n.direction.copy(F).sub(k).normalize(),n.color.set(e.color.r,e.color.g,e.color.b),n.intensity=e.intensity,n.volumetricIntensity=e.userData?.volumetricIntensity??0,n.castShadow=e.castShadow&&this.directionalShadowsEnabled,n.shadowBias=t.bias,n.shadowNormalBias=t.normalBias,n.shadowRadius=t.radius,n.shadowIntensity=t.intensity,n.shadowMapSize=Math.max(1,t.mapSize.width,t.mapSize.height),n.shadowCameraLeft=r.left,n.shadowCameraRight=r.right,n.shadowCameraTop=r.top,n.shadowCameraBottom=r.bottom,n.shadowCameraNear=r.near,n.shadowCameraFar=r.far,g.push(n)}}else if(i.isPointLight){if(n&&!1!==this.sceneCaptureOptions?.includeLocalLights){const e=i;!0===e.userData.vfxTransientLight?this.selectTransientPointLight(e,M):v.length<b&&this.extractPointLight(e,v)}}else if(i.isSpotLight){if(n&&!1!==this.sceneCaptureOptions?.includeLocalLights&&x.length<y){const e=i,t=e.shadow,r=t.camera,n=this.extractedSpotLightsScratch[x.length];n.sourceLight=e,e.target.matrixWorldAutoUpdate&&e.target.updateMatrixWorld(!0),k.setFromMatrixPosition(e.matrixWorld),F.setFromMatrixPosition(e.target.matrixWorld);const a=e.distance>0?e.distance:r.far;if(!Mi(this.cameraFrustumPlanesScratch,k.x,k.y,k.z,a))continue;n.position.copy(k),n.direction.copy(F).sub(k).normalize(),n.color.set(e.color.r,e.color.g,e.color.b),n.intensity=e.intensity,n.volumetricIntensity=e.userData?.volumetricIntensity??0,n.range=a,n.angle=e.angle,n.penumbra=e.penumbra,n.decay=e.decay,n.castShadow=e.castShadow,n.shadowBias=t.bias,n.shadowNormalBias=t.normalBias,n.shadowRadius=t.radius,n.shadowIntensity=t.intensity,n.shadowMapSize=Math.max(1,t.mapSize.width,t.mapSize.height),n.shadowCameraNear=r.near,n.shadowCameraFar=e.distance>0?e.distance:r.far,n.shadowCameraFov=e.angle*(360/Math.PI)*t.focus,n.map=e.map??null,x.push(n)}}else n&&i.isBatchedMesh?this.collectBatchedMesh(i,a,D,B,t,M,P):n&&i.isInstancedMesh?this.collectInstancedMesh(i,a,D,B):n&&i.isSkinnedMesh?this.collectSkinnedMesh(i,a,D,B):n&&i.isLine?this.collectLine(i,a,D,B):n&&i.isSprite?this.collectSprite(i,a,D,B):n&&i.isMesh&&this.collectMesh(i,a,D,B);const s=this.staticSceneSpatialIndex.traversalChildren(i);for(let e=s.length-1;e>=0;e-=1)T.push(s[e])}const I=this.dynamicBatchingEnabled?o.length:0;this.updateTransparentDrawSortDepths(i,M,P),i.sort(di),Number.isFinite(S.x)||(S.set(-6,-6,-6),C.set(6,6,6)),this.dynamicBatchingEnabled&&this.sortOpaqueDraws(l);for(let e=0;e<l.length;){const t=l[e];if(!this.dynamicBatchingEnabled){t.sourceRanges=void 0,t.indexed&&!t.hasRenderCallbacks?s.push(t):o.push(t),e++;continue}const 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;this.dynamicBatchingEnabled&&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}v.sort(Zp),x.sort(Zp);for(let e=4;e<v.length;e+=1)v[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=g[0]??null,V.point=v[0]??null,V.spot=x[0]??null;const L=this.extractedFrameScratch;L.scene=e,L.camera=t,L.fogVolumeObjects=w,L.transparentDraws=i,L.instanceData=d,L.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??f(r.sourceObject);r.cameraDetailRejected||!this.isSphereVisibleScratch(r.boundsCenter.x,r.boundsCenter.y,r.boundsCenter.z,r.boundsRadius,r.sourceObject?.frustumCulled??!0)||null===this.sceneCaptureOptions&&!m(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 L.shadowDraws=G,L}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 hd(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 id;f.setIndex([0,2,1,2,3,1,2,4,3,4,5,3,4,6,5,6,7,5]),f.setAttribute("position",new rd(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 od(new Float32Array(d),3)),f.setAttribute("instanceEnd",new od(new Float32Array(h),3)),f.instanceCount=d.length/3;const m=Pi(n);f.boundingSphere=new gd(m.center.clone(),m.radius),o={signature:s,sourceGeometry:n,mesh:new hd(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 hd(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){if(null!==this.sceneCaptureOptions)return this.captureMotionHistory.matrix.set(t),this.captureMotionHistory;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.motionHistoryExtractionVersion-1&&!i&&n*n+a*a+s*s<=o*o,r}commitObjectMotionHistory(e,t){null===this.sceneCaptureOptions&&(e.matrix.set(t),e.generation=this.motionVectorHistoryGeneration,e.lastExtractionVersion=this.motionHistoryExtractionVersion)}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.hasRenderCallbacks(e)?void 0:this.staticSceneSpatialIndex.getMeshSnapshot(e);let l=o?null:this.getGeometryResource(n,!0);const c=this.meshExtractionCache.get(e),u=c?.geometryResource===l?c:null,d=o||u?null:Pi(n),h=o?.boundsCenter??u?.localBoundsCenter??d.center,p=o?.boundsRadius??u?.localBoundsRadius??d.radius,f=e.matrixWorld.elements,g=h.x,v=h.y,x=h.z,w=o?.boundsCenter.x??f[0]*g+f[4]*v+f[8]*x+f[12],b=o?.boundsCenter.y??f[1]*g+f[5]*v+f[9]*x+f[13],y=o?.boundsCenter.z??f[2]*g+f[6]*v+f[10]*x+f[14];let S,C=o?.boundsRadius;if(void 0===C){const e=f[0]*f[0]+f[1]*f[1]+f[2]*f[2],t=f[4]*f[4]+f[5]*f[5]+f[6]*f[6],r=f[8]*f[8]+f[9]*f[9]+f[10]*f[10];C=p*Math.sqrt(Math.max(e,t,r,1e-10))}if(!i(w,b,y,C,e.frustumCulled))return;if(o&&null===this.sceneCaptureOptions&&i!==this.isSphereVisibleForCompilationScratch){const t=o.detailCulling;if(S=!m(o.boundsCenter,C,this.cameraViewProjScratch,this.state.width,this.state.height,this.transparentSortCameraPositionScratch,t.minScreenSize*(this.cameraDetailHistory.get(e)?.85:1.15),t.maxDistance),this.cameraDetailHistory.set(e,!S),S&&(!e.castShadow||!this.isSpatialShadowSphereVisible(w,b,y,C)))return}l??=this.getGeometryResource(n,!0);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=Li(e),D=c&&c.customDepthMaterial===B&&c.geometryResource.lastValidatedExtractionVersion===this.extractionVersion&&(!s&&c.material===a&&c.resolvedMaterial===P||s&&null!==c.materials&&null!==c.resolvedMaterials&&Nr(c.materials,a)&&qr(c.resolvedMaterials,M))?c:this.getMeshExtractionCacheEntry(e,a,P,M,B,l),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,f),L=Hp(e),G=qp(e);let R,z=0,U=null;if(!(n instanceof ld&&I>1)||e instanceof md||this.hasRenderCallbacks(e))for(let e=0;e<I;e+=1){const r=ni(t,f,1,1,1,1,void 0,V.matrix,L,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 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)}U=t.data,U.update(I,f,V.matrix,L,G,V.valid?1:0),!U.residentBufferDirty&&U.residentInstanceBinding.buffer||this.residentInstanceUploadsScratch.push(U)}if(this.commitObjectMotionHistory(V,f),r(f),o&&!this.dynamicBatchingEnabled&&null===this.sceneCaptureOptions){let e=this.staticMeshDraws.get(o);e&&e.templates===D.templates||(e={templates:D.templates,draws:[]},this.staticMeshDraws.set(o,e)),R=e.draws}for(let t=0;t<T;t+=1){const r=D.templates[t];let i=R?.[t];i?(i.receiveShadow!==e.receiveShadow&&(i.materialResource=null),i.receiveShadow=e.receiveShadow,i.castShadow=e.castShadow,i.renderOrder=e.renderOrder,i.instanceStart=z,i.instanceCount=I):(i=this.populateDrawCall(R?this.createDrawCall():this.acquireDrawCall(),r,z,I,w,b,y,C,o),R&&(R[t]=i)),i.cameraDetailRejected=S,i.residentInstanceBinding=U?.residentInstanceBinding??r.residentInstanceBinding,r.transparent?this.transparentDraws.push(i):this.pushDraw(i);const n=s?a[r.geometryGroup?.materialIndex??0]:a;this.pushToonOutlineDraw(i,n)}}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=Li(e),l=this.getGeometryResource(e.geometry,!0),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],C=s[5],M=s[9],P=s[13],B=s[2],D=s[6],T=s[10],I=s[14],V=s[3],L=s[7],G=s[11],R=s[15];for(let n=0;n<e.count;n+=1){const e=16*n,s=n*S,c=u[e+0]??0,d=u[e+1]??0,f=u[e+2]??0,z=u[e+3]??0,U=u[e+4]??0,A=u[e+5]??0,F=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=z,J=U,Q=A,ee=F,te=$,re=E,ie=O,ne=_,ae=j,se=N,oe=W,le=H,ce=q):(K=v*c+x*d+w*f+b*z,J=v*U+x*A+w*F+b*$,re=v*E+x*O+w*_+b*j,se=v*N+x*W+w*H+b*q,Z=y*c+C*d+M*f+P*z,Q=y*U+C*A+M*F+P*$,ie=y*E+C*O+M*_+P*j,oe=y*N+C*W+M*H+P*q,Y=B*c+D*d+T*f+I*z,ee=B*U+D*A+T*F+I*$,ne=B*E+D*O+T*_+I*j,le=B*N+D*W+T*H+I*q,X=V*c+L*d+G*f+R*z,te=V*U+L*A+G*F+R*$,ae=V*E+L*O+G*_+R*j,ce=V*N+L*W+G*H+R*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);Ti(r,i,k.set(de,he,pe),ve)}c.cachedDrawBoundsCenter.copy(r).add(i).multiplyScalar(.5);const z=i.x-c.cachedDrawBoundsCenter.x,U=i.y-c.cachedDrawBoundsCenter.y,A=i.z-c.cachedDrawBoundsCenter.z;c.cachedDrawBoundsRadius=Math.sqrt(z*z+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=k;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*Bi(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=Li(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*Bi(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,Hp(e),qp(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=Li(e),c=(e.geometry.index,this.getGeometryResource(e.geometry,!0)),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?z.fromArray(p,16*n):e.getMatrixAt(n,z),U.multiplyMatrices(e.matrixWorld,z);const h=u.localBoundsCenter,g=U.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,U,M,P,B,D,n);r(U.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 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),w.push(r)),r.activeCount+=1,C+=1):m.geometryIdsSnapshot[e]=-1}const M=m.cachedInstanceData.beginWriteInstances(C);let P=0;for(let e=0;e<w.length;e+=1){const t=w[e];t.instanceStart=P,t.writeOffset=P*S,P+=t.activeCount}const B=wi(g),D=g[0],T=g[4],I=g[8],V=g[12],L=g[1],G=g[5],R=g[9],A=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,C,P,U,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,C=p[e+13]??0,P=p[e+14]??0,U=p[e+15]??0}else{e.getMatrixAt(t,z);const r=z.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,C=r[13]??0,P=r[14]??0,U=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=C,ae=P,se=U):(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*C+I*P+V*U,H=L*n+G*a+R*s+A*o,Y=L*l+G*c+R*u+A*d,ee=L*h+G*g+R*v+A*x,ne=L*w+G*C+R*P+A*U,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*C+$*P+E*U,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+_*C+j*P+N*U);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+=S;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 wd,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,M,0,S)}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,P,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,M,0,S),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(),e.temporalDepthSupported=Vh(e.draws)}}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=Ii(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=Yp){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=Yp,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===Yp)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=Yp){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*C;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*C;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*C*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+=Ii(e)}executeVisibilityPass(e,t){Wh.call(this,e,t)}executeStaticVisibilityPasses(e,t){Kh.call(this,e,t)}getOrCreateStaticVisibilityBindGroup(e,t){return Zh.call(this,e,t)}executeDirectionalShadowPass(e,t,r,i){Yh.call(this,e,t,r,i)}executePointShadowPass(e,t,r,i){Jh.call(this,e,t,r,i)}executeSpotShadowPass(e,t,r,i){Qh.call(this,e,t,r,i)}executeDepthPrepass(e,t,r,i){tp.call(this,e,t,r,i)}executeStaticDepthPrepass(e,t,r){rp.call(this,e,t,r)}executeStaticTemporalDepthResolvePass(e){np.call(this,e)}getOrCreateStaticDepthPrepassBundle(e,t){return sp.call(this,e,t)}executeHiZPasses(e,t=!1,r=!1){cp.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&&this.state.lightBuffer))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:1,resource:{buffer:this.state.lightBuffer}},{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={},s){if(!this.state.mainDepthView||0===t.length)return;const o=t.map(e=>this.getColorTargetFormat(e)),l=this.getColorFormatsId(o),c=t.map(e=>s?.colorView??this.getColorTargetView(e)),u=!s&&this.sampleCount>1,d=u?t.map(e=>this.ensureMsaaColorTarget(e)):[],h=this.getColorTargetDimensions(t[0]),p=u?this.ensureMsaaDepthTarget(h.width,h.height):null,f=e.beginRenderPass({label:"renderer-material-pass",colorAttachments:t.map((e,t)=>({view:d[t]?.view??c[t],resolveTarget:d[t]?c[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:d[t]?"discard":"store"})),depthStencilAttachment:{view:s?.depthView??p?.view??this.state.mainDepthView,depthClearValue:1,depthLoadOp:p?"clear":a.loadDepth?"load":"clear",depthStoreOp:p?"discard":"store"}});let m=null,g=null,v=null,x=null,w=null;const b=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 l=this.getMaterialResourceForDraw(e,o,s?1:this.sampleCount),c=this.resolveSceneBindGroupForDraw(e,r);if(m!==l.pipeline&&(m=l.pipeline,v=null,w=null,f.setPipeline(m)),v!==e.geometryKey&&(v=e.geometryKey,this.bindGeometryVertexBuffers(f,e.geometry,t,l.vertexAttributes,e.instanceStart,e.instanceCount,e.wireframe)),x!==c&&(x=c,f.setBindGroup(0,c)),g!==a){if(g=a,f.setBindGroup(1,l.bindGroup),!l.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");f.setBindGroup(3,this.createGraphTextureBindGroup(a,l.graphTextureBindGroupLayout))}l.usesSkinning&&e.skinning&&w!==e.skinning.bindGroup&&(w=e.skinning.bindGroup,f.setBindGroup(2,w)),e.indexed&&(e.wireframe?t.wireframeIndex:t.index)?f.drawIndexed(e.count,e.instanceCount,e.start,0,e.instanceStart):f.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)},y=a.drawStage??"all";if(a.objectFilter||a.overrideMaterial){const e=e=>{if(s){if(!this.isSphereVisibleScratch(e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius,!0))return;if(e.material.requiresLatePass())return;this.prepareDrawGeometryVertexBuffers(e),e={...e,receiveShadow:!1,materialResource:null}}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)b({...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;b(t?{...e,material:t}:e)};if("late"!==y){for(const t of this.getCameraStaticDrawSets())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"!==y){if(s)for(const t of this.staticDrawSets)if(t.publicSet.enabled&&"late"===t.drawStage)for(const r of t.draws)e(r);for(const t of i.transparentDraws)e(t)}return void f.end()}if("late"!==y){const e=this.renderBundleScratch;e.length=0;for(const t of this.getCameraStaticDrawSets()){if(!t.publicSet.enabled||!this.isStaticDrawSetCameraVisible(t)||0===t.draws.length||"opaque"!==t.drawStage)continue;if(this.getHiZOcclusionCullingActive()&&t.lastVisibilityFrameToken===this.staticFrameToken){const r=this.getOrCreateStaticVisibleSceneBindGroup(t),i=this.getOrCreateStaticIndirectSubmissionStreams(t,r,o);for(const r of i){if(this.getMultiDrawIndirectActive()){if(e.length&&(f.executeBundles(e),e.length=0),f.setPipeline(r.materialResource.pipeline),this.bindGeometryVertexBuffers(f,r.geometry,r.geometryResource,r.materialResource.vertexAttributes,0,1,r.material.wireframe),f.setBindGroup(0,r.sceneBindGroup),f.setBindGroup(1,r.materialResource.bindGroup),!r.materialResource.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");f.setBindGroup(3,this.createGraphTextureBindGroup(r.material,r.materialResource.graphTextureBindGroupLayout)),f.multiDrawIndexedIndirect(t.drawMetadataResource.indirectBuffer,5*r.indirectStartIndex*Uint32Array.BYTES_PER_ELEMENT,r.indirectCount)}else e.push(this.getOrCreateIndirectForwardBundle(r,t.drawMetadataResource,t.indirectForwardBundleCache,`${t.label}-static-indirect-material-bundle`,o,!1,l));n.drawCallCount+=r.drawCallCount,n.triangleCount+=r.triangleCount}continue}const i=this.getOrCreateStaticMaterialBundle(t,r,n,o);i&&e.push(i)}if(e.length&&f.executeBundles(e),e.length=0,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],o);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",o,!0,l);t?(this.renderBundleScratch[0]=t,f.executeBundles(this.renderBundleScratch)):this.submitIndirectStreamDirect(f,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,o);if(e)this.renderBundleScratch[0]=e,f.executeBundles(this.renderBundleScratch);else for(const e of i.gpuOpaqueDraws)b(e)}const t=hi(i.directOpaqueDraws)||i.directOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(i.directOpaqueDraws,r,n,o);if(t)this.renderBundleScratch[0]=t,f.executeBundles(this.renderBundleScratch);else for(const e of i.directOpaqueDraws)b(e)}if("opaque"!==y)for(const e of i.transparentDraws)b(e);f.end()}executeForwardPass(e,t,r,i,n,a,s=!1,o="all",l=!1,c=this.sampleCount){up.call(this,e,t,r,i,n,a,s,o,l,c)}executeStaticForwardPass(e,t,r,i="all",n=this.sampleCount){dp.call(this,e,t,r,i,n)}getOrCreateStaticDirectForwardBundle(e,t,r=this.sampleCount){return hp.call(this,e,t,r)}refreshStaticDrawMaterialResources(e){fp.call(this,e)}syncStaticVisibleMaterialBindingCaches(e){pp.call(this,e)}recordStaticDrawStats(e,t){mp.call(this,e,t)}hasEnabledStaticDrawSets(){return gp.call(this)}executePresentPass(e,t,r){vp.call(this,e,t,r)}clearDirectionalShadow(e){xp.call(this,e)}clearPointShadow(e){wp.call(this,e)}clearSpotShadow(e){bp.call(this,e)}drawDepthLike(e,t,r,i){yp.call(this,e,t,r,i)}getGeometryResource(e,t=!1){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=this.geometryCache.get(e);if((t||!this.invokeObjectRenderCallbacks)&&r&&r.lastValidatedExtractionVersion===this.extractionVersion)return r;if(r&&this.updateDynamicGeometryAttributes(e,r))return r.lastValidatedExtractionVersion=this.extractionVersion,r;if(r&&r.lastValidatedExtractionVersion===this.extractionVersion)return r;if(r&&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,r))return r.lastValidatedExtractionVersion=this.extractionVersion,r;r&&(this.clearIndirectBundleCache(),this.retireGeometryResource(r));const i=e.getAttribute("position");if(!i)throw new Error("BufferGeometry is missing the required position attribute.");const n=i.count,a=Yr(i,n,3,[0,0,0]),s=Yr(e.getAttribute("normal"),n,3,[0,0,1]),o=Yr(e.getAttribute("uv"),n,2,[0,0]),l=Yr(e.getAttribute("color"),n,4,[1,1,1,1]),c=e.getAttribute("skinIndex"),u=e.getAttribute("skinWeight"),d=c?Xr(c,n,"uint32x4",[]):void 0,h=u?Xr(u,n,"float32x4",[]):void 0,p={signature:$r(e),indexVersion:e.index?.version??0,drawRangeStart:e.drawRange.start,drawRangeCount:e.drawRange.count,vertexCount:n,attributes:["position","normal","uv","color",...c?["skinIndex"]:[],...u?["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,a,s,o,l,d,h,e.index?.array),extraAttributeBuffers:new Map,extraAttributeBufferVersions:new Map,wireframeIndex:null,wireframeIndexFormat:null};return this.geometryCache.set(e,p),p}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 rd&&!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 wd,localBoundsMax:new wd,localBoundsCenter:new wd,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(null!==this.sceneCaptureOptions)return;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 wd(1/0,1/0,1/0)),a=Array.from({length:e.skeleton.bones.length},()=>new wd(-1/0,-1/0,-1/0));for(let e=0;e<t.count;e+=1){k.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(k),l.max(k))}}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=Pi(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=Di(a.center,a.radius,e.bindMatrix,t.skinning.palette.skeleton.boneMatrices,16*n,e.bindMatrixInverse,k);r.min(F.copy(k).addScalar(-s)),i.max(F.copy(k).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:this.getSharedVertexAttributeLayout(e.vertexAttributes)},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=this.getSharedVertexAttributeLayout(i),r.skinned}getSharedVertexAttributeLayout(e){const t=JSON.stringify(e.map(e=>[e.name,e.shaderLocation,e.format,e.stepMode??"vertex",e.defaultValue??null]));let r=this.sharedVertexAttributeLayouts.get(t);return r||(r=e.map(e=>({...e,defaultValue:e.defaultValue?.slice()})),this.sharedVertexAttributeLayouts.set(t,r)),r}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(!s&&(o||r.defaultValue)){const e=this.getDefaultVertexAttributeBuffer(r,o?l+Math.max(1,n):t.vertexCount);return this.cacheGeometryVertexBufferFast(t,r,l,void 0,0,e),e}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,u=l.get(r);u&&u.buffer!==a&&this.clearIndirectBundleCache(),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,o=`interleaved:${this.getGeometryAttributeGroupBufferKey(r)}:instance-start=${s}`;let l=this.packedVertexGroups.get(t);l||(l=new Map,this.packedVertexGroups.set(t,l));let c=l.get(o);c||(c=new ki(r),l.set(o,c));const u=c.update(e,t.vertexCount,s,n),d=t.extraAttributeBuffers.get(o);if(!u&&d)return d;const h=c.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(o,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,a=!1){let s=this.preparedVertexBufferCache.get(t);s||(s=new WeakMap,this.preparedVertexBufferCache.set(t,s));let o=s.get(r);o||(o={instanced:r.some(e=>"instance"===e.stepMode),ranges:new Map},s.set(r,o));const l=o.instanced?Math.max(0,Math.trunc(i)):0,c=o.instanced?n:1;let u=o.ranges.get(l);if((a||!this.invokeObjectRenderCallbacks)&&u&&u.extractionVersion===this.extractionVersion&&u.instanceCount===c&&u.instanceBufferSize===this.state.instanceBufferSize)return u.buffers;u||(u={extractionVersion:-1,instanceCount:c,instanceBufferSize:0,buffers:[]},o.ranges.set(l,u));let d=this.vertexBufferBindingPlanCache.get(r);d||(d=this.getVertexAttributeGroups(r).map(e=>({group:e,standardAttribute:1===e.length?this.getStandardVertexAttribute(e[0]):null})),this.vertexBufferBindingPlanCache.set(r,d));for(let r=0;r<d.length;r+=1){const{group:a,standardAttribute:s}=d[r],o=s?t[s]:null;u.buffers[r]=o??(1===a.length?this.getGeometryVertexBuffer(e,t,a[0],i,n):this.getInterleavedGeometryVertexBuffer(e,t,a,i,n))}return u.extractionVersion=this.extractionVersion,u.instanceCount=c,u.instanceBufferSize=this.state.instanceBufferSize,u.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,nf)?"uv"!==e.name||"float32x2"!==e.format||void 0!==e.defaultValue&&!Kr(e.defaultValue,rf)?"color"!==e.name||"float32x4"!==e.format||void 0!==e.defaultValue&&!Kr(e.defaultValue,af)?"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,t=!1){for(let r=0;r<(e.customDepthMaterial?2:1);r++){const i=0===r?e.material:e.customDepthMaterial,n=this.getMaterialVertexAttributes(i,null!==e.skinning);this.prepareGeometryVertexBuffers(e.geometry,e.geometryResource,n,e.instanceStart,e.instanceCount,t)}}getDefaultVertexAttributeBuffer(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=Math.max(1,t,"instance"===e.stepMode?Math.ceil(this.state.instanceBufferSize/(Float32Array.BYTES_PER_ELEMENT*S)):0),i=2**Math.ceil(Math.log2(r)),n=`${e.format}:${(e.defaultValue??[]).join(",")}`;let a=this.defaultVertexAttributeBuffers.get(n);a||(a=new Map,this.defaultVertexAttributeBuffers.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-attribute-${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=Pi(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=Pi(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 Ri(1024),cachedBoundsMin:new wd,cachedBoundsMax:new wd,cachedDrawBoundsCenter:new wd,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,A),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 wd,localBoundsRadius:f?.radius??1};l[n]=m,c[n]={template:m,boundsMin:new wd,boundsMax:new wd,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 Ri(1024),cachedDraws:[],cachedBoundsMin:new wd,cachedBoundsMax:new wd,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=Yp,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 cd&&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)))}for(const e of a.draws){if(e.customDepthMaterial||null===e.material.depthVertexShader||e.material.vertexAttributes.some(e=>"instance"===e.stepMode))continue;const t=`prepass-visible:${e.material.uuid}:${this.drawUsesBatching(e)}:${gi(e)}`;n.has(t)||(n.add(t),i.push(this.getDepthPassMaterialResourceAsync(e.material,"prepass","packed-visible",!1,this.drawUsesBatching(e),gi(e))))}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=Cd(`${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(;_d(e.charCodeAt(a));)a++;if("("!==e[a++])continue;for(;_d(e.charCodeAt(a));)a++;if(!e.startsWith("position",a))continue;for(a+=8;_d(e.charCodeAt(a));)a++;if(")"!==e[a++])continue;Od.lastIndex=a;const s=Od.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:b,NUM_SPOT_LIGHTS:y,NUM_DIR_LIGHT_SHADOWS:4,NUM_POINT_LIGHT_SHADOWS:b,NUM_SPOT_LIGHT_SHADOWS:y,NUM_CLIPPING_PLANES:0,UNION_CLIPPING_PLANES:0,USE_SKINNING:r,RENDERER_MOTION_VECTORS:!t.includes("shared-depth"),...this.createTexturePreprocessorDefines(e)};return e.side===ad?n.DOUBLE_SIDED=!0:e.side===td&&(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=Yp,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:"packed-visible"===n?this.state.visibleDepthSceneBindGroupLayout: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=dh(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:Jp(t),cullMode:Qp(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:"packed-visible"===n?this.state.visibleDepthSceneBindGroupLayout: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=dh(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 sf(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:Jp(t),cullMode:Qp(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=ch(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:Wp(x,s,jp(t))},primitive:{topology:Jp(t),cullMode:Jp(t).startsWith("triangle")&&t.side!==ad?t.side===td?"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=ch(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 sf(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:Wp(g,s,jp(t))},primitive:{topology:Jp(t),cullMode:Jp(t).startsWith("triangle")&&t.side!==ad?t.side===td?"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??Yp,u=void 0===i||1===i.length&&i[0]===B,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??Yp,u=void 0===i||1===i.length&&i[0]===B,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,r){if(!this.state.device||!this.state.cameraBuffer)return;const i=this.cameraProjectionScratch.copy(e.projectionMatrix);r||0===this.projectionJitterPixels.x&&0===this.projectionJitterPixels.y||(i.elements[8]-=2*this.projectionJitterPixels.x/this.state.width,i.elements[9]-=2*this.projectionJitterPixels.y/this.state.height);const n=this.cameraViewProjScratch.copy(T).multiply(i).multiply(e.matrixWorldInverse);e.getWorldPosition(k);const a=this.cameraUniformScratch;a.set(n.elements,0),a[16]=k.x,a[17]=k.y,a[18]=k.z,a[19]=1,a[20]=r?.width??this.state.width,a[21]=r?.height??this.state.height,a[22]=r?1:this.state.pixelRatio,a[23]=this.state.frameTimeSeconds,a.set(e.matrixWorldInverse.elements,24),a.set(U.multiplyMatrices(T,i).elements,40),a[56]=e.near,a[57]=e.far,a[58]=1/Math.max(e.far-e.near,1e-4),a[59]=!r&&this.tiledLightingEnabled?1:0;const s=r?null:t.fog;null!=s?(a[60]=s.color.r,a[61]=s.color.g,a[62]=s.color.b,a[63]=1,"density"in s?(a[64]=0,a[65]=0,a[66]=s.density,a[67]=1):(a[64]=s.near,a[65]=s.far,a[66]=0,a[67]=0)):(a.fill(0,60,68),a[67]=-1);const o=!r&&this.motionVectorProjectionPending?this.motionVectorProjection:e.projectionMatrix,l=(r?z:this.motionVectorCurrentViewProj).copy(T).multiply(o).multiply(e.matrixWorldInverse);a.set(l.elements,68),a.set((!r&&this.motionVectorHistoryValid?this.motionVectorPreviousViewProj:l).elements,84),a[100]=!r&&this.motionVectorHistoryValid?1:0,a[101]=r?.width??this.state.width,a[102]=r?.height??this.state.height,a[103]=0,r||(this.motionVectorProjectionPending=!1),this.state.device.queue.writeBuffer(this.state.cameraBuffer,0,a,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;const t=this.lightUniformScratch;null===this.sceneCaptureOptions&&this.updateSpotLightMapAtlas(e.lights.spots),t.fill(0),t[0]=e.lights.ambient.x,t[1]=e.lights.ambient.y,t[2]=e.lights.ambient.z,t[3]=e.lights.ambient.w,t[4]=e.lights.directionals.length,t[5]=e.lights.points.length,t[6]=e.lights.spots.length,t[7]=Math.min(this.csmCascadeCount,e.lights.directionals.length);for(let e=0;e<this.csmCascadeCount;e+=1){const r=this.csmCascadeRanges[e],i=3976+4*e;t[i+0]=r.x,t[i+1]=r.y}const r=e.lights.hemisphere;null!=r&&(t[3992]=r.skyColor.x,t[3993]=r.skyColor.y,t[3994]=r.skyColor.z,t[3995]=r.intensity,t[3996]=r.groundColor.x,t[3997]=r.groundColor.y,t[3998]=r.groundColor.z,t[3999]=r.intensity,t[4e3]=r.direction.x,t[4001]=r.direction.y,t[4002]=r.direction.z,t[4003]=1);for(let r=0;r<e.lights.directionals.length;r+=1){const i=e.lights.directionals[r],n=this.directionalShadowCameras[r],a=8+4*r;t[a+0]=i.direction.x,t[a+1]=i.direction.y,t[a+2]=i.direction.z,t[a+3]=1;const s=24+4*r;t[s+0]=i.color.x,t[s+1]=i.color.y,t[s+2]=i.color.z,t[s+3]=i.intensity;const o=40+4*r;t[o+0]=i.shadowBias,t[o+1]=i.castShadow?1:0,t[o+2]=this.state.directionalShadowTextureSize,t[o+3]=i.shadowNormalBias;const l=56+4*r;t[l+0]=i.shadowRadius,t[l+1]=i.shadowIntensity;const c=i.shadowViewProjection??=new dd;t.set(yi(n,c).elements,72+16*r)}for(let r=0;r<e.lights.points.length;r+=1){const i=e.lights.points[r],n=136+4*r;t[n+0]=i.position.x,t[n+1]=i.position.y,t[n+2]=i.position.z,t[n+3]=i.range;const a=392+4*r;t[a+0]=i.color.x,t[a+1]=i.color.y,t[a+2]=i.color.z,t[a+3]=i.intensity;const s=648+4*r;t[s+0]=i.distance,t[s+1]=i.decay;const o=904+4*r;t[o+0]=i.shadowBias,t[o+1]=i.castShadow?1:0,t[o+2]=this.state.pointShadowTextureSize,t[o+3]=i.shadowNormalBias;const l=1160+4*r;t[l+0]=i.shadowRadius,t[l+1]=i.shadowIntensity,t[l+2]=i.shadowCameraNear,t[l+3]=i.shadowCameraFar}for(let r=0;r<e.lights.spots.length;r+=1){const i=e.lights.spots[r],n=1416+4*r;t[n+0]=i.position.x,t[n+1]=i.position.y,t[n+2]=i.position.z,t[n+3]=i.range;const a=1672+4*r;t[a+0]=i.direction.x,t[a+1]=i.direction.y,t[a+2]=i.direction.z,t[a+3]=Math.cos(i.angle);const s=1928+4*r;t[s+0]=i.color.x,t[s+1]=i.color.y,t[s+2]=i.color.z,t[s+3]=i.intensity;const o=2184+4*r;t[o+0]=i.shadowBias,t[o+1]=i.castShadow?1:0,t[o+2]=this.state.spotShadowTextureSize,t[o+3]=i.shadowNormalBias;const l=2440+4*r;t[l+0]=i.shadowRadius,t[l+1]=i.shadowIntensity;const c=2696+4*r;if(t[c+0]=i.range,t[c+1]=Math.cos(i.angle*(1-i.penumbra)),t[c+2]=i.decay,t[c+3]=null!=i.map?1:0,i.castShadow||null!=i.map){const e=this.spotShadowCameras[r];e.near=i.shadowCameraNear,e.far=i.shadowCameraFar,e.fov=i.shadowCameraFov,e.aspect=1,e.position.copy(i.position),F.copy(i.position).add(i.direction),e.lookAt(F),e.updateMatrixWorld(!0),e.updateProjectionMatrix(),t.set(yi(e,this.shadowViewProjScratch).elements,2952+16*r)}}this.state.device.queue.writeBuffer(this.state.lightBuffer,0,t,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 rf=[0,0],nf=[0,0,1],af=[1,1,1,1];async function sf(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,t)}finally{r&&i&&n&&r.pipelines.push({kind:i,material:n,durationMs:performance.now()-o,vertexCodeLength:a,fragmentCodeLength:s})}}import{DataTexture as of,Matrix4 as lf,RepeatWrapping as cf}from"three";var uf={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}}},df=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 of(i,5,5);return n.wrapS=cf,n.wrapT=cf,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=xf(e)}get enabled(){return this.options.enabled}get temporalEnabled(){return!1!==this.options.temporal}setOptions(e){Object.assign(this.options,xf({...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(uf[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 hf(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 pf(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 ff(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 mf(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}},hf=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 lf;webGpuProjectionInverse=new lf;frameIndex=0;updateUniforms=e=>(this.webGpuProjection.copy(gf).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)},pf=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=vf;uniforms=new Float32Array(this.uniformBufferSize/4);inverseProjection=new lf;updateUniforms=e=>(this.inverseProjection.copy(gf).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)},ff=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 lf;updateUniforms=e=>(this.webGpuProjectionInverse.copy(gf).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)},mf=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"},gf=(new lf).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);var vf="\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 xf(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:bf(e.resolutionScale??1,.25,1),thickness:Math.max(.001,e.thickness??1),distanceExponent:Math.max(.01,e.distanceExponent??1),distanceFalloff:bf(e.distanceFalloff??1,0,1),directions:yf(e.directions??3,1,8),steps:yf(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:wf(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:bf(e.temporal?.historyWeight??.9,0,.98),depthRejection:bf(e.temporal?.depthRejection??.08,.001,1),neighborhoodClamp:e.temporal?.neighborhoodClamp??!0}}}function wf(e){return e<=4?4:e<=8?8:e<=12?12:16}function bf(e,t,r){return Math.min(r,Math.max(t,e))}function yf(e,t,r){return Math.floor(bf(e,t,r))}import{Matrix4 as Sf}from"three";var Cf=class{options;passes=new Map;constructor(e={}){var t,r,i;this.options={resolutionScale:Tf(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:Tf(e.maxRoughness??.8,.01,1),steps:(t=e.steps??2048,r=8,i=2048,Math.round(Tf(t,r,i))),pixelStride:Tf(e.pixelStride??1,1,4),normalSpace:e.normalSpace??"world",blur:e.blur??!0,blurRadius:Tf(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 Mf(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 Pf(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 Bf(t.sceneColor,a,s,this.options.intensity),this.passes.set(o,l)),e.addFullscreenPass(l),s}},Mf=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 Sf;inverseProjection=new Sf;updateUniforms=e=>(this.projection.copy(Df).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)},Pf=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}"},Bf=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 Df=(new Sf).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);function Tf(e,t,r){return Math.min(r,Math.max(t,e))}import{Matrix4 as If,Vector2 as Vf}from"three";var Lf=(new If).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),Gf=class{renderScale;sampleCount;minCurrentWeight;motionWeightScale;depthThreshold;relativeDepthThreshold;targetPrefix;writeIndex=0;historyValid=!1;frameIndex=0;renderWidth=1;renderHeight=1;outputWidth=1;outputHeight=1;jitter=new Vf;unjitteredProjection=new If;previousJitterUv=new Vf;currentJitterUv=new Vf;previousViewProjection=new If;resolvePasses=new Map;constructor(e={}){this.renderScale=Uf(e.renderScale??1,.25,1),this.sampleCount=Math.max(1,Math.floor(e.sampleCount??32)),this.minCurrentWeight=Uf(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(zf(this.frameIndex%this.sampleCount+1,2)-.5,zf(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 Rf(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=Uf(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(Lf).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}},Rf=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 If;currentViewProjectionInverse=new If;updateUniforms=e=>(this.state.updateResolveUniforms(this.uniforms,this.currentViewProjection,this.currentViewProjectionInverse,e),this.uniforms)};function zf(e,t){let r=1,i=0;for(;e>0;)r/=t,i+=r*(e%t),e=Math.floor(e/t);return i}function Uf(e,t,r){return Math.min(r,Math.max(t,e))}var Af=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=Ff(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 kf(t,i,this),this.passes.set(n,a)),e.addFullscreenPass(a),i}},kf=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),Ff(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 Ff(e,t,r){return Math.min(r,Math.max(t,e))}import{ClampToEdgeWrapping as $f,DataTexture as Ef,LinearFilter as Of,NoColorSpace as _f,RGFormat as jf,UnsignedByteType as Nf}from"three";var Wf={low:{searchSteps:4,diagonalSteps:0},medium:{searchSteps:8,diagonalSteps:0},high:{searchSteps:16,diagonalSteps:8},ultra:{searchSteps:32,diagonalSteps:16}},Hf=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=nm(e.cornerRounding??.25,0,1),this.sharpness=nm(e.sharpness??0,0,1),this.quality=Wf[e.quality??"high"],this.targetPrefix=e.targetPrefix??"smaa",this.areaTexture=function(){const e=new Ef(function(){if(Yf)return Yf;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){Xf(e,16*n+r,16*a+t,Jf(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){Xf(e,80+20*s+r,20*o+t,tm(i,r,t))}}return Yf=e,e}(),160,80,jf,Nf);return e.name="SMAA-Area-Lookup",e.colorSpace=_f,e.minFilter=Of,e.magFilter=Of,e.wrapS=$f,e.wrapT=$f,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 qf(t,i,this),this.edgePasses.set(s,o));const l=`${i}:${n}`;let c=this.weightPasses.get(l);c||(c=new Kf(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 Zf(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}},qf=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"},Kf=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,nm(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"},Zf=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([nm(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 Yf=null;function Xf(e,t,r,i){const n=2*(160*r+t);e[n]=Math.floor(255*nm(i[0],0,1)),e[n+1]=Math.floor(255*nm(i[1],0,1))}function Jf(e,t,r){const i=t+r+1,n=.5,a=-.5,s=()=>Qf([0,a],[i/2,0],t),o=()=>Qf([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 em(i,s(),o());case 4:return t<=r?Qf([0,n],[i/2,0],t):[0,0];case 6:case 14:case 7:return Qf([0,n],[i,a],t);case 8:return t>=r?Qf([i/2,0],[i,n],t):[0,0];case 9:case 11:case 13:return Qf([0,a],[i,n],t);case 12:return em(i,Qf([0,n],[i/2,0],t),Qf([i/2,0],[i,n],t))}}function Qf(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 em(e,t,r){const i=e=>[.5*Math.sqrt(2*e[0]),.5*Math.sqrt(2*e[1])],n=nm(e/32,0,1),a=i(t),s=i(r);return[im(a[0],t[0],n)+im(s[0],r[0],n),im(a[1],t[1],n)+im(s[1],r[1],n)]}function tm(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 rm(o(1,1),o(0,0));case 1:return rm(s([1,0],[i,i]),o(0,0));case 2:return rm(s([0,0],[1+i,i]),o(0,0));case 3:return o(0,0);case 4:return rm(s([1,1],[i,i]),s([1,1],[1+i,i]));case 5:return rm(s([1,1],[i,i]),o(0,0));case 6:return s([1,1],[1+i,i]);case 7:return rm(s([1,1],[1+i,i]),o(0,0));case 8:return rm(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 rm(s([0,0],[1+i,1+i]),o(0,0));case 11:return rm(s([1,0],[1+i,1+i]),o(0,0));case 12:return s([1,1],[1+i,1+i]);case 13:return rm(s([1,1],[1+i,1+i]),s([1,0],[1+i,1+i]));case 14:return rm(s([1,1],[1+i,1+i]),s([1,1],[1+i,i]));case 15:return rm(s([1,1],[1+i,1+i]),o(0,0));default:return[0,0]}}function rm(e,t){return[.5*(e[0]+t[0]),.5*(e[1]+t[1])]}function im(e,t,r){return e+(t-e)*r}function nm(e,t,r){return Math.min(r,Math.max(t,e))}var am=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=cm(e.radius??.2,0,1),this.levels=(t=e.levels??5,r=1,i=5,Math.floor(cm(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 sm(o,a,this):new om(`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 om(`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 lm(t,s,a,this,this.levels),this.passes.set(o,l)),e.addFullscreenPass(l),a}},sm=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}"},om=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},lm=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,cm(this.state.radius,0,1),0,0]),this.uniforms);fragmentShader};function cm(e,t,r){return Math.min(r,Math.max(t,e))}var um=[1,1,1],dm=[0,0,0],hm=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 pm(t,r,this.options),this.passes.set(i,n)),e.addFullscreenPass(n),r}},pm=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,um),t(e?.contrast,um),t(e?.gamma,um),t(e?.gain,um),t(e?.offset,dm)};return t(this.state.whiteBalance,um),t(this.state.tint,um),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 fm}from"three";var mm=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 gm(t,r,i,this.options),this.passes.set(n,a)),e.addFullscreenPass(a),i}},gm=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 fm;updateUniforms=e=>(this.inverseProjection.copy(vm).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); }"},vm=(new fm).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);import{Matrix4 as xm,Vector2 as wm,Vector3 as bm}from"three";var ym=(new xm).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),Sm=(e=>(e[e.Disabled=0]="Disabled",e[e.CameraOnly=1]="CameraOnly",e[e.ObjectAndCamera=2]="ObjectAndCamera",e[e.ForceObjectBlur=3]="ForceObjectBlur",e))(Sm||{}),Cm={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}},Mm=class{options;targetPrefix;currentViewProjection=new xm;currentInverseViewProjection=new xm;currentInverseProjection=new xm;previousViewProjection=new xm;pendingViewProjection=new xm;previousProjection=new xm;previousCameraWorld=new xm;previousCameraPosition=new bm;currentCameraPosition=new bm;currentJitterUv=new wm;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:Bm(e.sampleCount??8),shutterScale:Dm(e.shutterScale??.75,0,4),maxBlurPixels:Dm(e.maxBlurPixels??18,0,128),cameraBlurScale:Dm(e.cameraBlurScale??.1,0,4),objectBlurScale:Dm(e.objectBlurScale??1,0,8),depthRejectionStrength:Dm(e.depthRejectionStrength??24,0,200),velocityThresholdPixels:Dm(e.velocityThresholdPixels??.6,0,16),dilation:e.dilation??!0,debugVelocity:e.debugVelocity??!1,targetFrameRate:Dm(e.targetFrameRate??60,15,240),maxFrameTime:Dm(e.maxFrameTime??.1,1/240,1),cameraCutDistance:Dm(e.cameraCutDistance??8,0,1e3),cameraCutRotationThreshold:Dm(e.cameraCutRotationThreshold??.75,0,2),projectionCutThreshold:Dm(e.projectionCutThreshold??.25,0,4)},this.targetPrefix=e.targetPrefix??"motionBlur"}applyPreset(e){Object.assign(this.options,Cm[e]),this.options.sampleCount=Bm(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(ym).multiply(e.projectionMatrix).multiply(e.matrixWorldInverse),this.currentViewProjection.copy(this.pendingViewProjection),this.currentInverseViewProjection.copy(this.currentViewProjection).invert(),this.currentInverseProjection.copy(ym).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=Bm(n.sampleCount),o=`${t}:${r}:${i}:${a}:${s}`;let l=this.passes.get(o);return l||(l=new Pm(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,Bm(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}},Pm=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 Bm(e){return e<=0?0:e<=4?4:e<=8?8:e<=12?12:16}function Dm(e,t,r){return Math.min(r,Math.max(t,e))}var Tm=class{enabled;visibleEdgeColor;edgeStrength;edgeThickness;edgeSoftness;selectedObjects=new Set;selectionMembers=new Set;addSelectionMember=e=>{this.selectionMembers.add(e)};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=Im(!1),this.skinnedMaskMaterial=Im(!0)}setSelectedObjects(e){this.selectionMembers.clear(),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.selectionMembers;i.clear();for(const e of this.selectedObjects)i.has(e)||e.traverse(this.addSelectionMember);e.addMaterialPass({name:"OutlineMask",outputs:r,clearColor:[0,0,0,0],loadDepth:!0,objectFilter:e=>null!==e&&i.has(e),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=[Im(!1,i.instanceIndex),Im(!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 Vm(r,n,this)),this.addCachedPass(e,`blur-h:${n}:${a}`,()=>new Lm("OutlineBlurHorizontal",n,a,!0,this)),this.addCachedPass(e,`blur-v:${a}:${s}`,()=>new Lm("OutlineBlurVertical",a,s,!1,this)),this.addCachedPass(e,`composite:${t}:${s}:${o}`,()=>new Gm(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.selectionMembers.clear(),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 Im(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 Vm=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}"},Lm=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}"},Gm=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 Rm,BackSide as zm,Bone as Um,BatchedMesh as Am,BoxGeometry as km,BufferAttribute as Fm,BufferGeometry as $m,CanvasTexture as Em,Color as Om,CompressedArrayTexture as _m,CompressedArrayTexture as jm,CompressedCubeTexture as Nm,CompressedTexture as Wm,CubeTexture as Hm,Data3DTexture as qm,DataArrayTexture as Km,DataTexture as Zm,DepthTexture as Ym,DirectionalLight as Xm,DoubleSide as Jm,FrontSide as Qm,Group as eg,HemisphereLight as tg,InstancedMesh as rg,MathUtils as ig,Matrix4 as ng,Mesh as ag,Object3D as sg,OrthographicCamera as og,PerspectiveCamera as lg,PlaneGeometry as cg,PointLight as ug,RepeatWrapping as dg,Scene as hg,Skeleton as pg,SkinnedMesh as fg,SphereGeometry as mg,SpotLight as gg,Texture as vg,Vector2 as xg,Vector3 as wg,Vector4 as bg}from"three";export{Rm as AmbientLight,zm as BackSide,Am as BatchedMesh,am as BloomEffect,Um as Bone,km as BoxGeometry,Fm as BufferAttribute,$m as BufferGeometry,Em as CanvasTexture,Om as Color,hm as ColorGradingEffect,_m as CompressedArrayTexture,Nm as CompressedCubeTexture,Wm as CompressedTexture,jm as CompressedTextureArray,N as ComputeKernel,Hm as CubeTexture,Tr as DEFAULT_WGSL_VERTEX_ATTRIBUTES,qm as Data3DTexture,Km as DataArrayTexture,Zm as DataTexture,mm as DepthOfFieldEffect,Ym as DepthTexture,Xm as DirectionalLight,Jm as DoubleSide,Af as FXAAEffect,cr as FrameGraphBuilder,Qm as FrontSide,df as GTAOEffect,uf as GTAO_PRESETS,eg as Group,tg as HemisphereLight,rg as InstancedMesh,Cm as MOTION_BLUR_PRESETS,ig as MathUtils,ng as Matrix4,ag as Mesh,Mm as MotionBlurEffect,Sm as MotionBlurMode,sg as Object3D,og as OrthographicCamera,Tm as OutlineEffect,lg as PerspectiveCamera,cg as PlaneGeometry,ug as PointLight,jd as RenderGraph,dg as RepeatWrapping,B as SCENE_COLOR_FORMAT,Hf as SMAAEffect,Cf as SSREffect,hg as Scene,pg as Skeleton,fg as SkinnedMesh,mg as SphereGeometry,gg as SpotLight,Gf as TemporalAAEffect,vg as Texture,ve as VOLUMETRIC_FOG_MATERIAL_WGSL,te as VOLUMETRIC_FOG_PRESETS,xg as Vector2,wg as Vector3,bg as Vector4,ue as VolumetricFogEffect,ee as VolumetricFogVolumeObject,Ir as WGSLShaderMaterial,Qd as WebGpuPMREMGenerator,tf as WebGpuRenderer,uh as buildParticleLightingShaderHeader,xe as configureVolumetricFogMaterial,j as createComputePipelineAsync,_ as createRenderPipelineAsync,r as registerPipelineDiagnosticOrigin,f as resolveDetailCulling,d 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])}const n=(console.groupCollapsed??console.info).bind(console),a=(console.table??console.info).bind(console);n("[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:")))}),a([...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 s=u(r);a(s.map(({variants:e,...t})=>t)),console.info("GPU VFX variant report (copy this array)",s);const o=u(r,!1);a(o.map(({variants:e,...t})=>t)),console.info("Material variant report (copy this array)",o),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)}function d(e,t){e.userData.detailCulling=t}var h=Object.freeze({minScreenSize:10,maxDistance:0,shadowMinScreenSize:2,shadowMaxDistance:0}),p=[];function f(e,t){let r=!!t;for(let t=e;t&&!r;t=t.parent)r=!!t.userData.detailCulling;if(!r)return h;let i=!0,{minScreenSize:n,maxDistance:a,shadowMinScreenSize:s,shadowMaxDistance:o}=h,l=!0;const c=e=>{e&&(i=e.enabled??i,n=e.minScreenSize??n,a=e.maxDistance??a,l=e.shadow?.enabled??l,s=e.shadow?.minScreenSize??s,o=e.shadow?.maxDistance??o)};c(t),p.length=0;for(let t=e;t;t=t.parent)p.push(t);for(let e=p.length-1;e>=0;e--)c(p[e].userData.detailCulling);const u=e=>Number.isFinite(e)&&e>0?e:0;return{minScreenSize:i?u(n):0,maxDistance:u(a),shadowMinScreenSize:l?u(s):0,shadowMaxDistance:u(o)}}function m(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}function g(e,t,r,i,n){const a=e.boundsCenter,s=e.boundsRadius;if(e.maxDistance>0&&a.distanceTo(n)-s>e.maxDistance)return!1;if(e.minScreenSize<=0)return!0;const o=t.elements,l=a.x,c=a.y,u=a.z,d=Math.hypot(o[3],o[7],o[11]),h=o[3]*l+o[7]*c+o[11]*u+o[15]-s*d;if(h<=1e-4)return!0;const p=Math.hypot(o[0],o[4],o[8]),f=Math.hypot(o[1],o[5],o[9]),m=(Math.abs(o[0]*l+o[4]*c+o[8]*u+o[12])+s*p)/h,g=(Math.abs(o[1]*l+o[5]*c+o[9]*u+o[13])+s*f)/h;return e.maxMemberRadius*Math.max((p+m*d)*r,(f+g*d)*i)/h>=.85*e.minScreenSize}import{Matrix4 as v,Sphere as x,Vector3 as w}from"three";var b=64,y=64,S=40,C=12,M=new Float32Array(S),P=new Float32Array([1,1,1,1]),D="rgba16float",B="rgba8unorm",T=(new v).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),I=[new w(0,-1,0),new w(0,-1,0),new w(0,0,1),new w(0,0,-1),new w(0,-1,0),new w(0,-1,0)],V=[new w(1,0,0),new w(-1,0,0),new w(0,1,0),new w(0,-1,0),new w(0,0,1),new w(0,0,-1)],z=4004,L=[{name:"position",shaderLocation:0,format:"float32x3"}],G=[{name:"position",shaderLocation:0,format:"float32x3"},{name:"skinIndex",shaderLocation:1,format:"uint32x4"},{name:"skinWeight",shaderLocation:2,format:"float32x4"}],R=new v,U=new v,A=(new v,new v,new x),k=new w,F=new w,$=new w,E=(new w,new w,new w,new w,new WeakMap);async function O(e,t){const r=E.get(e)??Promise.resolve();let i;const n=new Promise(e=>{i=e});E.set(e,r.catch(()=>{}).then(()=>n)),await r.catch(()=>{});try{return await new Promise(e=>requestAnimationFrame(()=>e())),t()}finally{i()}}function _(e,t){return i(e,t),"function"==typeof e.createRenderPipelineAsync?e.createRenderPipelineAsync(t):O(e,()=>e.createRenderPipeline(t))}function j(e,t){return i(e,t),"function"==typeof e.createComputePipelineAsync?e.createComputePipelineAsync(t):O(e,()=>e.createComputePipeline(t))}var N=class e{layout;pipeline;static async createAsync(t,r){const{pipelineDescriptor:i}=W(t,r),n=await j(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}=W(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 W(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{DirectionalLight as H,DoubleSide as q,Light as K,NoBlending as Z,PointLight as Y,SpotLight as X,Vector3 as J}from"three";var Q="\nfn rendererSdfgiSample(worldPosition: vec3<f32>, worldNormal: vec3<f32>, bank: u32) -> vec3<f32> {\n let originCell = sdfgiField[bank + 0];\n let settings = sdfgiField[bank + 1]; // spacing, probe count per axis, intensity, normal bias\n if (settings.z <= 0.0 || sdfgiField[bank + 2].x < 0.5) { return vec3<f32>(0.0); }\n let n = u32(settings.y);\n let normal = normalize(worldNormal);\n let position = worldPosition + normal * settings.w;\n let local = (position - originCell.xyz - vec3<f32>(originCell.w * 2.0)) / settings.x;\n let edge = min(local, vec3<f32>(f32(n - 1u)) - local);\n let fade = smoothstep(0.0, 1.0, min(edge.x, min(edge.y, edge.z)));\n if (fade <= 0.0) { return vec3<f32>(0.0); }\n // Quadratic B-spline support overlaps two probe planes at a cell boundary.\n // Trilinear's single shared plane can consist entirely of inactive probes\n // near geometry, causing a discontinuous normalized blend and square seams.\n let base = vec3<i32>(floor(local + vec3<f32>(0.5))) - vec3<i32>(1);\n var result = vec3<f32>(0.0);\n var weightSum = 0.0;\n var unoccludedWeightSum = 0.0;\n for (var neighbor = 0u; neighbor < 27u; neighbor++) {\n let cell = base + vec3<i32>(i32(neighbor % 3u), i32((neighbor / 3u) % 3u), i32(neighbor / 9u));\n if (any(cell < vec3<i32>(0)) || any(cell >= vec3<i32>(i32(n)))) { continue; }\n let distance = abs(local - vec3<f32>(cell));\n let tail = max(vec3<f32>(1.5) - distance, vec3<f32>(0.0));\n let spatial = select(0.5 * tail * tail, vec3<f32>(0.75) - distance * distance, distance <= vec3<f32>(0.5));\n let spatialWeight = spatial.x * spatial.y * spatial.z;\n if (spatialWeight <= 0.0) { continue; }\n let index = 4u + u32(cell.x + i32(n) * (cell.y + i32(n) * cell.z)) * 10u;\n if (sdfgiField[bank + index].w < 0.5) { continue; }\n let probePosition = originCell.xyz + vec3<f32>(originCell.w * 2.0) + vec3<f32>(cell) * settings.x;\n let delta = position - probePosition;\n let distanceToProbe = length(delta);\n let direction = delta / max(distanceToProbe, 0.0001);\n // Keep directional bounds separate. Averaging a nearby wall with an open\n // direction creates a large variance that incorrectly admits light through\n // the wall. Moments store distances projected onto each cardinal axis.\n var visibility = 1.0;\n for (var axis = 0u; axis < 3u; axis++) {\n let moment = sdfgiField[bank + index + 4u + axis * 2u + select(1u, 0u, delta[axis] >= 0.0)].xy;\n let variance = max(moment.y - moment.x * moment.x, originCell.w * originCell.w * 0.001);\n let difference = max(abs(delta[axis]) - moment.x - originCell.w * 0.05, 0.0);\n let bound = variance / (variance + difference * difference);\n visibility = min(visibility, bound * bound * bound);\n }\n let facing = max(0.05, dot(-direction, normal) * 0.5 + 0.5);\n let unoccludedWeight = spatialWeight * facing * facing;\n let weight = unoccludedWeight * visibility;\n let irradiance = sdfgiField[bank + index].xyz * 0.282095\n + sdfgiField[bank + index + 1u].xyz * (0.488603 * normal.x)\n + sdfgiField[bank + index + 2u].xyz * (0.488603 * normal.y)\n + sdfgiField[bank + index + 3u].xyz * (0.488603 * normal.z);\n result += max(irradiance, vec3<f32>(0.0)) * weight;\n weightSum += weight;\n unoccludedWeightSum += unoccludedWeight;\n }\n // Visibility and normal weights can be tiny near walls or inactive probes.\n // A large denominator floor turns those weights into dark lattice patches\n // instead of normalizing the remaining valid irradiance.\n // Normalization must not amplify an entirely occluded neighborhood back to\n // full brightness. Fade unsupported lighting continuously instead of using\n // a fixed denominator cutoff that would expose the probe lattice again.\n let support = weightSum / max(unoccludedWeightSum, 1e-8);\n let confidence = smoothstep(0.0, 0.1, support);\n return result / max(weightSum, 1e-8) * (fade * confidence);\n}\nfn rendererSdfgiIrradiance(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> vec3<f32> {\n let intensity = sdfgiField[1].z;\n if (intensity <= 0.0 || sdfgiField[2].x < 0.5) { return vec3<f32>(0.0); }\n let blend = sdfgiField[2].y;\n var previous = vec3<f32>(0.0);\n if (blend < 1.0 && sdfgiField[2].z > 0.5) {\n previous = rendererSdfgiSample(worldPosition, worldNormal, u32(sdfgiField[3].x));\n }\n if (blend <= 0.0) { return previous * intensity; }\n let current = rendererSdfgiSample(worldPosition, worldNormal, 0u);\n return mix(previous, current, blend) * intensity;\n}\n";var ee="\nstruct Params {\n originCell: vec4<f32>,\n grid: vec4<u32>, // voxel resolution, probe resolution, ray count, frame\n settings: vec4<f32>, // probe spacing, history weight, bias, max ray distance\n sky: vec4<f32>,\n update: vec4<u32>, // first probe, probe count, reset history, maximum steps\n lights: vec4<u32>, // count\n};\nfn cellIndex(cell: vec3<u32>, n: u32) -> u32 { return cell.x + n * (cell.y + n * cell.z); }\nfn cellPosition(index: u32, n: u32) -> vec3<u32> { return vec3<u32>(index % n, (index / n) % n, index / (n * n)); }\n",te=ee+"\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read> surfaces: array<vec4<f32>>;\n@group(0) @binding(2) var<storage, read_write> output: array<vec4<i32>>;\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let n = params.grid.x;\n if (id.x >= n * n * n) { return; }\n let cell = cellPosition(id.x, n);\n output[id.x] = vec4<i32>(vec3<i32>(cell), select(0, 1, surfaces[id.x * 3u].w > 0.0));\n}\n",re=ee+"\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<uniform> jump: vec4<u32>;\n@group(0) @binding(2) var<storage, read> source: array<vec4<i32>>;\n@group(0) @binding(3) var<storage, read_write> output: array<vec4<i32>>;\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let n = params.grid.x;\n if (id.x >= n * n * n) { return; }\n let position = vec3<i32>(cellPosition(id.x, n));\n var nearest = source[id.x];\n var best = 1e20;\n if (nearest.w != 0) { let delta = vec3<f32>(nearest.xyz - position); best = dot(delta, delta); }\n for (var z = -1; z <= 1; z++) { for (var y = -1; y <= 1; y++) { for (var x = -1; x <= 1; x++) {\n let cell = position + vec3<i32>(x, y, z) * i32(jump.x);\n if (any(cell < vec3<i32>(0)) || any(cell >= vec3<i32>(i32(n)))) { continue; }\n let candidate = source[cellIndex(vec3<u32>(cell), n)];\n if (candidate.w == 0) { continue; }\n let delta = vec3<f32>(candidate.xyz - position);\n let distanceSquared = dot(delta, delta);\n if (distanceSquared < best) { nearest = candidate; best = distanceSquared; }\n } } }\n output[id.x] = nearest;\n}\n",ie="\nfn distanceField(position: vec3<f32>) -> vec2<f32> {\n let local = (position - params.originCell.xyz) / params.originCell.w;\n let n = params.grid.x;\n if (any(local < vec3<f32>(0.0)) || any(local >= vec3<f32>(f32(n)))) { return vec2<f32>(params.settings.w, -1.0); }\n let seed = nearest[cellIndex(vec3<u32>(local), n)];\n if (seed.w == 0) { return vec2<f32>(params.settings.w, -1.0); }\n // Distance to the voxel box. A circumscribed sphere inflates its faces and\n // corners, making nearby receivers appear occluded even outside the voxel.\n let distance = length(max(abs(local - vec3<f32>(seed.xyz) - vec3<f32>(0.5)) - vec3<f32>(0.5), vec3<f32>(0.0)));\n return vec2<f32>(distance * params.originCell.w, f32(cellIndex(vec3<u32>(seed.xyz), n)));\n}\nfn trace(origin: vec3<f32>, direction: vec3<f32>, limit: f32) -> vec2<f32> {\n var distance = 0.0;\n for (var step = 0u; step < params.update.w; step++) {\n let sample = distanceField(origin + direction * distance);\n if (sample.y < 0.0) { return vec2<f32>(-1.0, limit); }\n if (sample.x < params.originCell.w * 0.2) { return vec2<f32>(sample.y, distance); }\n distance += max(sample.x * 0.8, params.originCell.w * 0.2);\n if (distance >= limit) { return vec2<f32>(-1.0, limit); }\n }\n // A step-budget miss is conservatively occluded, avoiding light leaks.\n return vec2<f32>(-2.0, distance);\n}\n",ne=ee+"\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read> surfaces: array<vec4<f32>>;\n@group(0) @binding(2) var<storage, read> nearest: array<vec4<i32>>;\n@group(0) @binding(3) var<storage, read> lights: array<vec4<f32>>;\n@group(0) @binding(4) var<storage, read_write> radiance: array<vec4<f32>>;\n"+ie+"\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let n = params.grid.x;\n if (id.x >= n * n * n) { return; }\n let albedo = surfaces[id.x * 3u];\n if (albedo.w == 0.0) { radiance[id.x * 2u] = vec4<f32>(0.0); radiance[id.x * 2u + 1u] = vec4<f32>(0.0); return; }\n let surface = surfaces[id.x * 3u + 1u];\n let position = params.originCell.xyz + (vec3<f32>(cellPosition(id.x, n)) + vec3<f32>(0.5)) * params.originCell.w;\n var illumination = vec3<f32>(0.0);\n var backIllumination = vec3<f32>(0.0);\n for (var light = 0u; light < params.lights.x; light++) {\n let source = lights[light * 4u]; // position/directional flag\n let color = lights[light * 4u + 1u].xyz;\n let directionRange = lights[light * 4u + 2u];\n let coneDecay = lights[light * 4u + 3u];\n var direction = directionRange.xyz;\n var limit = params.settings.w;\n var attenuation = 1.0;\n if (source.w > 0.5) {\n let delta = source.xyz - position;\n limit = length(delta);\n direction = delta / max(limit, 0.0001);\n attenuation = 1.0 / max(pow(limit, coneDecay.z), 0.01);\n if (directionRange.w > 0.0) {\n let ratio = limit / directionRange.w;\n attenuation *= pow(clamp(1.0 - pow(ratio, 4.0), 0.0, 1.0), 2.0);\n }\n if (source.w > 1.5) {\n let cone = dot(-direction, directionRange.xyz);\n if (coneDecay.y - coneDecay.x > 0.00001) { attenuation *= smoothstep(coneDecay.x, coneDecay.y, cone); }\n else { attenuation *= select(0.0, 1.0, cone >= coneDecay.x); }\n }\n }\n let cosine = select(max(dot(surface.xyz, direction), 0.0), abs(dot(surface.xyz, direction)), surface.w > 0.5);\n if (cosine * attenuation <= 0.00001) { continue; }\n let biasNormal = surface.xyz * select(1.0, -1.0, dot(surface.xyz, direction) < 0.0);\n let shadow = trace(position + biasNormal * params.originCell.w * 1.8, direction, limit);\n if (shadow.x == -1.0) {\n if (dot(surface.xyz, direction) >= 0.0) { illumination += color * (cosine * attenuation); }\n else { backIllumination += color * (cosine * attenuation); }\n }\n }\n // Keep both sides separate so a double-sided wall cannot transmit sunlight.\n let emission = surfaces[id.x * 3u + 2u].xyz;\n radiance[id.x * 2u] = vec4<f32>(emission + albedo.xyz * illumination * 0.318309886, 1.0);\n radiance[id.x * 2u + 1u] = vec4<f32>(emission + albedo.xyz * backIllumination * 0.318309886, 1.0);\n}\n",ae=ee+"\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read> surfaces: array<vec4<f32>>;\n@group(0) @binding(2) var<storage, read> nearest: array<vec4<i32>>;\n@group(0) @binding(3) var<storage, read> radiance: array<vec4<f32>>;\n@group(0) @binding(4) var<storage, read_write> field: array<vec4<f32>>;\n"+ie+"\n@compute @workgroup_size(32)\nfn main(@builtin(global_invocation_id) id: vec3<u32>) {\n if (id.x >= params.update.y) { return; }\n let p = params.grid.y;\n let probe = (params.update.x + id.x) % (p * p * p);\n let base = 4u + probe * 10u;\n let position = params.originCell.xyz + vec3<f32>(params.originCell.w * 2.0)\n + vec3<f32>(cellPosition(probe, p)) * params.settings.x;\n if (distanceField(position).x < params.originCell.w * 0.6) {\n for (var i = 0u; i < 10u; i++) { field[base + i] = vec4<f32>(0.0); }\n return;\n }\n var coefficients: array<vec3<f32>, 4>;\n var moments: array<vec3<f32>, 6>;\n let count = params.grid.z;\n // Keep each probe's integration directions stable. Rotating every update\n // repeatedly hits/misses small emissive surfaces and makes their light pulse,\n // including in a completely stationary scene. Different probes retain\n // different azimuths to avoid aligning sampling errors across the lattice.\n // Seed from the global lattice coordinate, never the index in the moving\n // volume, so a retained world probe traces the same rays after a scroll.\n let worldProbe = bitcast<vec3<u32>>(vec3<i32>(round((position - vec3<f32>(params.originCell.w * 2.0)) / params.settings.x)));\n var hash = (worldProbe.x * 73856093u) ^ (worldProbe.y * 19349663u) ^ (worldProbe.z * 83492791u);\n hash = hash ^ (hash >> 16u);\n let rotation = f32(hash & 65535u) * (6.283185307 / 65536.0);\n for (var ray = 0u; ray < count; ray++) {\n let y = 1.0 - 2.0 * (f32(ray) + 0.5) / f32(count);\n let radius = sqrt(max(0.0, 1.0 - y * y));\n let angle = f32(ray) * 2.39996323 + rotation;\n let direction = vec3<f32>(cos(angle) * radius, y, sin(angle) * radius);\n let hit = trace(position, direction, params.settings.w);\n var visibilityDistance = hit.y;\n var incoming = vec3<f32>(0.0);\n if (hit.x == -1.0) { incoming = params.sky.xyz; }\n if (hit.x >= 0.0) {\n let index = u32(hit.x);\n let normal = surfaces[index * 3u + 1u];\n // Trace conservatively against voxel boxes, but measure visibility to\n // the captured physical surface plane. Using the thick voxel shell here\n // falsely hides floor-adjacent receivers behind the floor's own voxels.\n let center = params.originCell.xyz + (vec3<f32>(cellPosition(index, params.grid.x)) + vec3<f32>(0.5)) * params.originCell.w;\n let plane = center + normal.xyz * surfaces[index * 3u + 2u].w;\n let denominator = dot(direction, normal.xyz);\n if (abs(denominator) > 0.0001) {\n let planeDistance = dot(plane - position, normal.xyz) / denominator;\n let intersection = position + direction * planeDistance;\n if (planeDistance >= 0.0 && all(abs(intersection - center) <= vec3<f32>(params.originCell.w * 1.5))) {\n visibilityDistance = planeDistance;\n }\n }\n let front = dot(normal.xyz, -direction) > 0.0;\n if (normal.w > 0.5 || front) { incoming = radiance[index * 2u + select(1u, 0u, front)].xyz; }\n }\n coefficients[0] += incoming * 0.282095;\n coefficients[1] += incoming * (0.488603 * direction.x);\n coefficients[2] += incoming * (0.488603 * direction.y);\n coefficients[3] += incoming * (0.488603 * direction.z);\n for (var axis = 0u; axis < 6u; axis++) {\n var axisDirection = vec3<f32>(0.0);\n axisDirection[axis / 2u] = select(-1.0, 1.0, axis % 2u == 0u);\n let projection = max(dot(direction, axisDirection), 0.0);\n let weight = pow(projection, 8.0);\n let distance = visibilityDistance * projection;\n moments[axis] += vec3<f32>(distance, distance * distance, 1.0) * weight;\n }\n }\n let history = select(0.0, params.settings.y, params.update.z == 0u && field[base].w > 0.5);\n for (var i = 0u; i < 4u; i++) {\n let convolution = select(2.094395102, 3.141592654, i == 0u);\n let value = coefficients[i] * (12.566370614 / f32(count)) * convolution;\n field[base + i] = vec4<f32>(mix(value, field[base + i].xyz, history), 1.0);\n }\n for (var i = 0u; i < 6u; i++) {\n let value = moments[i].xy / max(moments[i].z, 0.00001);\n field[base + 4u + i] = vec4<f32>(mix(value, field[base + 4u + i].xy, history), 0.0, 0.0);\n }\n}\n";function se(e,t,r,i){return null!=e&&Number.isFinite(e)?Math.min(i,Math.max(r,e)):t}function oe(e,t,r,i,n,a){e[t]=r,e[t+1]=i,e[t+2]=n,e[t+3]=a}var le={label:"SDFGISeed"},ce={label:"SDFGIJumpFlood"},ue={label:"SDFGILightInjection"},de={label:"SDFGIProbeUpdate"},he={label:"SDFGIProbeSnapshot"},pe=class e{constructor(t,r={}){if(this.device=t,this.resolution=r.resolution??64,![32,64,128].includes(this.resolution))throw new Error("SDFGI resolution must be 32, 64, or 128.");this.extent=se(r.extent,48,4,4096),this.probeResolution=Math.round(se(r.probeResolution,12,4,24)),this.cellSize=this.extent/this.resolution,this.spacing=this.cellSize*Math.max(1,Math.floor((this.resolution-4)/(this.probeResolution-1))),this.setOptions(r);const i=this.resolution**3,n=(e,r,i=!1)=>{if(!i&&r>t.limits.maxStorageBufferBindingSize)throw new Error(`SDFGI ${e} exceeds the adapter's storage buffer limit.`);const n=t.createBuffer({label:`sdfgi-${e}`,size:r,usage:(i?GPUBufferUsage.UNIFORM:GPUBufferUsage.STORAGE)|GPUBufferUsage.COPY_DST|("probes"===e||"surfaces"===e||"surface-statistics"===e?GPUBufferUsage.COPY_SRC:0)});return this.buffers.push(n),this.stats.gpuBytes+=r,n};this.params=n("params",96,!0),this.surfaces=n("surfaces",48*i),this.fieldBankBytes=16*(4+this.probeResolution**3*10),this.field=n("probes",2*this.fieldBankBytes),this.lightBuffer=n("lights",this.lightData.byteLength),this.surfaceConfig=n("surface-config",32),this.surfaceAccum=n("surface-accum",32*i),this.surfaceStatistics=n("surface-statistics",16);const a=[n("nearest-a",16*i),n("nearest-b",16*i)],s=n("radiance",32*i),o=(e,r,i)=>new N(t,{label:`sdfgi-${e}`,code:r,bindGroupLayoutEntries:i.map((e,t)=>((e,t)=>({binding:e,visibility:GPUShaderStage.COMPUTE,buffer:{type:t}}))(t,e))}),l=(e,r)=>e.createBindGroup(t,r.map((e,t)=>({binding:t,resource:{buffer:e}})));this.snapshot=o("probe-snapshot","\n@group(0) @binding(0) var<storage, read_write> field: array<vec4<f32>>;\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let bankSize = arrayLength(&field) / 2u;\n let index = id.x + 4u;\n if (index < bankSize) { field[bankSize + index] = field[index]; }\n}\n",["storage"]),this.snapshotBinding=l(this.snapshot,[this.field]),this.resolveSurface=o("resolve-surface","\n@group(0) @binding(0) var<storage, read> config: array<vec4<f32>>;\n@group(0) @binding(1) var<storage, read> accum: array<u32>;\n@group(0) @binding(2) var<storage, read_write> surfaces: array<vec4<f32>>;\n@group(0) @binding(3) var<storage, read_write> statistics: array<atomic<u32>>;\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) id: vec3<u32>) {\n let n = u32(config[1].x);\n if (id.x >= n * n * n) { return; }\n let base = id.x * 8u;\n let count = accum[base];\n if (count == 0u) {\n surfaces[id.x * 3u] = vec4<f32>(0.0);\n surfaces[id.x * 3u + 1u] = vec4<f32>(0.0);\n surfaces[id.x * 3u + 2u] = vec4<f32>(0.0);\n return;\n }\n let inverseCount = 1.0 / f32(count);\n let color = vec3<f32>(f32(accum[base + 1u]), f32(accum[base + 2u]), f32(accum[base + 3u])) * (inverseCount / 4096.0);\n let emission = vec3<f32>(f32(accum[base + 4u]), f32(accum[base + 5u]), f32(accum[base + 6u])) * (inverseCount / 1024.0);\n let packed = accum[base + 7u];\n let packedNormal = unpack4x8snorm(packed & 0x00ffffffu);\n let metadata = packed >> 24u;\n let doubleSided = f32(metadata >> 7u);\n let planeOffset = (f32(metadata & 127u) / 127.0 - 0.5) * 3.0 * config[0].w;\n let normal = packedNormal.xyz * inverseSqrt(max(dot(packedNormal.xyz, packedNormal.xyz), 0.0001));\n surfaces[id.x * 3u] = vec4<f32>(color, 1.0);\n surfaces[id.x * 3u + 1u] = vec4<f32>(normal, doubleSided);\n surfaces[id.x * 3u + 2u] = vec4<f32>(emission, planeOffset);\n atomicAdd(&statistics[0], 1u);\n}\n",["read-only-storage","read-only-storage","storage","storage"]),this.resolveSurfaceBinding=l(this.resolveSurface,[this.surfaceConfig,this.surfaceAccum,this.surfaces,this.surfaceStatistics]),this.seed=o("seed",te,["uniform","read-only-storage","storage"]),this.seedBinding=l(this.seed,[this.params,this.surfaces,a[0]]);const c=o("jump-flood",re,["uniform","uniform","read-only-storage","storage"]);let u=0;for(let e=this.resolution/2;e>=.5;e/=2){const r=n(`jump-${this.jumps.length}`,16,!0);t.queue.writeBuffer(r,0,new Uint32Array([Math.max(1,e),0,0,0])),this.jumps.push({kernel:c,binding:l(c,[this.params,r,a[u],a[1-u]])}),u=1-u}if(this.inject=o("light-injection",ne,["uniform","read-only-storage","read-only-storage","read-only-storage","storage"]),this.injectBinding=l(this.inject,[this.params,this.surfaces,a[u],this.lightBuffer,s]),this.probes=o("probe-update",ae,["uniform","read-only-storage","read-only-storage","read-only-storage","storage"]),this.probeBinding=l(this.probes,[this.params,this.surfaces,a[u],s,this.field]),r.cascades){const i=r.cascades,n=Math.round(se(i.count,2,2,3)),a=se(i.extentScale,2,1.5,8),s=Math.round(se(i.updateInterval,4,1,60)),o=Math.round(se(i.raysPerProbe,32,16,256)),l=se(i.updateFraction,.125,.01,1);this.distantVolumes=[];try{for(let c=1;c<n;c++){const n=this.extent*a**c;if(n>4096)throw new Error("SDFGI cascade extent exceeds 4096.");const u=new e(t,{...r,cascades:!1,extent:n,resolution:i.resolution??32,probeResolution:i.probeResolution??8,raysPerProbe:Math.min(this.rays,o),updateFraction:Math.min(this.fraction,l)});this.distantVolumes.push({volume:u,interval:s*2**(c-1),rays:o,fraction:l,scheduled:!1,settingsDirty:!1}),this.stats.gpuBytes+=u.stats.gpuBytes}}catch(e){throw this.dispose(),e}this.stats.cascadeCount=n}}device;stats={cascadeCount:1,ready:!1,building:!1,triangles:0,occupiedCells:0,geometryCpuMs:0,geometryBuildMs:0,gpuBytes:0,updatedProbes:0};resolution;extent;probeResolution;cellSize;spacing;enabled=!0;intensity=1;rays=64;fraction=.25;history=.85;steps=64;sky=[0,0,0];buffers=[];uniformData=new ArrayBuffer(96);floats=new Float32Array(this.uniformData);integers=new Uint32Array(this.uniformData);header=new Float32Array(16);lightData=new Float32Array(256);field;fieldBankBytes;snapshot;snapshotBinding;populatedProbes=0;blend=1;previousValid=!1;lastUpdateSeconds=0;params;surfaces;seed;seedBinding;jumps=[];inject;injectBinding;probes;probeBinding;lightBuffer;surfaceConfig;surfaceAccum;surfaceStatistics;surfaceConfigData=new Float32Array(8);resolveSurface;resolveSurfaceBinding;configuredSurfaces=new WeakSet;surfaceCapture=null;captureAxis=0;pendingTriangleCount=0;pendingCounts=0;configured=new WeakSet;watched=new Set;lights=new Set;staticDrawRoots=new Map;cascadeDirectionalLights=[];scene=null;grid=null;pending=null;dirty=!0;upload=!1;frame=0;probeOffset=0;disposed=!1;cameraPosition=new J;sourcePosition=new J;targetPosition=new J;direction=new J;buildMs=0;lightCount=0;distantVolumes=null;cascadeFrame=0;setOptions(e){const t=this.enabled,r=this.intensity;if(this.enabled=e.enabled??this.enabled,this.intensity=se(e.intensity,this.intensity,0,10),this.rays=Math.round(se(e.raysPerProbe,this.rays,16,256)),this.fraction=se(e.updateFraction,this.fraction,.01,1),this.history=se(e.historyWeight,this.history,0,.99),this.steps=Math.round(se(e.maxSteps,this.steps,16,256)),e.skyColor)for(let t=0;t<3;t++)this.sky[t]=se(e.skyColor[t],0,0,100);if(this.distantVolumes)for(const e of this.distantVolumes)e.volume.setOptions({enabled:this.enabled,intensity:this.intensity,historyWeight:this.history,maxSteps:this.steps,skyColor:this.sky,raysPerProbe:Math.min(this.rays,e.rays),updateFraction:Math.min(this.fraction,e.fraction)}),!e.volume.grid||t===this.enabled&&r===this.intensity||(e.settingsDirty=!0)}invalidate(){if(this.dirty=!0,this.distantVolumes)for(const e of this.distantVolumes)e.volume.invalidate()}get surfaceResolution(){return 2*this.resolution}setSurfaceCapture(e){this.surfaceCapture?.dispose(),this.surfaceCapture=e,this.invalidate()}setSurfaceCaptureFactory(e){if(this.setSurfaceCapture(e(this)),this.distantVolumes)for(const t of this.distantVolumes)t.volume.setSurfaceCapture(e(t.volume))}configureSurfaceMaterial(e){if(!this.configuredSurfaces.has(e)){if(!e.fragmentShader.includes("sdfgiWriteSurface("))throw new Error("SDFGI capture requires an attribute-only material graph.");this.configuredSurfaces.add(e),e.fragmentShader.includes("fn sdfgiWriteSurface(")||(e.fragmentShader+="\nfn sdfgiWriteSurface(position: vec3<f32>, normal: vec3<f32>, diffuse: vec3<f32>, emission: vec3<f32>, doubleSided: bool) {\n let originCell = sdfgiSurfaceConfig[0];\n let n = u32(sdfgiSurfaceConfig[1].x);\n let color = vec3<u32>(round(clamp(diffuse, vec3<f32>(0.0), vec3<f32>(1.0)) * 4096.0));\n let emissive = vec3<u32>(round(clamp(emission, vec3<f32>(0.0), vec3<f32>(64.0)) * 1024.0));\n let surfaceNormal = normalize(normal);\n let packedNormal = pack4x8snorm(vec4<f32>(surfaceNormal, 0.0)) & 0x00ffffffu;\n // Half-voxel coverage in each projection and a small normal extrusion keep\n // subpixel edges connected without relying on conservative-raster hardware.\n for (var offset = -1; offset <= 1; offset++) {\n let local = (position - originCell.xyz) / originCell.w + surfaceNormal * (f32(offset) * 0.5);\n if (any(local < vec3<f32>(0.0)) || any(local >= vec3<f32>(f32(n)))) { continue; }\n let cell = vec3<u32>(local);\n let center = originCell.xyz + (vec3<f32>(cell) + vec3<f32>(0.5)) * originCell.w;\n // The fourth normal byte carries a two-sided flag and a seven-bit plane\n // offset over +/-1.5 cells, including the conservative extrusion shell.\n let planeOffset = dot(position - center, surfaceNormal) / originCell.w;\n let planeBits = u32(round(clamp(planeOffset / 3.0 + 0.5, 0.0, 1.0) * 127.0));\n let metadata = planeBits | select(0u, 128u, doubleSided);\n let base = (cell.x + n * (cell.y + n * cell.z)) * 8u;\n atomicAdd(&sdfgiSurfaceAccum[base], 1u);\n atomicAdd(&sdfgiSurfaceAccum[base + 1u], color.x);\n atomicAdd(&sdfgiSurfaceAccum[base + 2u], color.y);\n atomicAdd(&sdfgiSurfaceAccum[base + 3u], color.z);\n atomicAdd(&sdfgiSurfaceAccum[base + 4u], emissive.x);\n atomicAdd(&sdfgiSurfaceAccum[base + 5u], emissive.y);\n atomicAdd(&sdfgiSurfaceAccum[base + 6u], emissive.z);\n // The normal and its plane offset stay atomic and refer to the same\n // captured surface, including where several surfaces share a voxel.\n atomicStore(&sdfgiSurfaceAccum[base + 7u], packedNormal | (metadata << 24u));\n }\n}\n"),e.depthTest=e.depthWrite=e.transparent=e.wireframe=!1,e.side=q,e.blending=Z,e.setStorageBuffer("sdfgiSurfaceAccum",{buffer:this.surfaceAccum,type:"array<atomic<u32>>",visibility:"fragment",access:"read_write"}),e.setStorageBuffer("sdfgiSurfaceConfig",{buffer:this.surfaceConfig,type:"array<vec4<f32>>",visibility:"fragment"})}}registerStaticDrawRoot(e){this.staticDrawRoots.set(e,(this.staticDrawRoots.get(e)??0)+1),this.invalidate();let t=!1;return()=>{if(t)return;t=!0;const r=(this.staticDrawRoots.get(e)??1)-1;r>0?this.staticDrawRoots.set(e,r):this.staticDrawRoots.delete(e),this.invalidate()}}setCascadedDirectionalLights(e){if(this.cascadeDirectionalLights=e,this.distantVolumes)for(const t of this.distantVolumes)t.volume.setCascadedDirectionalLights(e)}configureMaterial(e){if(!1!==e.userData.receiveGI){if(this.configured.has(e))!0!==e.defines.USE_SDFGI&&e.setDefine("USE_SDFGI",!0);else if(e.fragmentShader.includes("rendererIndirectDiffuseAt(")){if(this.configured.add(e),e.setStorageBuffer("sdfgiField",{buffer:this.field,type:"array<vec4<f32>>",visibility:"fragment"}),this.distantVolumes){e.setDefine("SDFGI_CASCADE_COUNT",this.stats.cascadeCount);for(let t=0;t<this.distantVolumes.length;t++)e.setStorageBuffer(`sdfgiField${t+1}`,{buffer:this.distantVolumes[t].volume.field,type:"array<vec4<f32>>",visibility:"fragment"})}e.setDefine("USE_SDFGI",!0)}}else!0===e.defines.USE_SDFGI&&e.setDefine("USE_SDFGI",!1)}added=e=>{this.watch(e.child),this.hasStaticGeometry(e.child)&&this.invalidate()};removed=e=>{const t=this.hasStaticGeometry(e.child);e.child.traverse(e=>{e.removeEventListener("childadded",this.added),e.removeEventListener("childremoved",this.removed),this.watched.delete(e),e instanceof K&&this.lights.delete(e)}),t&&this.invalidate()};hasStaticGeometry(e){let t=!1;return e.traverse(e=>{if(!t&&e.isMesh&&!e.isSkinnedMesh){for(let t=e;t;t=t.parent)if(!1===t.userData.sdfgi||!0===t.userData.isSky)return;t=!0}}),t}watch(e){e.traverse(e=>{this.watched.has(e)||(this.watched.add(e),e.addEventListener("childadded",this.added),e.addEventListener("childremoved",this.removed),(e instanceof H||e instanceof Y||e instanceof X)&&this.lights.add(e))})}unwatch(){for(const e of this.watched)e.removeEventListener("childadded",this.added),e.removeEventListener("childremoved",this.removed);this.watched.clear(),this.lights.clear()}prepare(e,t){if(this.disposed)return;if(this.stats.geometryCpuMs=0,this.stats.updatedProbes=0,this.scene!==e&&(this.unwatch(),this.scene=e,this.watch(e),this.grid=null,this.pending=null,this.dirty=!0,this.stats.ready=!1,this.blend=1,this.previousValid=!1),!this.enabled||!this.surfaceCapture)return;t.getWorldPosition(this.cameraPosition);const r=this.pending??this.grid;if(r&&this.blend>=1){const e=r.origin;(Math.abs(this.cameraPosition.x-e.x-this.extent/2)>.25*this.extent||Math.abs(this.cameraPosition.y-e.y-this.extent/2)>.25*this.extent||Math.abs(this.cameraPosition.z-e.z-this.extent/2)>.25*this.extent)&&(this.dirty=!0)}const i=performance.now();if(this.dirty&&(!this.stats.ready||this.blend>=1)){this.dirty=!1;const e=this.spacing,t=this.cameraPosition.clone().addScalar(-this.extent/2);t.set(Math.floor(t.x/e)*e,Math.floor(t.y/e)*e,Math.floor(t.z/e)*e),this.pending={origin:t,resolution:this.resolution,extent:this.extent},oe(this.surfaceConfigData,0,t.x,t.y,t.z,this.cellSize),oe(this.surfaceConfigData,4,this.resolution,0,0,0),this.device.queue.writeBuffer(this.surfaceConfig,0,this.surfaceConfigData);const r=this.device.createCommandEncoder({label:"sdfgi-clear-surfaces"});r.clearBuffer(this.surfaceAccum),this.device.queue.submit([r.finish()]),this.captureAxis=0,this.pendingTriangleCount=0,this.buildMs=0}if(this.pending&&(this.pendingTriangleCount=Math.max(this.pendingTriangleCount,this.surfaceCapture.capture(e,this.pending,this.captureAxis++)),this.stats.geometryCpuMs=performance.now()-i,this.buildMs+=this.stats.geometryCpuMs,3===this.captureAxis&&(this.grid=this.pending,this.pending=null,this.upload=!0,this.stats.triangles=this.pendingTriangleCount,this.stats.geometryBuildMs=this.buildMs)),this.stats.building=this.dirty||null!=this.pending||this.pendingCounts>0,this.updateLights(),this.distantVolumes){this.cascadeFrame++;for(const r of this.distantVolumes){const i=r.volume;r.scheduled=r.settingsDirty||null!=i.scene&&i.scene!==e||null!=i.pending||i.upload||i.blend<1||this.cascadeFrame%r.interval===0,r.scheduled&&(i.prepare(e,t),this.stats.geometryCpuMs+=i.stats.geometryCpuMs),this.stats.building||=i.stats.building}}}updateLights(){let e=0;for(let t=0;t<2;t++)for(const r of 0===t?this.cascadeDirectionalLights:this.lights){if(0===t?r!==this.cascadeDirectionalLights[0]:this.cascadeDirectionalLights.includes(r))continue;let i=!0;for(let e=r;e;e=e.parent)if(!e.visible){i=!1;break}if(!i||r.intensity<=0||!1===r.userData.sdfgi)continue;if(16===e)break;const n=16*e++;r.getWorldPosition(this.sourcePosition);let a=0,s=0,o=0,l=-1,c=-1;r instanceof H||r instanceof X?(r.target.getWorldPosition(this.targetPosition),this.direction.subVectors(this.targetPosition,this.sourcePosition).normalize(),r instanceof H?this.direction.negate():(a=2,l=Math.cos(r.angle),c=Math.cos(r.angle*(1-r.penumbra)))):(a=1,this.direction.set(0,0,0)),(r instanceof Y||r instanceof X)&&(s=r.distance,o=r.decay),oe(this.lightData,n,this.sourcePosition.x,this.sourcePosition.y,this.sourcePosition.z,a),oe(this.lightData,n+4,r.color.r*r.intensity,r.color.g*r.intensity,r.color.b*r.intensity,0),oe(this.lightData,n+8,this.direction.x,this.direction.y,this.direction.z,s),oe(this.lightData,n+12,l,c,o,0)}this.lightCount=e}addPasses(e){e.addPass({name:"SDFGIUpdate",execute:e=>this.encode(e.encoder)})}encode(e,t=performance.now()/1e3){if(this.encodeVolume(e,t),this.distantVolumes)for(const r of this.distantVolumes)(r.scheduled||r.settingsDirty)&&(r.volume.encodeVolume(e,t),r.settingsDirty=!1,this.stats.updatedProbes+=r.volume.stats.updatedProbes)}encodeVolume(e,t){if(this.stats.updatedProbes=0,this.disposed)return;const r=this.grid,i=this.probeResolution**3,n=Math.ceil(i*this.fraction);if(this.upload&&this.enabled&&r)this.previousValid=this.stats.ready,this.previousValid&&(this.device.queue.writeBuffer(this.field,this.fieldBankBytes,this.header),this.dispatch(e,he,this.snapshot,this.snapshotBinding,Math.ceil(10*i/64))),this.populatedProbes=0,this.probeOffset=0,this.blend=0;else if(this.enabled&&this.populatedProbes>=i){const e=Math.max(0,t-this.lastUpdateSeconds);this.blend=Math.min(1,this.blend+e/.4)}if(this.lastUpdateSeconds=t,this.header[0]=r?.origin.x??0,this.header[1]=r?.origin.y??0,this.header[2]=r?.origin.z??0,this.header[3]=this.cellSize,this.header[4]=this.spacing,this.header[5]=this.probeResolution,this.header[6]=this.enabled?this.intensity:0,this.header[7]=1.25*this.cellSize,this.header[8]=r&&this.enabled?1:0,this.header[9]=this.blend,this.header[10]=this.previousValid?1:0,this.header[12]=this.fieldBankBytes/16,this.device.queue.writeBuffer(this.field,0,this.header),!this.enabled||!r)return;oe(this.floats,0,r.origin.x,r.origin.y,r.origin.z,this.cellSize),oe(this.integers,4,this.resolution,this.probeResolution,this.rays,this.frame++),oe(this.floats,8,this.spacing,this.history,this.cellSize,1.732051*this.extent),oe(this.floats,12,this.sky[0],this.sky[1],this.sky[2],0),oe(this.integers,16,this.probeOffset,n,this.upload?1:0,this.steps),oe(this.integers,20,this.lightCount,0,0,0),this.device.queue.writeBuffer(this.params,0,this.uniformData),this.device.queue.writeBuffer(this.lightBuffer,0,this.lightData);const a=Math.ceil(this.resolution**3/64);if(this.upload){e.clearBuffer(this.field,64,this.fieldBankBytes-64),e.clearBuffer(this.surfaceStatistics),this.dispatch(e,{label:"SDFGIResolveSurface"},this.resolveSurface,this.resolveSurfaceBinding,a),this.readSurfaceCount(e,r),this.dispatch(e,le,this.seed,this.seedBinding,a);for(const t of this.jumps)this.dispatch(e,ce,t.kernel,t.binding,a)}this.dispatch(e,ue,this.inject,this.injectBinding,a),this.dispatch(e,de,this.probes,this.probeBinding,Math.ceil(n/32)),this.probeOffset=(this.probeOffset+n)%i,this.populatedProbes=Math.min(i,this.populatedProbes+n),this.upload=!1,this.stats.ready=!0,this.stats.updatedProbes=n}readSurfaceCount(e,t){const r=this.device.createBuffer({label:"sdfgi-cell-count",size:16,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});e.copyBufferToBuffer(this.surfaceStatistics,0,r,0,16),this.pendingCounts++,Promise.resolve().then(async()=>{try{await r.mapAsync(GPUMapMode.READ),this.disposed||this.grid!==t||(this.stats.occupiedCells=new Uint32Array(r.getMappedRange())[0]),r.unmap()}catch{}finally{r.destroy(),this.pendingCounts--}})}dispatch(e,t,r,i,n){const a=e.beginComputePass(t);a.setPipeline(r.pipeline),a.setBindGroup(0,i),a.dispatchWorkgroups(n),a.end()}dispose(){if(this.disposed=!0,this.unwatch(),this.surfaceCapture?.dispose(),this.distantVolumes)for(const e of this.distantVolumes)e.volume.dispose();this.staticDrawRoots.clear();for(const e of this.buffers)e.destroy()}};import{OrthographicCamera as fe,Vector3 as me}from"three";var ge=class{camera=new fe;center=new me;target;options;variants;constructor(e,t,r,i=!1){this.variants=i?new Map:null,this.target=e.createSceneCapture(null,t.surfaceResolution,t.surfaceResolution),this.options={objectFilter:e=>{if(e?.isSkinnedMesh)return!1;for(let t=e;t;t=t.parent)if(!1===t.userData.sdfgi||!0===t.userData.isSky)return!1;return!0},overrideMaterial:(e,i)=>{if(i||e.transparent||!1===e.userData.sdfgi)return null;let n=r(e);if(n&&this.variants){const e=n;let t=this.variants.get(e);t||(t=e.clone(),this.variants.set(e,t)),t.uniforms=e.uniforms,t.textures=e.textures,t.uniformValuesNeedsUpdate=!0,n=t}return n&&t.configureSurfaceMaterial(n),n},includeLocalLights:!1,postProcess:()=>{}}}capture(e,t,r){const{origin:i,extent:n}=t;this.center.copy(i).addScalar(n/2);const a=this.camera;return a.left=a.bottom=-n/2,a.right=a.top=n/2,a.near=.01,a.far=n+2,a.position.copy(this.center).setComponent(r,this.center.getComponent(r)+n/2+1),a.up.set(0,1===r?0:1,1===r?1:0),a.lookAt(this.center),a.updateProjectionMatrix(),this.target.capture(e,a,this.options),this.target.triangleCount}dispose(){if(this.target.dispose(),this.variants){for(const e of this.variants.values())e.dispose();this.variants.clear()}}};import{Color as ve,DirectionalLight as xe,Matrix4 as we,Object3D as be,PointLight as ye,Scene as Se,SpotLight as Ce,Vector3 as Me}from"three";var Pe=class extends be{constructor(e){super(),this.volume=e}volume;isFogVolumeObject=!0},De={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}}},Be=20,Te=16,Ie=(new we).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),Ve=new Me,ze=new Me,Le=new Me,Ge={label:"VolumetricFogFroxelPass"};function Re(e,t,r,i,n,a){e[t]=r,e[t+1]=i,e[t+2]=n,e[t+3]=a}var Ue=class{constructor(e=new Se,t={}){this.scene=e,this.options=Ae(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*Be);const r=this.options.maxDirectionalLights+this.options.maxPointLights+this.options.maxSpotLights;this.lightData=new Float32Array(r*Te),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 xe&&e.layers.test(t.layers)&&!this.collectedDirectionals.includes(e)?this.collectedDirectionals.push(e):e instanceof ye&&e.layers.test(t.layers)?this.collectedPoints.push(e):e instanceof Ce&&e.layers.test(t.layers)&&this.collectedSpots.push(e)};executeFroxelPass=e=>{this.executeFroxels(e)};projectionInverse=new we;viewProjectionInverse=new we;previousTemporalViewProjection=new we;previousFroxelViewProjection=new we;previousFroxelCameraPosition=new Me;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=Ae({...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(De[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 ke(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 Ee(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 Oe(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 $e(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(Ie).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),Re(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(ze);let n=r+.01;for(let e=0;e<this.volumeCount;e++){const t=e*Be,r=this.volumeData[t]-ze.x,i=this.volumeData[t+1]-ze.y,a=this.volumeData[t+2]-ze.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*Be+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(Ie).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,Re(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,Re(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(ze),Re(this.uniforms,32,ze.x,ze.y,ze.z,Math.max(e.camera.far-r,1e-4)),Re(this.uniforms,36,this.options.scatteringIntensity,this.options.spatialJitter?1:0,0,0),this.uniforms.set((this.froxelHistoryValid?this.previousFroxelViewProjection:this.projectionInverse).elements,40),Re(this.uniforms,56,this.previousFroxelCameraPosition.x,this.previousFroxelCameraPosition.y,this.previousFroxelCameraPosition.z,this.froxelHistoryValid&&!1!==this.options.temporal?1:0),Re(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*Be*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*Te*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(Ge);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*Be);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)*Te);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(ze);let a=0;for(let t=0;t<e.length;t+=1){const s=e[t],o=Number(s instanceof be?s.userData?.volumetricIntensity??0:s.volumetricIntensity);if(!Number.isFinite(o)||o<=0)continue;const l=s instanceof be?s.getWorldPosition(Ve):s.position,c=ze.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*Be;t.object.getWorldPosition(Ve),t.object.getWorldScale(Le),Re(this.volumeData,r,Ve.x,Ve.y,Ve.z,5*Math.max(Le.x,Le.y,Le.z)),Re(this.volumeData,r+4,t.albedo.r,t.albedo.g,t.albedo.b,Math.max(0,t.baseDensity)),Re(this.volumeData,r+8,t.heightFalloff,t.heightOffset,t.startDistance??3,-Math.max(-.99,Math.min(.99,t.scatteringDistribution))),Re(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*Te;t.getWorldPosition(Ve),t.target.getWorldPosition(ze),ze.sub(Ve).normalize(),Re(this.lightData,r,ze.x,ze.y,ze.z,0);const i=t.intensity*(t.userData?.volumetricIntensity??1);Re(this.lightData,r+4,t.color.r*i,t.color.g*i,t.color.b*i,0)}writeExtractedDirectional(e,t){const r=e*Te;Re(this.lightData,r,t.direction.x,t.direction.y,t.direction.z,0);const i=t.intensity*t.volumetricIntensity;Re(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*Te;t.getWorldPosition(Ve),Re(this.lightData,i,Ve.x,Ve.y,Ve.z,Math.max(.001,t.distance||this.options.maxDistance));const n=t.intensity*(t.userData?.volumetricIntensity??1);Re(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*Te;Re(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;Re(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*Te;t.getWorldPosition(Ve),t.target.getWorldPosition(ze),ze.sub(Ve).normalize(),Re(this.lightData,i,Ve.x,Ve.y,Ve.z,Math.max(.001,t.distance||this.options.maxDistance));const n=t.intensity*(t.userData?.volumetricIntensity??1);Re(this.lightData,i+4,t.color.r*n,t.color.g*n,t.color.b*n,Math.max(0,t.decay)),Re(this.lightData,i+8,ze.x,ze.y,ze.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*Te;Re(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;Re(this.lightData,i+4,t.color.x*n,t.color.y*n,t.color.z*n,Math.max(0,t.decay)),Re(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:Ne.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 Ae(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 ve(.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 ke=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=We;data=new Float32Array(20);inverseProjection=new we;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(Ie).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),Re(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=He;data=new Float32Array(20);inverseProjection=new we;frameIndex=0;setFrameIndex(e){this.frameIndex=e}updateUniforms=e=>(this.inverseProjection.copy(Ie).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),Re(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)},$e=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 we;currentViewProjectionInverse=new we;updateUniforms=e=>(this.state.updateTemporalUniforms(this.uniforms,this.currentViewProjection,this.currentViewProjectionInverse,this.temporal,e),Re(this.uniforms,36,e.camera.position.x,e.camera.position.y,e.camera.position.z,e.camera.far),this.uniforms)},Ee=class{name;sampler="linear";uniformBufferSize=80;inputs;outputs;fragmentShader;data=new Float32Array(20);inverseProjection=new we;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(Ie).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),this.data)},Oe=class{name="VolumetricFogBlurCompositePass";sampler="linear";uniformBufferSize=64;inputs;inputDimensions={};outputs;fragmentShader;data=new Float32Array(16);inverseProjection=new we;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?qe:Ke}updateUniforms=e=>(this.inverseProjection.copy(Ie).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements),this.data)},_e="\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 je(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 Ne="\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}",We="\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}",He="\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 qe="\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}",Ke="\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 Ze,DepthFormat as Ye,DepthStencilFormat as Xe,FloatType as Je,HalfFloatType as Qe,IntType as et,RED_GREEN_RGTC2_Format as tt,RED_RGTC1_Format as rt,RGBA_ASTC_10x10_Format as it,RGBA_ASTC_10x5_Format as nt,RGBA_ASTC_10x6_Format as at,RGBA_ASTC_10x8_Format as st,RGBA_ASTC_12x10_Format as ot,RGBA_ASTC_12x12_Format as lt,RGBA_ASTC_4x4_Format as ct,RGBA_ASTC_5x4_Format as ut,RGBA_ASTC_5x5_Format as dt,RGBA_ASTC_6x5_Format as ht,RGBA_ASTC_6x6_Format as pt,RGBA_ASTC_8x5_Format as ft,RGBA_ASTC_8x6_Format as mt,RGBA_ASTC_8x8_Format as gt,RGBA_BPTC_Format as vt,RGBA_ETC2_EAC_Format as xt,RGBA_S3TC_DXT1_Format as wt,RGBA_S3TC_DXT3_Format as bt,RGBA_S3TC_DXT5_Format as yt,RGBAFormat as St,RGBAIntegerFormat as Ct,RGFormat as Mt,RGIntegerFormat as Pt,RGB_ETC1_Format as Dt,RGB_ETC2_Format as Bt,RGB_S3TC_DXT1_Format as Tt,RGBFormat as It,RedFormat as Vt,RedIntegerFormat as zt,ShortType as Lt,SIGNED_RED_GREEN_RGTC2_Format as Gt,SIGNED_RED_RGTC1_Format as Rt,SRGBColorSpace as Ut,UnsignedByteType as At,UnsignedInt248Type as kt,UnsignedInt5999Type as Ft,UnsignedIntType as $t,UnsignedShortType as Et}from"three";function Ot(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=Wt(e,t),n=Yt(e),a=function(e){return"3d"===Zt(e)?"3d":"2d"}(e),s=Ht(e,i,t),o=qt(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:Kt(n,s),wgslSamplerType:"comparison"===o?"sampler_comparison":"sampler",width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers,mipLevelCount:l,compressed:Xt(e)}}function _t(e,t){const r=Ot(e,t);return[r.format,r.textureDimension,r.viewDimension,r.sampleType,r.samplerBindingType,r.width,r.height,r.depthOrArrayLayers,r.mipLevelCount].join(":")}function jt(e){const t=Ht(e,Wt(e,void 0,!1));return[Kt(Yt(e),t),"comparison"===qt(e,t)?"sampler_comparison":"sampler"].join(":")}function Nt(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}}function Wt(e,t,r=!0){const i=e.format,n=e.type,a=e.colorSpace===Ut;let s=null;if(Xt(e))switch(i){case Tt:case wt:s=a?"bc1-rgba-unorm-srgb":"bc1-rgba-unorm";break;case bt:s=a?"bc2-rgba-unorm-srgb":"bc2-rgba-unorm";break;case yt:s=a?"bc3-rgba-unorm-srgb":"bc3-rgba-unorm";break;case rt:s="bc4-r-unorm";break;case Rt:s="bc4-r-snorm";break;case tt:s="bc5-rg-unorm";break;case Gt:s="bc5-rg-snorm";break;case vt:s=a?"bc7-rgba-unorm-srgb":"bc7-rgba-unorm";break;case Bt:case Dt:s=a?"etc2-rgb8unorm-srgb":"etc2-rgb8unorm";break;case xt:s=a?"etc2-rgba8unorm-srgb":"etc2-rgba8unorm";break;case ct:s=a?"astc-4x4-unorm-srgb":"astc-4x4-unorm";break;case ut:s=a?"astc-5x4-unorm-srgb":"astc-5x4-unorm";break;case dt:s=a?"astc-5x5-unorm-srgb":"astc-5x5-unorm";break;case ht:s=a?"astc-6x5-unorm-srgb":"astc-6x5-unorm";break;case pt:s=a?"astc-6x6-unorm-srgb":"astc-6x6-unorm";break;case ft:s=a?"astc-8x5-unorm-srgb":"astc-8x5-unorm";break;case mt:s=a?"astc-8x6-unorm-srgb":"astc-8x6-unorm";break;case gt:s=a?"astc-8x8-unorm-srgb":"astc-8x8-unorm";break;case nt:s=a?"astc-10x5-unorm-srgb":"astc-10x5-unorm";break;case at:s=a?"astc-10x6-unorm-srgb":"astc-10x6-unorm";break;case st:s=a?"astc-10x8-unorm-srgb":"astc-10x8-unorm";break;case it:s=a?"astc-10x10-unorm-srgb":"astc-10x10-unorm";break;case ot:s=a?"astc-12x10-unorm-srgb":"astc-12x10-unorm";break;case lt:s=a?"astc-12x12-unorm-srgb":"astc-12x12-unorm";break;case St:s=a?"rgba8unorm-srgb":"rgba8unorm"}else switch(i){case St:switch(n){case Ze:s="rgba8snorm";break;case Lt:s="rgba16sint";break;case Et:s="rgba16uint";break;case $t:s="rgba32uint";break;case et:s="rgba32sint";break;case At:s=a?"rgba8unorm-srgb":"rgba8unorm";break;case Qe:s="rgba16float";break;case Je:s="rgba32float"}break;case It:switch(n){case Ft:s="rgb9e5ufloat";break;case 35899:s="rg11b10ufloat"}break;case Vt:switch(n){case Ze:s="r8snorm";break;case Lt:s="r16sint";break;case Et:s="r16uint";break;case $t:s="r32uint";break;case et:s="r32sint";break;case At:s="r8unorm";break;case Qe:s="r16float";break;case Je:s="r32float"}break;case Mt:switch(n){case Ze:s="rg8snorm";break;case Lt:s="rg16sint";break;case Et:s="rg16uint";break;case $t:s="rg32uint";break;case et:s="rg32sint";break;case At:s="rg8unorm";break;case Qe:s="rg16float";break;case Je:s="rg32float"}break;case Ye:switch(n){case Et:s="depth16unorm";break;case $t:s="depth24plus";break;case Je:s="depth32float"}break;case Xe:switch(n){case kt:s="depth24plus-stencil8";break;case Je:Jt("depth32float-stencil8",t,e,"DepthTexture with DepthStencilFormat + FloatType"),s="depth32float-stencil8"}break;case zt:switch(n){case et:s="r32sint";break;case $t:s="r32uint"}break;case Pt:switch(n){case et:s="rg32sint";break;case $t:s="rg32uint"}break;case Ct:switch(n){case et:s="rgba32sint";break;case $t: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&&Jt(o,t,e,`Texture format "${s}"`),s}function Ht(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===et)return"sint";if(e.type===$t)return"uint";if(e.type===Je&&!Qt(r,"float32-filterable")&&("r32float"===t||"rg32float"===t||"rgba32float"===t))return"unfilterable-float"}return"float"}function qt(e,t){const r=e.compareFunction;return"depth"===t&&null!=r?"comparison":"float"===t?"filtering":"non-filtering"}function Kt(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 Zt(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 Yt(e){const t=Zt(e);return"cube"===t?"cube":"2d-array"===t?"2d-array":"3d"===t?"3d":"2d"}function Xt(e){return!0===e.isCompressedTexture||!0===e.isCompressedArrayTexture}function Jt(e,t,r,i){if(!Qt(t,e))throw new Error(`${i} for "${r.name||r.uuid}" requires the WebGPU feature "${e}", which is not enabled on this device.`)}function Qt(e,t){return!!e&&(e instanceof Set?e.has(t):"features"in e?e.features.has(t):e.has(t))}import{Color as er,Matrix3 as tr,Matrix4 as rr,Vector2 as ir,Vector3 as nr,Vector4 as ar}from"three";var sr=new ArrayBuffer(8),or=new Float64Array(sr),lr=new Uint32Array(sr),cr={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 ur(e,t){return Math.ceil(e/t)*t}function dr(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 hr(e,t,r,i){for(let n=0;n<i;n+=1)e[t+n]=pr(r,n,i)}function pr(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 tr||e instanceof rr)return e.elements[t]??0;if(e instanceof er)return 0===t?e.r:1===t?e.g:2===t?e.b:3===t&&r>=4?1:0;if(e instanceof ir||e instanceof nr||e instanceof ar){if(0===t)return e.x;if(1===t)return e.y;if(2===t&&(e instanceof nr||e instanceof ar))return e.z;if(3===t&&e instanceof ar)return e.w}return 0}function fr(e,t,r){for(let i=0;i<3;i+=1){const n=3*i,a=t+4*i;e[a+0]=pr(r,n+0,9),e[a+1]=pr(r,n+1,9),e[a+2]=pr(r,n+2,9),e[a+3]=0}}function mr(e){let t=0;const r=[];for(const[i,n]of Object.entries(e)){const e=cr[n.type];t=ur(t,e.alignment),r.push({name:i,offset:t,type:n.type}),t+=e.size}return{byteLength:ur(t,16),entries:r}}function gr(e,t){const r=new ArrayBuffer(t.byteLength);return xr(e,t,new DataView(r),new Float32Array(r)),r}var vr=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 xr(e,this.layout,this.view,this.floats),this.buffer}};function xr(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":dr(r,n.offset,n.type,t.value);break;case"vec2<f32>":hr(i,a,t.value,2);break;case"vec3<f32>":hr(i,a,t.value,3);break;case"vec4<f32>":hr(i,a,t.value,4);break;case"mat3x3<f32>":fr(i,a,t.value);break;case"mat4x4<f32>":t.value instanceof rr?i.set(t.value.elements,a):hr(i,a,t.value,16)}}}function wr(e,t){let r=Math.imul(e^t,16777619);return r^=r>>>13,r>>>0}function br(e,t){return or[0]=t,e=wr(e,lr[0]??0),e=wr(e,lr[1]??0)}function yr(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 er?t>=4?[e.r,e.g,e.b,1]:[e.r,e.g,e.b]:e instanceof ir?[e.x,e.y]:e instanceof nr?[e.x,e.y,e.z]:e instanceof ar?[e.x,e.y,e.z,e.w]:e instanceof tr||e instanceof rr?Array.from(e.elements):[]}(t,r);e=wr(e,i.length);for(let t=0;t<i.length;t+=1)e=br(e,i[t]??0);return e}var Sr="\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 Cr(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 Mr=new WeakMap;function Pr(e){let t=Mr.get(e);return t||(t={outputFormats:[],inputDimensions:[]},Mr.set(e,t)),t}var Dr=new WeakMap;function Br(e,t,r,i,n){let a=Dr.get(e);a||Dr.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 Tr(){return{children:new WeakMap}}function Ir(e,t,r,i){let n=e;for(const e of t){let t=n.children.get(e);t||(t=Tr(),n.children.set(e,t)),n=t}return n.bindGroup??=r.createBindGroup(i),n.bindGroup}var Vr=new WeakMap,zr=new WeakMap;function Lr(e){return e?"string"==typeof e?[e]:Array.from(e):[]}function Gr(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,dependsOn:e.dependsOn,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=Lr(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=Lr(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}=Pr(e);s.length=t.length;for(let e=0;e<t.length;e++)s[e]=a.getColorFormat(t[e]);const l=i.map(([,e])=>_t(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=Vr.get(e);r||(r=new WeakMap,Vr.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])=>Ot(e,a.device)),l=[Sr,"@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}=Br(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:Tr()},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=Cr(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=Ir(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=Lr(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=mr(e.shader.uniforms);this.addPass({name:e.name,inputs:a,outputs:t,execute:a=>{const{outputFormats:o}=Pr(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])=>_t(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=zr.get(e);r||(r=new WeakMap,zr.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])=>Ot(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=Gr(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=Gr(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=>` ${Gr(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=[Sr,u,f,g,e.shader.fragmentShader].filter(Boolean).join("\n\n"),x=JSON.stringify([o,l]),{bindGroupLayout:w,pipeline:b}=Br(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:Tr()},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 vr(s)).update(e.shader.uniforms));const g=2*(i.length+n.length),v=Cr(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=Ir(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 Ar,EqualCompare as kr,GreaterCompare as Fr,GreaterEqualCompare as $r,InterleavedBufferAttribute as Er,LessCompare as Or,LessEqualCompare as _r,MirroredRepeatWrapping as jr,NearestFilter as Nr,NearestMipmapLinearFilter as Wr,NearestMipmapNearestFilter as Hr,NeverCompare as qr,NotEqualCompare as Kr,Object3D as Zr,RepeatWrapping as Yr,Vector3 as Xr}from"three";import{Material as Jr}from"three";var Qr=[{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]}],ei=class e extends Jr{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=ni(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=ri(p??Qr),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=mr(this.uniforms)),this.uniformLayoutCache}setUniform(e,t){const r=ni(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=ri(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:ii(t.value)}])),this.textures={...e.textures},this.sceneTextures={...e.sceneTextures},this.graphTextures={...e.graphTextures},this.storageBuffers={...e.storageBuffers},this.vertexAttributes=ri(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}:${jt(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"}:${t.access??"read"};`;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=wr(r,n.offset),n.type){case"f32":case"i32":case"u32":r=br(r,"boolean"==typeof a.value?a.value?1:0:Number(a.value));break;case"vec2<f32>":r=yr(r,a.value,2);break;case"vec3<f32>":r=yr(r,a.value,3);break;case"vec4<f32>":r=yr(r,a.value,4);break;case"mat3x3<f32>":r=yr(r,a.value,9);break;case"mat4x4<f32>":r=yr(r,a.value,16);break;default:r=wr(r,i+17)}else r=wr(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=Ot(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 ti(e){return!0===e.isWGSLShaderMaterial}function ri(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 ii(e){return Array.isArray(e)?Array.from(e):"number"==typeof e||"boolean"==typeof e?e:e.clone()}function ni(e,t){const r=si(t)?t:null,i=null!==r&&"value"in r?r.value:t;if(function(e){return ai(e,"isTexture")}(i))return{kind:"texture",texture:i};if(!function(e){return"number"==typeof e||"boolean"==typeof e||Array.isArray(e)||ai(e,"isColor")||ai(e,"isVector2")||ai(e,"isVector3")||ai(e,"isVector4")||ai(e,"isMatrix3")||ai(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(ai(t,"isColor"))return"vec3<f32>";if(ai(t,"isVector2"))return"vec2<f32>";if(ai(t,"isVector3"))return"vec3<f32>";if(ai(t,"isVector4"))return"vec4<f32>";if(ai(t,"isMatrix3"))return"mat3x3<f32>";if(ai(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 ai(e,t){return si(e)&&!0===e[t]}function si(e){return"object"==typeof e&&null!==e}var oi=new WeakMap,li=1;function ci(e){return e?"version"in e?e.version:e.data.version:0}function ui(e){const t=Object.keys(e.attributes).sort().map(t=>{const r=e.getAttribute(t);return[t,ci(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 di(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 hi(e){return e.startsWith("uint32")?"uint32":e.startsWith("sint32")?"sint32":"float32"}function pi(e,t){switch(t){case"uint32":return new Uint32Array(e);case"sint32":return new Int32Array(e);default:return new Float32Array(e)}}function fi(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 mi(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 gi(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 vi(e){switch(e){case"vertex":return GPUShaderStage.VERTEX;case"vertex-fragment":return GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT;default:return GPUShaderStage.FRAGMENT}}function xi(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 wi(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 bi(e,t,r){try{return e.beginComputePass({timestampWrites:{querySet:t,...r}}).end(),!0}catch{return!1}}function yi(e,t,r,i){if(e instanceof Ar&&!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 Si(e,t,r,i,n=0,a){const s=di(r),o=hi(r);if(!e)return function(e,t,r,i,n,a){const s=pi(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)fi(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 Ar&&!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:pi(l,o);if("float32"===o&&!e.normalized&&(e instanceof Ar?e.getComponent===Ar.prototype.getComponent:e.getComponent===Er.prototype.getComponent)){const r=e instanceof Er,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){fi(c,t+r,o,l&&r<e.itemSize?e.getComponent(a,r):i[r]??0)}}return c}function Ci(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 Mi(e,t){return{start:e.drawRange.start,count:Ci(e,t,e.drawRange.start,e.drawRange.count)}}function Pi(e){return e===Yr?"repeat":e===jr?"mirror-repeat":"clamp-to-edge"}function Di(e){return e===Nr||e===Hr||e===Wr?"nearest":"linear"}function Bi(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 Ti(e){return e}function Ii(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 Vi(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 zi(e,t,r){const i=e.elements;for(let e=0;e<16;e+=1)i[e]=t[r+e]??0;return e}function Li(e){const t=oi.get(e);if(void 0!==t)return t;const r=li+=1;return oi.set(e,r),r}function Gi(e,t,r,i,n,a){return[Li(e),Li(t),r?1:0,i,n,a?Li(a):0].join(":")}function Ri(e,t,r,i,n,a){let s=2166136261;return s=Fi(s,e),s=Fi(s,t),s=Fi(s,r?1:0),s=Fi(s,i),s=Fi(s,n),s=Fi(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 Ai(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 ki(e){for(let t=0;t<e.length;t+=1)if(e[t].hasRenderCallbacks)return!0;return!1}function Fi(e,t){let r=Math.imul((e^t)>>>0,16777619);return r^=r>>>13,r>>>0}function $i(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&&Oi(e)===Oi(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 Ei(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&&Oi(e)===Oi(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 Oi(e){return e.frontFaceCW}function _i(e,t){for(let r=0;r<16;r+=1)t[r]=e[r]??0}function ji(e,t){for(let r=0;r<16;r+=1)if((e[r]??0)!==(t[r]??0))return!1;return!0}function Ni(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 Wi(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 Hi(e,t){return t.multiplyMatrices(U.multiplyMatrices(T,e.projectionMatrix),e.matrixWorldInverse)}function qi(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];return Ki(t,0,s-i,u-o,f-d,x-m),Ki(t,4,s+i,u+o,f+d,x+m),Ki(t,8,s+n,u+l,f+h,x+g),Ki(t,12,s-n,u-l,f-h,x-g),Ki(t,16,s-a,u-c,f-p,x-v),Ki(t,20,a,c,p,v),t}function Ki(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 Zi(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 Yi(e){return null===e.boundingSphere&&e.computeBoundingSphere(),e.boundingSphere?{center:e.boundingSphere.center.clone(),radius:e.boundingSphere.radius}:{center:new Xr,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 Ji(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],D=i[n+10],B=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],z=y*o[4]+S*o[5]+C*o[6],L=y*o[8]+S*o[9]+C*o[10],G=M*o[0]+P*o[1]+D*o[2],R=M*o[4]+P*o[5]+D*o[6],U=M*o[8]+P*o[9]+D*o[10],A=l[0]*B+l[4]*V+l[8]*G,k=l[0]*T+l[4]*z+l[8]*R,F=l[0]*I+l[4]*L+l[8]*U,$=l[1]*B+l[5]*V+l[9]*G,E=l[1]*T+l[5]*z+l[9]*R,O=l[1]*I+l[5]*L+l[9]*U,_=l[2]*B+l[6]*V+l[10]*G,j=l[2]*T+l[6]*z+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 Qi(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 en(e){return Math.floor(Math.max(0,e.count)/3)*Math.max(0,e.instanceCount)}function tn(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 rn(e){const t=e.customDepthMaterial;return t&&ti(t)?t:null}var nn=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,source:null},this.palettes.set(e,r)),e.boneMatrices.length<t&&(e.boneMatrices=new Float32Array(t)),r.published!==e.boneMatrices&&(r.source=e.boneMatrices.length===t?e.boneMatrices:new Float32Array(e.boneMatrices.buffer,e.boneMatrices.byteOffset,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],D=s[8],B=s[12],T=s[1],I=s[5],V=s[9],z=s[13],L=s[2],G=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*G+d*k,n[o+8]=l*D+c*V+u*R+d*F,n[o+12]=l*B+c*z+u*U+d*$,n[o+1]=h*M+p*T+f*L+m*A,n[o+5]=h*P+p*I+f*G+m*k,n[o+9]=h*D+p*V+f*R+m*F,n[o+13]=h*B+p*z+f*U+m*$,n[o+2]=g*M+v*T+x*L+w*A,n[o+6]=g*P+v*I+x*G+w*k,n[o+10]=g*D+v*V+x*R+w*F,n[o+14]=g*B+v*z+x*U+w*$,n[o+3]=b*M+y*T+S*L+C*A,n[o+7]=b*P+y*I+S*G+C*k,n[o+11]=b*D+y*V+S*R+C*F,n[o+15]=b*B+y*z+S*U+C*$}t&&null!==e.boneTexture&&(e.boneTexture.needsUpdate=!0)}(e,!1);let i=!1;for(let n=0;n<t;n++)if(r.values[n]!==e.boneMatrices[n]){i=!0;break}return i&&r.values.set(r.source),!i&&r.published===e.boneMatrices||null===e.boneTexture||(e.boneTexture.needsUpdate=!0),r.published=e.boneMatrices,i}},an=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/S}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+S);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+=S,u}appendRange(e,t,r){if(r<=0)return;const i=t*S,n=i+r*S;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*S;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}},sn=class{disposed=!1;cachedInstanceData=new an;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 on,InterleavedBufferAttribute as ln}from"three";var cn=class{constructor(e){this.attributes=e;let t=0;for(const r of e){this.offsets.push(t);const e=di(r.format);this.components.push(e),this.kinds.push(hi(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=ci(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 ln,u=t&&!t.normalized&&(c?t.getComponent===ln.prototype.getComponent:t.getComponent===on.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{Color as un,CompressedArrayTexture as dn,Matrix3 as hn,Matrix4 as pn,Vector2 as fn,Vector3 as mn,Vector4 as gn}from"three";import{Color as vn,Matrix3 as xn,Matrix4 as wn}from"three";function bn(e){return!0===e.isWgslCompiler}function yn(e){return!0===e.isWgslFragmentCompiler}function Sn(e){return e instanceof zn?e:new Ln(e)}function Cn(e){return e instanceof An||e instanceof qn?new ia(e):e instanceof ra?e:new na(e)}function Mn(e){return e instanceof ra?new Fn(e):e instanceof An?e:new kn(e)}function Pn(e){return e instanceof ra||e instanceof An?new Zn(e):e instanceof qn?e:new Kn(e)}var Dn={level:0};function Bn(e){return Number.isInteger(e)?e+".":e.toString()}var Tn=class{scopeLevel=Dn.level};function In(e,t,r,i,n){if(bn(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 na&&t instanceof na&&void 0!==e.number&&void 0!==t.number){return{out:`${Bn(e.number-t.number)}`}}const a=`${i}_op_${n.variable()}`;return{chunk:`${i} ${a} = ${n.get(e)} ${r} ${n.get(t)};`,out:a}}function Vn(e,t,r,i){const n=`${r}_op_${i.variable()}`,a=`${t}${i.get(e)}`;return{chunk:bn(i)?i.local(r,n,a):`${r} ${n} = ${a};`,out:n}}var zn=class extends Tn{static typeName="bool";isBoolean(){return!0}and(e){return new Rn(this,Sn(e))}or(e){return new Un(this,Sn(e))}},Ln=class extends zn{bool;constructor(e){super(),this.bool=e}isBoolean(){return!0}compile(e){return{out:`${this.bool}`}}},Gn=class extends zn{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return In(this.a,this.b,this.op,"bool",e)}},Rn=class extends Gn{constructor(e,t){super(e,t,"&&")}},Un=class extends Gn{constructor(e,t){super(e,t,"||")}},An=class extends Tn{static typeName="int";isInt(){return!0}add(e){return new _n(this,Mn(e))}subtract(e){return new jn(this,Mn(e))}multiply(e){return new Wn(this,Mn(e))}divide(e){return new Nn(this,Mn(e))}gt(e){return new wo(this,Mn(e))}lt(e){return new bo(this,Mn(e))}gte(e){return new yo(this,Mn(e))}lte(e){return new So(this,Mn(e))}equals(e){return Bo(this,Mn(e))}notEquals(e){return To(this,Mn(e))}mod(e){return new Hn(this,Mn(e))}bitAnd(e){return new $n(this,Mn(e),"&")}bitOr(e){return new $n(this,Mn(e),"|")}bitXor(e){return new $n(this,Mn(e),"^")}bitNot(){return new On(this,"~")}shiftLeft(e){return new En(this,Pn(e),"<<")}shiftRight(e){return new En(this,Pn(e),">>")}},kn=class extends An{number;constructor(e){super(),this.number=e}compile(e){return{out:`${Math.floor(this.number)}`}}},Fn=class extends An{number;constructor(e){super(),this.number=e}compile(e){return bn(e)?{out:`i32(${e.get(this.number)})`}:{out:`int(${e.get(this.number)})`}}},$n=class extends An{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return In(this.a,this.b,this.op,"int",e)}},En=class extends An{value;amount;op;constructor(e,t,r){super(),this.value=e,this.amount=t,this.op=r}compile(e){return In(this.value,this.amount,this.op,"int",e)}},On=class extends An{value;op;constructor(e,t){super(),this.value=e,this.op=t}compile(e){return Vn(this.value,this.op,"int",e)}},_n=class extends $n{constructor(e,t){super(e,t,"+")}},jn=class extends $n{constructor(e,t){super(e,t,"-")}},Nn=class extends $n{constructor(e,t){super(e,t,"/")}},Wn=class extends $n{constructor(e,t){super(e,t,"*")}},Hn=class extends $n{constructor(e,t){super(e,t,"%")}},qn=class extends Tn{static typeName="int";isuInt(){return!0}add(e){return new Jn(this,Pn(e))}subtract(e){return new Qn(this,Pn(e))}multiply(e){return new ta(this,Pn(e))}divide(e){return new ea(this,Pn(e))}gt(e){return new Co(this,Pn(e))}lt(e){return new Mo(this,Pn(e))}gte(e){return new Po(this,Pn(e))}lte(e){return new Do(this,Pn(e))}equals(e){return Bo(this,Pn(e))}notEquals(e){return To(this,Pn(e))}bitAnd(e){return new Yn(this,Pn(e),"&")}bitOr(e){return new Yn(this,Pn(e),"|")}bitXor(e){return new Yn(this,Pn(e),"^")}bitNot(){return new Xn(this,"~")}shiftLeft(e){return new Yn(this,Pn(e),"<<")}shiftRight(e){return new Yn(this,Pn(e),">>")}},Kn=class extends qn{number;constructor(e){super(),this.number=e}compile(e){return bn(e)?{out:`${Math.floor(this.number)}u`}:{out:`${Math.floor(this.number)}`}}},Zn=class extends qn{number;constructor(e){super(),this.number=e}compile(e){return bn(e)?{out:`u32(${e.get(this.number)})`}:{out:`uint(${e.get(this.number)})`}}},Yn=class extends qn{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return In(this.a,this.b,this.op,"uint",e)}},Xn=class extends qn{value;op;constructor(e,t){super(),this.value=e,this.op=t}compile(e){return Vn(this.value,this.op,"uint",e)}},Jn=class extends Yn{constructor(e,t){super(e,t,"+")}},Qn=class extends Yn{constructor(e,t){super(e,t,"-")}},ea=class extends Yn{constructor(e,t){super(e,t,"/")}},ta=class extends Yn{constructor(e,t){super(e,t,"*")}},ra=class extends Tn{static typeName="float";isFloat(){return!0}add(e){return new sa(this,Cn(e))}subtract(e){return new oa(this,Cn(e))}divide(e){return new la(this,Cn(e))}multiply(e){return new ca(this,Cn(e))}multiplyVec2(e){return new Sa(this,e)}multiplyVec3(e){return new Za(this,e)}multiplyVec4(e){return new us(this,e)}gt(e){return new mo(this,Cn(e))}lt(e){return new go(this,Cn(e))}gte(e){if(this instanceof na&&e instanceof na&&void 0!==this.number&&void 0!==e.number){const t=this.number>=e.number;return new Ln(t)}return new vo(this,Cn(e))}lte(e){return new xo(this,Cn(e))}equals(e){return Bo(this,Cn(e))}notEquals(e){return To(this,Cn(e))}},ia=class extends ra{number;constructor(e){super(),this.number=e}compile(e){return bn(e)?{out:`f32(${e.get(this.number)})`}:{out:`float(${e.get(this.number)})`}}},na=class extends ra{number;constructor(e){super(),this.number=e}compile(e){if(bn(e))return{out:e.floatLiteral(this.number)};return{out:`${Bn(this.number)}`}}},aa=class extends ra{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return In(this.a,this.b,this.op,"float",e)}},sa=class extends aa{constructor(e,t){super(e,t,"+")}},oa=class extends aa{constructor(e,t){super(e,t,"-")}},la=class extends aa{constructor(e,t){super(e,t,"/")}},ca=class extends aa{constructor(e,t){super(e,t,"*")}},ua=class extends Tn{static typeName="vec2";isVec2(){return!0}get x(){return ho(this)}get y(){return po(this)}get yx(){return new ha(po(this),ho(this))}subtractScalar(e){return new va(this,Cn(e))}subtract(e){return new ma(this,e)}addScalar(e){return new ga(this,Cn(e))}add(e){return new fa(this,e)}divideScalar(e){return new wa(this,Cn(e))}divide(e){return new ba(this,e)}multiplyScalar(e){return new xa(this,Cn(e))}multiply(e){return new ya(this,e)}multiplyMat(e){return new Is(this,e)}equals(e){return Bo(this,e)}notEquals(e){return To(this,e)}},da=class extends ua{vec;constructor(e){super(),this.vec=e}compile(e){const t=e.variable();if(bn(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(${Bn(this.vec.x)},${Bn(this.vec.y)});`,out:`vec2_${t}`}}},ha=class extends ua{_x;_y;constructor(e,t){super(),this._x=e,this._y=t}compile(e){const t=e.variable();if(bn(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}`}}},pa=class extends ua{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return In(this.a,this.b,this.op,"vec2",e)}},fa=class extends pa{constructor(e,t){super(e,t,"+")}},ma=class extends pa{constructor(e,t){super(e,t,"-")}},ga=class extends pa{constructor(e,t){super(e,t,"+")}},va=class extends pa{constructor(e,t){super(e,t,"-")}},xa=class extends pa{constructor(e,t){super(e,t,"*")}},wa=class extends pa{constructor(e,t){super(e,t,"/")}},ba=class extends pa{constructor(e,t){super(e,t,"/")}},ya=class extends pa{constructor(e,t){super(e,t,"*")}},Sa=class extends pa{constructor(e,t){super(e,t,"*")}},Ca=class extends Tn{static typeName="ivec2";isiVec2(){return!0}get x(){return new co(this,"x")}get y(){return new co(this,"y")}subtractScalar(e){return new Va(this,Mn(e))}subtract(e){return new Ta(this,e)}addScalar(e){return new Ia(this,Mn(e))}add(e){return new Ba(this,e)}divideScalar(e){return new La(this,Mn(e))}divide(e){return new Ga(this,e)}multiplyScalar(e){return new za(this,Mn(e))}multiply(e){return new Ra(this,e)}multiplyMat(e){return new ds(this,e)}equals(e){return Bo(this,e)}notEquals(e){return To(this,e)}},Ma=class extends Ca{vec;constructor(e){super(),this.vec=e}compile(e){const t=e.variable();if(bn(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(${Bn(this.vec.x)},${Bn(this.vec.y)});`,out:`vec2_${t}`}}},Pa=class extends Ca{_x;_y;constructor(e,t){super(),this._x=e,this._y=t}compile(e){return bn(e)?{out:e.construct("ivec2",[e.get(this._x),e.get(this._y)])}:{out:`ivec2(${e.get(this._x)},${e.get(this._y)})`}}},Da=class extends Ca{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return In(this.a,this.b,this.op,"ivec2",e)}},Ba=class extends Da{constructor(e,t){super(e,t,"+")}},Ta=class extends Da{constructor(e,t){super(e,t,"-")}},Ia=class extends Da{constructor(e,t){super(e,t,"+")}},Va=class extends Da{constructor(e,t){super(e,t,"-")}},za=class extends Da{constructor(e,t){super(e,t,"*")}},La=class extends Da{constructor(e,t){super(e,t,"/")}},Ga=class extends Da{constructor(e,t){super(e,t,"/")}},Ra=class extends Da{constructor(e,t){super(e,t,"*")}},Ua=class extends Tn{static typeName="vec3";isVec3(){return!0}get x(){return ho(this)}get y(){return po(this)}get z(){return fo(this)}get xy(){return new $a(this,"xy")}get xz(){return new $a(this,"xz")}get yz(){return new $a(this,"yz")}get zx(){return new $a(this,"zx")}get rgb(){return new no(this)}rgba(e){return this.rgb.rgba(e)}subtractScalar(e){return new Na(this,Cn(e))}subtract(e){return new _a(this,e)}addScalar(e){return new ja(this,Cn(e))}add(e){return new Oa(this,e)}divideScalar(e){return new Ha(this,Cn(e))}divide(e){return new qa(this,e)}multiplyScalar(e){return new Wa(this,Cn(e))}multiply(e){return new Ka(this,e)}multiplyMat(e){return new Os(this,e)}equals(e){return Bo(this,e)}notEquals(e){return To(this,e)}},Aa=class extends Ua{vec;constructor(e){super(),this.vec=e}compile(e){const t=e.variable();if(bn(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(${Bn(this.vec.x)},${Bn(this.vec.y)},${Bn(this.vec.z)});`,out:`vec3_${t}`}}},ka=class extends Ua{_x;_y;_z;constructor(e,t,r){super(),this._x=e,this._y=t,this._z=r}compile(e){const t=e.variable();if(bn(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}`}}},Fa=class extends Ua{source;swizzle;constructor(e,t="xyz"){super(),this.source=e,this.swizzle=t}compile(e){return{out:`${e.get(this.source)}.${this.swizzle}`}}},$a=class extends ua{source;swizzle;constructor(e,t="xy"){super(),this.source=e,this.swizzle=t}compile(e){return{out:`${e.get(this.source)}.${this.swizzle}`}}},Ea=class extends Ua{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return In(this.a,this.b,this.op,"vec3",e)}},Oa=class extends Ea{constructor(e,t){super(e,t,"+")}},_a=class extends Ea{constructor(e,t){super(e,t,"-")}},ja=class extends Ea{constructor(e,t){super(e,t,"+")}},Na=class extends Ea{constructor(e,t){super(e,t,"-")}},Wa=class extends Ea{constructor(e,t){super(e,t,"*")}},Ha=class extends Ea{constructor(e,t){super(e,t,"/")}},qa=class extends Ea{constructor(e,t){super(e,t,"/")}},Ka=class extends Ea{constructor(e,t){super(e,t,"*")}},Za=class extends Ea{constructor(e,t){super(e,t,"*")}},Ya=class extends Tn{static typeName="vec4";isVec4(){return!0}get x(){return ho(this)}get y(){return po(this)}get z(){return fo(this)}get w(){return new lo(this,"w")}get xy(){return new $a(this,"xy")}get xz(){return new $a(this,"xz")}get yz(){return new $a(this,"yz")}get zx(){return new $a(this,"zx")}get zw(){return new $a(this,"zw")}get xyz(){return new Fa(this,"xyz")}get rgb(){return new io(this.x,this.y,this.z)}get rgba(){return new ao(this)}subtractScalar(e){return new as(this,Cn(e))}subtract(e){return new is(this,e)}addScalar(e){return new ns(this,Cn(e))}add(e){return new rs(this,e)}divideScalar(e){return new os(this,Cn(e))}divide(e){return new ls(this,e)}multiplyScalar(e){return new ss(this,Cn(e))}multiply(e){return new cs(this,e)}multiplyMat(e){return new Js(this,e)}equals(e){return Bo(this,e)}notEquals(e){return To(this,e)}},Xa=class extends Ya{vec;constructor(e){super(),this.vec=e}compile(e){const t=e.variable();if(bn(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(${Bn(this.vec.x)},${Bn(this.vec.y)},${Bn(this.vec.z)},${Bn(this.vec.w)});`,out:`vec4_${t}`}}},Ja=class extends Ya{_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(bn(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}`}}},Qa=class extends Ya{_xyz;_w;constructor(e,t){super(),this._xyz=e,this._w=t}compile(e){const t=e.variable();if(bn(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}`}}},es=class extends Ya{_xy;_zw;constructor(e,t){super(),this._xy=e,this._zw=t}compile(e){const t=e.variable();if(bn(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}`}}},ts=class extends Ya{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return In(this.a,this.b,this.op,"vec4",e)}},rs=class extends ts{constructor(e,t){super(e,t,"+")}},is=class extends ts{constructor(e,t){super(e,t,"-")}},ns=class extends ts{constructor(e,t){super(e,t,"+")}},as=class extends ts{constructor(e,t){super(e,t,"-")}},ss=class extends ts{constructor(e,t){super(e,t,"*")}},os=class extends ts{constructor(e,t){super(e,t,"/")}},ls=class extends ts{constructor(e,t){super(e,t,"/")}},cs=class extends ts{constructor(e,t){super(e,t,"*")}},us=class extends ts{constructor(e,t){super(e,t,"*")}},ds=class extends Da{constructor(e,t){super(e,t,"*")}},hs=class extends Tn{static typeName="uvec4";isuVec4(){return!0}get x(){return new uo(this,"x")}get y(){return new uo(this,"y")}get z(){return new uo(this,"z")}get w(){return new uo(this,"w")}subtractScalar(e){return new vs(this,Pn(e))}subtract(e){return new ms(this,e)}addScalar(e){return new gs(this,Pn(e))}add(e){return new fs(this,e)}divideScalar(e){return new ws(this,Pn(e))}divide(e){return new bs(this,e)}multiplyScalar(e){return new xs(this,Pn(e))}multiply(e){return new ys(this,e)}equals(e){return Bo(this,e)}notEquals(e){return To(this,e)}},ps=class extends hs{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return In(this.a,this.b,this.op,"ivec2",e)}},fs=class extends ps{constructor(e,t){super(e,t,"+")}},ms=class extends ps{constructor(e,t){super(e,t,"-")}},gs=class extends ps{constructor(e,t){super(e,t,"+")}},vs=class extends ps{constructor(e,t){super(e,t,"-")}},xs=class extends ps{constructor(e,t){super(e,t,"*")}},ws=class extends ps{constructor(e,t){super(e,t,"/")}},bs=class extends ps{constructor(e,t){super(e,t,"/")}},ys=class extends ps{constructor(e,t){super(e,t,"*")}},Ss=class extends Tn{static typeName="mat2";isMat2(){return!0}col(e){return new Ro(this,e)}add(e){return new Ms(this,e)}subtract(e){return new Ps(this,e)}divideScalar(e){return new Bs(this,Cn(e))}multiplyScalar(e){return new Ts(this,e)}multiplyVec(e){return new Vs(this,e)}multiply(e){return new Ds(this,e)}equals(e){return Bo(this,e)}notEquals(e){return To(this,e)}},Cs=class extends Ss{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return In(this.a,this.b,this.op,"mat2",e)}},Ms=class extends Cs{constructor(e,t){super(e,t,"+")}},Ps=class extends Cs{constructor(e,t){super(e,t,"-")}},Ds=class extends Cs{constructor(e,t){super(e,t,"*")}},Bs=class extends Cs{constructor(e,t){super(e,t,"*")}},Ts=class extends Cs{constructor(e,t){super(e,t,"*")}},Is=class extends pa{constructor(e,t){super(e,t,"*")}},Vs=class extends pa{constructor(e,t){super(e,t,"*")}},zs=class extends Tn{static typeName="mat3";isMat3(){return!0}col(e){return new Uo(this,e)}add(e){return new As(this,e)}subtract(e){return new ks(this,e)}divideScalar(e){return new $s(this,Cn(e))}multiplyScalar(e){return new Es(this,e)}multiplyVec(e){return new _s(this,e)}multiply(e){return new Fs(this,e)}equals(e){return Bo(this,e)}notEquals(e){return To(this,e)}},Ls=class extends zs{mat;constructor(e){super(),this.mat=e}compile(e){return{out:`mat3(${e.get(this.mat)})`}}},Gs=class extends zs{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 xn||"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:bn(e)?e.local("mat3",t,e.construct("mat3",r.map(t=>e.floatLiteral(t)))):`mat3 ${t} = mat3(${r.map(Bn).join(",")});`,out:t}}},Rs=class extends zs{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 bn(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 )`}}},Us=class extends zs{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return In(this.a,this.b,this.op,"mat3",e)}},As=class extends Us{constructor(e,t){super(e,t,"+")}},ks=class extends Us{constructor(e,t){super(e,t,"-")}},Fs=class extends Us{constructor(e,t){super(e,t,"*")}},$s=class extends Us{constructor(e,t){super(e,t,"*")}},Es=class extends Us{constructor(e,t){super(e,t,"*")}},Os=class extends Ea{constructor(e,t){super(e,t,"*")}},_s=class extends Ea{constructor(e,t){super(e,t,"*")}},js=class extends Tn{static typeName="mat4";isMat4(){return!0}col(e){return new Ao(this,e)}add(e){return new qs(this,e)}subtract(e){return new Ks(this,e)}divideScalar(e){return new Ys(this,Cn(e))}multiplyScalar(e){return new Xs(this,Cn(e))}multiplyVec(e){return new Qs(this,e)}multiply(e){return new Zs(this,e)}equals(e){return Bo(this,e)}notEquals(e){return To(this,e)}},Ns=class extends js{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 bn(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 ${Bn(this.a1)},${Bn(this.b1)},${Bn(this.c1)},${Bn(this.d1)},\n ${Bn(this.a2)},${Bn(this.b2)},${Bn(this.c2)},${Bn(this.d2)},\n ${Bn(this.a3)},${Bn(this.b3)},${Bn(this.c3)},${Bn(this.d3)},\n ${Bn(this.a4)},${Bn(this.b4)},${Bn(this.c4)},${Bn(this.d4)}\n );`,out:r};if((i=this.a1)instanceof wn||"object"==typeof i&&null!=i&&!0===i.isMatrix4&&"function"==typeof i.toArray){if(bn(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=>Bn(e)).join(",")});`,out:r}}throw new Error("Invalid parameters to Matrix4");var i}},Ws=class extends js{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(bn(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}`}}},Hs=class extends js{a;b;op;constructor(e,t,r){super(),this.a=e,this.b=t,this.op=r}compile(e){return In(this.a,this.b,this.op,"mat4",e)}},qs=class extends Hs{constructor(e,t){super(e,t,"+")}},Ks=class extends Hs{constructor(e,t){super(e,t,"-")}},Zs=class extends Hs{constructor(e,t){super(e,t,"*")}},Ys=class extends Hs{constructor(e,t){super(e,t,"/")}},Xs=class extends Hs{constructor(e,t){super(e,t,"*")}},Js=class extends ts{constructor(e,t){super(e,t,"*")}},Qs=class extends ts{constructor(e,t){super(e,t,"*")}},eo=class extends Ya{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}},to=class extends Ua{isRgb(){return!0}get r(){return this.x}get g(){return this.y}get b(){return this.z}rgba(e){return new oo(this,Cn(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}},ro=class extends eo{_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(bn(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}`}}},io=class extends to{_r;_g;_b;constructor(e,t,r){super(),this._r=e,this._g=t,this._b=r}compile(e){const t=e.variable();if(bn(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}`}}},no=class extends to{vec;constructor(e){super(),this.vec=e}compile(e){return{out:`${e.get(this.vec)}`}}},ao=class extends eo{vec;constructor(e){super(),this.vec=e}compile(e){return{out:`${e.get(this.vec)}`}}},so=class extends to{color;constructor(e){super(),this.color=e}compile(e){const t=new vn(this.color),r=e.variable();if(bn(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(${Bn(t.r)},${Bn(t.g)},${Bn(t.b)});`,out:`vec3_${r}`}}},oo=class extends eo{_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(bn(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}`}}},lo=class extends ra{vec;component;constructor(e,t){super(),this.vec=e,this.component=t}compile(e){return{out:`${e.get(this.vec)}.${this.component}`}}},co=class extends An{vec;component;constructor(e,t){super(),this.vec=e,this.component=t}compile(e){return{out:`${e.get(this.vec)}.${this.component}`}}},uo=class extends qn{vec;component;constructor(e,t){super(),this.vec=e,this.component=t}compile(e){return{out:`${e.get(this.vec)}.${this.component}`}}};function ho(e){return new lo(e,"x")}function po(e){return new lo(e,"y")}function fo(e){return new lo(e,"z")}var mo=class extends zn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} > ${e.get(this.b)}`}}},go=class extends zn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} < ${e.get(this.b)}`}}},vo=class extends zn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} >= ${e.get(this.b)}`}}},xo=class extends zn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} <= ${e.get(this.b)}`}}},wo=class extends zn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} > ${e.get(this.b)}`}}},bo=class extends zn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} < ${e.get(this.b)}`}}},yo=class extends zn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} >= ${e.get(this.b)}`}}},So=class extends zn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} <= ${e.get(this.b)}`}}},Co=class extends zn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} > ${e.get(this.b)}`}}},Mo=class extends zn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} < ${e.get(this.b)}`}}},Po=class extends zn{a;b;constructor(e,t){super(),this.a=e,this.b=t}compile(e){return{out:`${e.get(this.a)} >= ${e.get(this.b)}`}}},Do=class extends zn{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 Bo(e,t){return new class extends zn{compile(r){return{out:`${r.get(e)} == ${r.get(t)}`}}}}function To(e,t){return new class extends zn{compile(r){return{out:`${r.get(e)} != ${r.get(t)}`}}}}var Io=class extends Tn{static get typeName(){return"sampler2D"}sample(e,t){return new Lo(this,e,t)}sampleGrad(e,t,r){return new Go(this,e,t,r)}},Vo=class extends Tn{static typeName="usampler2D";sample(e,t){return new zo(this,e,t)}},zo=class extends hs{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}`}}},Lo=class extends eo{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(bn(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=yn(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}`}}},Go=class extends eo{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(bn(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 ua{mat;i;constructor(e,t){super(),this.mat=e,this.i=t}compile(e){return{out:`${e.get(this.mat)}[${this.i}]`}}},Uo=class extends Ua{mat;i;constructor(e,t){super(),this.mat=e,this.i=t}compile(e){return{out:`${e.get(this.mat)}[${this.i}]`}}},Ao=class extends Ya{mat;i;constructor(e,t){super(),this.mat=e,this.i=t}compile(e){return{out:`${e.get(this.mat)}[${this.i}]`}}};var ko=class extends Ya{name;constructor(e){super(),this.name=e}compile(e){return e instanceof rl||yn(e)?e.defineVarying("vec4",this):function(e,t,r){return yn(e)?e.defineBuiltinVarying(r,t):bn(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")}},Fo=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)}},$o=class extends zn{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 Fo(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)}},Eo=class extends ra{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 Fo(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)}},Oo=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 Fo(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)}},_o=class extends Io{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new Fo(t):void 0}get value(){return this.currentValue}set value(e){this.currentValue=e,null!=this.binding&&(this.binding.value=e)}compile(e){return bn(e)?e.defineTexture(this.name,this.value):e.defineUniform("sampler2D",this.name,this.value,this.ifdef,this.binding)}},jo=class extends Ua{a;isVarying=!0;constructor(e){super(),this.a=e}compile(e){if(e instanceof rl||yn(e))return e.defineVarying("vec3",this.a);throw new Error("A varying can not be defined as input to another varying.")}},No=class extends Ya{a;isVarying=!0;constructor(e){super(),this.a=e}compile(e){if(e instanceof rl||yn(e))return e.defineVarying("vec4",this.a);throw new Error("A varying can not be defined as input to another varying.")}};function Wo(e){return new ll(e)}function Ho(e){return e.multiplyScalar(Cn(-1))}function qo(e,t,r){if((e instanceof ra||"number"==typeof e)&&(t instanceof ra||"number"==typeof t))return new io(Cn(e),Cn(t),Cn(r??0)).divideScalar(255);if((i=e)instanceof un||!0===i?.isColor||"number"==typeof e||"string"==typeof e)return new so(e);var i;throw"Unsupported arguments to construct RGB"}function Ko(e,t){return e instanceof fn?new Ma(e):new Pa(Mn(e),Mn(null!=t?t:e))}function Zo(e,t){if(e instanceof Ua||e instanceof Ya)return e.xy;if(("number"==typeof e||e instanceof ra)&&("number"==typeof t||t instanceof ra||null==t))return new ha(Cn(e),Cn(t??e));if("number"==typeof e){if(t instanceof ra)return new ha(Cn(e),Cn(t));if("number"==typeof t||null==t)return new da(new fn(e,null!=t?t:e))}else if(e instanceof fn)return new da(e);if(e instanceof mn||e instanceof gn)return new da(new fn(e.x,e.y));if(e instanceof ra)return new ha(Cn(e),Cn(null!=t?t:e));throw new Error("Invalid arguments for vec2")}function Yo(e,t,r){if((e instanceof ra||"number"==typeof e)&&void 0===t)return new ka(Cn(e),Cn(e),Cn(e));if(e instanceof Ua)return e;if(e instanceof Ya)return e.xyz;if(("number"==typeof e||e instanceof ra)&&("number"==typeof t||t instanceof ra)&&("number"==typeof r||r instanceof ra))return new ka(Cn(e),Cn(t),Cn(r));if(e instanceof mn||e instanceof gn)return new Aa(e);throw new Error("Invalid arguments for vec3")}function Xo(e,t,r,i){if((e instanceof ra||"number"==typeof e)&&void 0===t)return new Ja(Cn(e),Cn(e),Cn(e),Cn(e));if(e instanceof Ua)return new Qa(e,Cn(t));if(el(e)&&el(t)&&el(r)&&el(i))return new Ja(Cn(e),Cn(t),Cn(r),Cn(i));if(e instanceof ua){if(t instanceof ua)return new es(e,t)}else if(e instanceof gn)return new Xa(e);throw"Unsupported combination of inputs"}function Jo(e,t,r){if(e instanceof hn)return new Gs(e);if("number"==typeof e&&void 0===t)return new Gs(e,e,e,e,e,e,e,e,e);if(e instanceof Ua&&t instanceof Ua&&r instanceof Ua)return new Rs(e.x,e.y,e.z,t.x,t.y,t.z,r.x,r.y,r.z);if(e instanceof js)return new Ls(e);throw"Unsupported combination of inputs"}function Qo(e,t,r,i){if(e instanceof pn)return new Ns(e);if("number"==typeof e&&void 0===t)return new Ns(e,e,e,e,e,e,e,e,e,e,e,e,e,e,e,e);if(e instanceof Ya&&t instanceof Ya&&r instanceof Ya&&i instanceof Ya)return new Ws(e,t,r,i);throw"Unsupported combination of inputs"}function el(e){return"number"==typeof e||e instanceof ra}var tl=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=[]){Dn.level,this.scopeLevelChunkIndex[Dn.level]=this.chunks.length-1,Dn.level++,Dn.level;const r=this.getCachedOuts(Dn.level);for(const e of t){const t=this.cachedOuts.get(e);null!=t&&r.set(e,t)}null==this.chunkBuffers[Dn.level]&&(this.chunkBuffers[Dn.level]=[]),this.chunkBuffers[Dn.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(Dn.level).clear(),0===Dn.level)throw"stop scope only after entering";const t=this.getScopeChunks(Dn.level);this.chunkBuffers[Dn.level].pop(),Dn.level--;const r=this.getScopeChunks(Dn.level);r.push(...t),r.push(e),Dn.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?Dn.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(Dn.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 Fo&&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 `}},rl=class extends tl{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=Dn.level;Dn.level=0;const a=this.vertexCompiler.get(t);Dn.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=Dn.level;Dn.level=0;const i=this.vertexCompiler.get(Mn(r));Dn.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}},il=/^\s*(?:(\w+)) (?=\w+)/g,nl=/^\s*(?:(\w+)) (?=(\w+))/g,al=class extends An{compile(e){return bn(e)?{out:e.currentLoopIndex()}:{out:"UNROLLED_LOOP_INDEX"}}},sl=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(Mn(this.limit)),capacity:this.limit}}compileElement(e,t){return`${e.get(this)}[${e.get(t)}]`}get(e){const t=this,r=Mn(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;Dn.level++;const r=new al,i=e(t.get(r),r);Dn.level--;const n=i.constructor;return new class extends n{compile(e){if(bn(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&&yn(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(Mn(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(Mn(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(nl))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(il,"")}),e.chunks[l-1]=e.chunks[l-1].replace("//VARIABLES",u),{out:`loop_sum_${r}`}}}}map(t){const r=this;Dn.level++;const i=new al,n=t(r.get(i),i),a=n.constructor;return Dn.level--,new class extends e{type=a;limit=r.limit;compile(e){if(bn(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(Mn(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(nl))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(il,"")}),e.chunks[l-1]=e.chunks[l-1].replace("//VARIABLES",u),{out:`loop_map_${t}`}}}}};var ol=class e extends sl{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(bn(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(Mn(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(bn(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)}},ll=class e extends sl{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)}},cl=class extends An{expr;constructor(e){super(),this.expr=e}compile(e){if(bn(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}}},ul=class extends Ua{expr;constructor(e){super(),this.expr=e}compile(e){return bn(e)?pl(e,"vec3",this.expr):{out:this.expr}}},dl=class extends Ya{expr;constructor(e){super(),this.expr=e}compile(e){return bn(e)?pl(e,"vec4",this.expr):{out:this.expr}}},hl=class extends js{expr;constructor(e){super(),this.expr=e}compile(e){if(bn(e))switch(this.expr){case"modelMatrix":return fl(e,"rendererModelMatrix");case"modelViewMatrix":return fl(e,"rendererModelViewMatrix");case"projectionMatrix":return{out:"rendererProjectionMatrix()"};case"viewMatrix":return{out:"rendererViewMatrix()"};case"instanceMatrix":case"vertexTransform":return{out:gl};default:throw ml("mat4",this.expr)}return{out:this.expr}}};function pl(e,t,r){if("instanceColor"===r&&("vec3"===t||"vec4"===t)){if(yn(e))return e.defineVarying(t,"vec3"===t?new ul(r):new dl(r));const i="rendererObjectColor(input.instanceIndex)";return{out:"vec3"===t?`${i}.xyz`:i}}if("uv"===r||"position"===r||"normal"===r||"color"===r)return yn(e)?e.defineBuiltinVarying(t,r):{out:`input.${r}`};if("cameraPosition"===r&&"vec3"===t)return{out:"rendererCameraPosition()"};if(yn(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 ml(t,r)}function fl(e,t){if(yn(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 ml(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 gl="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 vl,Vector3 as xl}from"three";var wl=new Ns((new vl).identity()),bl={tangent:new ko("tangent"),position:new ul("position"),normal:new ul("normal"),uv:new class extends ua{expr;constructor(e){super(),this.expr=e}compile(e){return bn(e)?pl(e,"vec2",this.expr):{out:this.expr}}}("uv"),color:new ko("color").rgba},yl=(new jo(bl.position),new jo(bl.normal),new class extends ua{a;isVarying=!0;constructor(e){super(),this.a=e}compile(e){if(e instanceof rl||yn(e))return e.defineVarying("vec2",this.a);throw new Error("A varying can not be defined as input to another varying.")}}(bl.uv),{instanceMatrix:new class extends js{compile(e){if(bn(e))return{out:e.get(wl)};const t=e.variable();return{chunk:`\n mat4 instanceMatrixOpt_${t} = ${e.get(wl)};\n #ifdef USE_INSTANCING\n instanceMatrixOpt_${t} = instanceMatrix;\n #endif\n `,out:`instanceMatrixOpt_${t}`}}},modelMatrix:new hl("modelMatrix"),modelViewMatrix:new hl("modelViewMatrix"),projectionMatrix:new hl("projectionMatrix"),viewMatrix:new hl("viewMatrix"),normalMatrix:new class extends zs{expr;constructor(e){super(),this.expr=e}compile(e){if(bn(e)){if("normalMatrix"===this.expr)return fl(e,"rendererNormalMatrix");throw ml("mat3",this.expr)}return{out:this.expr}}}("normalMatrix"),cameraPosition:new ul("cameraPosition")});new dl("projectionMatrix * modelViewMatrix * vec4( position , 1.0 )");function Sl(e,t){const r=Object.getPrototypeOf(t).constructor;return new class extends r{compile(i){const n=i.variable(),a=`out_${e}_${n}`;if(bn(i)){const n=Gl(e,1,r.typeName),s=function(e,t){if("inverse"!==e)return;switch(t){case"mat2":return Rl;case"mat3":return Ul;case"mat4":return Al;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 Cl(e){return Sl("transpose",e)}function Ml(e){return Ll(ra,"length",e)}function Pl(e){return Sl("normalize",e)}function Dl(e){return Sl("exp2",e)}function Bl(e){return Sl("sqrt",e)}function Tl(e){return Sl("inversesqrt",e)}function Il(e){return Sl("abs",e)}function Vl(e){return Sl("dFdx",e)}function zl(e){return Sl("dFdy",e)}function Ll(e,t,...r){return new class extends e{compile(i){const n=r.map(e=>i.get("number"==typeof e?Cn(e):e)),a=i.variable(),s=`out_${t}_${a}`;if(bn(i)){const a="mod"===t?`(${n[0]} - ${n[1]} * floor(${n[0]} / ${n[1]}))`:`${Gl(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 Gl(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 Rl="\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",Ul="\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",Al="\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 kl(e,t,r){return Ll(e instanceof eo?eo:e instanceof to?to:e instanceof Ya?Ya:e instanceof Ua?Ua:e instanceof ua?ua:ra,"mix",e,t,r)}function Fl(e,t,r){return Ll(Object.getPrototypeOf(r).constructor,"smoothstep",e,t,r)}function $l(e,t){return Ll(Object.getPrototypeOf(e).constructor,"pow",e,t)}function El(e,t){return Ll(Object.getPrototypeOf(e).constructor,"max",e,t)}function Ol(e,t){return Ll(Object.getPrototypeOf(e).constructor,"min",e,t)}function _l(e,t){return Ll(ra,"dot",e,t)}function jl(e,t){return Ll(Object.getPrototypeOf(e).constructor,"cross",e,t)}function Nl(e,t){return new Hl(e,Mn(t))}function Wl(e,t,r){return e instanceof Io?new ql(e,t,Mn(r)):new Kl(e,t,Mn(r))}var Hl=class extends Ca{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 bn(e)?{chunk:e.local("ivec2",t,`vec2<i32>(textureDimensions(${r}Texture, ${i}))`),out:t}:{chunk:`ivec2 ${t} = textureSize(${r}, ${i});`,out:t}}},ql=class extends eo{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 bn(e)?{chunk:e.local("vec4",t,`textureLoad(${r}Texture, ${i}, ${n})`),out:t}:{chunk:`vec4 ${t} = texelFetch(${r}, ${i}, ${n});`,out:t}}},Kl=class extends hs{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 bn(e)?{chunk:e.local("uvec4",t,`textureLoad(${r}Texture, ${i}, ${n})`),out:t}:{chunk:`uvec4 ${t} = texelFetch(${r}, ${i}, ${n});`,out:t}}};function Zl(e){return t=e,r=Cn(0),i=Cn(1),Ll(Object.getPrototypeOf(t).constructor,"clamp",t,r,i);var t,r,i}var Yl=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}},Xl=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}},Jl=class extends tl{externalBindings;textureBindings;vertexAttributeBindings;getMain(){return this.chunks.join("\n")}isWgslCompiler=!0;wgslDefinitions=[];uniqueWgslDefinitions=new Set;loopIndices=[];vertexAttributes=new Map;rendererVertexPosition="input.position";rendererVertexNormal="input.normal";constructor(e={},t=new Yl,r=new Xl(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=Ql(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=Ql(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=Ql(i);return this.textureSampleTypes.set(n,!0===r.isDepthTexture?"depth":"float"),{out:n}}getTextureSampleType(e){return this.textureSampleTypes.get(e)??"float"}};function Ql(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}var ec=/\b(?:(?:attribute|varying|uniform|texture2D|gl_Position|#if|#ifdef|#endif|float\s*\(|vec[234]\s*\(|mat[234]\s*\()\b|(?:float|vec[234])\s+[A-Za-z_]\w*\s*=)/;function tc(e){if(ec.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 rc=0,ic=new WeakMap;function nc(e,t,r){const i=Object.entries(e),n="tsg_function_"+ ++rc,a={},s=[];let o=!1;const l=t.typeName;for(const[e,t]of i){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))throw new Error(`Invalid shader function parameter name "${e}".`);if(!ac(t.typeName))throw new Error(`Shader functions do not support parameter type "${t.typeName}".`)}if(!ac(l))throw new Error(`Shader functions do not support return type "${l}".`);const c=t;class u extends c{inputs;constructor(e){super(),this.inputs=e}compile(e){const c=bn(e);for(const u of(e=>{const c=e?1:0,u=s[c];if(null!=u)return u;if(o)throw new Error("Recursive shader functions are not supported.");o=!0;const d=Dn.level;Dn.level=0;try{const o=e?new Jl:void 0,u=o??new tl;ic.set(u,a);const d=Object.create(null),h=i.map(([e,t],r)=>{const i=`arg${r}`,n=t;return d[e]=new class extends n{compile(e){if(ic.get(e)!==a)throw new Error("Shader function parameters cannot escape their function body.");return{out:i}}},o?`${i}: ${o.type(t.typeName)}`:`${t.typeName} ${i}`}),p=r(d);if(!(p instanceof t))throw new Error("Shader function body returned an incompatible node type.");const f=u.get(p);if(Object.keys(u.uniformTypes).length||Object.keys(u.uniforms).length||o&&(Object.keys(o.textures).length||Object.keys(o.sceneTextures).length||Object.keys(o.graphTextures).length||o.getVertexAttributes().length||u.pars.length)||!e&&u.pars.some(e=>/^\s*(?:uniform|attribute|varying)\s+/m.test(e))||Object.keys(u.outputs).length)throw new Error("Shader functions require explicit parameters, not captured resource bindings.");const m=u.getMain(),g=o?o.getWgslDefinitions():u.pars;if(e){tc(m),tc(f);for(const e of g)tc(e)}const v=o?`fn ${n}(${h.join(", ")}) -> ${o.type(l)} {\n${m}\nreturn ${f};\n}`:`${l} ${n}(${h.join(", ")}) {\n${m}\nreturn ${f};\n}`,x=[...g,v];return s[c]=x,x}finally{Dn.level=d,o=!1}})(c))bn(e)?e.addWgslDefinition(u):e.addDefinition(u);const u=i.map(([t,r])=>{const i=this.inputs[t];if(!(i instanceof r))throw new Error(`Incompatible shader function argument "${t}".`);return e.get(i)}),d=`function_result_${e.variable()}`,h=`${n}(${u.join(", ")})`;return{out:d,chunk:bn(e)?e.local(l,d,h):`${l} ${d} = ${h};`}}}return e=>new u({...e})}function ac(e){return/^(?:bool|float|int|uint|[iu]?vec[234]|mat[234])$/.test(e)}var sc=class extends ra{vec;component;constructor(e,t){super(),this.vec=e,this.component=t}compile(e){return{out:`${e.get(this.vec)}.${this.component}`}}};var oc=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 `}},lc=new class extends An{compile(e){return bn(e)?{out:"i32(rendererCsmCascadeCount())"}:{out:"CSM_CASCADES"}}},cc=(new ol("lightProbe",Ua,9),new ol("pointLights",class extends oc{static typeName="PointLight";position=this.get(Ua,"position");color=this.get(to,"color");distance=this.get(ra,"distance");decay=this.get(ra,"decay")},new cl("NUM_POINT_LIGHTS")),new ol("spotLights",class extends oc{static typeName="SpotLight";position=this.get(Ua,"position");direction=this.get(Ua,"direction");color=this.get(to,"color");distance=this.get(ra,"distance");decay=this.get(ra,"decay");coneCos=this.get(ra,"coneCos");penumbraCos=this.get(ra,"penumbraCos")},new cl("NUM_SPOT_LIGHTS")),new ol("hemisphereLights",class extends oc{static typeName="HemisphereLight";direction=this.get(Ua,"direction");skyColor=this.get(to,"skyColor");groundColor=this.get(to,"groundColor")},new cl("NUM_HEMI_LIGHTS")),new ol("directionalLights",class extends oc{static typeName="DirectionalLight";direction=this.get(Ua,"direction");color=this.get(to,"color")},new cl("NUM_DIR_LIGHTS")),new ol("rectAreaLights",class extends oc{static typeName="RectAreaLight";color=this.get(to,"color");position=this.get(Ua,"position");halfWidth=this.get(Ua,"halfWidth");halfHeight=this.get(Ua,"halfHeight")},new cl("NUM_RECT_AREA_LIGHTS")),new _o("ltc_1"),new _o("ltc_2"),new class extends Ua{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new Fo(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 $o("receiveShadow"),new ol("pointLightShadows",class extends oc{static typeName="PointLightShadow";shadowBias=this.get(ra,"shadowBias");shadowNormalBias=this.get(ra,"shadowNormalBias");shadowRadius=this.get(ra,"shadowRadius");shadowMapSize=this.get(ua,"shadowMapSize");shadowCameraNear=this.get(ra,"shadowCameraNear");shadowCameraFar=this.get(ra,"shadowCameraFar")},new cl("NUM_POINT_LIGHT_SHADOWS"))),uc=(new ol("pointShadowMap",Io,new cl("NUM_POINT_LIGHT_SHADOWS")),new ol("pointShadowMatrix",js,new cl("NUM_POINT_LIGHT_SHADOWS"))),dc=new ol("directionalLightShadows",class extends oc{static typeName="DirectionalLightShadow";shadowBias=this.get(ra,"shadowBias");shadowNormalBias=this.get(ra,"shadowNormalBias");shadowRadius=this.get(ra,"shadowRadius");shadowMapSize=this.get(ua,"shadowMapSize")},new cl("NUM_DIR_LIGHT_SHADOWS")),hc=(new ol("directionalShadowMap",Io,new cl("NUM_DIR_LIGHT_SHADOWS")),new ol("directionalShadowMatrix",js,new cl("NUM_DIR_LIGHT_SHADOWS"))),pc=new ol("spotLightShadows",class extends oc{static typeName="SpotLightShadow";shadowBias=this.get(ra,"shadowBias");shadowNormalBias=this.get(ra,"shadowNormalBias");shadowRadius=this.get(ra,"shadowRadius");shadowMapSize=this.get(ua,"shadowMapSize")},new cl("NUM_SPOT_LIGHT_SHADOWS")),fc=(new ol("spotShadowMap",Io,new cl("NUM_SPOT_LIGHT_SHADOWS")),new ol("spotShadowMatrix",js,new cl("NUM_SPOT_LIGHT_SHADOWS")));new ol("CSM_cascades",ua,lc);import*as mc from"three";import{ShaderMaterial as gc,UniformsUtils as vc}from"three";function xc(e,t,r,i){return new class extends e{compile(n){if(t instanceof Ln&&void 0!==t.bool)return t.bool?{out:n.get(r)}:{out:n.get(i)};const a=`select_out_${n.variable()}`;return bn(n)?{chunk:n.local(e.typeName,a,`select(${n.get(i)}, ${n.get(r)}, ${n.get(t)})`),out:a}:{chunk:`${e.typeName} ${a}; if (${n.get(t)}) { ${a} = ${n.get(r)}; } else { ${a} = ${n.get(i)}; }`,out:a}}}}var wc=(e,t,r)=>{if(t instanceof zn&&r instanceof zn)return xc(zn,e,t,r);if(t instanceof ra&&r instanceof ra)return xc(ra,e,t,r);if(t instanceof ua&&r instanceof ua)return xc(ua,e,t,r);if(t instanceof Ua&&r instanceof Ua)return xc(Ua,e,t,r);if(t instanceof Ya&&r instanceof Ya)return xc(Ya,e,t,r);if(t instanceof Ss&&r instanceof Ss)return xc(Ss,e,t,r);if(t instanceof zs&&r instanceof zs)return xc(zs,e,t,r);if(t instanceof js&&r instanceof js)return xc(js,e,t,r);throw new Error("Can not select on type of "+t+" and "+r)};function bc(e,t,r){return new class extends Object.getPrototypeOf(t).constructor{compile(i){if(bn(i))return{out:i.get(t)};const n=`select_out_${i.variable()}`,a=t.constructor.typeName,s=i.forceAppend;i.forceAppend=!0;const o=Dn.level;Dn.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 `),Dn.level=o,i.forceAppend=s,{out:n}}}}var yc=new _o("batchingTexture",void 0,"USE_BATCHING"),Sc=new class extends Vo{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new Fo(t):void 0}get value(){return this.currentValue}set value(e){this.currentValue=e,null!=this.binding&&(this.binding.value=e)}compile(e){return bn(e)?e.defineTexture(this.name,this.value):e.defineUniform("usampler2D",this.name,this.value,this.ifdef,this.binding)}}("batchingIdTexture",void 0,"USE_BATCHING"),Cc=(new _o("batchingColorTexture",void 0,"USE_BATCHING"),class extends ra{drawId;constructor(e){super(),this.drawId=e}compile(e){if(bn(e))return{out:`f32(${e.get(this.drawId)})`};const t=Nl(Sc,0).x,r=this.drawId.mod(t),i=this.drawId.divide(t);return{out:e.get(Cn(Wl(Sc,Ko(r,i),0).x))}}}),Mc=new class extends An{compile(e){return bn(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 Pc=function(e){const t=Nl(yc,0).x,r=Mn(e).multiply(4),i=r.mod(t),n=r.divide(t);return Qo(Wl(yc,Ko(i,n),0),Wl(yc,Ko(i.add(1),n),0),Wl(yc,Ko(i.add(2),n),0),Wl(yc,Ko(i.add(3),n),0))}(new Cc(Mc)),Dc=new Oo("bindMatrix",void 0,"USE_SKINNING"),Bc=new Oo("bindMatrixInverse",void 0,"USE_SKINNING"),Tc=new _o("boneTexture",void 0,"USE_SKINNING"),Ic=class extends js{index;constructor(e){super(),this.index=e}compile(e){if(bn(e))throw new Error("WebGPU skinning must use the renderer-owned skinning path.");const t=`tsgSkinningBoneMatrix(${e.get(Tc)}, ${e.get(this.index)})`,r=`bone_matrix_${e.variable()}`;return{out:r,pars:"\nmat4 tsgSkinningBoneMatrix(sampler2D bones, float index) {\n int size = textureSize(bones, 0).x;\n int j = int(index) * 4;\n int x = j % size;\n int y = j / size;\n return mat4(\n texelFetch(bones, ivec2(x, y), 0),\n texelFetch(bones, ivec2(x + 1, y), 0),\n texelFetch(bones, ivec2(x + 2, y), 0),\n texelFetch(bones, ivec2(x + 3, y), 0)\n );\n}",chunk:`mat4 ${r} = ${t};`}}},Vc=new dl("skinIndex"),zc=new dl("skinWeight"),Lc=new Ic(Vc.x),Gc=new Ic(Vc.y),Rc=new Ic(Vc.z),Uc=new Ic(Vc.w),Ac=Xo(0,0,0,0),kc={boneX:js,boneY:js,boneZ:js,boneW:js,weights:Ya,bind:js,inverseBind:js},Fc={boneX:Lc,boneY:Gc,boneZ:Rc,boneW:Uc,weights:zc,bind:Dc,inverseBind:Bc},$c=nc(kc,js,e=>{let t=Qo(Ac,Ac,Ac,Ac);return t=t.add(e.boneX.multiplyScalar(e.weights.x)),t=t.add(e.boneY.multiplyScalar(e.weights.y)),t=t.add(e.boneZ.multiplyScalar(e.weights.z)),t=t.add(e.boneW.multiplyScalar(e.weights.w)),e.inverseBind.multiply(t).multiply(e.bind)})(Fc);var Ec=nc({...kc,position:Ya},Ya,e=>{const t=e.bind.multiplyVec(e.position),r=Ac.add(e.boneX.multiplyVec(t).multiplyScalar(e.weights.x)).add(e.boneY.multiplyVec(t).multiplyScalar(e.weights.y)).add(e.boneZ.multiplyVec(t).multiplyScalar(e.weights.z)).add(e.boneW.multiplyVec(t).multiplyScalar(e.weights.w));return e.inverseBind.multiplyVec(r)}),Oc=new hl("vertexTransform"),_c=yl.instanceMatrix.multiplyVec(Oc.multiplyVec(qc(bl.position)));_c=bc("USE_SKINNING",_c,e=>{return t=e,Ec({...Fc,position:t});var t}),_c=bc("USE_BATCHING",_c,e=>Pc.multiplyVec(e));var jc,Nc=yl.modelViewMatrix.multiplyVec(_c),Wc={position:_c,mvPosition:Nc,worldPosition:yl.modelMatrix.multiplyVec(_c).xyz,normal:Pl(yl.normalMatrix.multiplyVec(Cl((jc=Oc,Sl("inverse",jc))).multiplyVec(qc(bc("USE_INSTANCING",bc("USE_BATCHING",bc("USE_SKINNING",bl.normal,e=>{return t=bl.normal,$c.multiplyVec(Xo(t,0)).xyz;var t}),e=>{const t=Jo(Pc);return t.multiplyVec(e.divide(Yo(_l(t.col(0),t.col(0)),_l(t.col(1),t.col(1)),_l(t.col(2),t.col(2)))))}),e=>{const t=Jo(new hl("instanceMatrix"));return t.multiplyVec(e.divide(Yo(_l(t.col(0),t.col(0)),_l(t.col(1),t.col(1)),_l(t.col(2),t.col(2)))))}),1)).xyz)),viewDir:Pl(Ho(Nc.xyz))},Hc={position:new No(Wc.position),mvPosition:new No(Wc.mvPosition),normal:Pl(new jo(Wc.normal)),worldPosition:new jo(Wc.worldPosition),viewDir:new jo(Wc.viewDir)};function qc(e,t=1){return new Ja(new sc(e,"x"),function(e){return new sc(e,"y")}(e),function(e){return new sc(e,"z")}(e),new na(t))}new Ns(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),function(e,t=1){if(e instanceof Ua)return new ro(e.x,e.y,e.z,Cn(t));if(e instanceof Ya)return new ro(e.x,e.y,e.z,null!=t?Cn(t):e.w);const r=new un(e);new ro(Cn(r.r),Cn(r.g),Cn(r.b),Cn(t))}(0);var Kc=new Eo("cameraNear"),Zc=new Eo("shadowFar");new $o("receiveShadow",!1),Cn(1e-6);nc({lightDistance:ra,cutoffDistance:ra,decayExponent:ra},ra,e=>function(e,t,r){const i=Cn(1).divide(El($l(e,r),Cn(.01)));return wc(t.gt(Cn(0)),i.multiply($l(Zl(Cn(1).subtract($l(e.divide(t),Cn(4)))),Cn(2))),i)}(e.lightDistance,e.cutoffDistance,e.decayExponent));var Yc=Cn(.3183098861837907),Xc=Hc.mvPosition.z.multiply(Cn(-1)).divide(Zc.subtract(Kc)),Jc=Wc.mvPosition.z.multiply(Cn(-1)).divide(Zc.subtract(Kc)),Qc=class extends ra{glslDepth;fragment;constructor(e,t){super(),this.glslDepth=e,this.fragment=t}compile(e){if(bn(e)){return{out:`-(rendererCamera.view * vec4<f32>(${this.fragment&&yn(e)?"input.worldPosition":`rendererWorldPosition(${e.getRendererVertexPosition()}, input.instanceIndex).xyz`}, 1.0)).z / max(rendererCameraFar() - rendererCameraNear(), 0.0001)`}}return{out:e.get(this.glslDepth)}}};new Qc(Xc,!0),new Qc(Jc,!1),Cn(1);import{Matrix3 as eu}from"three";var tu=Cn(1),ru=Cn(-2),iu=Cn(.8),nu=Cn(-1),au=Cn(.4),su=Cn(2),ou=Cn(.305),lu=Cn(3),cu=Cn(.21),uu=Cn(4);function du(e){return wc(e.gte(iu),tu.subtract(e).multiply(nu.subtract(ru)).divide(tu.subtract(iu)).add(ru),wc(e.gte(au),iu.subtract(e).multiply(su.subtract(nu)).divide(iu.subtract(au)).add(nu),wc(e.gte(ou),au.subtract(e).multiply(lu.subtract(su)).divide(au.subtract(ou)).add(su),wc(e.gte(cu),ou.subtract(e).multiply(uu.subtract(lu)).divide(ou.subtract(cu)).add(lu),Cn(-2).multiply(function(e){return Sl("log2",e)}(Cn(1.16).multiply(e)))))))}nc({roughness:ra},ra,({roughness:e})=>du(e));function hu(e,t){const r=_l(e,t),i=Cn(.8543985).add(Cn(.4965155).add(Cn(.0145206).multiply(Il(r))).multiply(Il(r))),n=Cn(3.417594).add(Cn(4.1616724).add(Il(r)).multiply(Il(r))),a=i.divide(n),s=wc(r.gt(0),a,Cn(.5).multiply(Tl(El(Cn(1).subtract(r.multiply(r)),Cn(1e-7)))).subtract(a));return jl(e,t).multiplyScalar(s)}function pu(e,t,r,i,n){const a=jl(n[1].subtract(n[0]),n[3].subtract(n[0])),s=Pl(t.subtract(e.multiplyScalar(_l(t,e)))),o=Ho(jl(e,s)),l=i.multiply(Cl(Jo(s,o,e))),c=n.map(e=>l.multiplyVec(e.subtract(r))).map(e=>Pl(e));let u=hu(c[0],c[1]);u=u.add(hu(c[1],c[2])),u=u.add(hu(c[2],c[3])),u=u.add(hu(c[3],c[0]));const d=function(e){const t=Ml(e);return El(t.multiply(t).add(e.z).divide(t.add(1)),Cn(0))}(u);return wc(_l(a,r.subtract(n[0])).lt(0),Cn(0),d)}nc({normal:Ua,view:Ua,roughness:ra},ua,e=>function(e,t,r){const i=Cn(64),n=i.subtract(1).divide(i),a=Cn(.5).divide(i),s=Zl(_l(e,t));return Zo(r,Bl(Cn(1).subtract(s))).multiplyScalar(n).addScalar(a)}(e.normal,e.view,e.roughness)),nc({normal:Ua,view:Ua,position:Ua,inverse:zs,corner0:Ua,corner1:Ua,corner2:Ua,corner3:Ua},ra,e=>pu(e.normal,e.view,e.position,e.inverse,[e.corner0,e.corner1,e.corner2,e.corner3]));import{Color as fu,ColorManagement as mu,HalfFloatType as gu,LinearMipmapLinearFilter as vu,NoToneMapping as xu,UnsignedByteType as wu,Vector2 as bu,WebGLRenderTarget as yu}from"three";Su=Yo(Ml(yl.modelMatrix.col(0).xyz),Ml(yl.modelMatrix.col(1).xyz),Ml(yl.modelMatrix.col(2).xyz)),new class extends Object.getPrototypeOf(Su).constructor{compile(e){if(e instanceof rl||yn(e))return e.defineVarying(Su.constructor.typeName,Su);throw new Error("A varying can not be defined as input to another varying.")}},Yo(0,0,0);var Su,Cu=Yo(1,1,1),Mu=Cn(1),Pu=Cn(0),Du=Cn(1e-6);function Bu(e){return e.multiplyScalar(Tl(El(_l(e,e),Du)))}new Eo("envMapIntensity",1),new class extends zs{name;ifdef;binding;currentValue;constructor(e,t,r,i=!1){super(),this.name=e,this.ifdef=r,this.currentValue=t,this.binding=i?new Fo(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 eu),new _o("envMap"),nc({viewDir:Ua,normal:Ua,roughness:ra},Ua,({viewDir:e,normal:t,roughness:r})=>Bu(kl(function(e,t){return Ll(Object.getPrototypeOf(e).constructor,"reflect",e,t)}(Ho(e),t),t,r.multiply(r))));var Tu=yl.modelMatrix.multiplyVec(Wc.position),Iu=Bu(Xo(Wc.normal,0).multiplyMat(yl.viewMatrix).xyz),Vu=cc.map((e,t)=>{const r=Tu.add(Xo(Iu.multiplyScalar(e.shadowNormalBias),0));return uc.get(t).multiplyVec(r)}),zu=(Wo(Vu),pc.map((e,t)=>{const r=Tu.add(Xo(Iu.multiplyScalar(e.shadowNormalBias),0));return fc.get(t).multiplyVec(r)})),Lu=(Wo(zu),dc.map((e,t)=>{const r=Tu.add(Xo(Iu.multiplyScalar(e.shadowNormalBias),0));return hc.get(t).multiplyVec(r)}));Wo(Lu);function Gu(e){return e.multiply(e)}function Ru(e,t,r,i,n){const a=Bu(e.add(t)),s=Zl(_l(r,e)),o=Zl(_l(r,t)),l=function(e,t){const r=Gu(e),i=Mu.divide(r),n=Gu(t),a=El(Mu.subtract(n),Cn(.0078125));return Cn(2).add(i).multiply($l(a,i.multiply(.5))).divide(Cn(2*Math.PI))}(n,Zl(_l(r,a))),c=function(e,t){return Zl(Mu.divide(Cn(4).multiply(t.add(e).subtract(t.multiply(e)))))}(o,s);return i.multiplyScalar(l.multiply(c))}nc({lightDir:Ua,viewDir:Ua,normal:Ua,sheenColor:Ua,sheenRoughness:ra},Ua,e=>Ru(e.lightDir,e.viewDir,e.normal,e.sheenColor,e.sheenRoughness));function Uu(e,t,r){const i=Zl(_l(e,t)),n=Gu(r),a=wc(r.lt(.25),Cn(-339.2).multiply(n).add(Cn(161.4).multiply(r)).subtract(Cn(25.9)),Cn(-8.48).multiply(n).add(Cn(14.3).multiply(r)).subtract(Cn(9.95))),s=wc(r.lt(.25),Cn(44).multiply(n).subtract(Cn(23.7).multiply(r)).add(Cn(3.26)),Cn(1.97).multiply(n).subtract(Cn(3.27).multiply(r)).add(Cn(.72))),o=function(e){return Sl("exp",e)}(a.multiply(i).add(s)).add(wc(r.lt(.25),Pu,Cn(.1).multiply(r.subtract(.25))));return Zl(o.multiply(Yc))}nc({normal:Ua,viewDir:Ua,roughness:ra},ra,e=>Uu(e.normal,e.viewDir,e.roughness));nc({eyePos:Ua,surfNorm:Ua,uv:ua},zs,e=>function(e,t,r){const i=Yo(Vl(e.x),Vl(e.y),Vl(e.z)),n=Yo(zl(e.x),zl(e.y),zl(e.z)),a=Vl(r),s=zl(r),o=t,l=jl(n,o),c=jl(o,i),u=l.multiplyScalar(a.x).add(c.multiplyScalar(s.x)),d=l.multiplyScalar(a.y).add(c.multiplyScalar(s.y)),h=El(_l(u,u),_l(d,d)),p=wc(h.equals(Pu),Pu,Tl(h));return Jo(u.multiplyScalar(p),d.multiplyScalar(p),o)}(e.eyePos,e.surfNorm,e.uv));function Au(e,t,r,i){const n=i.specularColor,a=i.specularF90,s=Gu(i.roughness),o=Bu(e.add(t)),l=Zl(_l(r,e)),c=Zl(_l(r,t)),u=Zl(_l(r,o)),d=function(e,t,r){const i=Dl(Cn(-5.55473).multiply(r).subtract(Cn(6.98316)).multiply(r));return e.multiplyScalar(Mu.subtract(i)).addScalar(t.multiply(i))}(n,a,Zl(_l(t,o))),h=i.iridescence&&i.iridescenceFresnel?kl(d,i.iridescenceFresnel,i.iridescence):d;let p=function(e,t,r){const i=Gu(e),n=Mu.subtract(i),a=t.multiply(Bl(n.multiply(Gu(r)).add(i))),s=r.multiply(Bl(n.multiply(Gu(t)).add(i)));return Cn(.5).divide(El(a.add(s),Du))}(s,l,c),f=function(e,t){const r=Gu(e),i=Gu(t).multiply(r.subtract(Mu)).add(Mu);return Yc.multiply(r).divide(Gu(i))}(s,u);if(null!=i.anisotropy&&null!=i.alphaT&&null!=i.anisotropyT&&null!=i.anisotropyB){const r=_l(i.anisotropyT,e),n=_l(i.anisotropyT,t),a=_l(i.anisotropyT,o),d=_l(i.anisotropyB,e),h=_l(i.anisotropyB,t),m=_l(i.anisotropyB,o);p=function(e,t,r,i,n,a,s,o){const l=o.multiply(Ml(Yo(e.multiply(r),t.multiply(i),s))),c=s.multiply(Ml(Yo(e.multiply(n),t.multiply(a),o)));return Zl(Cn(.5).divide(l.add(c)))}(i.alphaT,s,n,h,r,d,c,l),f=function(e,t,r,i,n){const a=e.multiply(t),s=Yo(t.multiply(i),e.multiply(n),a.multiply(r)),o=_l(s,s),l=a.divide(o);return Yc.multiply(a).multiply(Gu(l))}(i.alphaT,s,u,a,m)}return h.multiplyScalar(p.multiply(f))}var ku={lightDir:Ua,viewDir:Ua,normal:Ua,f0:Ua,f90:ra,roughness:ra,iridescence:ra,iridescenceFresnel:Ua,anisotropy:ra,alphaT:ra,anisotropyT:Ua,anisotropyB:Ua},Fu=([0,1,2,3].map(e=>nc(ku,Ua,t=>Au(t.lightDir,t.viewDir,t.normal,{specularColor:t.f0,specularF90:t.f90,roughness:t.roughness,iridescence:1&e?t.iridescence:void 0,iridescenceFresnel:1&e?t.iridescenceFresnel:void 0,anisotropy:2&e?t.anisotropy:null,alphaT:2&e?t.alphaT:null,anisotropyT:2&e?t.anisotropyT:null,anisotropyB:2&e?t.anisotropyB:null}))),nc({viewDir:Ua,normal:Ua,roughness:ra,bitangent:Ua,anisotropy:ra},Ua,({viewDir:e,normal:t,roughness:r,bitangent:i,anisotropy:n})=>{let a=jl(i,e);return a=Bu(jl(a,i)),a=Bu(kl(a,t,Gu(Gu(Mu.subtract(n.multiply(Mu.subtract(r))))))),a}),Yo(1),Yo(1),qo(0),qo(0),Hc.normal,Zo(1,0),nc({geometricNormal:Ua,roughnessFactor:ra},ra,({geometricNormal:e,roughnessFactor:t})=>{const r=El(Il(Vl(e)),Il(zl(e))),i=El(El(r.x,r.y),r.z);return Ol(El(t,Cn(.0525)).add(i),Mu)}),Xo(-1,-.0275,-.572,.022)),$u=Xo(1,.0425,1.04,-.04);nc({normal:Ua,viewDir:Ua,roughness:ra},ua,e=>function(e,t,r){const i=Zl(_l(e,t)),n=r.multiplyVec4(Fu).add($u),a=Ol(n.x.multiply(n.x),Dl(Cn(-9.28).multiply(i))).multiply(n.x).add(n.y);return Zo(-1.04,1.04).multiplyScalar(a).add(Zo(n.z,n.w))}(e.normal,e.viewDir,e.roughness)),nc({Fr:Ua,singleScatter:Ua,Ems:ra},Ua,({Fr:e,singleScatter:t,Ems:r})=>{const i=e.add(Cu.subtract(e).multiplyScalar(.047619));return t.multiply(i).divide(Cu.subtract(r.multiplyVec3(i))).multiplyScalar(r)}),new class extends Ua{glslValue;constructor(e){super(),this.glslValue=e}compile(e){return bn(e)?yn(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)}}}(Hc.normal);import{Matrix3 as Eu}from"three";var Ou=Cn(1),_u=Cn(0),ju=Cn(1e-6);function Nu(e){return e.multiply(e)}nc({outgoingLight:Ua,diffuseColor:Ua,eyeBrightness:ra,eyeIrisColor:Ua,irisMask:ra,eyeLowerLightMask:ra,eyeIrisGlow:ra,eyeHighlightColor:Ua,eyeHighlightMask:ra,eyeHighlightStrength:ra,eyeMask:ra},Ua,e=>{const t=e.outgoingLight.multiplyScalar(.35).add(e.diffuseColor.multiplyScalar(e.eyeBrightness.multiply(.65))),r=e.eyeIrisColor.multiplyScalar(e.irisMask.multiply(e.eyeLowerLightMask).multiply(e.eyeIrisGlow)),i=e.eyeHighlightColor.multiplyScalar(e.eyeHighlightMask.multiply(e.eyeHighlightStrength));return kl(e.outgoingLight,t,e.eyeMask).add(r).add(i)}),nc({dotNV:ra,rimPower:ra,rimThreshold:ra,rimSoftness:ra,rimColor:Ua,rimMask:ra,rimStrength:ra},Ua,e=>{const t=$l(Ou.subtract(e.dotNV),e.rimPower),r=Fl(e.rimThreshold.subtract(e.rimSoftness),e.rimThreshold.add(e.rimSoftness),t);return e.rimColor.multiplyScalar(r.multiply(e.rimMask).multiply(e.rimStrength))});var Wu=nc({lightDirection:Ua,normal:Ua,viewDir:Ua,alpha2:ra,dotNV:ra,specularThreshold:ra,specularSoftness:ra,specularToonness:ra,specularIntensity:ra},Ua,e=>{const t=Pl(e.lightDirection.add(e.viewDir)),r=Zl(_l(e.normal,e.lightDirection)),i=Zl(_l(e.normal,t)),n=Zl(_l(e.viewDir,t)),a=Nu(i).multiply(e.alpha2.subtract(Ou)).add(Ou),s=Cn(Yc).multiply(e.alpha2).divide(El(Nu(a),ju)),o=Cn(.5).divide(El(r.multiply(Bl(Ou.subtract(e.alpha2).multiply(Nu(e.dotNV)).add(e.alpha2))).add(e.dotNV.multiply(Bl(Ou.subtract(e.alpha2).multiply(Nu(r)).add(e.alpha2)))),ju)),l=Dl(Cn(-5.55473).multiply(n).subtract(6.98316).multiply(n)),c=Yo(.04).multiplyScalar(Ou.subtract(l)).addScalar(l),u=c.multiplyScalar(s.multiply(o).multiply(r)),d=El(El(u.x,u.y),u.z),h=Fl(e.specularThreshold.subtract(e.specularSoftness),e.specularThreshold.add(e.specularSoftness),d);return kl(u,c.multiplyScalar(h),e.specularToonness).multiplyScalar(e.specularIntensity)});yl.modelMatrix.multiplyVec(Wc.position),Pl(Xo(Wc.normal,0).multiplyMat(yl.viewMatrix).xyz),nc({lightDirection:Ua,normal:Ua,viewDir:Ua,fw:ra,skinShadowTint:Ua,rim:Ua,alpha2:ra,dotNV:ra,backscatterPower:ra,backscatterStrength:ra,diffuseColor:Ua,faceMask:ra,faceShadow:ra,faceShadowOffset:ra,faceShadowSoftness:ra,faceShadowStrength:ra,shadowSoftness:ra,shadowThreshold:ra,skinMask:ra,subsurfaceColor:Ua,subsurfaceStrength:ra,subsurfaceWrap:ra,thickness:ra,specularThreshold:ra,specularSoftness:ra,specularToonness:ra,specularIntensity:ra},Ua,e=>{const t=_l(e.normal,e.lightDirection),r=Zl(t.add(e.subsurfaceWrap).divide(Ou.add(e.subsurfaceWrap))),i=kl(t,r,e.skinMask),n=kl(Fl(e.shadowThreshold.subtract(e.shadowSoftness).subtract(e.fw),e.shadowThreshold.add(e.shadowSoftness).add(e.fw),i),Fl(e.faceShadow.subtract(e.faceShadowSoftness),e.faceShadow.add(e.faceShadowSoftness),t.multiply(.5).add(.5).add(e.faceShadowOffset)),e.faceMask.multiply(e.faceShadowStrength)),a=kl(e.diffuseColor.multiply(e.skinShadowTint),e.diffuseColor,n).multiplyScalar(Yc),s=El(r.subtract(Zl(t)),_u).multiply(e.skinMask).multiply(e.subsurfaceStrength),o=$l(Zl(_l(e.viewDir,Ho(e.lightDirection))),e.backscatterPower).multiply(Zl(_u.subtract(t))).multiply(e.skinMask).multiply(e.thickness).multiply(e.subsurfaceStrength).multiply(e.backscatterStrength);return a.add(Wu({lightDirection:e.lightDirection,normal:e.normal,viewDir:e.viewDir,alpha2:e.alpha2,dotNV:e.dotNV,specularThreshold:e.specularThreshold,specularSoftness:e.specularSoftness,specularToonness:e.specularToonness,specularIntensity:e.specularIntensity})).add(e.subsurfaceColor.multiplyScalar(s)).add(e.subsurfaceColor.multiplyScalar(o)).add(e.rim.multiplyScalar(Fl(Cn(-.25),Cn(.25),t)))}),qo(0),qo(0),Cn(1),Hc.normal,qo(8950960),qo(16740429),qo(9424895),qo(16777215),qo(12179967);nc({eyePos:Ua,surfNorm:Ua,mapN:Ua,faceDirection:ra,uv:ua},Ua,e=>function(e,t,r,i,n){const a=Yo(Vl(e.x),Vl(e.y),Vl(e.z)),s=Yo(zl(e.x),zl(e.y),zl(e.z)),o=Vl(n),l=zl(n),c=t,u=jl(s,c),d=jl(c,a),h=u.multiplyScalar(o.x).add(d.multiplyScalar(l.x)),p=u.multiplyScalar(o.y).add(d.multiplyScalar(l.y)),f=El(_l(h,h),_l(p,p)),m=Cn(0),g=wc(f.equals(m),m,i.multiply(Tl(f)));return Pl(h.multiplyScalar(r.x.multiply(g)).add(p.multiplyScalar(r.y.multiply(g))).add(c.multiplyScalar(r.z)))}(e.eyePos,e.surfNorm,e.mapN,e.faceDirection,e.uv));var Hu={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}))`}}};Hu.arrays.pointLights;var qu=255/256,Ku=[1,256,65536,16777216],Zu=[qu,1/Ku[1]],Yu=(Zo(Zu[0],Zu[1]),[qu/Ku[0],qu/Ku[1],1/Ku[2]]),Xu=(Yo(Yu[0],Yu[1],Yu[2]),[qu/Ku[0],qu/Ku[1],qu/Ku[2],1/Ku[3]]),Ju=(Xo(Xu[0],Xu[1],Xu[2],Xu[3]),class extends ra{constructor(e){super(),this.name=e}name;compile(){return{out:this.name}}}),Qu=new Ju("radius"),ed=new Ju("scale"),td=new Ju("threshold"),rd=new Ju("boundary"),id=new Ju("maxDistance"),nd=new Ju("distanceSquared"),ad=id.add(Qu),sd=function(e){const t=new Jl,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 tc(i),tc(n),{expression:r,statements:i,definitions:n}}(td.lte(0).or(Qu.multiply(ed).gte(td.multiply(rd))).and(id.lte(0).or(nd.lte(ad.multiply(ad))))),od=`\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${`${sd.definitions}\nfn shadowDetailVisible(radius: f32, scale: f32, threshold: f32, boundary: f32,\n maxDistance: f32, distanceSquared: f32) -> bool {\n ${sd.statements}\n return ${sd.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`,ld="\n// Roughly eight f32 ULPs near depth 1. A 0.001 bias spans hundreds of\n// world units at distance with conventional perspective depth.\nconst OCCLUSION_DEPTH_BIAS: f32 = 0.000001;\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 nearestW = clip.w - radius * length(rowW);\n if (nearestW <= 0.0001) { return 0.0; }\n let depth = clip.z / clip.w;\n // For any sphere offset u, depth(u) - depth(center) equals\n // dot(rowZ - depth * rowW, u) / (clip.w + dot(rowW, u)).\n // Bound that difference, preserving the correlation of clip Z and W.\n // Independently minimizing Z and maximizing W grossly underestimates\n // distant depths and makes hidden buildings pass the occlusion test.\n let depthRadius = radius * length(rowZ - depth * rowW) / nearestW;\n return max(0.0, depth - depthRadius);\n}\n",cd=`\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\n${ld}\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 + OCCLUSION_DEPTH_BIAS;\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`,ud=`\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\n${ld}\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 + OCCLUSION_DEPTH_BIAS;\n}\n\nfn cullInstance(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// Only sets fitting in one workgroup may use fused clear/cull/build.\nstruct CompactIndirectArgs {\n indexCount: u32,\n instanceCount: u32,\n firstIndex: u32,\n baseVertex: i32,\n firstInstance: u32,\n};\n@group(0) @binding(10) var<storage, read_write> compactIndirectArgs: array<CompactIndirectArgs>;\n@group(0) @binding(11) var<storage, read_write> compactPostIndirectArgs: array<CompactIndirectArgs>;\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let compact = (visibilityParams.flags & 8u) != 0u;\n let postpass = (visibilityParams.flags & 4u) != 0u;\n let index = globalId.x;\n if (compact && !postpass) {\n if (index < visibilityParams.drawCount) {\n atomicStore(&visibleCounts[index], 0u);\n atomicStore(&postVisibleCounts[index], 0u);\n }\n if (index < visibilityParams.instanceCount) {\n atomicStore(&visibleInstanceMask[index], atomicLoad(&visibleInstanceMask[index]) & 4u);\n }\n }\n if (compact) { storageBarrier(); }\n cullInstance(globalId);\n if (compact) {\n storageBarrier();\n if (index < visibilityParams.drawCount) {\n let primaryCount = atomicLoad(&visibleCounts[index]);\n let postCount = atomicLoad(&postVisibleCounts[index]);\n compactIndirectArgs[index].instanceCount = primaryCount + postCount;\n if (postpass) {\n compactPostIndirectArgs[index].instanceCount = postCount;\n compactPostIndirectArgs[index].firstInstance = compactIndirectArgs[index].firstInstance + primaryCount;\n }\n }\n }\n}\n`,dd="\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",hd="\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",pd="\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",fd="\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",md=`\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${fd}\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`,gd=`\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${fd}\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`,vd=`\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${fd}\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`,xd="\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 wd(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 bd=wd(!1),yd=wd(!0),Sd=class{enabled=!0;available=!1;sets=new Map;device=null;layout=null;clear=null;cull=null;pipeline=null;frame=0;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=od,n=dd.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([N.createAsync(e,{label:"directional-shadow-clear",code:i,entryPoint:"clear",bindGroupLayoutEntries:r}),N.createAsync(e,{label:"directional-shadow-cull",code:i,bindGroupLayoutEntries:r}),_(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={materials:[],depthDrawIndices:[],materialVersion:0,preparedFrame:-1,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},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)}beginFrame(){this.frame++}prepareCascade(e,t,r,i){for(let t=0;t<6;t++){const r=e.planes[t],i=4*t;this.paramData[i]=r.normal.x,this.paramData[i+1]=r.normal.y,this.paramData[i+2]=r.normal.z,this.paramData[i+3]=r.constant}this.paramData[24]=r.x,this.paramData[25]=r.y,this.paramData[26]=r.z,this.paramData[28]=Math.max(Math.abs(t.projectionMatrix.elements[0]),Math.abs(t.projectionMatrix.elements[5]))*i}prepareSet(e,t,r){if(r.preparedFrame===this.frame)return;if(-1===r.preparedFrame){for(let e=0;e<t.draws.length;e++){const i=t.draws[e],n=i.detailCulling,a=this.eligible(i)?1:0,s=4*e;r.eligibility[e]=a,a&&(r.eligibleDrawCount++,i.castShadow&&(r.triangleCount+=en(i)),(i.customDepthMaterial||null!==i.material.depthVertexShader)&&r.depthDrawIndices.push(e)),r.policyData[s]=n.shadowMinScreenSize,r.policyData[s+1]=n.shadowMaxDistance,r.policyData[s+2]=i.castShadow?1:0,r.policyData[s+3]=a,r.materials[e]=null}this.device.queue.writeBuffer(r.policies,0,r.policyData)}let i=!1;for(const n of r.depthDrawIndices){const a=t.draws[n],s=a.customDepthMaterial??a.material,o=e.getDepthPassMaterialResourceForDraw(s,"directionalShadow",a,"packed-visible");r.materials[n]!==o&&(i=!0),r.materials[n]=o}i&&r.materialVersion++,r.preparedFrame=this.frame}prepare(e,t,r,i,n){if(!this.enabled||!this.available||r.instanceCount>64*this.device.limits.maxComputeWorkgroupsPerDimension)return null;const a=this.getSet(r);this.prepareSet(e,r,a);let s=a.layers.get(i);if(!s){const e=GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,t=this.buffer(`${r.label}-shadow-cull-params`,128,GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST),n=this.buffer(`${r.label}-shadow-indirect`,a.commands.byteLength,e|GPUBufferUsage.INDIRECT),o=this.buffer(`${r.label}-shadow-indices`,4*r.instanceCount,e),l=this.buffer(`${r.label}-shadow-history`,4*r.instanceCount,e);this.device.queue.writeBuffer(n,0,a.commands);const c=[t,r.instanceVisibilityResource.instanceMetadataBuffer,a.policies,n,o,l].map((e,t)=>({binding:t,resource:{buffer:e}}));s={params:t,indirect:n,indices:o,history:l,clearGroup:this.clear.createBindGroup(this.device,c),cullGroup:this.cull.createBindGroup(this.device,c),shadowGroup:this.device.createBindGroup({layout:this.layout,entries:[{binding:0,resource:{buffer:i}},{binding:1,resource:{buffer:r.instanceBuffer}},{binding:2,resource:{buffer:o}}]}),bundle:null,materials:[],eligibilityVersion:-1,materialVersion:-1,bundles:[],materialCacheKey:`directional-shadow-gpu-${a.layers.size}`},a.layers.set(i,s),r.depthMaterialResources.set(s.materialCacheKey,s.materials)}this.paramInts[29]=r.instanceCount,this.paramInts[30]=r.draws.length,this.device.queue.writeBuffer(s.params,0,this.paramData);const o=s.materialVersion!==a.materialVersion;if(o){for(let e=0;e<a.materials.length;e++)s.materials[e]=a.materials[e];s.materialVersion=a.materialVersion}s.bundle&&s.eligibilityVersion===a.eligibilityVersion&&!o||this.buildBundle(e,r,a,s);const l=n??t.beginComputePass({label:`${r.label}-directional-shadow-selection`});return l.setPipeline(this.clear.pipeline),l.setBindGroup(0,s.clearGroup),l.dispatchWorkgroups(Math.ceil(r.draws.length/64)),l.setPipeline(this.cull.pipeline),l.setBindGroup(0,s.cullGroup),l.dispatchWorkgroups(Math.ceil(r.instanceCount/64)),n||l.end(),a.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??L,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}},Cd=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=Li(r),u=Li(e),d=s?Li(s):0;l={material:r,customDepthMaterial:s,indexed:i,start:n,count:a,materialId:c,geometryId:u,depthMaterialId:d,batchKey:Gi(r,e,i,n,a,s),batchHash:Ri(c,u,i,n,a,d)},o[t]=l}return l}},Md=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 j(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 Pd,BackSide as Dd,BufferAttribute as Bd,BufferGeometry as Td,Color as Id,DoubleSide as Vd,InstancedBufferAttribute as zd,InstancedBufferGeometry as Ld,InstancedMesh as Gd,MultiplyBlending as Rd,Matrix4 as Ud,Mesh as Ad,OrthographicCamera as kd,PerspectiveCamera as Fd,SkinnedMesh as $d,Sphere as Ed,SubtractiveBlending as Od,Vector2 as _d,Vector3 as jd,Vector4 as Nd,ShaderMaterial as Wd}from"three";var Hd=/^[A-Za-z_][A-Za-z0-9_]*$/;function qd(e,t={},r={}){const i=function(e){const t=new Map;for(const[r,i]of Object.entries(e))Hd.test(r)&&!1!==i&&null!=i&&t.set(r,{name:r,parameters:null,body:Kd(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=Zd(t),c=Xd(a);if(!r){s.push(c?Qd(t,i,n):"");continue}const{name:u,rest:d}=r;switch(u){case"define":if(c){const t=Yd(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&&oh(d,i);a.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),s.push("");break}case"elif":{const t=Jd(a,l,e+1,u);if(t.elseSeen)throw new Error(`${l}:${e+1}: #elif after #else`);const r=t.parentActive&&!t.branchTaken&&oh(d,i);t.active=r,t.branchTaken=t.branchTaken||r,s.push("");break}case"else":{const t=Jd(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":Jd(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 Kd(e){return"boolean"==typeof e?e?"1":"0":String(e)}function Zd(e){const t=/^\s*#\s*([A-Za-z_][A-Za-z0-9_]*)(.*)$/.exec(e);return t?{name:t[1],rest:t[2]??""}:null}function Yd(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=sh(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(!Hd.test(e))throw new Error(`${r}:${i}: invalid macro parameter "${e}"`);return t.set(a,{name:a,parameters:o,body:ch(s.slice(e+1)).trim()||"1"}),a}return t.set(a,{name:a,parameters:null,body:ch(s).trim()||"1"}),a}function Xd(e){for(const t of e)if(!t.active)return!1;return!0}function Jd(e,t,r,i){const n=e[e.length-1];if(!n)throw new Error(`${t}:${r}: #${i} without matching #if`);return n}function Qd(e,t,r){let i=e;for(let e=0;e<8;e+=1){const e=i;if(i=th(i,r),i=eh(i,t),i===e)return i}return i}function eh(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 th(e,t){if(0===t.size||!e.includes("("))return e;let r=e;for(const e of t.values())null!==e.parameters&&(r=rh(r,e));return r}function rh(e,t){let r="",i=0;for(;i<e.length;){const n=ih(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=sh(e,a);if(s<0){r+=e.slice(i);break}const o=ah(e.slice(a+1,s));r+=e.slice(i,n),r+=nh(t,o),i=s+1}return r}function ih(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 nh(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${uh(n)}\\b`,"g"),a)}return r}function ah(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 sh(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 oh(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}(ch(e));return 0!==new lh(r,t).parseExpression()}var lh=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 ch(e){const t=e.indexOf("//");return t>=0?e.slice(0,t):e}function uh(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var dh=/(?!\s*@invariant)\s+(?=(?:[A-Za-z_]\w*\s*:|vec4(?:\s*<\s*f32\s*>|f)\b))/y;function hh(e){return 32===e||9===e||10===e||13===e}var ph=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 fh,HalfFloatType as mh,LinearFilter as gh,LinearSRGBColorSpace as vh,RGBAFormat as xh,Texture as wh}from"three";var bh=[.125,.215,.35,.446,.526,.582],yh=20,Sh=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]]}(),Ch=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=Mh(r,this.equirectBindGroupLayout,Bh,"pmrem-equirectangular"),this.blurPipeline=Mh(r,this.blurBindGroupLayout,Th.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<bh.length;e+=1)t.push({mip:4-e-1,size:16,sigma:bh[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=Ph(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=Sh[(n.length-e-1)%Sh.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 wh;return v.image={width:a,height:s},v.name="PMREM.cubeUv",v.mapping=fh,v.format=xh,v.type=mh,v.colorSpace=vh,v.minFilter=gh,v.magFilter=gh,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(yh);let i=0;for(let n=0;n<yh;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=Ph(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,yh).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 Mh(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 Ph(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 Dh="\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",Bh=`${Dh}\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`,Th=`${Dh}\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 Ih(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}function Vh(e,t){const r=Object.entries(e.uniforms).map(([e,t])=>` ${Ih(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=Ih(e),s=Ot(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=Ih(e);return`@group(1) @binding(${a+r}) var<storage, ${t.access??"read"}> ${i}: ${t.type};`}).join("\n")}`}function zh(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 Lh(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 Gh(e,t,r="packed",i=!0,n=!1,a){const s="particle"!==r&&!e.transparent&&!e.requiresLatePass(),o=!0===e.defines?.USE_SDFGI,l=e.defines?.SDFGI_CASCADE_COUNT,c=Vh(e,t),u=function(e){return Object.entries(e.getGraphTextureInputs()).map(([e,t],r)=>{const i=Ih(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),d="packed-visible"===r,h=i?"\nfn rendererDirectionalReceiverDepthGradient(matrix: mat4x4<f32>, worldNormal: vec3<f32>) -> vec2<f32> {\n // Directional shadow projections are orthographic. Transform the receiver\n // plane normal with the inverse transpose of the orthogonal matrix rows;\n // multiplying it as a direction would be wrong for unequal cascade extents.\n let x = vec3(matrix[0].x, matrix[1].x, matrix[2].x);\n let y = vec3(matrix[0].y, matrix[1].y, matrix[2].y);\n let z = vec3(matrix[0].z, matrix[1].z, matrix[2].z);\n let normal = vec3(\n dot(worldNormal, x) / max(dot(x, x), 1e-20),\n dot(worldNormal, y) / max(dot(y, y), 1e-20),\n dot(worldNormal, z) / max(dot(z, z), 1e-20)\n );\n // A plane parallel to the light has no usable depth gradient. Keep the\n // existing raster bias there instead of dividing by a near-zero value.\n if (abs(normal.z) <= length(normal) * 1e-4) {\n return vec2(0.0);\n }\n // NDC X/Y span two units; texture Y is inverted.\n return vec2(-2.0 * normal.x, 2.0 * normal.y) / normal.z;\n}\n\nfn rendererSampleDirectionalShadowOnPlane(lightIndex: u32, worldPosition: vec3<f32>, depthGradient: vec2<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 // Hardware PCF compares a 2x2 footprint with one reference depth. Cover\n // only that half-texel footprint; wider taps are corrected individually.\n let footprintBias = dot(abs(depthGradient), texel * 0.5);\n let depth = ndc.z + rendererDirectionalShadowBiasForLight(lightIndex) - footprintBias;\n let filterOffset = texel * radius;\n let leftUv = clamp(uv - vec2(filterOffset.x, 0.0), vec2(0.0), vec2(1.0));\n let rightUv = clamp(uv + vec2(filterOffset.x, 0.0), vec2(0.0), vec2(1.0));\n let upUv = clamp(uv - vec2(0.0, filterOffset.y), vec2(0.0), vec2(1.0));\n let downUv = clamp(uv + vec2(0.0, filterOffset.y), vec2(0.0), vec2(1.0));\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 leftUv,\n i32(lightIndex),\n depth + dot(depthGradient, leftUv - uv)\n );\n let right = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n rightUv,\n i32(lightIndex),\n depth + dot(depthGradient, rightUv - uv)\n );\n let up = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n upUv,\n i32(lightIndex),\n depth + dot(depthGradient, upUv - uv)\n );\n let down = textureSampleCompareLevel(\n rendererDirectionalShadowTexture,\n rendererShadowSampler,\n downUv,\n i32(lightIndex),\n depth + dot(depthGradient, downUv - uv)\n );\n let shadow = (center * 4.0 + left + right + up + down) * 0.125;\n return mix(1.0, shadow, rendererDirectionalShadowIntensityForLight(lightIndex));\n}\n\nfn rendererSampleDirectionalShadowForLight(lightIndex: u32, worldPosition: vec3<f32>) -> f32 {\n return rendererSampleDirectionalShadowOnPlane(lightIndex, worldPosition, vec2(0.0));\n}\n\nfn rendererSampleDirectionalShadowForLightWithNormal(lightIndex: u32, worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> f32 {\n let params = rendererLights.directionalShadowParams[lightIndex];\n let gradient = rendererDirectionalReceiverDepthGradient(rendererDirectionalShadowMatrixForLight(lightIndex), worldNormal);\n return rendererSampleDirectionalShadowOnPlane(lightIndex, worldPosition + normalize(worldNormal) * params.w, gradient);\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${d?"@group(0) @binding(8) var<storage, read> rendererVisibleInstanceIndices: array<u32>;":""}\n\nfn rendererResolveInstanceIndex(instanceIndex: u32) -> u32 {\n ${d?"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${zh("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 rendererIndirectDiffuseAt(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> vec3<f32> {\n return rendererIndirectDiffuse(worldNormal)${o?" + rendererSdfgiIrradiance(worldPosition, worldNormal)":""};\n}\n\n${o?2===l||3===l?function(e){let t="",r="var result = vec3<f32>(0.0);\nvar remaining = 1.0;\n";for(let i=0;i<e;i++){const e=0===i?"sdfgiField":`sdfgiField${i}`;t+=Q.replace(/\bsdfgiField\b/g,e).replace(/rendererSdfgiSample/g,`rendererSdfgiSample${i}`).replace(/rendererSdfgiIrradiance/g,`rendererSdfgiIrradiance${i}`),t+=`\nfn rendererSdfgiBankCoverage${i}(position: vec3<f32>, normal: vec3<f32>, bank: u32) -> f32 {\n let origin = ${e}[bank];\n let settings = ${e}[bank + 1u];\n if (settings.z <= 0.0 || ${e}[bank + 2u].x < 0.5) { return 0.0; }\n let local = (position + normalize(normal) * settings.w - origin.xyz - vec3<f32>(origin.w * 2.0)) / settings.x;\n let edge = min(local, vec3<f32>(settings.y - 1.0) - local);\n return smoothstep(0.0, 1.0, min(edge.x, min(edge.y, edge.z)));\n}\nfn rendererSdfgiCoverage${i}(position: vec3<f32>, normal: vec3<f32>) -> f32 {\n if (${e}[1].z <= 0.0 || ${e}[2].x < 0.5) { return 0.0; }\n let blend = ${e}[2].y;\n var previous = 0.0;\n if (blend < 1.0 && ${e}[2].z > 0.5) {\n previous = rendererSdfgiBankCoverage${i}(position, normal, u32(${e}[3].x));\n }\n return mix(previous, rendererSdfgiBankCoverage${i}(position, normal, 0u), blend);\n}\n`,r+=`\n if (remaining > 0.0) {\n let coverage = rendererSdfgiCoverage${i}(worldPosition, worldNormal);\n if (coverage > 0.0) {\n result += rendererSdfgiIrradiance${i}(worldPosition, worldNormal) * remaining;\n remaining *= 1.0 - coverage;\n }\n }\n`}return t+`\nfn rendererSdfgiIrradiance(worldPosition: vec3<f32>, worldNormal: vec3<f32>) -> vec3<f32> {\n ${r}\n return result;\n}\n`}(l):Q:""}\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${h}\n${Lh(n)}\n${c}\n${u}\n`}function Rh(e=!0,t){return Gh({uniforms:{},textures:{},storageBuffers:{},getGraphTextureInputs:()=>({})},void 0,"particle",e,!1,t)}function Uh(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=Vh(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${zh("camera"===t?"rendererCamera":"shadowCamera")}\n${Lh(n)}\n${s}\n`}var Ah=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)}},kh=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()}},Fh=new WeakMap,$h=new WeakMap,Eh=new WeakSet;function Oh(e){Fh.get(e)?.dispose(),Fh.delete(e)}function _h(e,t){Eh.has(t)||((!e.latestFrameProfile||t.profile.frameIndex>=e.latestFrameProfile.frameIndex)&&(e.latestFrameProfile=Wh(t.profile)),(t.pendingGpuRead||t.pendingVisibilityRead)&&Promise.all([t.pendingGpuRead?jh(t.profile,t.pendingGpuRead):Promise.resolve(),t.pendingVisibilityRead?Nh(t.profile,t.pendingVisibilityRead):Promise.resolve()]).then(()=>{if($h.get(t)!==Fh.get(e))return;const r=Wh(t.profile);(!e.latestFrameProfile||r.frameIndex>=e.latestFrameProfile.frameIndex)&&(e.latestFrameProfile=r),(!e.latestCompletedFrameProfile||r.frameIndex>=e.latestCompletedFrameProfile.frameIndex)&&(e.latestCompletedFrameProfile=r)}))}async function jh(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 Nh(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 Wh(e){return{...e,cpuPhases:{...e.cpuPhases},passes:e.passes.map(e=>({...e})),visibility:e.visibility?{...e.visibility}:null}}import{Frustum as Hh,Matrix4 as qh,Sphere as Kh}from"three";function Zh(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 Yh=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}},Xh=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}},Jh=new WeakMap;function Qh(e){if(e.transparent)return!0;let t=Jh.get(e);return void 0===t&&(t=e.alphaTest>0||/\bdiscard\b/.test(e.fragmentShader),Jh.set(e,t)),t}function ep(e){for(const t of e)if(t.customDepthMaterial||null!==t.skinning||t.material.vertexAttributes.some(e=>"instance"===e.stepMode)||null===t.material.depthVertexShader&&(Qh(t.material)||t.wireframe||!t.material.primitiveTopology.startsWith("triangle")))return!1;return!0}var tp=new WeakMap,rp={drawCallCount:0,triangleCount:0},ip=new Hh,np=new qh,ap=new Hh,sp=new qh,op=new Kh,lp=new WeakMap,cp=new WeakMap,up=k.clone();function dp(e,t,r,i,n=0){let a=lp.get(e);a||(a=new WeakMap,lp.set(e,a));let s=a.get(t);s||(s={pool:[],draws:[],key:new Xh},a.set(t,s));if(!s.key.update(sp,r,e.draws,up)&&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=cp.get(e);d||(d=new WeakMap,cp.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(op.center.copy(t.boundsCenter),op.radius=t.boundsRadius,ap.intersectsSphere(op))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=Zh(c,8*e,ap,u,n.shadowMinScreenSize,n.shadowMaxDistance,0!==h[e],up),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 hp(e){return e.usesBatching}function pp(e){return!e.wireframe&&e.material.primitiveTopology.startsWith("triangle")}function fp(e,t){return"pointShadow"===t?null!==e.material.pointShadowVertexShader&&null!==e.material.pointShadowFragmentShader:null!==e.material.depthVertexShader}function mp(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()}function gp(e){return e.instanceVisibilityResource.instanceCount<=64&&e.drawMetadataResource.count<=64}var vp=new WeakMap;function xp(e,t){if(!(this.state.staticVisibilityClearKernel&&this.state.staticVisibilityCullKernel&&this.state.staticVisibilityIndirectBuildKernel&&this.getHiZOcclusionCullingActive()&&this.state.device))return;let r=vp.get(this);r||(r=[],vp.set(this,r)),r.length=0;for(const e of this.getCameraStaticDrawSets()){if(!e.publicSet.enabled||!this.isStaticDrawSetCameraVisible(e)||e.cpuVisibility||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)|(gp(e)?8:0);i[1]===this.state.hizMipCount&&i[3]===a||(i[1]=this.state.hizMipCount,i[3]=a,this.state.device.queue.writeBuffer(n,0,Ti(i),0,4));this.getOrCreateStaticVisibilityBindGroup(e,t)&&("prepass"!==t||gp(e)||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;let i=!1;for(const e of r)if(!gp(e)){i=!0;break}if("prepass"===t&&i){const t=e.beginComputePass({label:"static-temporal-visibility-clear-pass"});t.setPipeline(this.state.staticVisibilityClearKernel.pipeline);for(const e of r)gp(e)||(t.setBindGroup(0,e.visibilityClearBindGroup),t.dispatchWorkgroups(Math.ceil(Math.max(e.drawMetadataResource.count,e.instanceVisibilityResource.instanceCount)/64)));t.end()}const n=e.beginComputePass({label:`static-temporal-visibility-${t}-cull-pass`});n.setPipeline(this.state.staticVisibilityCullKernel.pipeline);for(const e of r)n.setBindGroup(0,"prepass"===t?e.visibilityBindGroup:e.postVisibilityBindGroup),n.dispatchWorkgroups(Math.ceil(e.instanceVisibilityResource.instanceCount/64));n.end();const a=i?e.beginComputePass({label:`static-temporal-visibility-${t}-indirect-build-pass`}):null;a?.setPipeline(this.state.staticVisibilityIndirectBuildKernel.pipeline);for(const e of r)!gp(e)&&a&&(a.setBindGroup(0,"prepass"===t?e.visibilityIndirectBuildBindGroup:e.postVisibilityIndirectBuildBindGroup),a.dispatchWorkgroups(Math.ceil(e.drawMetadataResource.count/64))),"prepass"===t?e.lastPreVisibilityFrameToken=this.staticFrameToken:e.lastVisibilityFrameToken=this.staticFrameToken;a?.end(),r.length=0}function wp(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}},{binding:10,resource:{buffer:e.drawMetadataResource.indirectBuffer}},{binding:11,resource:{buffer:e.drawMetadataResource.postIndirectBuffer}}],`${e.label}-temporal-visibility-${t}-bind-group`);return"prepass"===t?e.visibilityBindGroup=i:e.postVisibilityBindGroup=i,e.visibilityBindGroupHizVersion=this.hizResourceVersion,i}function bp(e,t,r,i){if(!this.state.shadowDepthPipeline||0===this.state.directionalShadowLayerViews.length)return void this.clearDirectionalShadow(e);this.directionalShadowGpu.beginFrame();let n=!1;r.camera.getWorldPosition(up);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),ap.setFromProjectionMatrix(sp.multiplyMatrices(o.projectionMatrix,o.matrixWorldInverse));const l=this.queryStaticShadowResources(ap),c=this.getShadowCameraBuffer(t);this.writeShadowCameraBuffer(Hi(o,this.shadowViewProjScratch),0,0,0,1,c,o);const u=this.getSharedShadowBindGroupForCameraBuffer(c);let d;this.directionalShadowGpu.prepareCascade(ap,o,up,this.state.directionalShadowTextureSize);for(const r of l)r.publicSet.enabled&&0!==r.draws.length&&"late"!==r.drawStage&&(op.center.copy(r.spatialBounds.boundsCenter),op.radius=r.spatialBounds.boundsRadius,ap.intersectsSphere(op)&&(!d&&this.directionalShadowGpu.enabled&&this.directionalShadowGpu.available&&(d=e.beginComputePass({label:`renderer-directional-shadow-selection-${t}`})),this.directionalShadowGpu.prepare(this,e,r,c,d)));d?.end();const h=e.beginRenderPass({label:`renderer-directional-shadow-pass-${t}`,colorAttachments:[],depthStencilAttachment:{view:s,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});h.setPipeline(this.state.shadowDepthPipeline),h.setBindGroup(0,u),this.drawDepthLike(h,r.shadowDraws??[...r.gpuOpaqueDraws,...r.directOpaqueDraws],i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:u,shadowCameraBuffer:c,passKind:"directionalShadow",customDepthMode:"use"});for(const e of l){if(!e.publicSet.enabled||0===e.draws.length||"late"===e.drawStage)continue;if(op.center.copy(e.spatialBounds.boundsCenter),op.radius=e.spatialBounds.boundsRadius,!ap.intersectsSphere(op))continue;const t=this.directionalShadowGpu.submit(h,e,c,i)?this.directionalShadowGpu.sets.get(e):void 0;t?.eligibleDrawCount!==e.draws.length&&yp.call(this,h,e,o,dp.call(this,e,o,this.state.directionalShadowTextureSize,t?.eligibility,t?.eligibilityVersion),u,c,i)}h.end(),this.directionalShadowScheduler.commit(t)}n||this.clearDirectionalShadow(e)}function yp(e,t,r,i,n,a,s){let o=tp.get(t);o||(o=new WeakMap,tp.set(t,o));let l=o.get(r);l||(l=new Yh,o.set(r,l)),l.draws.length=0,l.directDraws.length=0;let c=0;for(const e of i)e.customDepthMaterial||fp(e,"directionalShadow")||e.hasRenderCallbacks||e.skinning||!e.indexed||e.wireframe||!pp(e)||"packed"!==this.getDrawInstanceAccessMode(e)?l.directDraws.push(e):(l.draws.push(e),c+=en(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});rp.drawCallCount=0,rp.triangleCount=0,Wp.call(this,e,l.draws,rp,{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),rp.drawCallCount=0,rp.triangleCount=0,Wp.call(this,e,l.draws,rp,{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 Sp(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),k.copy(a.position).add(V[n]),o.up.copy(I[n]),o.lookAt(k),o.updateMatrixWorld(!0),o.updateProjectionMatrix();const l=this.getShadowCameraBuffer(4+s);this.writeShadowCameraBuffer(Hi(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"}),Mp.call(this,u,o,c,l,"pointShadow",this.state.pointShadowPipeline,this.state.pointShadowPipelineDirect,i),u.end()}}}n||this.clearPointShadow(e)}function Cp(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),k.copy(a.position).add(a.direction),o.lookAt(k),o.updateMatrixWorld(!0),o.updateProjectionMatrix();const l=this.getShadowCameraBuffer(28+t);this.writeShadowCameraBuffer(Hi(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"}),Mp.call(this,u,o,c,l,"directionalShadow",this.state.shadowDepthPipeline,this.state.shadowDepthPipelineDirect,i),u.end()}n||this.clearSpotShadow(e)}function Mp(e,t,r,i,n,a,s,o){ip.setFromProjectionMatrix(np.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse));const l=this.renderBundleScratch;l.length=0;for(const e of this.queryStaticShadowResources(ip))for(const t of e.shadowChunks)op.center.copy(t.boundsCenter),op.radius=t.boundsRadius,ip.intersectsSphere(op)&&(l.push(Lp.call(this,e,r,i,n,a,s,t)),o.drawCallCount+=t.drawCallCount,o.triangleCount+=t.triangleCount);l.length&&e.executeBundles(l),l.length=0}function Pp(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 Dp(e,t,r){const i=this.renderBundleScratch;i.length=0;for(const e of this.getCameraStaticDrawSets()){if(!e.publicSet.enabled||!this.isStaticDrawSetCameraVisible(e)||0===e.draws.length||"late"===e.drawStage)continue;if(this.getHiZOcclusionCullingActive()&&e.lastPreVisibilityFrameToken===this.staticFrameToken&&Ip(e)){const t=this.getOrCreateStaticVisibleDepthSceneBindGroup(e);i.push(Bp.call(this,e,t))}else i.push(this.getOrCreateStaticDepthPrepassBundle(e,t));this.recordStaticDrawStats(e,r)}i.length&&e.executeBundles(i),i.length=0}function Bp(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}),o=zp.call(this,e,"prepass","packed-visible");s.setBindGroup(0,t);let l=null,c=null,u=null;for(let t=0;t<e.draws.length;t+=1){const i=e.draws[t],n=o[t];if(i.customDepthMaterial||!n&&(fp(i,"prepass")||Qh(i.material)||!pp(i)))continue;const a=n?.pipeline??this.state.depthPrepassPipelineVisible;l!==a&&(l=a,u=null,c=null,s.setPipeline(a)),n&&c!==n.bindGroup&&(c=n.bindGroup,s.setBindGroup(1,c)),u!==i.geometryKey&&(u=i.geometryKey,this.bindGeometryVertexBuffers(s,i.geometry,i.geometryResource,n?.vertexAttributes??L,0,1,i.wireframe)),s.drawIndexedIndirect(r,5*t*Uint32Array.BYTES_PER_ELEMENT)}const d=s.finish({label:a});return e.indirectDepthPrepassBundles[i]={sceneBindGroup:t,indirectBuffer:r,bundle:d},d}function Tp(e){if(this.sampleCount<=1||!this.state.mainDepthView||!this.getHiZOcclusionCullingActive())return;let t=null;const r=this.renderBundleScratch;r.length=0;for(const i of this.getCameraStaticDrawSets()){if(!i.publicSet.enabled||!this.isStaticDrawSetCameraVisible(i)||0===i.draws.length||"late"===i.drawStage||i.lastVisibilityFrameToken!==this.staticFrameToken||!Ip(i))continue;t||(t=e.beginRenderPass({label:"renderer-static-temporal-depth-resolve",colorAttachments:[],depthStencilAttachment:{view:this.state.mainDepthView,depthLoadOp:"load",depthStoreOp:"store"}}));const n=this.getOrCreateStaticVisibleDepthSceneBindGroup(i);r.push(Bp.call(this,i,n,i.drawMetadataResource.postIndirectBuffer,"postpass"))}r.length&&t.executeBundles(r),r.length=0,t?.end()}function Ip(e){return e.temporalDepthSupported??ep(e.draws)}function Vp(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=zp.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&&(Qh(r.material)||!pp(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??L,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 zp(e,t,r){const i=r?`${t}:${r}`:t,n=e.depthMaterialResources.get(i);if(n)return n;const a=e.draws.map(e=>{const i=fp(e,t);if(e.customDepthMaterial||!i)return null;return this.getDepthPassMaterialResourceForDraw(e.material,t,e,r)});return e.depthMaterialResources.set(i,a),a}function Lp(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=zp.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??L,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 Gp(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 Rp(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=ki(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||ki(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 Up(e,t,r,i="all",n=this.sampleCount){const a=this.renderBundleScratch;a.length=0;for(const s of this.getCameraStaticDrawSets())if(s.publicSet.enabled&&this.isStaticDrawSetCameraVisible(s)&&0!==s.draws.length&&("all"===i||s.drawStage===i)){if("opaque"===s.drawStage&&this.getHiZOcclusionCullingActive()&&s.lastVisibilityFrameToken===this.staticFrameToken){const t=this.getOrCreateStaticVisibleSceneBindGroup(s),i=this.getOrCreateStaticIndirectSubmissionStreams(s,t);for(const t of i)if(this.getMultiDrawIndirectActive()){if(a.length&&(e.executeBundles(a),a.length=0),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(s.drawMetadataResource.indirectBuffer,5*t.indirectStartIndex*Uint32Array.BYTES_PER_ELEMENT,t.indirectCount),r.drawCallCount+=t.drawCallCount,r.triangleCount+=t.triangleCount}else a.push(this.getOrCreateIndirectForwardBundle(t,s.drawMetadataResource,s.indirectForwardBundleCache,`${s.label}-static-indirect-forward-bundle`)),r.drawCallCount+=t.drawCallCount,r.triangleCount+=t.triangleCount;continue}a.push(this.getOrCreateStaticDirectForwardBundle(s,t,n)),this.recordStaticDrawStats(s,r)}a.length&&e.executeBundles(a),a.length=0}function Ap(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,hp(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 kp(e){for(const t of e.visibleMaterialBindings){const r=t.drawIndices[0];t.resource=e.draws[r]?.materialResource??e.visibleDrawMaterialResources[r]??null}}function Fp(e){for(const t of e)t.materialResource=this.getMaterialResource(t.material,this.getDrawInstanceAccessMode(t),t.receiveShadow,void 0,null!==t.skinning,hp(t))}function $p(e,t){t.drawCallCount+=e.drawCallCount,t.triangleCount+=e.triangleCount}function Ep(){return this.getCameraStaticDrawSets().some(e=>e.publicSet.enabled&&this.isStaticDrawSetCameraVisible(e)&&!e.cpuVisibility&&"opaque"===e.drawStage&&e.draws.length>0)}function Op(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 _p(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 jp(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 Np(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 Wp(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(op.center.copy(c.boundsCenter),op.radius=c.boundsRadius,!ap.intersectsSphere(op))continue;const e=c.detailCulling??f(c.sourceObject);if(!c.staticLocalBoundsCenter&&!m(c.boundsCenter,c.boundsRadius,sp,this.state.directionalShadowTextureSize,this.state.directionalShadowTextureSize,up,.85*e.shadowMinScreenSize,e.shadowMaxDistance))continue}if("prepass"!==i.passKind&&!c.castShadow)continue;if("prepass"===i.passKind&&null===c.material.depthVertexShader&&Qh(c.material))continue;if("skip"===i.customDepthMode&&c.customDepthMaterial)continue;const t=fp(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&&!pp(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 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??h)&&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??(h?G:L),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)}}import{Box3 as Hp,Mesh as qp,Sphere as Kp}from"three";import{Vector3 as Zp}from"three";var Yp=class{entries=[];pending=[];root=null;stack=[];stateStack=[];retired=0;add(e,t){const r={...t,boundsCenter:t.boundsCenter.clone(),value:e,active:!0};return this.pending.push(r),r}remove(e){e.active&&(e.active=!1,this.retired++)}clear(){this.entries.length=this.pending.length=this.stack.length=this.stateStack.length=0,this.root=null,this.retired=0}prepareQuery(){if(!this.root||this.pending.length+this.retired>Math.max(128,this.entries.length/4)){this.entries=this.entries.filter(e=>e.active);for(const e of this.pending)e.active&&this.entries.push(e);this.pending.length=0,this.retired=0,this.root=this.entries.length?this.build(0,this.entries.length):null}}query(e,t){if(!this.entries.length&&!this.pending.length)return;this.prepareQuery();const r=this.stack;for(r.length=0,this.root&&r.push(this.root);r.length;){const i=r.pop();if(e(i))if(i.left&&i.right)r.push(i.left,i.right);else for(let r=i.start;r<i.end;r++){const i=this.entries[r];i.active&&e(i)&&t(i.value)}}for(const r of this.pending)r.active&&e(r)&&t(r.value)}queryWithState(e,t,r){if(!this.entries.length&&!this.pending.length)return;this.prepareQuery();const i=this.stack,n=this.stateStack;for(i.length=n.length=0,this.root&&(i.push(this.root),n.push(r));i.length;){const r=i.pop(),a=e(r,n.pop());if(!(a<0))if(r.left&&r.right)i.push(r.left,r.right),n.push(a,a);else for(let i=r.start;i<r.end;i++){const r=this.entries[i];r.active&&e(r,a)>=0&&t(r.value)}}for(const i of this.pending)i.active&&e(i,r)>=0&&t(i.value)}build(e,t){let r=1/0,i=1/0,n=1/0,a=-1/0,s=-1/0,o=-1/0,l=0,c=1/0,u=0,d=!1,h=!1;for(let p=e;p<t;p++){const e=this.entries[p],t=e.boundsCenter,f=e.boundsRadius;r=Math.min(r,t.x-f),a=Math.max(a,t.x+f),i=Math.min(i,t.y-f),s=Math.max(s,t.y+f),n=Math.min(n,t.z-f),o=Math.max(o,t.z+f),l=Math.max(l,e.maxMemberRadius),c=Math.min(c,e.minScreenSize),d||=0===e.maxDistance,u=Math.max(u,e.maxDistance),h||=e.castShadow}const p=new Zp((r+a)/2,(i+s)/2,(n+o)/2),f={start:e,end:t,boundsCenter:p,boundsRadius:Math.hypot(a-p.x,s-p.y,o-p.z),maxMemberRadius:l,minScreenSize:c,maxDistance:d?0:u,castShadow:h,left:null,right:null};if(t-e>16){const l=a-r>=s-i&&a-r>=o-n?"x":s-i>=o-n?"y":"z",c=this.entries.slice(e,t).sort((e,t)=>e.boundsCenter[l]-t.boundsCenter[l]);for(let t=0;t<c.length;t++)this.entries[e+t]=c[t];const u=e+t>>>1;f.left=this.build(e,u),f.right=this.build(u,t)}return f}},Xp=class{index=new Yp;roots=new Set;children=new Map;invalidateChildren=e=>{e.target&&this.children.delete(e.target)};observed=new Set;indexedParents=new Map;registrations=new Set;registrationByRoot=new Map;meshSnapshots=new WeakMap;traversals=new WeakMap;getMeshSnapshot(e){return this.meshSnapshots.get(e)}queryScene=null;queryVisit=null;visitRoot=e=>{let t=e;for(;t&&t!==this.queryScene;t=t.parent)if(!t.visible)return;t===this.queryScene&&t?.visible&&this.queryVisit(e)};register(e){let t;this.registrationByRoot.get(e)?.dispose();let r=!1,i=!1,n=null;const a=new Set,s=[],o=()=>l(),l=()=>{if(t&&this.index.remove(t),t=void 0,this.roots.delete(e),this.traversals.delete(e),n){this.children.delete(n);const e=this.indexedParents.get(n)-1;e>0?this.indexedParents.set(n,e):(this.indexedParents.delete(n),this.observed.delete(n),n.removeEventListener("childadded",this.invalidateChildren),n.removeEventListener("childremoved",this.invalidateChildren)),n=null}for(const e of a)e.removeEventListener("childadded",o),e.removeEventListener("childremoved",o);a.clear();for(const e of s)this.meshSnapshots.delete(e);if(s.length=0,r||i)return;let l=!0,c=0,u=1/0,d=0,h=!1,p=!1;const m=new Hp,g=new Kp,v=new Hp;if(e.updateWorldMatrix(!0,!0),e.traverse(e=>{if(a.add(e),e.addEventListener("childadded",o),e.addEventListener("childremoved",o),e.isFogVolumeObject&&(l=!1),!(e instanceof qp))return void("Group"!==e.type&&"Object3D"!==e.type&&(l=!1));(e.isSkinnedMesh||e.isInstancedMesh||e.isBatchedMesh||!e.frustumCulled||e.morphTargetInfluences?.length)&&(l=!1);const t=f(e);e.geometry.boundingSphere||e.geometry.computeBoundingSphere(),e.geometry.boundingSphere?(g.copy(e.geometry.boundingSphere).applyMatrix4(e.matrixWorld),m.union(g.getBoundingBox(v))):l=!1,u=Math.min(u,t.minScreenSize),h||=0===t.maxDistance,p||=e.castShadow,d=Math.max(d,t.maxDistance),c++}),!l||!c)return;if(m.getBoundingSphere(g),!Number.isFinite(g.radius)||!Number.isFinite(g.center.lengthSq()))return;for(const e of a)e instanceof qp&&(g.copy(e.geometry.boundingSphere).applyMatrix4(e.matrixWorld),this.meshSnapshots.set(e,{boundsCenter:g.center.clone(),boundsRadius:g.radius,frontFaceCW:e.matrixWorld.determinant()<0,detailCulling:f(e)}),s.push(e));m.getBoundingSphere(g),this.roots.add(e);const x=Array.from(a),w=new Uint32Array(x.length),b=new Uint8Array(x.length),y=[];for(let e=0;e<x.length;e++){for(;y.length&&x[y[y.length-1]]!==x[e].parent;)w[y.pop()]=e;b[e]=x[e]instanceof qp?1:0,y.push(e)}for(;y.length;)w[y.pop()]=x.length;this.traversals.set(e,{objects:x,subtreeEnds:w,meshes:b}),n=e.parent,n&&(this.indexedParents.set(n,(this.indexedParents.get(n)??0)+1),this.children.delete(n)),t=this.index.add(e,{boundsCenter:g.center,boundsRadius:g.radius,maxMemberRadius:g.radius,minScreenSize:u,maxDistance:h?0:d,castShadow:p})},c=()=>l();e.addEventListener("added",c),e.addEventListener("removed",c),l();const u={update:()=>{i||l()},setEditing:e=>{i||e===r||(r=e,l())},dispose:()=>{i||(i=!0,l(),e.removeEventListener("added",c),e.removeEventListener("removed",c),this.registrations.delete(u),this.registrationByRoot.delete(e))}};return this.registrations.add(u),this.registrationByRoot.set(e,u),u}traversalChildren(e){if(!this.indexedParents.has(e))return e.children;let t=this.children.get(e);return t||(t=e.children.filter(e=>!this.roots.has(e)),this.children.set(e,t),this.observed.has(e)||(this.observed.add(e),e.addEventListener("childadded",this.invalidateChildren),e.addEventListener("childremoved",this.invalidateChildren))),t}visitMeshes(e,t,r){const i=this.traversals.get(e);if(!i)return;const{objects:n,subtreeEnds:a,meshes:s}=i;for(let e=0;e<n.length;){const i=n[e];!i.visible||r&&!r(i)?e=a[e]:(s[e]&&t(i),e++)}}query(e,t,r){this.queryScene=e,this.queryVisit=r;try{this.index.query(t,this.visitRoot)}finally{this.queryScene=null,this.queryVisit=null}}queryWithState(e,t,r,i){this.queryScene=e,this.queryVisit=r;try{this.index.queryWithState(t,this.visitRoot,i)}finally{this.queryScene=null,this.queryVisit=null}}dispose(){for(const e of this.registrations)e.dispose();for(const e of this.observed)e.removeEventListener("childadded",this.invalidateChildren),e.removeEventListener("childremoved",this.invalidateChildren);this.observed.clear(),this.indexedParents.clear(),this.children.clear(),this.roots.clear(),this.index.clear()}};import{Matrix4 as Jp,OrthographicCamera as Qp,Vector3 as ef}from"three";var tf=(e,t)=>void 0!==e&&Number.isFinite(e)&&e>0?e:t,rf=class{constructor(e){this.cameras=e,this.layers=e.map(()=>({valid:!1,source:null,direction:new ef,rangeX:0,rangeY:0,nextUpdateMs:0,lastUpdateMs:-1/0,candidate:new Qp}))}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 Jp;previousPosition=new ef;viewerPosition=new ef;corner=new ef;viewerValid=!1;revision=-1;timeMs=0;setOptions(e){this.settings={enabled:e.enabled??!1,maxUpdateHz:tf(e.maxUpdateHz,60),cascadeUpdateHz:(e.cascadeUpdateHz?.length?e.cascadeUpdateHz:[60,30,15,7.5]).map(e=>tf(e,60)),maxUpdatesPerFrame:Math.max(1,Math.floor(tf(e.maxUpdatesPerFrame,2))),coverageMargin:Number.isFinite(e.coverageMargin)?Math.max(0,Math.min(.5,e.coverageMargin)):.05,teleportDistance:tf(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{Sphere as nf,Vector3 as af}from"three";function sf(e,t){return e.id-t.id}function of(e){return`${Math.floor(e.x/32)}:${Math.floor(e.y/32)}:${Math.floor(e.z/32)}`}function lf(e,t){if(!t)return[e];const r=new Map;for(const t of e){const e=of(t.boundsCenter);let i=r.get(e);i||(i=[],r.set(e,i)),i.push(t)}return[...r.values()]}var cf=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;revision=0;spatialIndex=new Yp;spatialEntries=new Map;cameraCandidates=[];shadowCandidates=[];shadowFrustum=null;shadowSphere=new nf;testShadow=e=>!!e.castShadow&&(this.shadowSphere.center.copy(e.boundsCenter),this.shadowSphere.radius=e.boundsRadius,this.shadowFrustum.intersectsSphere(this.shadowSphere));collectShadow=e=>{e.publicSet.enabled&&"late"!==e.drawStage&&this.shadowCandidates.push(e)};markCameraVisible=e=>{e.publicSet.enabled&&(e.cameraVisible=!0,this.cameraCandidates.push(e))};updateCameraVisibility(e){for(const e of this.cameraCandidates)e.cameraVisible=!1;this.cameraCandidates.length=0,this.spatialIndex.query(e,this.markCameraVisible),this.cameraCandidates.sort(sf)}queryShadowResources(e){return this.shadowCandidates.length=0,this.shadowFrustum=e,this.spatialIndex.query(this.testShadow,this.collectShadow),this.shadowFrustum=null,this.shadowCandidates}nextStaticDrawSetId=1;activeObject=null;activeDetailDefaults;activeMaterialSnapshots=null;snapshotSources=new WeakMap;getSourceMaterial(e){return this.snapshotSources.get(e)??e}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(),this.snapshotSources.set(r,t),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 an(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 c=new Map;if(!(s.instanceCount>=512&&!a.some(e=>e.transparent)))return this.createResource(r,a,s,l);let u=1/0,d=1/0,h=1/0;for(const e of a)u=Math.min(u,e.boundsCenter.x),d=Math.min(d,e.boundsCenter.y),h=Math.min(h,e.boundsCenter.z);for(const e of a){const t=e.boundsCenter,r=`${Math.floor((t.x-u)/256)}:${Math.floor((t.y-d)/256)}:${Math.floor((t.z-h)/256)}`;let i=c.get(r);i||c.set(r,i=[]),i.push(e)}if(c.size<=1)return this.createResource(r,a,s,l);const p=[];try{for(const[e,t]of c)p.push(this.createResource(`${r}-${e}`,t,s,0===p.length?l:new Map))}catch(e){for(const e of p)e.dispose();if(!p.length)for(const e of l.values())e.dispose();throw e}let f=!0,m=!1;return{label:r,get enabled(){return f},set enabled(e){f=e;for(const t of p)t.enabled=e},get drawCount(){return p.reduce((e,t)=>e+t.drawCount,0)},get instanceCount(){return p.reduce((e,t)=>e+t.instanceCount,0)},dispose(){if(!m){m=!0;for(const e of p)e.dispose()}}}}createResource(e,t,r,i){if(!this.state.device)throw new Error("Renderer is not initialized.");const{draws:n,instanceData:a}=this.mergeStaticDraws(t,r),s=n.some(e=>e.transparent),o=n.some(e=>!e.transparent);if(s&&o)throw new Error(`StaticDrawSet "${e}" cannot mix opaque and late materials; register them as separate sets.`);const l=this.createVisibleMaterialBindings(n),c=this.createShadowChunks(n),u=Math.max(4,a.byteLength),d=this.state.device.createBuffer({label:`${e}-static-instance-buffer`,size:256*Math.ceil(u/256),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});a.floatLength>0?this.state.device.queue.writeBuffer(d,0,a.rawData.buffer,0,a.byteLength):this.state.device.queue.writeBuffer(d,0,M,0,S);const h={mode:"packed",buffer:d,colorBuffer:null,sceneBindGroup:null,shadowBindGroup:null,shadowBindGroups:new Map,sceneBindGroupVersion:0,shadowBindGroupVersion:0};for(const e of n)e.residentInstanceBinding=h;const p=this.createStaticDrawMetadataResource(e,n),f=this.createStaticInstanceVisibilityResource(e,n,a),m=new af(1/0,1/0,1/0),g=new af(-1/0,-1/0,-1/0);let v=0,x=1/0,w=0,b=!1;const y=f.metadata;for(let e=0;e<a.instanceCount;e++){const t=8*e,r=y[t+3];k.set(y[t],y[t+1],y[t+2]),Qi(m,g,k,r),v=Math.max(v,r),x=Math.min(x,y[t+6]),b||=0===y[t+7],w=Math.max(w,y[t+7])}const C=(new af).addVectors(m,g).multiplyScalar(.5),P={boundsCenter:C,boundsRadius:C.distanceTo(g),maxMemberRadius:v,minScreenSize:x,maxDistance:b?0:w,castShadow:n.some(e=>e.castShadow)},D=new Uint32Array([n.length,this.state.hizMipCount,a.instanceCount,0]),B=this.state.device.createBuffer({label:`${e}-visibility-params-buffer`,size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),T=new Uint32Array([n.length,this.state.hizMipCount,a.instanceCount,0]),I=this.state.device.createBuffer({label:`${e}-post-visibility-params-buffer`,size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});this.state.device.queue.writeBuffer(B,0,D,0,4),this.state.device.queue.writeBuffer(I,0,T,0,4);const V={temporalDepthSupported:ep(n),spatialBounds:P,cpuVisibility:!s&&1===n.length&&1===a.instanceCount,cameraVisible:!1,cameraDetailVisible:!1,id:this.nextStaticDrawSetId++,label:e,publicSet:null,ownedMaterials:[...i.values()],draws:n,shadowChunks:c,drawStage:s?"late":"opaque",drawCallCount:n.length,triangleCount:n.reduce((e,t)=>e+Math.floor(Math.max(0,t.count)/3)*Math.max(0,t.instanceCount),0),instanceCount:a.instanceCount,instanceBuffer:d,residentInstanceBinding:h,drawMetadataResource:p,instanceVisibilityResource:f,visibilityParamsBuffer:B,visibilityParamsUpload:D,postVisibilityParamsBuffer:I,postVisibilityParamsUpload:T,visibilityBindGroup:null,postVisibilityBindGroup:null,visibilityClearBindGroup:null,visibilityIndirectBuildBindGroup:null,postVisibilityIndirectBuildBindGroup:null,visibleSceneBindGroup:null,visibleSceneBindGroupVersion:0,visibleDepthSceneBindGroup:null,visibleDepthSceneBindGroupVersion:0,visibleMaterialBindings:l,visibleDrawMaterialResources:new Array(n.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};let z=!0;const L=this,G={label:e,get enabled(){return z},set enabled(e){z!==e&&(z=e,L.revision++)},get drawCount(){return V.draws.length},get instanceCount(){return V.instanceCount},dispose:()=>{this.disposeStaticDrawSetResource(V)}};return V.publicSet=G,this.staticDrawSets.push(V),this.revision++,a.instanceCount>0&&this.spatialEntries.set(V,this.spatialIndex.add(V,P)),G}createVisibleMaterialBindings(e){const t=new Map;for(let r=0;r<e.length;r+=1){const i=e[r],n=`${Li(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=of(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 af(.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(Ui);const r=[],i=e.reduce((e,t)=>e+t.instanceCount*S,0),n=new an(Math.max(1024,i));for(let i=0;i<e.length;){const a=e[i],s=n.instanceCount;n.appendRange(t,a.instanceStart,a.instanceCount);const o=a.sourceRanges;for(const e of o)e.instanceStart+=s-a.instanceStart;let l=a.instanceCount,c=a.boundsCenter.x-a.boundsRadius,u=a.boundsCenter.y-a.boundsRadius,d=a.boundsCenter.z-a.boundsRadius,h=a.boundsCenter.x+a.boundsRadius,p=a.boundsCenter.y+a.boundsRadius,f=a.boundsCenter.z+a.boundsRadius,m=i+1;for(;m<e.length&&Ei(a,e[m]);){const r=e[m];n.appendRange(t,r.instanceStart,r.instanceCount);for(const e of r.sourceRanges)o.push({sourceObject:e.sourceObject,instanceCount:e.instanceCount,instanceStart:s+l+e.instanceStart-r.instanceStart});l+=r.instanceCount;const i=r.boundsCenter.x-r.boundsRadius,a=r.boundsCenter.y-r.boundsRadius,g=r.boundsCenter.z-r.boundsRadius,v=r.boundsCenter.x+r.boundsRadius,x=r.boundsCenter.y+r.boundsRadius,w=r.boundsCenter.z+r.boundsRadius;i<c&&(c=i),a<u&&(u=a),g<d&&(d=g),v>h&&(h=v),x>p&&(p=x),w>f&&(f=w),m+=1}const g=.5*(c+h),v=.5*(u+p),x=.5*(d+f),w=h-g,b=p-v,y=f-x;a.instanceStart=s,a.instanceCount=l,a.boundsCenter.set(g,v,x),a.boundsRadius=Math.sqrt(w*w+b*b+y*y),r.push(a),i=m}return{draws:r,instanceData:n}}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(rn(e))return void n(e,"custom depth materials are not supported by StaticDrawSet v1");const s=this.getGeometryResource(e.geometry),o=Yi(e.geometry),l=k.copy(o.center).applyMatrix4(e.matrixWorld),c=o.radius*Xi(e.matrixWorld),u=Vi(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=Ci(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=Mi(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(rn(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=Mi(e.geometry,!0);if(o.count<=0||e.count<=0)return;const l=Yi(e.geometry),c=this.getGeometryResource(e.geometry),u=[];for(let t=0;t<e.count;t+=1){e.getMatrixAt(t,R),U.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=$.copy(l.center).applyMatrix4(U),o=l.radius*Xi(U);u.push({matrix:new Float32Array(U.elements),color0:r,color1:i,color2:n,color3:a,batchingId:t,boundsCenter:s.clone(),boundsRadius:o})}for(const i of lf(u,!s.transparent&&!s.requiresLatePass())){const n=k.set(1/0,1/0,1/0),a=F.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),Qi(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(rn(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=Ci(e.geometry,!0,r.start,r.count);if(i<=0)continue;const n=e.getBoundingSphereAt(t,A),a={geometryId:t,start:r.start,count:i,localBoundsCenter:n?n.center.clone():new af,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?zi(R,p,16*t):e.getMatrixAt(t,R),U.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=$.copy(i.localBoundsCenter).applyMatrix4(U),u=i.localBoundsRadius*Xi(U);i.instances.push({matrix:new Float32Array(U.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 lf(i.instances,!s.transparent&&!s.requiresLatePass())){const a=k.set(1/0,1/0,1/0),o=F.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),Qi(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,m,g=!1){const v=Li(i),x=i.wireframe&&"triangle-list"===i.primitiveTopology;x&&this.ensureWireframeIndex(e,r);const w=Li(t);return{geometry:e,geometryKey:x?r.wireframeIndex:t,geometryResource:r,material:i,customDepthMaterial:null,residentInstanceBinding:null,sourceObject:null,sourceRanges:[{sourceObject:this.activeObject,instanceStart:o,instanceCount:l}],detailCulling:f(this.activeObject,this.activeDetailDefaults),frontFaceCW:g,usesBatching:n,geometryGroup:null,batchKey:Gi(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 af(c,u,d),boundsRadius:h,sortDepth:0,transparentSortGroup:0,transparentSortOrder:0,staticLocalBoundsCenter:p.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*C),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*C;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*C*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??Yi(i.geometry).center,a=i.staticLocalBoundsRadius??Yi(i.geometry).radius;for(let t=0;t<i.instanceCount;t+=1){const l=i.instanceStart+t,c=l*S,u=8*l;R.fromArray(r.rawData,c);const d=k.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;const r=this.spatialEntries.get(e);r&&this.spatialIndex.remove(r),this.spatialEntries.delete(e),e.disposeDirectionalGpuShadows?.(),this.staticDrawSets.splice(t,1);const i=this.cameraCandidates.indexOf(e);i>=0&&this.cameraCandidates.splice(i,1),this.shadowCandidates.length=0,e.cameraVisible=!1,this.revision++;const n=new Set;for(const t of e.draws)t.materialResource&&n.add(t.materialResource);for(const t of e.visibleMaterialBindings)t.resource&&n.add(t.resource);for(const t of e.visibleDrawMaterialResources)t&&n.add(t);for(const t of e.depthMaterialResources.values())for(const e of t)e&&n.add(e);for(const e of n)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()}};import{RGBAFormat as uf}from"three";function df(e,t,r,i){const n=new Uint8Array(e.buffer,e.byteOffset,e.byteLength),a=new Uint8Array(n.byteLength);for(let e=0;e<i;e++){const i=e*t*r;for(let e=0;e<r;e++){const s=i+e*t;a.set(n.subarray(s,s+t),i+(r-e-1)*t)}}return a}var hf=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":Di(e.magFilter),n=r?"nearest":Di(e.minFilter),a=r?"nearest":Di(e.minFilter),s="comparison"===t?function(e){switch(e){case qr:return"never";case Or:return"less";case kr:return"equal";case _r:return"less-equal";case Fr:return"greater";case Kr:return"not-equal";case $r: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:Pi(e.wrapS),addressModeV:Pi(e.wrapT),addressModeW:Pi(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=Nt(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 a=0;a<n.length;a+=1){const s=n[a];if(!s?.data)continue;const o=s.width??Math.max(1,r.width>>a),l=s.height??Math.max(1,r.height>>a),c=s.depth??r.depthOrArrayLayers;this.state.device.queue.writeTexture({texture:t,mipLevel:a},Ti(e.flipY?df(s.data,o*i,l,c):s.data),{bytesPerRow:o*i,rowsPerImage:l},{width:o,height:l,depthOrArrayLayers:c})}return}const a=e.image;a?.data&&this.state.device.queue.writeTexture({texture:t},e.flipY?df(a.data,r.width*i,r.height,r.depthOrArrayLayers):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.");let 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&&e.format===uf){const e=Nt(r.format);null!==e&&(i={width:1,height:1,byteLength:e})}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}},Ti(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},Ti(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=Bi(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: ${pf(t)}`)}}return}const i=function(e){return Bi(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: ${pf(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=Ot(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 pf(e){return e instanceof Error?e.message:String(e)}function ff(e){if(e.transparent)switch(e.blending){case Pd:return{color:{srcFactor:"src-alpha",dstFactor:"one",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one",operation:"add"}};case Od:return{color:{srcFactor:"zero",dstFactor:"one-minus-src",operation:"subtract"},alpha:{srcFactor:"one",dstFactor:"one",operation:"subtract"}};case Rd: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 mf(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 gf(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=mf(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=mf(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 vf(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 xf(e){const t=Number(e.userData.motionBlurScale??1);return Number.isFinite(t)?Math.max(0,Math.min(t,8)):1}var wf="chromium-experimental-multi-draw-indirect";function bf(e,t){return Number(t.castShadow)-Number(e.castShadow)}var yf=[D],Sf=[{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 Cf(e){return e.wireframe&&"triangle-list"===e.primitiveTopology?"line-list":e.primitiveTopology}function Mf(e,t,r){if(!Cf(e).startsWith("triangle"))return"none";if("directionalShadow"===t){if(r&&null===e.shadowSide)return"none";const t=e.shadowSide??e.side;return t===Vd?"none":t===Dd?"front":"back"}return e.side===Vd?"none":e.side===Dd?"front":"back"}function Pf(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 Df=class{pipelineCompilationDiagnostics;canvas;clearColor;powerPreference;shadowMapSize;directionalShadowsEnabled=!0;spotShadowMapSize;pointShadowMapSize;fallbackMaterial;materialResolver;toonOutlineMaterialCache=new WeakMap;fallbackSkinnedMaterial;invokeObjectRenderCallbacks;sampleCount;renderScale;hiZOcclusionCullingEnabled;frameHiZOcclusionCullingNeeded=!0;multiDrawIndirectEnabled;dynamicBatchingEnabled;multiDrawIndirectSupported=!1;tiledPointLights=null;tiledLightingEnabled;transientPointLightsScratch=[];transientPointScoresScratch=new Float64Array(16);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;defaultVertexAttributeBuffers=new Map;textureManager=new hf(this.state,this.textureCache);renderGraph=new ph;nativePostSubmit;presentationOverlay;presentationOverlayContext={device:null,encoder:null,targetView:null,targetFormat:"bgra8unorm",presentationWidth:1,presentationHeight:1};directionalShadowCameras=Array.from({length:4},()=>new kd(-10,10,10,-10,.1,80));directionalShadowScheduler=new rf(this.directionalShadowCameras);directionalShadowGpu=new Sd;directionalShadowSubmissionStats={bundleHits:0,bundleBuilds:0,selectionHits:0,selections:0};pointShadowCameras=Array.from({length:4},()=>V.map(()=>new Fd(90,1,.1,25)));spotShadowCameras=Array.from({length:4},()=>new Fd(60,1,.5,500));colorTargetCache=new Map;msaaColorTargetCache=new Map;msaaDepthTargetCache=new Map;sourceInstanceDataScratch=new an(4096);opaqueInstanceDataScratch=new an(4096);finalInstanceDataScratch=new an(4096);residentInstanceUploadsScratch=[];gpuOpaqueDrawsScratch=[];directOpaqueDrawsScratch=[];stagedOpaqueDrawsScratch=[];residentOpaqueDrawsScratch=[];retiredGeometryResources=[];retiredGeometryBuffers=[];vertexAttributeBufferKeyCache=new WeakMap;standardVertexAttributeCache=new WeakMap;geometryVertexBufferFastCache=new WeakMap;vertexAttributeGroupCache=new WeakMap;materialVertexAttributeCache=new WeakMap;sharedVertexAttributeLayouts=new Map;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 cf(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 Nd;extractedHemisphereScratch=this.createExtractedHemisphereLightScratch();extractedBoundsMinScratch=new jd;extractedBoundsMaxScratch=new jd;extractedDirectionalLightsScratch=Array.from({length:4},()=>this.createExtractedDirectionalLightScratch());extractedPointLightsScratch=Array.from({length:b},()=>this.createExtractedPointLightScratch());extractedSpotLightsScratch=Array.from({length:y},()=>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(z);spotLightMapAtlasSignature="";spotLightMapAtlasSize=0;spotLightMapAtlasLayout=null;spotLightMapAtlasPipeline=null;csmCascadeRanges=Array.from({length:4},()=>new _d);csmCascadeCount=0;csmCascadeLights=[];shadowCameraUniformScratch=new Float32Array(64);cameraViewProjScratch=new Ud;cameraProjectionScratch=new Ud;projectionJitterPixels=new _d;temporalVisibilityCurrentViewProj=new Ud;temporalVisibilityPreviousViewProj=new Ud;motionVectorProjection=new Ud;motionVectorCurrentViewProj=new Ud;motionVectorPreviousViewProj=new Ud;motionVectorProjectionPending=!1;motionVectorHistoryValid=!1;motionVectorHistoryGeneration=1;lastMotionVectorTimeSeconds=Number.NaN;objectMotionHistory=new WeakMap;cameraFrustumPlanesScratch=new Float32Array(24);objectTraversalStackScratch=[];staticSceneSpatialIndex=new Xp;staticMeshDraws=new WeakMap;spatialShadowPlanes=Array.from({length:4},()=>new Float32Array(24));spatialShadowCount=0;spatialLocalShadowSpheres=new Float64Array(512);spatialLocalShadowCount=0;spatialShadowMatrix=new Ud;spatialIncludeOffscreen=!1;spatialCameraLayers=0;testSpatialCamera=e=>Zi(this.cameraFrustumPlanesScratch,e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius)&&g(e,this.cameraViewProjScratch,this.state.width,this.state.height,this.transparentSortCameraPositionScratch);testSpatialScene=(e,t)=>{if(this.spatialIncludeOffscreen)return 0;if(64!==t){if((t=function(e,t,r,i,n,a){for(let s=0,o=1;s<6;s++,o<<=1){if(!(a&o))continue;const l=4*s,c=e[l]*t+e[l+1]*r+e[l+2]*i+e[l+3];if(c<-n)return-1;c>=n&&(a&=~o)}return a}(this.cameraFrustumPlanesScratch,e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius,t))>=0&&g(e,this.cameraViewProjScratch,this.state.width,this.state.height,this.transparentSortCameraPositionScratch))return t;t=64}return e.castShadow&&this.isSpatialShadowSphereVisible(e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius)?t:-1};filterSpatialCaptureObject=e=>!1!==this.sceneCaptureOptions?.objectFilter?.(e)&&!1!==e.userData.sceneCapture;pushSpatialRoot=e=>{this.objectTraversalStackScratch.push(e)};collectSpatialMesh=e=>{0!==(e.layers.mask&this.spatialCameraLayers)&&(this.extractingCaster=e.castShadow,this.collectMesh(e,this.sourceInstanceDataScratch,this.updateExtractedBoundsFromMatrixScratch,this.spatialIncludeOffscreen?this.isSphereVisibleForCompilationScratch:this.isSpatialSphereVisible))};isSpatialSphereVisible=(e,t,r,i,n)=>!n||Zi(this.cameraFrustumPlanesScratch,e,t,r,i)||this.extractingCaster&&this.isSpatialShadowSphereVisible(e,t,r,i);isSpatialShadowSphereVisible(e,t,r,i){for(let n=0;n<this.spatialShadowCount;n++)if(Zi(this.spatialShadowPlanes[n],e,t,r,i))return!0;for(let n=0;n<this.spatialLocalShadowCount;n++){const a=4*n,s=this.spatialLocalShadowSpheres,o=e-s[a],l=t-s[a+1],c=r-s[a+2],u=i+s[a+3];if(o*o+l*l+c*c<=u*u)return!0}return!1}collectSpatialRoot=e=>{if(null!==this.sceneCaptureOptions)for(let t=e;t;t=t.parent)if(!1===this.sceneCaptureOptions.objectFilter?.(t)||!1===t.userData.sceneCapture)return;this.staticSceneSpatialIndex.visitMeshes(e,this.collectSpatialMesh,null===this.sceneCaptureOptions?void 0:this.filterSpatialCaptureObject)};shadowDrawsScratch=[];extractingCaster=!1;cameraDetailHistory=new WeakMap;isSphereVisibleScratch=(e,t,r,i,n)=>this.extractingCaster||!n||Zi(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 jd;transparentSortCameraForwardScratch=new jd;temporalVisibilityCurrentCameraPosition=new jd;temporalVisibilityPreviousCameraPosition=new jd;shadowViewProjScratch=new Ud;extractionVersion=0;motionHistoryExtractionVersion=0;sceneCaptureOptions=null;sceneCaptureDisposers=new Set;captureMotionHistory={matrix:new Float32Array(16),generation:0,lastExtractionVersion:-1,valid:!1};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 jd,target:new jd,direction:new jd,color:new jd,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 jd(0,1,0),skyColor:new jd,groundColor:new jd,intensity:0}}createExtractedPointLightScratch(){return{sourceLight:null,position:new jd,color:new jd,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 jd,direction:new jd(0,-1,0),color:new jd,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 Cd;skeletonPalettes=new nn;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 ei({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:Sf}),this.invokeObjectRenderCallbacks=e.invokeObjectRenderCallbacks??!0,this.state.directionalShadowTextureSize=this.shadowMapSize,this.state.pointShadowTextureSize=this.pointShadowMapSize,this.state.spotShadowTextureSize=this.shadowMapSize,this.sampleCount=tn(e.sampleCount),this.renderScale=Pf(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}invalidateMaterialResolution(){this.extractionVersion+=1}resolveMaterial(e){if(!1===e?.visible)return null;if(e&&ti(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 Wd)return null!=e.uniforms.hology_depth_map||null!=e.uniforms.hology_scene_map||null!=e.uniforms.hology_transmission_map;if(e instanceof ei)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 ei({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 Id(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:Vd,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 ei({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 Id(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!==Zr.prototype.onBeforeRender||e.onAfterRender!==Zr.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(wf)&&i.push(wf);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(wf),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(Md.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|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|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"}}]}),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(N.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(N.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(N.createAsync(this.state.device,{label:"renderer-visibility-cull",code:cd,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(N.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(N.createAsync(this.state.device,{label:"renderer-static-visibility-cull",code:ud,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"}},{binding:10,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:11,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}).then(e=>{this.state.staticVisibilityCullKernel=e})),u.push(N.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 N(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||Oh(this.state)}getRenderGraphProfilingEnabled(){return this.renderGraphProfilingEnabled}getTimestampQuerySupported(){return this.timestampQuerySupported}getSampleCount(){return this.sampleCount}setSampleCount(e){const t=tn(e);t!==this.sampleCount&&(this.sampleCount=t,this.destroyMsaaResources(),this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches())}setRenderScale(e){const t=Pf(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&&this.frameHiZOcclusionCullingNeeded}isStaticDrawSetCameraVisible(e){return null!==this.sceneCaptureOptions||e.cameraVisible}getCameraStaticDrawSets(){return null!==this.sceneCaptureOptions||this.spatialIncludeOffscreen?this.staticDrawSets:this.staticDrawSetManager.cameraCandidates}queryStaticShadowResources(e){return this.staticDrawSetManager.queryShadowResources(e)}updateVisibilityWorkload(e){this.staticDrawSetManager.updateCameraVisibility(this.testSpatialCamera);let t=e.gpuOpaqueDraws.length>=64;for(const e of this.staticDrawSetManager.cameraCandidates){if(!e.publicSet.enabled||"opaque"!==e.drawStage)continue;if(!e.cpuVisibility){t||=e.cameraVisible;continue}const r=e.draws[0],i=r.detailCulling;e.cameraDetailVisible=m(r.boundsCenter,r.boundsRadius,this.cameraViewProjScratch,this.state.width,this.state.height,this.transparentSortCameraPositionScratch,(i?.minScreenSize??0)*(e.cameraDetailVisible?.85:1.15),i?.maxDistance??0),e.cameraVisible=e.cameraDetailVisible&&Zi(this.cameraFrustumPlanesScratch,r.boundsCenter.x,r.boundsCenter.y,r.boundsCenter.z,r.boundsRadius)}t!==this.frameHiZOcclusionCullingNeeded&&(this.state.temporalHiZHistoryValid=!1),this.frameHiZOcclusionCullingNeeded=t}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:B,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)}createSceneCapture(e,t=512,r=t){const i=this.state.device;if(!i||!this.state.initialized)throw new Error("Renderer is not initialized.");const n=e?.getContext("webgpu");if(e&&!n)throw new Error("The capture canvas does not provide WebGPU.");t=Math.max(1,Math.floor(t)),r=Math.max(1,Math.floor(r)),e&&(e.width=t,e.height=r),n?.configure({device:i,format:this.state.format,alphaMode:"premultiplied"});const a=n?void 0:i.createTexture({label:"scene-capture-output",size:[t,r],format:this.state.format,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),s=a?.createView(),o=i.createTexture({label:"scene-capture-color",size:[t,r],format:D,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),l=i.createTexture({label:"scene-capture-depth",size:[t,r],format:"depth32float",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),c={colorView:o.createView(),depthView:l.createView(),width:t,height:r},u={drawCallCount:0,triangleCount:0};let d=!1;const h=()=>{d||(d=!0,n?.unconfigure(),a?.destroy(),o.destroy(),l.destroy(),this.sceneCaptureDisposers.delete(h))};return this.sceneCaptureDisposers.add(h),{textureView:s,get triangleCount(){return u.triangleCount},capture:(e,t,r={})=>{if(d||this.sceneCaptureOptions)throw new Error("Scene capture is unavailable.");this.sceneCaptureOptions=r;try{e.matrixWorldAutoUpdate&&e.updateMatrixWorld(),t.updateWorldMatrix(!0,!1);const a=this.extractScene(e,t);this.ensureShadowTextureSizes(a),this.uploadInstanceData(a.instanceData),this.uploadResidentInstanceData(a.residentInstanceUploads),this.ensureTiledLightingSize(),this.state.spotLightMapView||this.updateSpotLightMapAtlas([]),this.updateCameraUniforms(t,e,c),this.updateLightUniforms(a);const o=i.createCommandEncoder({label:"scene-capture-encoder"});u.drawCallCount=0,u.triangleCount=0,this.executeMaterialPass(o,["sceneColor"],this.getSharedSceneBindGroup(),a,u,{clearColor:r.clearColor,overrideMaterial:null==r.overrideMaterial?void 0:(e,t)=>r.overrideMaterial(this.staticDrawSetManager.getSourceMaterial(e),t),objectFilter:e=>r.objectFilter?.(e)??!0},c);const l=s??n.getCurrentTexture().createView();r.postProcess?r.postProcess({device:i,encoder:o,colorView:c.colorView,depthView:c.depthView,sampler:this.state.linearClampSampler,targetView:l,targetFormat:this.state.format,width:c.width,height:c.height,camera:t}):this.executePresentPass(o,c.colorView,l),i.queue.submit([o.finish()]),this.releaseRetiredGeometryResourcesAfterSubmit()}finally{this.sceneCaptureOptions=null}},dispose:h}}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 Ch({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)}registerStaticSpatialObject(e){return this.staticSceneSpatialIndex.register(e)}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);this.updateVisibilityWorkload(s);for(const e of s.gpuOpaqueDraws)this.prepareDrawGeometryVertexBuffers(e,!0);for(const e of s.directOpaqueDraws)this.prepareDrawGeometryVertexBuffers(e,!0);for(const e of s.transparentDraws)this.prepareDrawGeometryVertexBuffers(e,!0);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=Fh.get(e);a&&a.device===e.device||(a?.dispose(),a=new kh(e.device),Fh.set(e,a));const s=a,o={frameIndex:e.frameIndex+=1,renderWidth:e.width,renderHeight:e.height,presentationWidth:e.presentationWidth,presentationHeight:e.presentationHeight,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 Eh.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&&(bi(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&&(bi(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(!Eh.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=Wh(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=Wh(o)}}},h={profile:o,observer:d,pendingVisibilityRead:null,get pendingGpuRead(){return l},set pendingGpuRead(e){l=e}};return $h.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.getCameraStaticDrawSets())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(Eh.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=$h.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&&_h(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&&_h(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(){this.sharedVertexAttributeLayouts.clear(),this.staticSceneSpatialIndex.dispose();for(const e of this.sceneCaptureDisposers)e();Oh(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.defaultVertexAttributeBuffers.values())for(const t of e.values())t.destroy();this.defaultVertexAttributeBuffers.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(_(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(_(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(_(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(_(this.state.device,{label:"renderer-skinned-depth-prepass-pipeline",layout:n,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-depth-prepass-module",code:md}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(G)},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(_(this.state.device,{label:"renderer-directional-shadow-pipeline",layout:a,vertex:{module:this.state.device.createShaderModule({label:"renderer-directional-shadow-module",code:dd}),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",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}}).then(e=>{this.state.shadowDepthPipeline=e})),e.push(_(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:"back",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(_(this.state.device,{label:"renderer-skinned-directional-shadow-pipeline",layout:o,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-directional-shadow-module",code:gd}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(G)},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}}).then(e=>{this.state.skinnedShadowDepthPipeline=e})),e.push(_(this.state.device,{label:"renderer-point-shadow-pipeline",layout:a,vertex:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-module",code:hd}),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:hd}),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(_(this.state.device,{label:"renderer-point-shadow-direct-pipeline",layout:s,vertex:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-direct-module",code:pd}),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:pd}),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(_(this.state.device,{label:"renderer-skinned-point-shadow-pipeline",layout:o,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-point-shadow-module",code:vd}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(G)},fragment:{module:this.state.device.createShaderModule({label:"renderer-skinned-point-shadow-fragment-module",code:vd}),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(_(this.state.device,{label:"renderer-present-pipeline",layout:l,vertex:{module:this.state.device.createShaderModule({label:"renderer-present-module",code:xd}),entryPoint:"vsMain"},fragment:{module:this.state.device.createShaderModule({label:"renderer-present-fragment-module",code:xd}),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:bd});e.push(_(this.state.device,{label:"renderer-scene-color-snapshot-pipeline",layout:l,vertex:{module:c,entryPoint:"vsMain"},fragment:{module:c,entryPoint:"fsMain",targets:[{format:B}]},primitive:{topology:"triangle-list"}}).then(e=>{this.state.sceneColorSnapshotPipeline=e}));const u=this.state.device.createShaderModule({label:"physical-transmission-snapshot-module",code:yd});e.push(_(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 Ah("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 Ah("DirectionalShadowPass",()=>{this.executeDirectionalShadowPass(t,i,s,o)},{writes:["directionalShadow"]}))},addPointShadowPass:()=>{s.lights.points.some(e=>e.castShadow)&&e.addPass(new Ah("PointShadowPass",()=>{this.executePointShadowPass(t,i,s,o)},{writes:["pointShadow"]}))},addSpotShadowPass:()=>{s.lights.spots.some(e=>e.castShadow)&&e.addPass(new Ah("SpotShadowPass",()=>{this.executeSpotShadowPass(t,i,s,o)},{writes:["spotShadow"]}))},addDepthPrepass:()=>{d=!0,this.getHiZOcclusionCullingActive()&&this.hasEnabledStaticDrawSets()&&e.addPass(new Ah("TemporalStaticVisibilityPrepass",()=>{this.executeStaticVisibilityPasses(t,"prepass")},{reads:["hiz"],writes:["staticIndirectArgs"]})),e.addPass(new Ah("DepthPrepass",()=>{this.executeDepthPrepass(t,r,s,o)},{writes:["mainDepth"]}))},addHiZPasses:()=>{this.getHiZOcclusionCullingActive()&&e.addPass(new Ah("HiZPasses",()=>{this.executeHiZPasses(t)},{reads:["mainDepth"],writes:["hiz"]}))},addVisibilityPass:()=>{this.getHiZOcclusionCullingActive()&&(n||this.hasEnabledStaticDrawSets())&&(e.addPass(new Ah("VisibilityPass",()=>{n&&this.executeVisibilityPass(t,n),this.executeStaticVisibilityPasses(t,"postpass")},{reads:["hiz"],writes:["indirectArgs","staticIndirectArgs"]})),this.sampleCount>1&&this.hasEnabledStaticDrawSets()&&e.addPass(new Ah("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 Ah("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 Ah("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 Ah("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 Ah("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 Ah("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.getCameraStaticDrawSets().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 Ah("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.getCameraStaticDrawSets().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 Ah("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 Ah("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=i.overrideMaterial?d.flatMap(e=>{const t=(e=>"function"==typeof i.overrideMaterial?i.overrideMaterial(e.material,null!==e.skinning):i.overrideMaterial)(e);return null==t?[]:[{...e,material:t}]}):d;l?.push({draws:h,colorTargetFormats:n.map(e=>this.getColorTargetFormat(e)),sampleCount:this.sampleCount,staticDrawStage:a}),e.addPass(new Ah(i.name??"MaterialPass",()=>{this.executeMaterialPass(t,n,r,s,o,i)},{dependsOn:i.dependsOn,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 Ah(t.name,()=>{t.execute(f)},{reads:t.reads,writes:t.writes,dependsOn:t.dependsOn}))},addPresentPass:(r="sceneColor")=>{e.addPass(new Ah("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=this.createDrawCall(),this.drawCallPool[e]=t),t}createDrawCall(){return{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 jd,boundsRadius:0,sortDepth:0,transparentSortGroup:0,transparentSortOrder:0}}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 jd,boundsMax:new jd},this.opaqueBatchPool[e]=t),t}populateDrawCall(e,t,r,i,n,a,s,o,l){const c=t.wireframe;c&&this.ensureWireframeIndex(t.geometry,t.geometryResource);const u=t.sourceObject?Boolean(t.sourceObject.receiveShadow):t.receiveShadow;return this.shouldInvalidateDrawMaterialResource(e,t.material,u,t.usesBatching,null)&&(e.materialResource=null),e.geometry=t.geometry,e.geometryKey=c?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=l?.detailCulling??f(t.sourceObject),e.frontFaceCW=l?.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=c||t.indexed,e.wireframe=c,e.start=c?2*t.start:t.start,e.count=c?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=u,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,m,g,v,x,w,b,y,S,C,M,P,D,B,T,I=null){const V=!0===o?.isBatchedMesh,z=n.wireframe&&"triangle-list"===n.primitiveTopology;return z&&this.ensureWireframeIndex(t,i),this.shouldInvalidateDrawMaterialResource(e,n,w,V,I)&&(e.materialResource=null),e.geometry=t,e.geometryKey=z?i.wireframeIndex:r,e.geometryResource=i,e.material=n,e.customDepthMaterial=a,e.residentInstanceBinding=s,e.sourceObject=o,e.cameraDetailRejected=void 0,e.detailCulling=f(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=z||d,e.wireframe=z,e.start=z?2*h:h,e.count=z?2*p:p,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=M,e.boundsCenter.set(P,D,B),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=f(e.sourceObject),e.cameraDetailRejected=null===this.sceneCaptureOptions&&!m(k.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&&null===this.sceneCaptureOptions&&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($i(r.template,e)){c=r;break}}else $i(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 ei({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?Sf:[{name:"position",shaderLocation:0,format:"float32x3"},{name:"normal",shaderLocation:1,format:"float32x3",defaultValue:[0,0,1]}],uniforms:{outlineThickness:r.thickness??.003,outlineColor:(new Id).fromArray(r.color??[0,0,0]),outlineAlpha:r.alpha??e.opacity},side:Dd,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=e.transparent||(this.getToonOutlineParameters(t)?.alpha??t.opacity)<1||r.requiresLatePass(),n=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,i,e.renderOrder,!1,!1,!1,Li(r),e.sortGeometryId,0,e.instanceStart,e.instanceCount,e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius,e.skinning);this.pushDraw(n)}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)}}selectTransientPointLight(e,t){if(!(e.intensity>0&&e.distance>0))return;if(k.setFromMatrixPosition(e.matrixWorld),!Zi(this.cameraFrustumPlanesScratch,k.x,k.y,k.z,e.distance))return;const r=e.intensity*e.distance*e.distance/Math.max(1,k.distanceToSquared(t));if(!Number.isFinite(r))return;const i=this.transientPointLightsScratch,n=this.transientPointScoresScratch;let a=0;for(;a<i.length&&(n[a]>r||n[a]===r&&i[a].id<e.id);)a++;if(a>=n.length)return;for(let e=Math.min(i.length,n.length-1);e>a;e--)i[e]=i[e-1],n[e]=n[e-1];i[a]=e,n[a]=r}extractPointLight(e,t){const r=e.shadow,i=r.camera;k.setFromMatrixPosition(e.matrixWorld);const n=e.distance>0?e.distance:Math.max(i.far,25);if(!Zi(this.cameraFrustumPlanesScratch,k.x,k.y,k.z,n))return;const a=this.extractedPointLightsScratch[t.length];a.sourceLight=e,a.position.copy(k),a.color.set(e.color.r,e.color.g,e.color.b),a.intensity=e.intensity,a.volumetricIntensity=e.userData?.volumetricIntensity??0,a.distance=e.distance,a.range=n,a.decay=e.decay,a.castShadow=e.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=e.distance>0?e.distance:i.far,t.push(a)}extractScene(e,t,r=!1){this.extractionVersion+=1,null===this.sceneCaptureOptions&&(this.motionHistoryExtractionVersion+=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.dynamicBatchingEnabled?this.finalInstanceDataScratch:a;this.finalInstanceDataScratch.reset();const h=this.extractedAmbientScratch;h.set(0,0,0,0);let p=null;const g=this.activeDirectionalLightsScratch,v=this.activePointLightsScratch,x=this.activeSpotLightsScratch,w=this.fogVolumeObjectsScratch;g.length=0,v.length=0,this.transientPointLightsScratch.length=0,x.length=0,w.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),qi(Hi(t,this.cameraViewProjScratch),this.cameraFrustumPlanesScratch);const M=this.transparentSortCameraPositionScratch,P=this.transparentSortCameraForwardScratch;t.getWorldPosition(M),t.getWorldDirection(P);const D=r?this.isSphereVisibleForCompilationScratch:this.isSphereVisibleScratch,B=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(;;){if(0===T.length){for(const e of this.transientPointLightsScratch){if(v.length>=b)break;this.extractPointLight(e,v)}if(this.csmCascadeLights.length>0&&g.sort((e,t)=>{const r=e.sourceLight?this.csmCascadeLights.indexOf(e.sourceLight):-1,i=t.sourceLight?this.csmCascadeLights.indexOf(t.sourceLight):-1;return(r<0?4:r)-(i<0?4:i)}),!r&&null===this.sceneCaptureOptions){const e=this.staticDrawSetManager.revision;this.directionalShadowScheduler.prepare(g,t,this.csmCascadeRanges,this.csmCascadeCount,performance.now(),e)}if(this.spatialShadowCount=0,this.spatialLocalShadowCount=0,null===this.sceneCaptureOptions)for(let e=0;e<g.length;e++)g[e].castShadow&&qi(Hi(this.directionalShadowCameras[e],this.spatialShadowMatrix),this.spatialShadowPlanes[this.spatialShadowCount++]);for(const e of v){if(!e.castShadow)continue;const t=4*this.spatialLocalShadowCount++,r=this.spatialLocalShadowSpheres;r[t]=e.position.x,r[t+1]=e.position.y,r[t+2]=e.position.z,r[t+3]=e.shadowCameraFar*Math.sqrt(3)}for(const e of x){if(!e.castShadow)continue;const t=4*this.spatialLocalShadowCount++,r=this.spatialLocalShadowSpheres;r[t]=e.position.x,r[t+1]=e.position.y,r[t+2]=e.position.z;const i=Math.tan(e.shadowCameraFov*Math.PI/360);r[t+3]=e.shadowCameraFar*Math.sqrt(1+2*i*i)}for(this.spatialIncludeOffscreen=r,this.spatialCameraLayers=t.layers.mask,this.staticSceneSpatialIndex.queryWithState(e,this.testSpatialScene,this.pushSpatialRoot,63);T.length;)this.collectSpatialRoot(T.pop());break}const i=T.pop();if(this.extractingCaster=i.castShadow,!i.visible)continue;if(!1===this.sceneCaptureOptions?.objectFilter?.(i))continue;if(null!==this.sceneCaptureOptions&&!1===i.userData.sceneCapture)continue;if(i.isBone){const e=this.staticSceneSpatialIndex.traversalChildren(i);for(let t=e.length-1;t>=0;t--)T.push(e[t]);continue}const n=0!==(i.layers.mask&t.layers.mask);if(!0===i.isFogVolumeObject&&null!=i.volume)w.push(i);else if(i.isAmbientLight){if(n){const e=i;h.x+=e.color.r*e.intensity,h.y+=e.color.g*e.intensity,h.z+=e.color.b*e.intensity,h.w=1}}else if(i.isHemisphereLight){if(n&&null==p){const e=i,t=this.extractedHemisphereScratch;k.setFromMatrixPosition(e.matrixWorld),t.direction.copy(k),t.direction.lengthSq()<=1e-10?t.direction.set(0,1,0):t.direction.normalize(),t.skyColor.set(e.color.r,e.color.g,e.color.b),t.groundColor.set(e.groundColor.r,e.groundColor.g,e.groundColor.b),t.intensity=e.intensity,p=t}}else if(i.isDirectionalLight){if(n&&g.length<4&&!this.hasExtractedDirectionalLight(g,i)){const e=i,t=e.shadow,r=t.camera,n=this.extractedDirectionalLightsScratch[g.length];n.sourceLight=e,e.target.matrixWorldAutoUpdate&&e.target.updateMatrixWorld(!0),k.setFromMatrixPosition(e.matrixWorld),F.setFromMatrixPosition(e.target.matrixWorld),n.position.copy(k),n.target.copy(F),n.direction.copy(F).sub(k).normalize(),n.color.set(e.color.r,e.color.g,e.color.b),n.intensity=e.intensity,n.volumetricIntensity=e.userData?.volumetricIntensity??0,n.castShadow=e.castShadow&&this.directionalShadowsEnabled,n.shadowBias=t.bias,n.shadowNormalBias=t.normalBias,n.shadowRadius=t.radius,n.shadowIntensity=t.intensity,n.shadowMapSize=Math.max(1,t.mapSize.width,t.mapSize.height),n.shadowCameraLeft=r.left,n.shadowCameraRight=r.right,n.shadowCameraTop=r.top,n.shadowCameraBottom=r.bottom,n.shadowCameraNear=r.near,n.shadowCameraFar=r.far,g.push(n)}}else if(i.isPointLight){if(n&&!1!==this.sceneCaptureOptions?.includeLocalLights){const e=i;!0===e.userData.vfxTransientLight?this.selectTransientPointLight(e,M):v.length<b&&this.extractPointLight(e,v)}}else if(i.isSpotLight){if(n&&!1!==this.sceneCaptureOptions?.includeLocalLights&&x.length<y){const e=i,t=e.shadow,r=t.camera,n=this.extractedSpotLightsScratch[x.length];n.sourceLight=e,e.target.matrixWorldAutoUpdate&&e.target.updateMatrixWorld(!0),k.setFromMatrixPosition(e.matrixWorld),F.setFromMatrixPosition(e.target.matrixWorld);const a=e.distance>0?e.distance:r.far;if(!Zi(this.cameraFrustumPlanesScratch,k.x,k.y,k.z,a))continue;n.position.copy(k),n.direction.copy(F).sub(k).normalize(),n.color.set(e.color.r,e.color.g,e.color.b),n.intensity=e.intensity,n.volumetricIntensity=e.userData?.volumetricIntensity??0,n.range=a,n.angle=e.angle,n.penumbra=e.penumbra,n.decay=e.decay,n.castShadow=e.castShadow,n.shadowBias=t.bias,n.shadowNormalBias=t.normalBias,n.shadowRadius=t.radius,n.shadowIntensity=t.intensity,n.shadowMapSize=Math.max(1,t.mapSize.width,t.mapSize.height),n.shadowCameraNear=r.near,n.shadowCameraFar=e.distance>0?e.distance:r.far,n.shadowCameraFov=e.angle*(360/Math.PI)*t.focus,n.map=e.map??null,x.push(n)}}else n&&i.isBatchedMesh?this.collectBatchedMesh(i,a,B,D,t,M,P):n&&i.isInstancedMesh?this.collectInstancedMesh(i,a,B,D):n&&i.isSkinnedMesh?this.collectSkinnedMesh(i,a,B,D):n&&i.isLine?this.collectLine(i,a,B,D):n&&i.isSprite?this.collectSprite(i,a,B,D):n&&i.isMesh&&this.collectMesh(i,a,B,D);const s=this.staticSceneSpatialIndex.traversalChildren(i);for(let e=s.length-1;e>=0;e-=1)T.push(s[e])}const I=this.dynamicBatchingEnabled?o.length:0;this.updateTransparentDrawSortDepths(i,M,P),i.sort(Ai),Number.isFinite(S.x)||(S.set(-6,-6,-6),C.set(6,6,6)),this.dynamicBatchingEnabled&&this.sortOpaqueDraws(l);for(let e=0;e<l.length;){const t=l[e];if(!this.dynamicBatchingEnabled){t.sourceRanges=void 0,t.indexed&&!t.hasRenderCallbacks?s.push(t):o.push(t),e++;continue}const 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&&Ei(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;this.dynamicBatchingEnabled&&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}v.sort(bf),x.sort(bf);for(let e=4;e<v.length;e+=1)v[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=g[0]??null,V.point=v[0]??null,V.spot=x[0]??null;const z=this.extractedFrameScratch;z.scene=e,z.camera=t,z.fogVolumeObjects=w,z.transparentDraws=i,z.instanceData=d,z.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??f(r.sourceObject);r.cameraDetailRejected||!this.isSphereVisibleScratch(r.boundsCenter.x,r.boundsCenter.y,r.boundsCenter.z,r.boundsRadius,r.sourceObject?.frustumCulled??!0)||null===this.sceneCaptureOptions&&!m(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 z.shadowDraws=L,z}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=`${ui(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 Ad(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=ui(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 Td;f.setIndex([0,2,1,2,3,1,2,4,3,4,5,3,4,6,5,6,7,5]),f.setAttribute("position",new Bd(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 zd(new Float32Array(d),3)),f.setAttribute("instanceEnd",new zd(new Float32Array(h),3)),f.instanceCount=d.length/3;const m=Yi(n);f.boundingSphere=new Ed(m.center.clone(),m.radius),o={signature:s,sourceGeometry:n,mesh:new Ad(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 Ad(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){if(null!==this.sceneCaptureOptions)return this.captureMotionHistory.matrix.set(t),this.captureMotionHistory;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.motionHistoryExtractionVersion-1&&!i&&n*n+a*a+s*s<=o*o,r}commitObjectMotionHistory(e,t){null===this.sceneCaptureOptions&&(e.matrix.set(t),e.generation=this.motionVectorHistoryGeneration,e.lastExtractionVersion=this.motionHistoryExtractionVersion)}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.hasRenderCallbacks(e)?void 0:this.staticSceneSpatialIndex.getMeshSnapshot(e);let l=o?null:this.getGeometryResource(n,!0);const c=this.meshExtractionCache.get(e),u=c?.geometryResource===l?c:null,d=o||u?null:Yi(n),h=o?.boundsCenter??u?.localBoundsCenter??d.center,p=o?.boundsRadius??u?.localBoundsRadius??d.radius,f=e.matrixWorld.elements,g=h.x,v=h.y,x=h.z,w=o?.boundsCenter.x??f[0]*g+f[4]*v+f[8]*x+f[12],b=o?.boundsCenter.y??f[1]*g+f[5]*v+f[9]*x+f[13],y=o?.boundsCenter.z??f[2]*g+f[6]*v+f[10]*x+f[14];let S,C=o?.boundsRadius;if(void 0===C){const e=f[0]*f[0]+f[1]*f[1]+f[2]*f[2],t=f[4]*f[4]+f[5]*f[5]+f[6]*f[6],r=f[8]*f[8]+f[9]*f[9]+f[10]*f[10];C=p*Math.sqrt(Math.max(e,t,r,1e-10))}if(!i(w,b,y,C,e.frustumCulled))return;if(o&&null===this.sceneCaptureOptions&&i!==this.isSphereVisibleForCompilationScratch){const t=o.detailCulling;if(S=!m(o.boundsCenter,C,this.cameraViewProjScratch,this.state.width,this.state.height,this.transparentSortCameraPositionScratch,t.minScreenSize*(this.cameraDetailHistory.get(e)?.85:1.15),t.maxDistance),this.cameraDetailHistory.set(e,!S),S&&(!e.castShadow||!this.isSpatialShadowSphereVisible(w,b,y,C)))return}l??=this.getGeometryResource(n,!0);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 D=rn(e),B=c&&c.customDepthMaterial===D&&c.geometryResource.lastValidatedExtractionVersion===this.extractionVersion&&(!s&&c.material===a&&c.resolvedMaterial===P||s&&null!==c.materials&&null!==c.resolvedMaterials&&mi(c.materials,a)&&xi(c.resolvedMaterials,M))?c:this.getMeshExtractionCacheEntry(e,a,P,M,D,l),T=B.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,f),z=vf(e),L=xf(e);let G,R=0,U=null;if(!(n instanceof Ld&&I>1)||e instanceof $d||this.hasRenderCallbacks(e))for(let e=0;e<I;e+=1){const r=Ii(t,f,1,1,1,1,void 0,V.matrix,z,L,V.valid?1:0);0===e&&(R=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 sn,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)}U=t.data,U.update(I,f,V.matrix,z,L,V.valid?1:0),!U.residentBufferDirty&&U.residentInstanceBinding.buffer||this.residentInstanceUploadsScratch.push(U)}if(this.commitObjectMotionHistory(V,f),r(f),o&&!this.dynamicBatchingEnabled&&null===this.sceneCaptureOptions){let e=this.staticMeshDraws.get(o);e&&e.templates===B.templates||(e={templates:B.templates,draws:[]},this.staticMeshDraws.set(o,e)),G=e.draws}for(let t=0;t<T;t+=1){const r=B.templates[t];let i=G?.[t];i?(i.receiveShadow!==e.receiveShadow&&(i.materialResource=null),i.receiveShadow=e.receiveShadow,i.castShadow=e.castShadow,i.renderOrder=e.renderOrder,i.instanceStart=R,i.instanceCount=I):(i=this.populateDrawCall(G?this.createDrawCall():this.acquireDrawCall(),r,R,I,w,b,y,C,o),G&&(G[t]=i)),i.cameraDetailRejected=S,i.residentInstanceBinding=U?.residentInstanceBinding??r.residentInstanceBinding,r.transparent?this.transparentDraws.push(i):this.pushDraw(i);const n=s?a[r.geometryGroup?.materialIndex??0]:a;this.pushToonOutlineDraw(i,n)}}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=rn(e),l=this.getGeometryResource(e.geometry,!0),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&&ji(c.cachedMatrixWorld,e.matrixWorld.elements),g=Ni(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,_i(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=Ni(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],C=s[5],M=s[9],P=s[13],D=s[2],B=s[6],T=s[10],I=s[14],V=s[3],z=s[7],L=s[11],G=s[15];for(let n=0;n<e.count;n+=1){const e=16*n,s=n*S,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,F=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=F,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*F+b*$,re=v*E+x*O+w*_+b*j,se=v*N+x*W+w*H+b*q,Z=y*c+C*d+M*f+P*R,Q=y*U+C*A+M*F+P*$,ie=y*E+C*O+M*_+P*j,oe=y*N+C*W+M*H+P*q,Y=D*c+B*d+T*f+I*R,ee=D*U+B*A+T*F+I*$,ne=D*E+B*O+T*_+I*j,le=D*N+B*W+T*H+I*q,X=V*c+z*d+L*f+G*R,te=V*U+z*A+L*F+G*$,ae=V*E+z*O+L*_+G*j,ce=V*N+z*W+L*H+G*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);Qi(r,i,k.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,_i(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),Wi(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=k;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=rn(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=Vi(t,e.matrixWorld,1,1,1,1,void 0,h.matrix,vf(e),xf(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=Ci(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=Mi(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=rn(e),c=(e.geometry.index,this.getGeometryResource(e.geometry,!0)),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)&&ji(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 Wi(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),U.multiplyMatrices(e.matrixWorld,R);const h=u.localBoundsCenter,g=U.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,D=f?f[4*n+2]??1:1,B=f?f[4*n+3]??1:1,T=Vi(t,U,M,P,D,B,n);r(U.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=Li(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 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),w.push(r)),r.activeCount+=1,C+=1):m.geometryIdsSnapshot[e]=-1}const M=m.cachedInstanceData.beginWriteInstances(C);let P=0;for(let e=0;e<w.length;e+=1){const t=w[e];t.instanceStart=P,t.writeOffset=P*S,P+=t.activeCount}const D=Ni(g),B=g[0],T=g[4],I=g[8],V=g[12],z=g[1],L=g[5],G=g[9],A=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,C,P,U,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,C=p[e+13]??0,P=p[e+14]??0,U=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,w=r[12]??0,C=r[13]??0,P=r[14]??0,U=r[15]??0}D?(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=C,ae=P,se=U):(W=B*n+T*a+I*s+V*o,Z=B*l+T*c+I*u+V*d,Q=B*h+T*g+I*v+V*x,ie=B*w+T*C+I*P+V*U,H=z*n+L*a+G*s+A*o,Y=z*l+L*c+G*u+A*d,ee=z*h+L*g+G*v+A*x,ne=z*w+L*C+G*P+A*U,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*C+$*P+E*U,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+_*C+j*P+N*U);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+=S;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 jd,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,_i(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),Wi(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,M,0,S)}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,Ti(n),0,16*t.count):this.state.device.queue.writeBuffer(i.buffer,0,P,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,Ti(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,Ti(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,M,0,S),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(),e.temporalDepthSupported=ep(e.draws)}}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=en(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=yf){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=yf,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=Fi(i,e.key),i=Fi(i,Li(e.geometryResource.position)),i=Fi(i,e.geometryResource.index?Li(e.geometryResource.index):0),i=Fi(i,Li(t.indirectBuffer)),i=Fi(i,e.indirectStartIndex),i=Fi(i,e.indirectCount),i=Fi(i,this.sampleCount),i=Fi(i,e.material.version),i=Fi(i,this.graphTextureResourceVersion),i=Fi(i,r),i>>>0}getColorFormatsId(e){if(e===yf)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=Fi(i,e.length),i=Fi(i,this.sampleCount),i=Fi(i,Li(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=Fi(i,Li(a.material)),i=Fi(i,a.receiveShadow?1:0),i=Fi(i,a.material.version??0),i=Fi(i,Li(s.pipeline)),i=Fi(i,Li(s.bindGroup)),i=Fi(i,Li(o)),i=Fi(i,Li(a.geometryKey)),i=Fi(i,Li(a.geometryResource.position)),i=Fi(i,Li(a.geometryResource.normal)),i=Fi(i,Li(a.geometryResource.uv)),i=Fi(i,Li(a.geometryResource.color)),i=Fi(i,a.geometryResource.index?Li(a.geometryResource.index):0);for(const e of a.geometryResource.extraAttributeBuffers.values())i=Fi(i,Li(e));i=Fi(i,a.indexed?1:0),i=Fi(i,a.start),i=Fi(i,a.count),i=Fi(i,a.instanceStart),i=Fi(i,a.instanceCount);const l=a.material.getTexturesList();i=Fi(i,l.length);for(let e=0;e<l.length;e+=1){const t=l[e];i=Fi(i,Li(t)),i=Fi(i,t.version)}}return`forward-direct:${i}:${e.length}:samples=${this.sampleCount}:formats=${r.join("|")}`}getOrCreateDirectForwardBundle(e,t,r,i=yf){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=`${Li(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*C;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*C;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*C*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+=en(e)}executeVisibilityPass(e,t){mp.call(this,e,t)}executeStaticVisibilityPasses(e,t){xp.call(this,e,t)}getOrCreateStaticVisibilityBindGroup(e,t){return wp.call(this,e,t)}executeDirectionalShadowPass(e,t,r,i){bp.call(this,e,t,r,i)}executePointShadowPass(e,t,r,i){Sp.call(this,e,t,r,i)}executeSpotShadowPass(e,t,r,i){Cp.call(this,e,t,r,i)}executeDepthPrepass(e,t,r,i){Pp.call(this,e,t,r,i)}executeStaticDepthPrepass(e,t,r){Dp.call(this,e,t,r)}executeStaticTemporalDepthResolvePass(e){Tp.call(this,e)}getOrCreateStaticDepthPrepassBundle(e,t){return Vp.call(this,e,t)}executeHiZPasses(e,t=!1,r=!1){Gp.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&&this.state.lightBuffer))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:1,resource:{buffer:this.state.lightBuffer}},{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={},s){if(!this.state.mainDepthView||0===t.length)return;const o=t.map(e=>this.getColorTargetFormat(e)),l=this.getColorFormatsId(o),c=t.map(e=>s?.colorView??this.getColorTargetView(e)),u=!s&&this.sampleCount>1,d=u?t.map(e=>this.ensureMsaaColorTarget(e)):[],h=this.getColorTargetDimensions(t[0]),p=u?this.ensureMsaaDepthTarget(h.width,h.height):null,f=e.beginRenderPass({label:"renderer-material-pass",colorAttachments:t.map((e,t)=>({view:d[t]?.view??c[t],resolveTarget:d[t]?c[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:d[t]?"discard":"store"})),depthStencilAttachment:{view:s?.depthView??p?.view??this.state.mainDepthView,depthClearValue:1,depthLoadOp:p?"clear":a.loadDepth?"load":"clear",depthStoreOp:p?"discard":"store"}});let m=null,g=null,v=null,x=null,w=null;const b=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 l=this.getMaterialResourceForDraw(e,o,s?1:this.sampleCount),c=this.resolveSceneBindGroupForDraw(e,r);if(m!==l.pipeline&&(m=l.pipeline,v=null,w=null,f.setPipeline(m)),v!==e.geometryKey&&(v=e.geometryKey,this.bindGeometryVertexBuffers(f,e.geometry,t,l.vertexAttributes,e.instanceStart,e.instanceCount,e.wireframe)),x!==c&&(x=c,f.setBindGroup(0,c)),g!==a){if(g=a,f.setBindGroup(1,l.bindGroup),!l.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");f.setBindGroup(3,this.createGraphTextureBindGroup(a,l.graphTextureBindGroupLayout))}l.usesSkinning&&e.skinning&&w!==e.skinning.bindGroup&&(w=e.skinning.bindGroup,f.setBindGroup(2,w)),e.indexed&&(e.wireframe?t.wireframeIndex:t.index)?f.drawIndexed(e.count,e.instanceCount,e.start,0,e.instanceStart):f.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)},y=a.drawStage??"all";if(a.objectFilter||a.overrideMaterial){const e=e=>{if(s){if(!this.isSphereVisibleScratch(e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius,!0))return;if(e.material.requiresLatePass())return;this.prepareDrawGeometryVertexBuffers(e),e={...e,receiveShadow:!1,materialResource:null}}if(a.objectFilter){const t=e.sourceRanges?.filter(e=>a.objectFilter(e.sourceObject));if(0===t?.length)return;if(null!=t&&t.length<e.sourceRanges.length){const r="function"==typeof a.overrideMaterial?a.overrideMaterial(e.material,null!==e.skinning):a.overrideMaterial;if(null===r)return;for(const i of t)b({...e,sourceObject:i.sourceObject,instanceStart:i.instanceStart,instanceCount:i.instanceCount,material:r??e.material,sourceRanges:void 0});return}if(null==t&&!a.objectFilter(e.sourceObject))return}const t="function"==typeof a.overrideMaterial?a.overrideMaterial(e.material,null!==e.skinning):a.overrideMaterial;null!==t&&b(t?{...e,material:t}:e)};if("late"!==y){for(const t of this.getCameraStaticDrawSets())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"!==y){if(s)for(const t of this.staticDrawSets)if(t.publicSet.enabled&&"late"===t.drawStage)for(const r of t.draws)e(r);for(const t of i.transparentDraws)e(t)}return void f.end()}if("late"!==y){const e=this.renderBundleScratch;e.length=0;for(const t of this.getCameraStaticDrawSets()){if(!t.publicSet.enabled||!this.isStaticDrawSetCameraVisible(t)||0===t.draws.length||"opaque"!==t.drawStage)continue;if(this.getHiZOcclusionCullingActive()&&t.lastVisibilityFrameToken===this.staticFrameToken){const r=this.getOrCreateStaticVisibleSceneBindGroup(t),i=this.getOrCreateStaticIndirectSubmissionStreams(t,r,o);for(const r of i){if(this.getMultiDrawIndirectActive()){if(e.length&&(f.executeBundles(e),e.length=0),f.setPipeline(r.materialResource.pipeline),this.bindGeometryVertexBuffers(f,r.geometry,r.geometryResource,r.materialResource.vertexAttributes,0,1,r.material.wireframe),f.setBindGroup(0,r.sceneBindGroup),f.setBindGroup(1,r.materialResource.bindGroup),!r.materialResource.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");f.setBindGroup(3,this.createGraphTextureBindGroup(r.material,r.materialResource.graphTextureBindGroupLayout)),f.multiDrawIndexedIndirect(t.drawMetadataResource.indirectBuffer,5*r.indirectStartIndex*Uint32Array.BYTES_PER_ELEMENT,r.indirectCount)}else e.push(this.getOrCreateIndirectForwardBundle(r,t.drawMetadataResource,t.indirectForwardBundleCache,`${t.label}-static-indirect-material-bundle`,o,!1,l));n.drawCallCount+=r.drawCallCount,n.triangleCount+=r.triangleCount}continue}const i=this.getOrCreateStaticMaterialBundle(t,r,n,o);i&&e.push(i)}if(e.length&&f.executeBundles(e),e.length=0,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],o);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",o,!0,l);t?(this.renderBundleScratch[0]=t,f.executeBundles(this.renderBundleScratch)):this.submitIndirectStreamDirect(f,e,this.state.drawMetadataResource),n.drawCallCount+=e.drawCallCount,n.triangleCount+=e.triangleCount}}else{const e=ki(i.gpuOpaqueDraws)||i.gpuOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(i.gpuOpaqueDraws,r,n,o);if(e)this.renderBundleScratch[0]=e,f.executeBundles(this.renderBundleScratch);else for(const e of i.gpuOpaqueDraws)b(e)}const t=ki(i.directOpaqueDraws)||i.directOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(i.directOpaqueDraws,r,n,o);if(t)this.renderBundleScratch[0]=t,f.executeBundles(this.renderBundleScratch);else for(const e of i.directOpaqueDraws)b(e)}if("opaque"!==y)for(const e of i.transparentDraws)b(e);f.end()}executeForwardPass(e,t,r,i,n,a,s=!1,o="all",l=!1,c=this.sampleCount){Rp.call(this,e,t,r,i,n,a,s,o,l,c)}executeStaticForwardPass(e,t,r,i="all",n=this.sampleCount){Up.call(this,e,t,r,i,n)}getOrCreateStaticDirectForwardBundle(e,t,r=this.sampleCount){return Ap.call(this,e,t,r)}refreshStaticDrawMaterialResources(e){Fp.call(this,e)}syncStaticVisibleMaterialBindingCaches(e){kp.call(this,e)}recordStaticDrawStats(e,t){$p.call(this,e,t)}hasEnabledStaticDrawSets(){return Ep.call(this)}executePresentPass(e,t,r){Op.call(this,e,t,r)}clearDirectionalShadow(e){_p.call(this,e)}clearPointShadow(e){jp.call(this,e)}clearSpotShadow(e){Np.call(this,e)}drawDepthLike(e,t,r,i){Wp.call(this,e,t,r,i)}getGeometryResource(e,t=!1){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=this.geometryCache.get(e);if((t||!this.invokeObjectRenderCallbacks)&&r&&r.lastValidatedExtractionVersion===this.extractionVersion)return r;if(r&&this.updateDynamicGeometryAttributes(e,r))return r.lastValidatedExtractionVersion=this.extractionVersion,r;if(r&&r.lastValidatedExtractionVersion===this.extractionVersion)return r;if(r&&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||ci(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,r))return r.lastValidatedExtractionVersion=this.extractionVersion,r;r&&(this.clearIndirectBundleCache(),this.retireGeometryResource(r));const i=e.getAttribute("position");if(!i)throw new Error("BufferGeometry is missing the required position attribute.");const n=i.count,a=yi(i,n,3,[0,0,0]),s=yi(e.getAttribute("normal"),n,3,[0,0,1]),o=yi(e.getAttribute("uv"),n,2,[0,0]),l=yi(e.getAttribute("color"),n,4,[1,1,1,1]),c=e.getAttribute("skinIndex"),u=e.getAttribute("skinWeight"),d=c?Si(c,n,"uint32x4",[]):void 0,h=u?Si(u,n,"float32x4",[]):void 0,p={signature:ui(e),indexVersion:e.index?.version??0,drawRangeStart:e.drawRange.start,drawRangeCount:e.drawRange.count,vertexCount:n,attributes:["position","normal","uv","color",...c?["skinIndex"]:[],...u?["skinWeight"]:[]].map(t=>{const r=e.getAttribute(t);return{name:t,source:r,version:ci(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,a,s,o,l,d,h,e.index?.array),extraAttributeBuffers:new Map,extraAttributeBufferVersions:new Map,wireframeIndex:null,wireframeIndexFormat:null};return this.geometryCache.set(e,p),p}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||ci(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=ci(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 Bd&&!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=ui(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!==ci(i)||a.skinIndexAttribute!==t||a.skinIndexVersion!==ci(t)||a.skinWeightAttribute!==r||a.skinWeightVersion!==ci(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:ci(i),skinIndexAttribute:t,skinIndexVersion:ci(t),skinWeightAttribute:r,skinWeightVersion:ci(r),boneCount:e.skeleton.bones.length,resource:n,skinning:c,boneBounds:this.createSkinningBoneBounds(e,i,t,r),localBoundsMin:new jd,localBoundsMax:new jd,localBoundsCenter:new jd,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(null!==this.sceneCaptureOptions)return;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 jd(1/0,1/0,1/0)),a=Array.from({length:e.skeleton.bones.length},()=>new jd(-1/0,-1/0,-1/0));for(let e=0;e<t.count;e+=1){k.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(k),l.max(k))}}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=Yi(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=Ji(a.center,a.radius,e.bindMatrix,t.skinning.palette.skeleton.boneMatrices,16*n,e.bindMatrixInverse,k);r.min(F.copy(k).addScalar(-s)),i.max(F.copy(k).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=gi(this.state.device,t,GPUBufferUsage.INDEX,`${e}-index`)}return{position:gi(this.state.device,t,l|GPUBufferUsage.COPY_DST,`${e}-position`),normal:gi(this.state.device,r,c|GPUBufferUsage.COPY_DST,`${e}-normal`),uv:gi(this.state.device,i,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-uv`),color:gi(this.state.device,n,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-color`),skinIndex:a?gi(this.state.device,a,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-skin-index`):null,skinWeight:s?gi(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*di(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:this.getSharedVertexAttributeLayout(e.vertexAttributes)},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=this.getSharedVertexAttributeLayout(i),r.skinned}getSharedVertexAttributeLayout(e){const t=JSON.stringify(e.map(e=>[e.name,e.shaderLocation,e.format,e.stepMode??"vertex",e.defaultValue??null]));let r=this.sharedVertexAttributeLayouts.get(t);return r||(r=e.map(e=>({...e,defaultValue:e.defaultValue?.slice()})),this.sharedVertexAttributeLayouts.set(t,r)),r}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(!s&&(o||r.defaultValue)){const e=this.getDefaultVertexAttributeBuffer(r,o?l+Math.max(1,n):t.vertexCount);return this.cacheGeometryVertexBufferFast(t,r,l,void 0,0,e),e}const c=ci(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=Si(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=gi(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,u=l.get(r);u&&u.buffer!==a&&this.clearIndirectBundleCache(),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,o=`interleaved:${this.getGeometryAttributeGroupBufferKey(r)}:instance-start=${s}`;let l=this.packedVertexGroups.get(t);l||(l=new Map,this.packedVertexGroups.set(t,l));let c=l.get(o);c||(c=new cn(r),l.set(o,c));const u=c.update(e,t.vertexCount,s,n),d=t.extraAttributeBuffers.get(o);if(!u&&d)return d;const h=c.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=gi(this.state.device,h,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e.uuid}-interleaved-${a}`);return d&&(this.clearIndirectBundleCache(),this.retiredGeometryBuffers.push(d)),t.extraAttributeBuffers.set(o,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=gi(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,a=!1){let s=this.preparedVertexBufferCache.get(t);s||(s=new WeakMap,this.preparedVertexBufferCache.set(t,s));let o=s.get(r);o||(o={instanced:r.some(e=>"instance"===e.stepMode),ranges:new Map},s.set(r,o));const l=o.instanced?Math.max(0,Math.trunc(i)):0,c=o.instanced?n:1;let u=o.ranges.get(l);if((a||!this.invokeObjectRenderCallbacks)&&u&&u.extractionVersion===this.extractionVersion&&u.instanceCount===c&&u.instanceBufferSize===this.state.instanceBufferSize)return u.buffers;u||(u={extractionVersion:-1,instanceCount:c,instanceBufferSize:0,buffers:[]},o.ranges.set(l,u));let d=this.vertexBufferBindingPlanCache.get(r);d||(d=this.getVertexAttributeGroups(r).map(e=>({group:e,standardAttribute:1===e.length?this.getStandardVertexAttribute(e[0]):null})),this.vertexBufferBindingPlanCache.set(r,d));for(let r=0;r<d.length;r+=1){const{group:a,standardAttribute:s}=d[r],o=s?t[s]:null;u.buffers[r]=o??(1===a.length?this.getGeometryVertexBuffer(e,t,a[0],i,n):this.getInterleavedGeometryVertexBuffer(e,t,a,i,n))}return u.extractionVersion=this.extractionVersion,u.instanceCount=c,u.instanceBufferSize=this.state.instanceBufferSize,u.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&&!wi(e.defaultValue,Tf)?"uv"!==e.name||"float32x2"!==e.format||void 0!==e.defaultValue&&!wi(e.defaultValue,Bf)?"color"!==e.name||"float32x4"!==e.format||void 0!==e.defaultValue&&!wi(e.defaultValue,If)?"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,t=!1){for(let r=0;r<(e.customDepthMaterial?2:1);r++){const i=0===r?e.material:e.customDepthMaterial,n=this.getMaterialVertexAttributes(i,null!==e.skinning);this.prepareGeometryVertexBuffers(e.geometry,e.geometryResource,n,e.instanceStart,e.instanceCount,t)}}getDefaultVertexAttributeBuffer(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=Math.max(1,t,"instance"===e.stepMode?Math.ceil(this.state.instanceBufferSize/(Float32Array.BYTES_PER_ELEMENT*S)):0),i=2**Math.ceil(Math.log2(r)),n=`${e.format}:${(e.defaultValue??[]).join(",")}`;let a=this.defaultVertexAttributeBuffers.get(n);a||(a=new Map,this.defaultVertexAttributeBuffers.set(n,a));const s=a.get(i);if(s)return s;const o=gi(this.state.device,Si(void 0,i,e.format,e.defaultValue??[]),GPUBufferUsage.VERTEX,`renderer-default-attribute-${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&&mi(s.materials,o)&&xi(s.resolvedMaterials,i)))return s;const c=null!==e.geometry.index,u=Yi(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=Ci(e.geometry,c,t.start,t.count),u=Gi(s,e.geometry,c,t.start,l,n),h=Li(s),p=Li(e.geometry),f=n?Li(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=Mi(e.geometry,c),i=Gi(t,e.geometry,c,r.start,r.count,n),s=Li(t),o=Li(e.geometry),l=n?Li(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=Mi(e.geometry,n),s=Yi(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=Li(t),c=Li(e.geometry),u=r?Li(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:Gi(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 an(1024),cachedBoundsMin:new jd,cachedBoundsMax:new jd,cachedDrawBoundsCenter:new jd,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=Ci(e.geometry,o,a.start,a.count),u=Gi(t,e.geometry,o,a.start,s,r),d=Li(t),h=Li(e.geometry),p=r?Li(r):0,f=e.getBoundingSphereAt(n,A),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 jd,localBoundsRadius:f?.radius??1};l[n]=m,c[n]={template:m,boundsMin:new jd,boundsMax:new jd,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 an(1024),cachedDraws:[],cachedBoundsMin:new jd,cachedBoundsMax:new jd,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=gr(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=xi(e.textures,t.getTexturesList())&&wi(e.textureVersions,t.getTextureVersionsList())&&xi(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=gr(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:vi(t.visibility),buffer:{type:"read_write"===t.access?"storage":"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=yf,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 Gd&&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)))}for(const e of a.draws){if(e.customDepthMaterial||null===e.material.depthVertexShader||e.material.vertexAttributes.some(e=>"instance"===e.stepMode))continue;const t=`prepass-visible:${e.material.uuid}:${this.drawUsesBatching(e)}:${Oi(e)}`;n.has(t)||(n.add(t),i.push(this.getDepthPassMaterialResourceAsync(e.material,"prepass","packed-visible",!1,this.drawUsesBatching(e),Oi(e))))}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)}:${Oi(e)}`;n.has(r)||(n.add(r),i.push(this.getDepthPassMaterialResourceAsync(t,"directionalShadow","packed-visible",!1,this.drawUsesBatching(e),Oi(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=qd(`${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(;hh(e.charCodeAt(a));)a++;if("("!==e[a++])continue;for(;hh(e.charCodeAt(a));)a++;if(!e.startsWith("position",a))continue;for(a+=8;hh(e.charCodeAt(a));)a++;if(")"!==e[a++])continue;dh.lastIndex=a;const s=dh.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:b,NUM_SPOT_LIGHTS:y,NUM_DIR_LIGHT_SHADOWS:4,NUM_POINT_LIGHT_SHADOWS:b,NUM_SPOT_LIGHT_SHADOWS:y,NUM_CLIPPING_PLANES:0,UNION_CLIPPING_PLANES:0,USE_SKINNING:r,RENDERER_MOTION_VECTORS:!t.includes("shared-depth"),...this.createTexturePreprocessorDefines(e)};return e.side===Vd?n.DOUBLE_SIDED=!0:e.side===Dd&&(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===Oi(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=yf,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,Oi(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,Oi(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,Oi(r))}}getDepthPassMaterialResourceForDraw(e,t,r,i){return this.getDepthPassMaterialResource(e,t,i??this.getDrawInstanceAccessMode(r),null!==r.skinning,this.drawUsesBatching(r),Oi(r))}getDepthPassMaterialResourceAsyncForDraw(e,t,r){return this.getDepthPassMaterialResourceAsync(e,t,this.getDrawInstanceAccessMode(r),null!==r.skinning,this.drawUsesBatching(r),Oi(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:"packed-visible"===n?this.state.visibleDepthSceneBindGroupLayout: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=Uh(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:Cf(t),cullMode:Mf(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:"packed-visible"===n?this.state.visibleDepthSceneBindGroupLayout: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=Uh(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 Vf(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:Cf(t),cullMode:Mf(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=Gh(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:gf(x,s,ff(t))},primitive:{topology:Cf(t),cullMode:Cf(t).startsWith("triangle")&&t.side!==Vd?t.side===Dd?"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=Gh(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 Vf(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:gf(g,s,ff(t))},primitive:{topology:Cf(t),cullMode:Cf(t).startsWith("triangle")&&t.side!==Vd?t.side===Dd?"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??yf,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??yf,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,r){if(!this.state.device||!this.state.cameraBuffer)return;const i=this.cameraProjectionScratch.copy(e.projectionMatrix);r||0===this.projectionJitterPixels.x&&0===this.projectionJitterPixels.y||(i.elements[8]-=2*this.projectionJitterPixels.x/this.state.width,i.elements[9]-=2*this.projectionJitterPixels.y/this.state.height);const n=this.cameraViewProjScratch.copy(T).multiply(i).multiply(e.matrixWorldInverse);e.getWorldPosition(k);const a=this.cameraUniformScratch;a.set(n.elements,0),a[16]=k.x,a[17]=k.y,a[18]=k.z,a[19]=1,a[20]=r?.width??this.state.width,a[21]=r?.height??this.state.height,a[22]=r?1:this.state.pixelRatio,a[23]=this.state.frameTimeSeconds,a.set(e.matrixWorldInverse.elements,24),a.set(U.multiplyMatrices(T,i).elements,40),a[56]=e.near,a[57]=e.far,a[58]=1/Math.max(e.far-e.near,1e-4),a[59]=!r&&this.tiledLightingEnabled?1:0;const s=r?null:t.fog;null!=s?(a[60]=s.color.r,a[61]=s.color.g,a[62]=s.color.b,a[63]=1,"density"in s?(a[64]=0,a[65]=0,a[66]=s.density,a[67]=1):(a[64]=s.near,a[65]=s.far,a[66]=0,a[67]=0)):(a.fill(0,60,68),a[67]=-1);const o=!r&&this.motionVectorProjectionPending?this.motionVectorProjection:e.projectionMatrix,l=(r?R:this.motionVectorCurrentViewProj).copy(T).multiply(o).multiply(e.matrixWorldInverse);a.set(l.elements,68),a.set((!r&&this.motionVectorHistoryValid?this.motionVectorPreviousViewProj:l).elements,84),a[100]=!r&&this.motionVectorHistoryValid?1:0,a[101]=r?.width??this.state.width,a[102]=r?.height??this.state.height,a[103]=0,r||(this.motionVectorProjectionPending=!1),this.state.device.queue.writeBuffer(this.state.cameraBuffer,0,a,0,104)}updateTemporalVisibilityUniforms(e){if(!this.state.device||!this.state.temporalVisibilityBuffer)return;const t=Hi(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;const t=this.lightUniformScratch;null===this.sceneCaptureOptions&&this.updateSpotLightMapAtlas(e.lights.spots),t.fill(0),t[0]=e.lights.ambient.x,t[1]=e.lights.ambient.y,t[2]=e.lights.ambient.z,t[3]=e.lights.ambient.w,t[4]=e.lights.directionals.length,t[5]=e.lights.points.length,t[6]=e.lights.spots.length,t[7]=Math.min(this.csmCascadeCount,e.lights.directionals.length);for(let e=0;e<this.csmCascadeCount;e+=1){const r=this.csmCascadeRanges[e],i=3976+4*e;t[i+0]=r.x,t[i+1]=r.y}const r=e.lights.hemisphere;null!=r&&(t[3992]=r.skyColor.x,t[3993]=r.skyColor.y,t[3994]=r.skyColor.z,t[3995]=r.intensity,t[3996]=r.groundColor.x,t[3997]=r.groundColor.y,t[3998]=r.groundColor.z,t[3999]=r.intensity,t[4e3]=r.direction.x,t[4001]=r.direction.y,t[4002]=r.direction.z,t[4003]=1);for(let r=0;r<e.lights.directionals.length;r+=1){const i=e.lights.directionals[r],n=this.directionalShadowCameras[r],a=8+4*r;t[a+0]=i.direction.x,t[a+1]=i.direction.y,t[a+2]=i.direction.z,t[a+3]=1;const s=24+4*r;t[s+0]=i.color.x,t[s+1]=i.color.y,t[s+2]=i.color.z,t[s+3]=i.intensity;const o=40+4*r;t[o+0]=i.shadowBias,t[o+1]=i.castShadow?1:0,t[o+2]=this.state.directionalShadowTextureSize,t[o+3]=i.shadowNormalBias;const l=56+4*r;t[l+0]=i.shadowRadius,t[l+1]=i.shadowIntensity;const c=i.shadowViewProjection??=new Ud;t.set(Hi(n,c).elements,72+16*r)}for(let r=0;r<e.lights.points.length;r+=1){const i=e.lights.points[r],n=136+4*r;t[n+0]=i.position.x,t[n+1]=i.position.y,t[n+2]=i.position.z,t[n+3]=i.range;const a=392+4*r;t[a+0]=i.color.x,t[a+1]=i.color.y,t[a+2]=i.color.z,t[a+3]=i.intensity;const s=648+4*r;t[s+0]=i.distance,t[s+1]=i.decay;const o=904+4*r;t[o+0]=i.shadowBias,t[o+1]=i.castShadow?1:0,t[o+2]=this.state.pointShadowTextureSize,t[o+3]=i.shadowNormalBias;const l=1160+4*r;t[l+0]=i.shadowRadius,t[l+1]=i.shadowIntensity,t[l+2]=i.shadowCameraNear,t[l+3]=i.shadowCameraFar}for(let r=0;r<e.lights.spots.length;r+=1){const i=e.lights.spots[r],n=1416+4*r;t[n+0]=i.position.x,t[n+1]=i.position.y,t[n+2]=i.position.z,t[n+3]=i.range;const a=1672+4*r;t[a+0]=i.direction.x,t[a+1]=i.direction.y,t[a+2]=i.direction.z,t[a+3]=Math.cos(i.angle);const s=1928+4*r;t[s+0]=i.color.x,t[s+1]=i.color.y,t[s+2]=i.color.z,t[s+3]=i.intensity;const o=2184+4*r;t[o+0]=i.shadowBias,t[o+1]=i.castShadow?1:0,t[o+2]=this.state.spotShadowTextureSize,t[o+3]=i.shadowNormalBias;const l=2440+4*r;t[l+0]=i.shadowRadius,t[l+1]=i.shadowIntensity;const c=2696+4*r;if(t[c+0]=i.range,t[c+1]=Math.cos(i.angle*(1-i.penumbra)),t[c+2]=i.decay,t[c+3]=null!=i.map?1:0,i.castShadow||null!=i.map){const e=this.spotShadowCameras[r];e.near=i.shadowCameraNear,e.far=i.shadowCameraFar,e.fov=i.shadowCameraFov,e.aspect=1,e.position.copy(i.position),F.copy(i.position).add(i.direction),e.lookAt(F),e.updateMatrixWorld(!0),e.updateProjectionMatrix(),t.set(Hi(e,this.shadowViewProjScratch).elements,2952+16*r)}}this.state.device.queue.writeBuffer(this.state.lightBuffer,0,t,0,z)}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 Bf=[0,0],Tf=[0,0,1],If=[1,1,1,1];async function Vf(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,t)}finally{r&&i&&n&&r.pipelines.push({kind:i,material:n,durationMs:performance.now()-o,vertexCodeLength:a,fragmentCodeLength:s})}}import{DataTexture as zf,Matrix4 as Lf,RepeatWrapping as Gf}from"three";var Rf={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}}},Uf=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 zf(i,5,5);return n.wrapS=Gf,n.wrapT=Gf,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=_f(e)}get enabled(){return this.options.enabled}get temporalEnabled(){return!1!==this.options.temporal}setOptions(e){Object.assign(this.options,_f({...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(Rf[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 Af(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 kf(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 Ff(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 $f(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}},Af=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 Lf;webGpuProjectionInverse=new Lf;frameIndex=0;updateUniforms=e=>(this.webGpuProjection.copy(Ef).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)},kf=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=Of;uniforms=new Float32Array(this.uniformBufferSize/4);inverseProjection=new Lf;updateUniforms=e=>(this.inverseProjection.copy(Ef).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)},Ff=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 Lf;updateUniforms=e=>(this.webGpuProjectionInverse.copy(Ef).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)},$f=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"},Ef=(new Lf).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);var Of="\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 _f(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:Nf(e.resolutionScale??1,.25,1),thickness:Math.max(.001,e.thickness??1),distanceExponent:Math.max(.01,e.distanceExponent??1),distanceFalloff:Nf(e.distanceFalloff??1,0,1),directions:Wf(e.directions??3,1,8),steps:Wf(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:jf(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:Nf(e.temporal?.historyWeight??.9,0,.98),depthRejection:Nf(e.temporal?.depthRejection??.08,.001,1),neighborhoodClamp:e.temporal?.neighborhoodClamp??!0}}}function jf(e){return e<=4?4:e<=8?8:e<=12?12:16}function Nf(e,t,r){return Math.min(r,Math.max(t,e))}function Wf(e,t,r){return Math.floor(Nf(e,t,r))}import{Matrix4 as Hf}from"three";var qf=class{options;passes=new Map;constructor(e={}){this.options=em(e)}get enabled(){return this.options.enabled}get surfaceRaySteps(){return this.options.surfaceSteps}setOptions(e){const t=em({...this.options,...e});Object.keys(t).every(e=>t[e]===this.options[e])||(Object.assign(this.options,t),this.passes.clear())}addPasses(e,t){if(!this.enabled)return t.sceneColor;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 Kf(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 Zf(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 Yf(t.sceneColor,a,s,this.options.intensity),this.passes.set(o,l)),e.addFullscreenPass(l),s}},Kf=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 Hf;inverseProjection=new Hf;updateUniforms=e=>(this.projection.copy(Xf).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)},Zf=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}"},Yf=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 Xf=(new Hf).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);function Jf(e,t,r){return Math.min(r,Math.max(t,e))}function Qf(e,t,r){return Math.round(Jf(e,t,r))}function em(e){return{enabled:e.enabled??!0,surfaceSteps:Qf(e.surfaceSteps??0,0,32),resolutionScale:Jf(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:Jf(e.maxRoughness??.8,.01,1),steps:Qf(e.steps??2048,8,2048),pixelStride:Jf(e.pixelStride??1,1,4),normalSpace:e.normalSpace??"world",blur:e.blur??!0,blurRadius:Jf(e.blurRadius??6,1,12),targetPrefix:e.targetPrefix??"ssr"}}import{Matrix4 as tm,Vector2 as rm}from"three";var im=(new tm).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),nm=class{renderScale;sampleCount;minCurrentWeight;motionWeightScale;depthThreshold;relativeDepthThreshold;targetPrefix;writeIndex=0;historyValid=!1;frameIndex=0;renderWidth=1;renderHeight=1;outputWidth=1;outputHeight=1;jitter=new rm;unjitteredProjection=new tm;previousJitterUv=new rm;currentJitterUv=new rm;previousViewProjection=new tm;resolvePasses=new Map;constructor(e={}){this.renderScale=om(e.renderScale??1,.25,1),this.sampleCount=Math.max(1,Math.floor(e.sampleCount??32)),this.minCurrentWeight=om(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(sm(this.frameIndex%this.sampleCount+1,2)-.5,sm(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 am(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=om(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(im).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}},am=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 tm;currentViewProjectionInverse=new tm;updateUniforms=e=>(this.state.updateResolveUniforms(this.uniforms,this.currentViewProjection,this.currentViewProjectionInverse,e),this.uniforms)};function sm(e,t){let r=1,i=0;for(;e>0;)r/=t,i+=r*(e%t),e=Math.floor(e/t);return i}function om(e,t,r){return Math.min(r,Math.max(t,e))}var lm=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=um(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 cm(t,i,this),this.passes.set(n,a)),e.addFullscreenPass(a),i}},cm=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),um(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 um(e,t,r){return Math.min(r,Math.max(t,e))}import{ClampToEdgeWrapping as dm,DataTexture as hm,LinearFilter as pm,NoColorSpace as fm,RGFormat as mm,UnsignedByteType as gm}from"three";var vm={low:{searchSteps:4,diagonalSteps:0},medium:{searchSteps:8,diagonalSteps:0},high:{searchSteps:16,diagonalSteps:8},ultra:{searchSteps:32,diagonalSteps:16}},xm=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=Vm(e.cornerRounding??.25,0,1),this.sharpness=Vm(e.sharpness??0,0,1),this.quality=vm[e.quality??"high"],this.targetPrefix=e.targetPrefix??"smaa",this.areaTexture=function(){const e=new hm(function(){if(Sm)return Sm;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){Cm(e,16*n+r,16*a+t,Mm(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){Cm(e,80+20*s+r,20*o+t,Bm(i,r,t))}}return Sm=e,e}(),160,80,mm,gm);return e.name="SMAA-Area-Lookup",e.colorSpace=fm,e.minFilter=pm,e.magFilter=pm,e.wrapS=dm,e.wrapT=dm,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 wm(t,i,this),this.edgePasses.set(s,o));const l=`${i}:${n}`;let c=this.weightPasses.get(l);c||(c=new bm(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 ym(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}},wm=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"},bm=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,Vm(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"},ym=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([Vm(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 Sm=null;function Cm(e,t,r,i){const n=2*(160*r+t);e[n]=Math.floor(255*Vm(i[0],0,1)),e[n+1]=Math.floor(255*Vm(i[1],0,1))}function Mm(e,t,r){const i=t+r+1,n=.5,a=-.5,s=()=>Pm([0,a],[i/2,0],t),o=()=>Pm([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 Dm(i,s(),o());case 4:return t<=r?Pm([0,n],[i/2,0],t):[0,0];case 6:case 14:case 7:return Pm([0,n],[i,a],t);case 8:return t>=r?Pm([i/2,0],[i,n],t):[0,0];case 9:case 11:case 13:return Pm([0,a],[i,n],t);case 12:return Dm(i,Pm([0,n],[i/2,0],t),Pm([i/2,0],[i,n],t))}}function Pm(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 Dm(e,t,r){const i=e=>[.5*Math.sqrt(2*e[0]),.5*Math.sqrt(2*e[1])],n=Vm(e/32,0,1),a=i(t),s=i(r);return[Im(a[0],t[0],n)+Im(s[0],r[0],n),Im(a[1],t[1],n)+Im(s[1],r[1],n)]}function Bm(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 Tm(o(1,1),o(0,0));case 1:return Tm(s([1,0],[i,i]),o(0,0));case 2:return Tm(s([0,0],[1+i,i]),o(0,0));case 3:return o(0,0);case 4:return Tm(s([1,1],[i,i]),s([1,1],[1+i,i]));case 5:return Tm(s([1,1],[i,i]),o(0,0));case 6:return s([1,1],[1+i,i]);case 7:return Tm(s([1,1],[1+i,i]),o(0,0));case 8:return Tm(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 Tm(s([0,0],[1+i,1+i]),o(0,0));case 11:return Tm(s([1,0],[1+i,1+i]),o(0,0));case 12:return s([1,1],[1+i,1+i]);case 13:return Tm(s([1,1],[1+i,1+i]),s([1,0],[1+i,1+i]));case 14:return Tm(s([1,1],[1+i,1+i]),s([1,1],[1+i,i]));case 15:return Tm(s([1,1],[1+i,1+i]),o(0,0));default:return[0,0]}}function Tm(e,t){return[.5*(e[0]+t[0]),.5*(e[1]+t[1])]}function Im(e,t,r){return e+(t-e)*r}function Vm(e,t,r){return Math.min(r,Math.max(t,e))}var zm=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=Um(e.radius??.2,0,1),this.levels=(t=e.levels??5,r=1,i=5,Math.floor(Um(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 Lm(o,a,this):new Gm(`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 Gm(`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 Rm(t,s,a,this,this.levels),this.passes.set(o,l)),e.addFullscreenPass(l),a}},Lm=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}"},Gm=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},Rm=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,Um(this.state.radius,0,1),0,0]),this.uniforms);fragmentShader};function Um(e,t,r){return Math.min(r,Math.max(t,e))}var Am=[1,1,1],km=[0,0,0],Fm=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 $m(t,r,this.options),this.passes.set(i,n)),e.addFullscreenPass(n),r}},$m=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,Am),t(e?.contrast,Am),t(e?.gamma,Am),t(e?.gain,Am),t(e?.offset,km)};return t(this.state.whiteBalance,Am),t(this.state.tint,Am),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 Em}from"three";var Om=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 _m(t,r,i,this.options),this.passes.set(n,a)),e.addFullscreenPass(a),i}},_m=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 Em;updateUniforms=e=>(this.inverseProjection.copy(jm).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); }"},jm=(new Em).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);import{Matrix4 as Nm,Vector2 as Wm,Vector3 as Hm}from"three";var qm=(new Nm).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),Km=(e=>(e[e.Disabled=0]="Disabled",e[e.CameraOnly=1]="CameraOnly",e[e.ObjectAndCamera=2]="ObjectAndCamera",e[e.ForceObjectBlur=3]="ForceObjectBlur",e))(Km||{}),Zm={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}},Ym=class{options;targetPrefix;currentViewProjection=new Nm;currentInverseViewProjection=new Nm;currentInverseProjection=new Nm;previousViewProjection=new Nm;pendingViewProjection=new Nm;previousProjection=new Nm;previousCameraWorld=new Nm;previousCameraPosition=new Hm;currentCameraPosition=new Hm;currentJitterUv=new Wm;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:Jm(e.sampleCount??8),shutterScale:Qm(e.shutterScale??.75,0,4),maxBlurPixels:Qm(e.maxBlurPixels??18,0,128),cameraBlurScale:Qm(e.cameraBlurScale??.1,0,4),objectBlurScale:Qm(e.objectBlurScale??1,0,8),depthRejectionStrength:Qm(e.depthRejectionStrength??24,0,200),velocityThresholdPixels:Qm(e.velocityThresholdPixels??.6,0,16),dilation:e.dilation??!0,debugVelocity:e.debugVelocity??!1,targetFrameRate:Qm(e.targetFrameRate??60,15,240),maxFrameTime:Qm(e.maxFrameTime??.1,1/240,1),cameraCutDistance:Qm(e.cameraCutDistance??8,0,1e3),cameraCutRotationThreshold:Qm(e.cameraCutRotationThreshold??.75,0,2),projectionCutThreshold:Qm(e.projectionCutThreshold??.25,0,4)},this.targetPrefix=e.targetPrefix??"motionBlur"}applyPreset(e){Object.assign(this.options,Zm[e]),this.options.sampleCount=Jm(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(qm).multiply(e.projectionMatrix).multiply(e.matrixWorldInverse),this.currentViewProjection.copy(this.pendingViewProjection),this.currentInverseViewProjection.copy(this.currentViewProjection).invert(),this.currentInverseProjection.copy(qm).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=Jm(n.sampleCount),o=`${t}:${r}:${i}:${a}:${s}`;let l=this.passes.get(o);return l||(l=new Xm(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,Jm(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}},Xm=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 Jm(e){return e<=0?0:e<=4?4:e<=8?8:e<=12?12:16}function Qm(e,t,r){return Math.min(r,Math.max(t,e))}var eg=class{enabled;visibleEdgeColor;edgeStrength;edgeThickness;edgeSoftness;selectedObjects=new Set;selectionMembers=new Set;addSelectionMember=e=>{this.selectionMembers.add(e)};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=tg(!1),this.skinnedMaskMaterial=tg(!0)}setSelectedObjects(e){this.selectionMembers.clear(),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.selectionMembers;i.clear();for(const e of this.selectedObjects)i.has(e)||e.traverse(this.addSelectionMember);e.addMaterialPass({name:"OutlineMask",outputs:r,clearColor:[0,0,0,0],loadDepth:!0,objectFilter:e=>null!==e&&i.has(e),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=[tg(!1,i.instanceIndex),tg(!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 rg(r,n,this)),this.addCachedPass(e,`blur-h:${n}:${a}`,()=>new ig("OutlineBlurHorizontal",n,a,!0,this)),this.addCachedPass(e,`blur-v:${a}:${s}`,()=>new ig("OutlineBlurVertical",a,s,!1,this)),this.addCachedPass(e,`composite:${t}:${s}:${o}`,()=>new ng(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.selectionMembers.clear(),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 tg(e,t=-1){return new ei({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 rg=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}"},ig=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}"},ng=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 ag,BackSide as sg,Bone as og,BatchedMesh as lg,BoxGeometry as cg,BufferAttribute as ug,BufferGeometry as dg,CanvasTexture as hg,Color as pg,CompressedArrayTexture as fg,CompressedArrayTexture as mg,CompressedCubeTexture as gg,CompressedTexture as vg,CubeTexture as xg,Data3DTexture as wg,DataArrayTexture as bg,DataTexture as yg,DepthTexture as Sg,DirectionalLight as Cg,DoubleSide as Mg,FrontSide as Pg,Group as Dg,HemisphereLight as Bg,InstancedMesh as Tg,MathUtils as Ig,Matrix4 as Vg,Mesh as zg,Object3D as Lg,OrthographicCamera as Gg,PerspectiveCamera as Rg,PlaneGeometry as Ug,PointLight as Ag,RepeatWrapping as kg,Scene as Fg,Skeleton as $g,SkinnedMesh as Eg,SphereGeometry as Og,SpotLight as _g,Texture as jg,Vector2 as Ng,Vector3 as Wg,Vector4 as Hg}from"three";export{ag as AmbientLight,sg as BackSide,lg as BatchedMesh,zm as BloomEffect,og as Bone,cg as BoxGeometry,ug as BufferAttribute,dg as BufferGeometry,hg as CanvasTexture,pg as Color,Fm as ColorGradingEffect,fg as CompressedArrayTexture,gg as CompressedCubeTexture,vg as CompressedTexture,mg as CompressedTextureArray,N as ComputeKernel,xg as CubeTexture,Qr as DEFAULT_WGSL_VERTEX_ATTRIBUTES,wg as Data3DTexture,bg as DataArrayTexture,yg as DataTexture,Om as DepthOfFieldEffect,Sg as DepthTexture,Cg as DirectionalLight,Mg as DoubleSide,lm as FXAAEffect,Rr as FrameGraphBuilder,Pg as FrontSide,Uf as GTAOEffect,Rf as GTAO_PRESETS,Dg as Group,Bg as HemisphereLight,Tg as InstancedMesh,Zm as MOTION_BLUR_PRESETS,Ig as MathUtils,Vg as Matrix4,zg as Mesh,Ym as MotionBlurEffect,Km as MotionBlurMode,Lg as Object3D,Gg as OrthographicCamera,eg as OutlineEffect,Rg as PerspectiveCamera,Ug as PlaneGeometry,Ag as PointLight,ph as RenderGraph,kg as RepeatWrapping,D as SCENE_COLOR_FORMAT,pe as SDFGI,ge as SDFGISurfaceCapture,xm as SMAAEffect,qf as SSREffect,Fg as Scene,$g as Skeleton,Eg as SkinnedMesh,Og as SphereGeometry,_g as SpotLight,nm as TemporalAAEffect,jg as Texture,_e as VOLUMETRIC_FOG_MATERIAL_WGSL,De as VOLUMETRIC_FOG_PRESETS,Ng as Vector2,Wg as Vector3,Hg as Vector4,Ue as VolumetricFogEffect,Pe as VolumetricFogVolumeObject,ei as WGSLShaderMaterial,Ch as WebGpuPMREMGenerator,Df as WebGpuRenderer,Rh as buildParticleLightingShaderHeader,je as configureVolumetricFogMaterial,j as createComputePipelineAsync,_ as createRenderPipelineAsync,r as registerPipelineDiagnosticOrigin,f as resolveDetailCulling,d as setObjectDetailCulling,t as setPipelineDiagnosticLoading};
|