@hology/webgpu-renderer 0.1.6 → 0.1.8
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 +61 -5
- package/dist/index.js +1 -1
- package/package.json +42 -42
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=class{layout;pipeline;constructor(e,t){this.layout=e.createBindGroupLayout({label:t.label?`${t.label}-layout`:void 0,entries:t.bindGroupLayoutEntries});const r=e.createPipelineLayout({label:t.label?`${t.label}-pipeline-layout`:void 0,bindGroupLayouts:[this.layout]});this.pipeline=e.createComputePipeline({label:t.label,layout:r,compute:{module:e.createShaderModule({label:t.label?`${t.label}-module`:void 0,code:t.code}),entryPoint:t.entryPoint??"main"}})}createBindGroup(e,t,r){return e.createBindGroup({label:r,layout:this.layout,entries:t})}};import{Color as t,DirectionalLight as r,Matrix4 as i,Object3D as n,PointLight as a,Scene as s,SpotLight as o,Vector3 as l}from"three";var c=class extends n{constructor(e){super(),this.volume=e}volume;isFogVolumeObject=!0},u={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:48,integrationSubsteps:1,shadowFilterTaps:1,temporalJitter:!0,temporal:{historyWeight:.94,depthRejection:.04,neighborhoodClamp:!0},blur:{scale:.5,radius:3,depthSigma:.05,spatialSigma:2,depthAwareUpsample:!0}}},d=16,h=(new i).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),p=new l,f=new l,m=new l,g=class{constructor(e=new s,t={}){this.scene=e,this.options=v(t),this.integratedVolume=`${this.options.targetPrefix}Integrated`,this.columnDepthBounds=`${this.options.targetPrefix}DepthBounds`,this.volumeData=new Float32Array(20*this.options.maxVolumes);const r=this.options.maxDirectionalLights+this.options.maxPointLights+this.options.maxSpotLights;this.lightData=new Float32Array(r*d)}scene;integratedVolume;columnDepthBounds;options;resources=new WeakMap;uniformStorage=new ArrayBuffer(160);uniforms=new Float32Array(this.uniformStorage);uniformIntegers=new Uint32Array(this.uniformStorage);volumeData;lightData;projectionInverse=new i;viewProjectionInverse=new i;previousTemporalViewProjection=new i;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=v({...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(u[e])}reset(){this.frameIndex=0,this.temporalWriteIndex=0,this.temporalHistoryValid=!1,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}),e.addPass({name:"VolumetricFogFroxelPass",inputs:{sceneDepth:t.depth},outputs:[this.integratedVolume,this.columnDepthBounds],execute:e=>this.executeFroxels(e)});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 x(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 w(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=this.addTemporalPass(e,t,n,i.scale);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 y(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 S(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 b(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(h).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),e.set([i.historyWeight,i.depthRejection,i.neighborhoodClamp?1:0,a?1:0],32),this.previousTemporalViewProjection.copy(t)}dispose(){this.compositePass=null,this.blurPassCache.clear(),this.temporalPassCache.clear()}executeFroxels(e){const t=this.getResources(e.device),r=this.collectSceneData(e.camera),i=Math.max(.01,e.camera.near),n=Math.max(i+.01,Math.min(e.camera.far,this.options.maxDistance)),a=Math.max(1,Math.floor(e.width/this.options.froxelPixelSize)),s=Math.max(1,Math.floor(e.height/this.options.froxelPixelSize));this.viewProjectionInverse.copy(h).multiply(e.camera.projectionMatrix).multiply(e.camera.matrixWorldInverse).invert(),this.uniforms.set(this.viewProjectionInverse.elements,0),this.uniforms.set(e.camera.position.toArray(),16),this.uniforms.set([i],19),this.uniforms.set([a,s,this.options.depthSlices,n],20),this.uniformIntegers.set([r.volumes,r.directional,r.point,r.spot],24),this.uniforms.set([this.options.ambientColor.r,this.options.ambientColor.g,this.options.ambientColor.b,this.options.temporalJitter?this.frameIndex++%1024+1:0],28),e.camera.getWorldDirection(f),this.uniforms.set([f.x,f.y,f.z,Math.max(e.camera.far-i,1e-4)],32),this.uniforms.set([this.options.scatteringIntensity,this.options.spatialJitter?1:0,0,0],36),e.device.queue.writeBuffer(t.uniformBuffer,0,this.uniforms),e.device.queue.writeBuffer(t.volumeBuffer,0,this.volumeData.buffer,this.volumeData.byteOffset,this.volumeData.byteLength),e.device.queue.writeBuffer(t.lightBuffer,0,this.lightData.buffer,this.lightData.byteOffset,this.lightData.byteLength);const o=e.getSceneLightingResources(),l=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:e.getTextureView(this.integratedVolume)},{binding:4,resource:{buffer:o.lightBuffer}},{binding:5,resource:e.comparisonSampler},{binding:6,resource:o.directionalShadowView},{binding:7,resource:o.pointShadowView},{binding:8,resource:o.spotShadowView},{binding:9,resource:e.depthView},{binding:10,resource:e.getTextureView(this.columnDepthBounds)}]}),c=e.encoder.beginComputePass({label:"VolumetricFogFroxelPass"});c.setPipeline(t.pipeline),c.setBindGroup(0,l),c.dispatchWorkgroups(Math.ceil(a/8),Math.ceil(s/8)),c.end()}collectSceneData(e){this.volumeData.fill(0),this.lightData.fill(0);const t=[...this.explicitVolumes],i=[];for(const t of this.cascadeDirectionalLights)t.visible&&t.layers.test(e.layers)&&!i.includes(t)&&i.push(t);const n=[],s=[],l=e=>{const r=e;r.isFogVolumeObject&&r.volume&&!t.includes(r.volume)&&t.push(r.volume)};if(void 0===this.volumeObjects)this.scene.traverseVisible(l);else for(const e of this.volumeObjects)l(e);void 0===this.extractedLights&&this.scene.traverseVisible(t=>{t instanceof r&&t.layers.test(e.layers)&&!i.includes(t)?i.push(t):t instanceof a&&t.layers.test(e.layers)?n.push(t):t instanceof o&&t.layers.test(e.layers)&&s.push(t)});const c=Math.min(t.length,this.options.maxVolumes);for(let e=0;e<c;e++)this.writeVolume(e,t[e]);const u=Math.min(this.extractedLights?.directionals.length??i.length,this.options.maxDirectionalLights),d=Math.min(this.extractedLights?.points.length??n.length,this.options.maxPointLights),h=Math.min(this.extractedLights?.spots.length??s.length,this.options.maxSpotLights);let p=0;for(let e=0;e<u;e++){const t=this.extractedLights?.directionals[e];t?this.writeExtractedDirectional(p++,t):this.writeDirectional(p++,i[e])}for(let e=0;e<d;e++){const t=this.extractedLights?.points[e];t?this.writeExtractedPoint(p++,t):this.writePoint(p++,n[e])}for(let e=0;e<h;e++){const t=this.extractedLights?.spots[e];t?this.writeExtractedSpot(p++,t):this.writeSpot(p++,s[e])}return{volumes:c,directional:u,point:d,spot:h}}writeVolume(e,t){const r=20*e;t.object.getWorldPosition(p),t.object.getWorldScale(m),this.volumeData.set([p.x,p.y,p.z,5*Math.max(m.x,m.y,m.z)],r),this.volumeData.set([t.albedo.r,t.albedo.g,t.albedo.b,Math.max(0,t.baseDensity)],r+4),this.volumeData.set([t.heightFalloff,t.heightOffset,t.startDistance??3,-Math.max(-.99,Math.min(.99,t.scatteringDistribution))],r+8),this.volumeData.set([t.emissive.r,t.emissive.g,t.emissive.b,t.ambientIntensity??1],r+12),this.volumeData[r+16]="lightShaft"===t.scatteringMode?1:0}lightColor(e){const t=e.intensity*(e.userData?.volumetricIntensity??1);return[e.color.r*t,e.color.g*t,e.color.b*t]}writeDirectional(e,t){const r=e*d;t.getWorldPosition(p),t.target.getWorldPosition(f),f.sub(p).normalize(),this.lightData.set([f.x,f.y,f.z,0],r),this.lightData.set([...this.lightColor(t),0],r+4)}writeExtractedDirectional(e,t){const r=e*d;this.lightData.set([t.direction.x,t.direction.y,t.direction.z,0],r);const i=t.intensity*t.volumetricIntensity;this.lightData.set([t.color.x*i,t.color.y*i,t.color.z*i,0],r+4)}writePoint(e,t){const r=e*d;t.getWorldPosition(p),this.lightData.set([p.x,p.y,p.z,Math.max(.001,t.distance||this.options.maxDistance)],r),this.lightData.set([...this.lightColor(t),Math.max(0,t.decay)],r+4)}writeExtractedPoint(e,t){const r=e*d;this.lightData.set([t.position.x,t.position.y,t.position.z,Math.max(.001,t.range||this.options.maxDistance)],r);const i=t.intensity*t.volumetricIntensity;this.lightData.set([t.color.x*i,t.color.y*i,t.color.z*i,Math.max(0,t.decay)],r+4)}writeSpot(e,t){const r=e*d;t.getWorldPosition(p),t.target.getWorldPosition(f),f.sub(p).normalize(),this.lightData.set([p.x,p.y,p.z,Math.max(.001,t.distance||this.options.maxDistance)],r),this.lightData.set([...this.lightColor(t),Math.max(0,t.decay)],r+4),this.lightData.set([f.x,f.y,f.z,Math.cos(t.angle)],r+8),this.lightData[r+12]=Math.cos(t.angle*(1-t.penumbra))}writeExtractedSpot(e,t){const r=e*d;this.lightData.set([t.position.x,t.position.y,t.position.z,Math.max(.001,t.range||this.options.maxDistance)],r);const i=t.intensity*t.volumetricIntensity;this.lightData.set([t.color.x*i,t.color.y*i,t.color.z*i,Math.max(0,t.decay)],r+4),this.lightData.set([t.direction.x,t.direction.y,t.direction.z,Math.cos(t.angle)],r+8),this.lightData[r+12]=Math.cos(t.angle*(1-t.penumbra))}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:160,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"}}]}),l=e.createShaderModule({label:"volumetric-fog-compute",code:M.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 v(e){return{enabled:e.enabled??!0,froxelPixelSize:Math.max(2,Math.floor(e.froxelPixelSize??8)),depthSlices:Math.max(8,Math.floor(e.depthSlices??48)),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 t(.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 x=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=B;data=new Float32Array(20);inverseProjection=new i;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(h).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),this.data.set([Math.max(.01,e.camera.near),Math.min(e.camera.far,this.maxDistance),this.frameIndex>0?this.frameIndex%1024:-1,this.ditherStrength],16),this.data)},w=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=D;data=new Float32Array(20);inverseProjection=new i;frameIndex=0;setFrameIndex(e){this.frameIndex=e}updateUniforms=e=>(this.inverseProjection.copy(h).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),this.data.set([Math.max(.01,e.camera.near),Math.min(e.camera.far,this.maxDistance),this.frameIndex>0?this.frameIndex%1024:-1,this.ditherStrength],16),this.data)},b=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 i;currentViewProjectionInverse=new i;updateUniforms=e=>(this.state.updateTemporalUniforms(this.uniforms,this.currentViewProjection,this.currentViewProjectionInverse,this.temporal,e),this.uniforms.set([e.camera.position.x,e.camera.position.y,e.camera.position.z,e.camera.far],36),this.uniforms)},y=class{name;sampler="linear";uniformBufferSize=80;inputs;outputs;fragmentShader;data=new Float32Array(20);inverseProjection=new i;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(h).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),this.data)},S=class{name="VolumetricFogBlurCompositePass";sampler="linear";uniformBufferSize=64;inputs;inputDimensions={fogVolume:"3d"};outputs;fragmentShader;data=new Float32Array(16);inverseProjection=new i;constructor(e,t,r,i,n,a,s){this.inputs=s?{sceneColor:e,sceneDepth:t,fogInput:r,fogVolume:i,fogBounds:n}:{sceneColor:e,fogInput:r},this.outputs=a,this.fragmentShader=s?T:I}updateUniforms=e=>(this.inverseProjection.copy(h).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements),this.data)},C="\nfn rendererSampleIntegratedFog(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 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((distance - bounds.x) / max(bounds.y - bounds.x, 0.001), 0.0, 1.0);\n let fog = rendererSampleIntegratedFog(uv, z);\n return vec4<f32>(fog.rgb + color.rgb * fog.a, color.a);\n}";function P(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 M="\nstruct FogUniforms { inverseViewProjection: mat4x4<f32>, cameraNear: vec4<f32>, dimensionsFar: vec4<f32>, counts: vec4<u32>, ambient: vec4<f32>, cameraForwardDepthRange: vec4<f32>, scattering: 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>,4>, pointColorIntensities: array<vec4<f32>,4>, pointShadowParams: array<vec4<f32>,4>, pointShadowParams2: array<vec4<f32>,4>,\n spotPositionRanges: array<vec4<f32>,4>, spotDirectionCones: array<vec4<f32>,4>, spotColorIntensities: array<vec4<f32>,4>,\n spotShadowParams: array<vec4<f32>,4>, spotShadowParams2: array<vec4<f32>,4>, spotParams: array<vec4<f32>,4>, spotShadowMatrices: array<mat4x4<f32>,4>,\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>;\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 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 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 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 let temporal=select(vec2<f32>(0.5),vec2<f32>(hash12(vec2<f32>(id.xy)+uniforms.ambient.w),hash12(vec2<f32>(id.yx)+uniforms.ambient.w+19.19)),uniforms.ambient.w>0.0);\n let rayJitter=hash12(vec2<f32>(id.xy)+vec2<f32>(uniforms.ambient.w*0.754877,uniforms.ambient.w*0.569841));\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 nearPlane = uniforms.cameraNear.w; let farPlane = uniforms.dimensionsFar.w;\n let depthSize=textureDimensions(sceneDepth);\n let cellMin=id.xy*depthSize/dims.xy;\n let cellEnd=((id.xy+vec2<u32>(1u))*depthSize+dims.xy-vec2<u32>(1u))/dims.xy;\n let cellMax=min(cellEnd-vec2<u32>(1u),depthSize-vec2<u32>(1u));\n let cellCenter=(cellMin+cellMax)/vec2<u32>(2u);var columnFar=max(sceneDistanceAt(cellCenter),max(max(sceneDistanceAt(cellMin),sceneDistanceAt(vec2<u32>(cellMax.x,cellMin.y))),max(sceneDistanceAt(vec2<u32>(cellMin.x,cellMax.y)),sceneDistanceAt(cellMax))));\n columnFar=clamp(columnFar,nearPlane,farPlane);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,columnFar);columnFar=max(columnFar,columnNear+0.001);textureStore(outputDepthBounds,vec2<i32>(id.xy),vec4<f32>(columnNear,columnFar,0.0,0.0));\n var previousDirectionalVisibility=array<f32,4>(1.0,1.0,1.0,1.0);var hasPreviousDirectionalVisibility=false;\n var transmittance = 1.0; var scattering = vec3<f32>(0.0); var previousDistance = columnNear;\n for (var z=0u; z<dims.z; z+=1u) {\n let sliceEnd = mix(columnNear,columnFar,f32(z+1u)/f32(dims.z)); let stepSize = sliceEnd-previousDistance;\n let substepSize=stepSize/f32(INTEGRATION_SUBSTEPS);\n for(var substep=0;substep<INTEGRATION_SUBSTEPS;substep+=1){\n // Share one stratified offset across all intervals on a ray. This turns\n // coherent Z terraces into stationary spatial error that blur can remove.\n let sampleOffset=select(0.5,rayJitter,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 // Directional visibility belongs to the integration interval endpoints.\n // Reusing the preceding endpoint gives trapezoidal shadow integration\n // with one new lookup per interval, instead of quantizing a whole slice\n // from a midpoint visibility sample.\n let shadowDistance=previousDistance+(f32(substep)+1.0)*substepSize;\n let shadowP=camera+ray*shadowDistance;\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));}let current=directionalVisibility(d,shadowP)*cascadeWeight;filteredDirectionalVisibility[d]=select(current,0.5*(previousDirectionalVisibility[d]+current),hasPreviousDirectionalVisibility);previousDirectionalVisibility[d]=current;}\n hasPreviousDirectionalVisibility=true;\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 li=0u;\n for (var d=0u; d<uniforms.counts.y; d+=1u) {\n let l=lights[li]; li+=1u;\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)*pointVisibility(q,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=smoothstep(l.directionCone.w,l.penumbra.x,cd); direct += l.colorDecay.rgb*attenuation(dist,l.positionRange.w,l.colorDecay.w)*cone*phaseHG(dot(ray,normalize(delta)),volume.heightStartPhase.w)*spotVisibility(s,p); }\n direct*=uniforms.scattering.x;\n if (volume.mode.x < 0.5) { lighting += direct; } else { lighting = direct; }\n sigma += density; source += lighting*volume.albedoDensity.rgb*density;\n }\n }\n if (sigma > 0.000001) { let extinction=exp(-sigma*substepSize); scattering += transmittance*source*((1.0-extinction)/sigma); transmittance*=extinction; }\n }\n textureStore(outputFog, vec3<i32>(i32(id.x),i32(id.y),i32(z)), vec4<f32>(scattering,transmittance)); previousDistance=sliceEnd;\n }\n}",B="\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 sampleIntegratedFog(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}\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((distance-bounds.x)/max(bounds.y-bounds.x,0.001),0.0,1.0);\n let frame=fullscreenUniforms[4].z; let ditherStrength=fullscreenUniforms[4].w;\n // Half a slice of stochastic Z movement hides integration-layer contours;\n // the RGB term removes display-quantization bands. Both converge under TAA.\n let sliceCount=f32(textureDimensions(fogVolumeTexture).z); let noise=fogDither(input.position.xy,max(frame,0.0));\n let zJitter=select(0.0,noise/max(sliceCount,1.0),frame>=0.0);\n let fog=sampleIntegratedFog(input.uv,z+zJitter);\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}",D="\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 sampleIntegratedFog(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}\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((distance-bounds.x)/max(bounds.y-bounds.x,0.001),0.0,1.0); let frame=fullscreenUniforms[4].z; let noise=fogDither(input.position.xy,max(frame,0.0));\n let slices=f32(textureDimensions(fogVolumeTexture).z); let zJitter=select(0.0,noise/max(slices,1.0),frame>=0.0); var fog=sampleIntegratedFog(input.uv,z+zJitter);\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 T="\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);}\nfn inverseProjection()->mat4x4<f32>{return mat4x4<f32>(fullscreenUniforms[0],fullscreenUniforms[1],fullscreenUniforms[2],fullscreenUniforms[3]);}\nfn viewDistance(uv:vec2<f32>)->f32{let depth=loadDepth(uv);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);}\nfn sampleIntegratedFog(uv:vec2<f32>,normalizedDepth:f32)->vec4<f32>{let slices=f32(textureDimensions(fogVolumeTexture).z);let slicePosition=clamp(normalizedDepth,0.0,1.0)*slices;let textureZ=clamp((slicePosition-0.5)/slices,0.0,1.0);let integrated=textureSampleLevel(fogVolumeTexture,fullscreenSampler,vec3<f32>(uv,textureZ),0.0);return mix(vec4<f32>(0.0,0.0,0.0,1.0),integrated,min(slicePosition,1.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 centerDistance=max(viewDistance(input.uv),0.0001);var bestUv=clamp(candidates[0],vec2<f32>(0.0),vec2<f32>(1.0));var bestDifference=abs(log(max(viewDistance(bestUv),0.0001)/centerDistance));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(log(max(viewDistance(uv),0.0001)/centerDistance));maxDifference=max(maxDifference,difference);if(difference<bestDifference){bestDifference=difference;bestUv=uv;}}\n let blurredUv=select(bestUv,input.uv,maxDifference<0.02);let blurredFog=textureSampleLevel(fogInputTexture,fullscreenSampler,blurredUv,0.0);let bounds=textureSampleLevel(fogBoundsTexture,fullscreenSampler,input.uv,0.0).rg;let z=clamp((centerDistance-bounds.x)/max(bounds.y-bounds.x,0.001),0.0,1.0);let directFog=sampleIntegratedFog(input.uv,z);let fog=select(directFog,blurredFog,bestDifference<0.02);return vec4<f32>(fog.rgb+color.rgb*fog.a,color.a);\n}",I="\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 R,DepthFormat as G,DepthStencilFormat as V,FloatType as z,HalfFloatType as U,IntType as L,RED_GREEN_RGTC2_Format as A,RED_RGTC1_Format as F,RGBA_ASTC_10x10_Format as E,RGBA_ASTC_10x5_Format as k,RGBA_ASTC_10x6_Format as O,RGBA_ASTC_10x8_Format as j,RGBA_ASTC_12x10_Format as $,RGBA_ASTC_12x12_Format as N,RGBA_ASTC_4x4_Format as W,RGBA_ASTC_5x4_Format as _,RGBA_ASTC_5x5_Format as H,RGBA_ASTC_6x5_Format as q,RGBA_ASTC_6x6_Format as K,RGBA_ASTC_8x5_Format as Z,RGBA_ASTC_8x6_Format as Y,RGBA_ASTC_8x8_Format as X,RGBA_BPTC_Format as J,RGBA_ETC2_EAC_Format as Q,RGBA_S3TC_DXT1_Format as ee,RGBA_S3TC_DXT3_Format as te,RGBA_S3TC_DXT5_Format as re,RGBAFormat as ie,RGBAIntegerFormat as ne,RGFormat as ae,RGIntegerFormat as se,RGB_ETC1_Format as oe,RGB_ETC2_Format as le,RGB_S3TC_DXT1_Format as ce,RGBFormat as ue,RedFormat as de,RedIntegerFormat as he,ShortType as pe,SIGNED_RED_GREEN_RGTC2_Format as fe,SIGNED_RED_RGTC1_Format as me,SRGBColorSpace as ge,UnsignedByteType as ve,UnsignedInt248Type as xe,UnsignedInt5999Type as we,UnsignedIntType as be,UnsignedShortType as ye}from"three";function Se(e,t){const r=De(e),i=function(e,t){const r=e.format,i=e.type,n=e.colorSpace===ge;let a=null;if(Te(e))switch(r){case ce:case ee:a=n?"bc1-rgba-unorm-srgb":"bc1-rgba-unorm";break;case te:a=n?"bc2-rgba-unorm-srgb":"bc2-rgba-unorm";break;case re:a=n?"bc3-rgba-unorm-srgb":"bc3-rgba-unorm";break;case F:a="bc4-r-unorm";break;case me:a="bc4-r-snorm";break;case A:a="bc5-rg-unorm";break;case fe:a="bc5-rg-snorm";break;case J:a=n?"bc7-rgba-unorm-srgb":"bc7-rgba-unorm";break;case le:case oe:a=n?"etc2-rgb8unorm-srgb":"etc2-rgb8unorm";break;case Q:a=n?"etc2-rgba8unorm-srgb":"etc2-rgba8unorm";break;case W:a=n?"astc-4x4-unorm-srgb":"astc-4x4-unorm";break;case _:a=n?"astc-5x4-unorm-srgb":"astc-5x4-unorm";break;case H:a=n?"astc-5x5-unorm-srgb":"astc-5x5-unorm";break;case q:a=n?"astc-6x5-unorm-srgb":"astc-6x5-unorm";break;case K:a=n?"astc-6x6-unorm-srgb":"astc-6x6-unorm";break;case Z:a=n?"astc-8x5-unorm-srgb":"astc-8x5-unorm";break;case Y:a=n?"astc-8x6-unorm-srgb":"astc-8x6-unorm";break;case X:a=n?"astc-8x8-unorm-srgb":"astc-8x8-unorm";break;case k:a=n?"astc-10x5-unorm-srgb":"astc-10x5-unorm";break;case O:a=n?"astc-10x6-unorm-srgb":"astc-10x6-unorm";break;case j:a=n?"astc-10x8-unorm-srgb":"astc-10x8-unorm";break;case E:a=n?"astc-10x10-unorm-srgb":"astc-10x10-unorm";break;case $:a=n?"astc-12x10-unorm-srgb":"astc-12x10-unorm";break;case N:a=n?"astc-12x12-unorm-srgb":"astc-12x12-unorm";break;case ie:a=n?"rgba8unorm-srgb":"rgba8unorm"}else switch(r){case ie:switch(i){case R:a="rgba8snorm";break;case pe:a="rgba16sint";break;case ye:a="rgba16uint";break;case be:a="rgba32uint";break;case L:a="rgba32sint";break;case ve:a=n?"rgba8unorm-srgb":"rgba8unorm";break;case U:a="rgba16float";break;case z:a="rgba32float"}break;case ue:switch(i){case we:a="rgb9e5ufloat";break;case 35899:a="rg11b10ufloat"}break;case de:switch(i){case R:a="r8snorm";break;case pe:a="r16sint";break;case ye:a="r16uint";break;case be:a="r32uint";break;case L:a="r32sint";break;case ve:a="r8unorm";break;case U:a="r16float";break;case z:a="r32float"}break;case ae:switch(i){case R:a="rg8snorm";break;case pe:a="rg16sint";break;case ye:a="rg16uint";break;case be:a="rg32uint";break;case L:a="rg32sint";break;case ve:a="rg8unorm";break;case U:a="rg16float";break;case z:a="rg32float"}break;case G:switch(i){case ye:a="depth16unorm";break;case be:a="depth24plus";break;case z:a="depth32float"}break;case V:switch(i){case xe:a="depth24plus-stencil8";break;case z:Ie("depth32float-stencil8",t,e,"DepthTexture with DepthStencilFormat + FloatType"),a="depth32float-stencil8"}break;case he:switch(i){case L:a="r32sint";break;case be:a="r32uint"}break;case se:switch(i){case L:a="rg32sint";break;case be:a="rg32uint"}break;case ne:switch(i){case L:a="rgba32sint";break;case be:a="rgba32uint"}}if(!a)throw new Error(`Texture format "${r}" with type "${i}" from "${e.constructor.name}" is not supported by this renderer yet.`);const s=function(e){if(e.startsWith("bc"))return"texture-compression-bc";if(e.startsWith("etc2")||e.startsWith("eac"))return"texture-compression-etc2";if(e.startsWith("astc"))return"texture-compression-astc";return null}(a);s&&Ie(s,t,e,`Texture format "${a}"`);return a}(e,t),n=function(e){const t=Be(e);if("cube"===t)return"cube";if("2d-array"===t)return"2d-array";if("3d"===t)return"3d";return"2d"}(e),a=function(e){return"3d"===Be(e)?"3d":"2d"}(e),s=function(e,t,r){if(!0===e.isDepthTexture)return"depth";if(t.endsWith("uint"))return"uint";if(t.endsWith("sint"))return"sint";if(!0===e.isDataTexture||!0===e.isDataArrayTexture||!0===e.isData3DTexture){if(e.type===L)return"sint";if(e.type===be)return"uint";if(e.type===z&&!Re(r,"float32-filterable")&&("r32float"===t||"rg32float"===t||"rgba32float"===t))return"unfilterable-float"}return"float"}(e,i,t),o=function(e,t){const r=e.compareFunction;if("depth"===t&&null!=r)return"comparison";if("float"===t)return"filtering";return"non-filtering"}(e,s),l=function(e){if(!0===e.isCompressedCubeTexture){const t=e.image;return Math.max(1,t?.[0]?.mipmaps?.length??1)}const t=e.mipmaps;return Math.max(1,t?.length??1)}(e);return{format:i,textureDimension:a,viewDimension:n,sampleType:s,samplerBindingType:o,wgslTextureType:Me(n,s),wgslSamplerType:"comparison"===o?"sampler_comparison":"sampler",width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers,mipLevelCount:l,compressed:Te(e)}}function Ce(e,t){const r=Se(e,t);return[r.format,r.textureDimension,r.viewDimension,r.sampleType,r.samplerBindingType,r.width,r.height,r.depthOrArrayLayers,r.mipLevelCount].join(":")}function Pe(e){const t=De(e),r=e.compareFunction;return[Be(e),e.format,e.type,e.colorSpace,r??"none",t.depthOrArrayLayers].join(":")}function Me(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 Be(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 De(e){if(!0===e.isCubeTexture){const t=e.image,r=t?.[0],i=r?.image??r;return{width:i?.width??1,height:i?.height??1,depthOrArrayLayers:6}}const t=e.image;return{width:t?.width??1,height:t?.height??1,depthOrArrayLayers:t?.depth??1}}function Te(e){return!0===e.isCompressedTexture||!0===e.isCompressedArrayTexture}function Ie(e,t,r,i){if(!Re(t,e))throw new Error(`${i} for "${r.name||r.uuid}" requires the WebGPU feature "${e}", which is not enabled on this device.`)}function Re(e,t){return!!e&&(e instanceof Set?e.has(t):"features"in e?e.features.has(t):e.has(t))}import{Color as Ge,Matrix3 as Ve,Matrix4 as ze,Vector2 as Ue,Vector3 as Le,Vector4 as Ae}from"three";var Fe=new ArrayBuffer(8),Ee=new Float64Array(Fe),ke=new Uint32Array(Fe),Oe={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 je(e,t){return Math.ceil(e/t)*t}function $e(e,t){return"number"==typeof e||"boolean"==typeof e?[Number(e)]:Array.isArray(e)?Array.from(e.slice(0,t)):e instanceof Ge?t>=4?[e.r,e.g,e.b,1]:[e.r,e.g,e.b]:e instanceof Ue?[e.x,e.y]:e instanceof Le?[e.x,e.y,e.z]:e instanceof Ae?[e.x,e.y,e.z,e.w]:e instanceof Ve||e instanceof ze?Array.from(e.elements):[]}function Ne(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 We(e,t,r,i){const n=$e(r,i);for(let r=0;r<i;r+=1)e[t+r]=n[r]??0}function _e(e,t,r){const i=r instanceof Ve?r.elements:Array.isArray(r)?Array.from(r):$e(r,9);for(let r=0;r<3;r+=1){const n=3*r,a=t+4*r;e[a+0]=i[n+0]??0,e[a+1]=i[n+1]??0,e[a+2]=i[n+2]??0,e[a+3]=0}}function He(e){let t=0;const r=[];for(const[i,n]of Object.entries(e)){const e=Oe[n.type];t=je(t,e.alignment),r.push({name:i,offset:t,type:n.type}),t+=e.size}return{byteLength:je(t,16),entries:r}}function qe(e,t){const r=new ArrayBuffer(t.byteLength),i=new DataView(r),n=new Float32Array(r);for(const r of t.entries){const t=e[r.name],a=r.offset/4;switch(r.type){case"f32":case"i32":case"u32":Ne(i,r.offset,r.type,t.value);break;case"vec2<f32>":We(n,a,t.value,2);break;case"vec3<f32>":We(n,a,t.value,3);break;case"vec4<f32>":We(n,a,t.value,4);break;case"mat3x3<f32>":_e(n,a,t.value);break;case"mat4x4<f32>":if(t.value instanceof ze)n.set(t.value.elements,a);else{const e=$e(t.value,16);n.set(e,a)}}}return r}function Ke(e,t){let r=Math.imul(e^t,16777619);return r^=r>>>13,r>>>0}function Ze(e,t){return Ee[0]=t,e=Ke(e,ke[0]??0),e=Ke(e,ke[1]??0)}function Ye(e,t,r){const i=$e(t,r);e=Ke(e,i.length);for(let t=0;t<i.length;t+=1)e=Ze(e,i[t]??0);return e}var Xe="\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",Je=new WeakMap,Qe=new WeakMap;function et(e){return e?"string"==typeof e?[e]:Array.from(e):[]}function tt(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}var rt=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){this.context.addSceneTextureCopyPass(e)}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,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=et(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=et(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 s=t.map(e=>a.getColorFormat(e)),o=i.map(([,e])=>Se(e,a.device)),l=i.map(([,e])=>Ce(e,a.device)).join("|"),c=r.map(([t])=>e.inputDimensions?.[t]??"2d"),u=`${s.join("|")}:${n.map((e,t)=>`${e}-${c[t]}`).join("|")}:${l}:${e.uniformBufferSize??0}`,d=function(e,t){let r=Je.get(e);r||(r=new WeakMap,Je.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=[Xe,"@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"===c[t]?"texture_3d<f32>":"texture_2d<f32>"};`).join("\n"),i.map(([e],t)=>{const i=r.length+1+2*t,n=o[t];return`@group(0) @binding(${i}) var ${e}Sampler: ${n.wgslSamplerType};\n@group(0) @binding(${i+1}) var ${e}Texture: ${n.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"),l=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"===c[t]?"3d":"2d"}})),...o.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"}}]:[]]}),p=a.device.createPipelineLayout({label:`${e.name}-pipeline-layout`,bindGroupLayouts:[l]});h={bindGroupLayout:l,pipeline:a.device.createRenderPipeline({label:`${e.name}-pipeline`,layout:p,vertex:{module:a.device.createShaderModule({label:`${e.name}-vertex-module`,code:t}),entryPoint:"vsMain"},fragment:{module:a.device.createShaderModule({label:`${e.name}-fragment-module`,code:t}),entryPoint:"fsMain",targets:s.map(e=>({format:e}))},primitive:{topology:"triangle-list"}}),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},d.set(u,h)}const{bindGroupLayout:p,pipeline:f,uniformBuffer:m}=h,g=e.updateUniforms?.(a)??null;m&&g&&a.device.queue.writeBuffer(m,0,g.buffer,g.byteOffset,g.byteLength);const v=[{binding:0,resource:"nearest"===e.sampler||"linear"!==e.sampler&&n.includes("depth")?a.nearestClampSampler:a.linearClampSampler},...r.map(([,e],t)=>({binding:t+1,resource:"depth"===n[t]?a.depthView:a.getColorView(e)}))];for(let e=0;e<i.length;e+=1){const t=a.getExternalTexture(i[e][1]),n=r.length+1+2*e;v.push({binding:n,resource:t.sampler},{binding:n+1,resource:t.view})}m&&v.push({binding:r.length+1+2*i.length,resource:{buffer:m}});const x=a.device.createBindGroup({label:`${e.name}-bind-group`,layout:p,entries:v}),w=a.encoder.beginRenderPass({label:e.name,colorAttachments:t.map(e=>({view:a.getColorView(e),clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}))});w.setPipeline(f),w.setBindGroup(0,x),w.draw(3),w.end()}})}addNodeFullscreenPass(e){const t=et(e.outputs),r=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]),i=Object.entries(e.shader.textures??{}),n=Object.fromEntries(r.map(([e,t])=>[e,t.resource])),a=He(e.shader.uniforms);this.addPass({name:e.name,inputs:n,outputs:t,execute:n=>{const s=t.map(e=>n.getColorFormat(e)),o=r.map(([e,t])=>`${e}:${t.dimension}:${t.sampleType}:${t.sampler??"filtering"}`).join("|"),l=i.map(([,e])=>Se(e,n.device)),c=i.map(([,e])=>Ce(e,n.device)).join("|"),u=a.entries.map(e=>`${e.name}:${e.type}:${e.offset}`).join("|"),d=`${s.join("|")}:${o}:${c}:${u}`,h=function(e,t){let r=Qe.get(e);r||(r=new WeakMap,Qe.set(e,r));let i=r.get(t);return i||(i=new Map,r.set(t,i)),i}(e.shader,n.device);let p=h.get(d);if(!p){const t=[];for(const[,e]of r){const r=t.length;t.push({binding:r,visibility:GPUShaderStage.FRAGMENT,sampler:{type:e.sampler??("depth-2d"===e.dimension?"non-filtering":"filtering")}},{binding:r+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 l.entries()){const e=t.length;t.push({binding:e,visibility:GPUShaderStage.FRAGMENT,sampler:{type:r.samplerBindingType}},{binding:e+1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:r.sampleType,viewDimension:r.viewDimension}})}const o=2*(r.length+i.length);a.byteLength>0&&t.push({binding:o,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}});const c=n.device.createBindGroupLayout({label:`${e.name}-node-layout`,entries:t}),u=n.device.createPipelineLayout({label:`${e.name}-node-pipeline-layout`,bindGroupLayouts:[c]}),f=r.map(([e,t],r)=>{const i=tt(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"),m=i.map(([e],t)=>{const i=2*(r.length+t),n=l[t],a=tt(e);return`@group(0) @binding(${i}) var ${a}Sampler: ${n.wgslSamplerType};\n@group(0) @binding(${i+1}) var ${a}Texture: ${n.wgslTextureType};`}).join("\n"),g=a.entries.map(e=>` ${tt(e.name)}: ${e.type},`).join("\n"),v=a.byteLength>0?`struct MaterialUniforms {\n${g}\n};\n@group(0) @binding(${o}) var<uniform> materialUniforms: MaterialUniforms;`:"",x=[Xe,f,m,v,e.shader.fragmentShader].filter(Boolean).join("\n\n");p={bindGroupLayout:c,pipeline:n.device.createRenderPipeline({label:`${e.name}-node-pipeline`,layout:u,vertex:{module:n.device.createShaderModule({label:`${e.name}-node-vertex-module`,code:x}),entryPoint:"vsMain"},fragment:{module:n.device.createShaderModule({label:`${e.name}-node-fragment-module`,code:x}),entryPoint:"fsMain",targets:s.map(e=>({format:e}))},primitive:{topology:"triangle-list"}}),uniformBuffer:a.byteLength>0?n.device.createBuffer({label:`${e.name}-node-uniforms`,size:a.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}):null},h.set(d,p)}const{pipeline:f,bindGroupLayout:m,uniformBuffer:g}=p;e.shader.syncLiveUniforms(e.shader.uniforms),g&&n.device.queue.writeBuffer(g,0,qe(e.shader.uniforms,a));const v=[];for(const[,e]of r){const t=v.length,r="comparison"===e.sampler?n.comparisonSampler:"non-filtering"===e.sampler||"depth-2d"===e.dimension?n.nearestClampSampler:n.linearClampSampler;v.push({binding:t,resource:r},{binding:t+1,resource:n.getTextureView(e.resource)})}for(const[,e]of i){const t=v.length,r=n.getExternalTexture(e);v.push({binding:t,resource:r.sampler},{binding:t+1,resource:r.view})}g&&v.push({binding:2*(r.length+i.length),resource:{buffer:g}});const x=n.device.createBindGroup({label:`${e.name}-node-bind-group`,layout:m,entries:v}),w=n.encoder.beginRenderPass({label:e.name,colorAttachments:t.map(e=>({view:n.getColorView(e),clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}))});w.setPipeline(f),w.setBindGroup(0,x),w.draw(3),w.end()}})}present(e=this.sceneColor){this.context.addPresentPass(e)}};import{AdditiveBlending as it,BackSide as nt,BufferAttribute as at,BufferGeometry as st,Color as ot,DoubleSide as lt,FrontSide as ct,InstancedBufferAttribute as ut,MultiplyBlending as dt,Matrix4 as ht,Mesh as pt,OrthographicCamera as ft,PerspectiveCamera as mt,Sphere as gt,SubtractiveBlending as vt,Vector2 as xt,Vector3 as wt,Vector4 as bt,ShaderMaterial as yt}from"three";var St=/^[A-Za-z_][A-Za-z0-9_]*$/;function Ct(e,t={},r={}){const i=function(e){const t=new Map;for(const[r,i]of Object.entries(e))St.test(r)&&!1!==i&&null!=i&&t.set(r,{name:r,parameters:null,body:Pt(i)});return t}(t),n=[],a=[],s=e.split(/\r?\n/),o=r.sourceName??"shader";for(let e=0;e<s.length;e+=1){const t=s[e],r=Mt(t),l=Dt(n);if(!r){a.push(l?It(t,i):"");continue}const{name:c,rest:u}=r;switch(c){case"define":l&&Bt(u,i,o,e+1),a.push("");break;case"undef":l&&i.delete(u.trim()),a.push("");break;case"ifdef":{const e=l,t=e&&i.has(u.trim());n.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),a.push("");break}case"ifndef":{const e=l,t=e&&!i.has(u.trim());n.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),a.push("");break}case"if":{const e=l,t=e&&Ft(u,i);n.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),a.push("");break}case"elif":{const t=Tt(n,o,e+1,c);if(t.elseSeen)throw new Error(`${o}:${e+1}: #elif after #else`);const r=t.parentActive&&!t.branchTaken&&Ft(u,i);t.active=r,t.branchTaken=t.branchTaken||r,a.push("");break}case"else":{const t=Tt(n,o,e+1,c);if(t.elseSeen)throw new Error(`${o}:${e+1}: duplicate #else`);t.active=t.parentActive&&!t.branchTaken,t.branchTaken=!0,t.elseSeen=!0,a.push("");break}case"endif":Tt(n,o,e+1,c),n.pop(),a.push("");break;case"error":if(l)throw new Error(`${o}:${e+1}: ${u.trim()||"#error"}`);a.push("");break;case"warning":case"line":case"version":case"pragma":a.push("");break;default:if(l)throw new Error(`${o}:${e+1}: unsupported preprocessor directive #${c}`);a.push("")}}if(n.length>0)throw new Error(`${o}: unterminated preprocessor conditional`);return a.join("\n")}function Pt(e){return"boolean"==typeof e?e?"1":"0":String(e)}function Mt(e){const t=/^\s*#\s*([A-Za-z_][A-Za-z0-9_]*)(.*)$/.exec(e);return t?{name:t[1],rest:t[2]??""}:null}function Bt(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=At(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(!St.test(e))throw new Error(`${r}:${i}: invalid macro parameter "${e}"`);return void t.set(a,{name:a,parameters:o,body:kt(s.slice(e+1)).trim()||"1"})}t.set(a,{name:a,parameters:null,body:kt(s).trim()||"1"})}function Dt(e){for(const t of e)if(!t.active)return!1;return!0}function Tt(e,t,r,i){const n=e[e.length-1];if(!n)throw new Error(`${t}:${r}: #${i} without matching #if`);return n}function It(e,t){let r=e;for(let e=0;e<8;e+=1){const e=r;if(r=Gt(r,t),r=Rt(r,t),r===e)return r}return r}function Rt(e,t){return e.replace(/\b[A-Za-z_][A-Za-z0-9_]*\b/g,e=>{const r=t.get(e);return r&&null===r.parameters?r.body:e})}function Gt(e,t){let r=e;for(const e of t.values())null!==e.parameters&&(r=Vt(r,e));return r}function Vt(e,t){let r="",i=0;for(;i<e.length;){const n=zt(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=At(e,a);if(s<0){r+=e.slice(i);break}const o=Lt(e.slice(a+1,s));r+=e.slice(i,n),r+=Ut(t,o),i=s+1}return r}function zt(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 Ut(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${Ot(n)}\\b`,"g"),a)}return r}function Lt(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 At(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 Ft(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}(kt(e));return 0!==new Et(r,t).parseExpression()}var Et=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 kt(e){const t=e.indexOf("//");return t>=0?e.slice(0,t):e}function Ot(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}import{Material as jt}from"three";var $t=[{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]}],Nt=class e extends jt{isWGSLShaderMaterial=!0;vertexShader;fragmentShader;depthVertexShader;depthFragmentShader;pointShadowVertexShader;pointShadowFragmentShader;defines;uniforms;textures;sceneTextures;graphTextures;storageBuffers;vertexAttributes;primitiveTopology;wireframe;uniformLayoutCache=null;programCacheKeyCache=null;textureListCache=null;textureVersionsCache=[];textureVersionHashCache=0;storageBufferBindingListCache=null;storageBufferListCache=null;textureLayoutKeyDeviceCache=null;textureLayoutKeyCache=null;uniformValuesAutoUpdate=!0;uniformValuesAutoVersion=0;set uniformValuesNeedsUpdate(e){e&&this.uniformValuesAutoVersion++}constructor(e){super();const{vertexShader:t,fragmentShader:r,depthVertexShader:i,depthFragmentShader:n,pointShadowVertexShader:a,pointShadowFragmentShader:s,defines:o,uniforms:l,textures:c,sceneTextures:u,graphTextures:d,storageBuffers:h,vertexAttributes:p,primitiveTopology:f,uniformValuesAutoUpdate:m,wireframe:g,...v}=e,x=function(e,t){const r={},i={...t};for(const[t,n]of Object.entries(e)){const e=qt(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=_t(p??$t),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=He(this.uniforms)),this.uniformLayoutCache}setUniform(e,t){const r=qt(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=_t(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:Ht(t.value)}])),this.textures={...e.textures},this.sceneTextures={...e.sceneTextures},this.graphTextures={...e.graphTextures},this.storageBuffers={...e.storageBuffers},this.vertexAttributes=_t(e.vertexAttributes),this.primitiveTopology=e.primitiveTopology,this.wireframe=e.wireframe,this.uniformValuesAutoUpdate=e.uniformValuesAutoUpdate,this.uniformValuesAutoVersion=e.uniformValuesAutoVersion,this.uniformLayoutCache=null,this.invalidateBindingCache(),this.invalidateProgramStructureCache(),this}clone(){return new e({vertexShader:this.vertexShader,fragmentShader:this.fragmentShader}).copy(this)}customProgramCacheKey(){if(null!==this.programCacheKeyCache)return this.programCacheKeyCache;const e=Object.keys(this.defines).sort((e,t)=>e.localeCompare(t));let t=`vertex:${this.vertexShader};fragment:${this.fragmentShader};depthVertex:${this.depthVertexShader??""};depthFragment:${this.depthFragmentShader??""};pointShadowVertex:${this.pointShadowVertexShader??""};pointShadowFragment:${this.pointShadowFragmentShader??""};`;for(const r of e)t+=`${r}:${String(this.defines[r])};`;for(const e in this.uniforms)t+=`uniform:${e}:${this.uniforms[e].type};`;for(const[e,r]of Object.entries(this.textures))t+=`texture:${e}:${Pe(r)};`;for(const[e,r]of Object.entries(this.sceneTextures))t+=`sceneTexture:${e}:${r};`;for(const[e,r]of Object.entries(this.getGraphTextureInputs()))t+=`graphTexture:${e}:${r.resource}:${r.dimension}:${r.sampleType??"float"}:${r.sampler??"filtering"}:${Number(r.requiresLatePass??!1)};`;for(const[e,r]of Object.entries(this.storageBuffers))t+=`storage:${e}:${r.type}:${r.visibility??"fragment"};`;for(const e of this.vertexAttributes){const r=e.defaultValue?e.defaultValue.join(","):"";t+=`attribute:${e.name}:${e.shaderLocation}:${e.format}:${e.stepMode??"vertex"}:${r};`}return t+=`topology:${this.primitiveTopology};wireframe:${Number(this.wireframe)};transparent:${Number(this.transparent)};blending:${this.blending};premultipliedAlpha:${Number(this.premultipliedAlpha)};blendSrc:${this.blendSrc};blendDst:${this.blendDst};blendEquation:${this.blendEquation};blendSrcAlpha:${this.blendSrcAlpha};blendDstAlpha:${this.blendDstAlpha};blendEquationAlpha:${this.blendEquationAlpha};depthWrite:${Number(this.depthWrite)};depthTest:${Number(this.depthTest)};side:${String(this.side)};shadowSide:${String(this.shadowSide)};`,this.programCacheKeyCache=t,this.programCacheKeyCache}getTexturesList(){return null===this.textureListCache&&(this.textureListCache=Object.values(this.textures)),this.textureListCache}usesSceneTextures(){return Object.keys(this.sceneTextures).length>0||Object.values(this.graphTextures).some(e=>"sceneColorSnapshot"===e.resource||"sceneDepthSnapshot"===e.resource)}getGraphTextureInputs(){const e={...this.graphTextures};for(const[t,r]of Object.entries(this.sceneTextures))e[t]="sceneDepth"===r?{resource:"sceneDepthSnapshot",dimension:"depth-2d",sampleType:"depth",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=Ke(r,n.offset),n.type){case"f32":case"i32":case"u32":r=Ze(r,"boolean"==typeof a.value?a.value?1:0:Number(a.value));break;case"vec2<f32>":r=Ye(r,a.value,2);break;case"vec3<f32>":r=Ye(r,a.value,3);break;case"vec4<f32>":r=Ye(r,a.value,4);break;case"mat3x3<f32>":r=Ye(r,a.value,9);break;case"mat4x4<f32>":r=Ye(r,a.value,16);break;default:r=Ke(r,i+17)}else r=Ke(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=>Ce(t,e)).join("|")),this.textureLayoutKeyCache}invalidateProgramStructureCache(){this.programCacheKeyCache=null}invalidateBindingCache(){this.textureListCache=null,this.textureVersionsCache.length=0,this.textureVersionHashCache=0,this.storageBufferBindingListCache=null,this.storageBufferListCache=null,this.textureLayoutKeyDeviceCache=null,this.textureLayoutKeyCache=null}};function Wt(e){return!0===e.isWGSLShaderMaterial}function _t(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 Ht(e){return Array.isArray(e)?Array.from(e):"number"==typeof e||"boolean"==typeof e?e:e.clone()}function qt(e,t){const r=Zt(t)?t:null,i=null!==r&&"value"in r?r.value:t;if(function(e){return Kt(e,"isTexture")}(i))return{kind:"texture",texture:i};if(!function(e){return"number"==typeof e||"boolean"==typeof e||Array.isArray(e)||Kt(e,"isColor")||Kt(e,"isVector2")||Kt(e,"isVector3")||Kt(e,"isVector4")||Kt(e,"isMatrix3")||Kt(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(Kt(t,"isColor"))return"vec3<f32>";if(Kt(t,"isVector2"))return"vec2<f32>";if(Kt(t,"isVector3"))return"vec3<f32>";if(Kt(t,"isVector4"))return"vec4<f32>";if(Kt(t,"isMatrix3"))return"mat3x3<f32>";if(Kt(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 Kt(e,t){return Zt(e)&&!0===e[t]}function Zt(e){return"object"==typeof e&&null!==e}var Yt=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 Xt,HalfFloatType as Jt,LinearFilter as Qt,LinearSRGBColorSpace as er,RGBAFormat as tr,Texture as rr}from"three";var ir=[.125,.215,.35,.446,.526,.582],nr=20,ar=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]]}(),sr=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=or(r,this.equirectBindGroupLayout,ur,"pmrem-equirectangular"),this.blurPipeline=or(r,this.blurBindGroupLayout,dr.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<ir.length;e+=1)t.push({mip:4-e-1,size:16,sigma:ir[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=lr(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=ar[(n.length-e-1)%ar.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 rr;return v.image={width:a,height:s},v.name="PMREM.cubeUv",v.mapping=Xt,v.format=tr,v.type=Jt,v.colorSpace=er,v.minFilter=Qt,v.magFilter=Qt,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(nr);let i=0;for(let n=0;n<nr;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=lr(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,nr).set(e.weights),new Float32Array(t)}({atlasWidth:a,atlasHeight:s,outputFaceSize:c.size,inputMip:l.mip,dTheta:g,sampleCount:x,latitudinal:h,poleAxis:d,weights:w,maxMip:o}));f.push(b);const y=this.context.device.createBindGroup({layout:this.blurBindGroupLayout,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:r.createView()},{binding:2,resource:n}]}),S=3*c.size*Math.max(0,4-c.mip),C=4*(2**o-c.size),P=t.beginRenderPass({colorAttachments:[{view:i.createView(),loadOp:p?"clear":"load",storeOp:"store",clearValue:[0,0,0,1]}]});P.setViewport(S,C,3*c.size,2*c.size,0,1),P.setScissorRect(S,C,3*c.size,2*c.size),P.setPipeline(this.blurPipeline),P.setBindGroup(0,y),P.draw(36),P.end()}};function or(e,t,r,i){const n=e.createShaderModule({code:r,label:`${i}-shader`});return 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 lr(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 cr="\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",ur=`${cr}\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`,dr=`${cr}\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 hr(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}function pr(e,t){const r=Object.entries(e.uniforms).map(([e,t])=>` ${hr(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=hr(e),s=Se(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=hr(e);return`@group(1) @binding(${a+r}) var<storage, read> ${i}: ${t.type};`}).join("\n")}`}function fr(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 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 mr(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 gr(e,t,r="packed",i=!0,n=!1){const a=pr(e,t),s=function(e){return Object.entries(e.getGraphTextureInputs()).map(([e,t],r)=>{const i=hr(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),o="packed-visible"===r,l=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 return vec3<f32>(uv * 0.5 + vec2(0.5, 0.5), 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 = rendererPointLightRangeForLight(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>, 4>,\n pointColorIntensities: array<vec4<f32>, 4>,\n pointShadowParams: array<vec4<f32>, 4>,\n pointShadowParams2: array<vec4<f32>, 4>,\n spotPositionRanges: array<vec4<f32>, 4>,\n spotDirectionCones: array<vec4<f32>, 4>,\n spotColorIntensities: array<vec4<f32>, 4>,\n spotShadowParams: array<vec4<f32>, 4>,\n spotShadowParams2: array<vec4<f32>, 4>,\n spotParams: array<vec4<f32>, 4>,\n spotShadowMatrices: array<mat4x4<f32>, 4>,\n csmCascadeRanges: array<vec4<f32>, 4>,\n hemisphereSkyColorIntensity: vec4<f32>,\n hemisphereGroundColorIntensity: vec4<f32>,\n hemisphereDirection: vec4<f32>,\n};\n\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\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${o?"@group(0) @binding(8) var<storage, read> rendererVisibleInstanceIndices: array<u32>;":""}\n\nfn rendererResolveInstanceIndex(instanceIndex: u32) -> u32 {\n ${o?"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\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${fr("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.pointPositionRanges[lightIndex].w;\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 2.0\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\n${l}\n${mr(n)}\n${a}\n${s}\n`}function vr(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=pr(e,r);return`\n${a}\n\n${"instanced-direct"===i?"\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let base = instanceIndex * 4u;\n return mat4x4<f32>(\n rendererInstanceMatrices[base + 0u],\n rendererInstanceMatrices[base + 1u],\n rendererInstanceMatrices[base + 2u],\n rendererInstanceMatrices[base + 3u]\n );\n}\n\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> {\n return rendererInstanceColors[instanceIndex];\n}\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 {\n return instanceIndex;\n}\n":"\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> {\n return rendererInstances[instanceIndex].color;\n}\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 {\n return u32(round(rendererInstances[instanceIndex].batching.x));\n}\n"}\n\nfn rendererInverseMat3(m: mat3x3<f32>) -> mat3x3<f32> {\n let a = m[0];\n let b = m[1];\n let c = m[2];\n let r0 = cross(b, c);\n let r1 = cross(c, a);\n let r2 = cross(a, b);\n let det = dot(r2, c);\n let safeDet = select(det, select(-1e-8, 1e-8, det >= 0.0), abs(det) < 1e-8);\n let invDet = 1.0 / safeDet;\n return transpose(mat3x3<f32>(r0 * invDet, r1 * invDet, r2 * invDet));\n}\n\nfn rendererInstanceNormalMatrix(instanceIndex: u32) -> mat3x3<f32> {\n let model = rendererInstanceModelMatrix(instanceIndex);\n let model3x3 = mat3x3<f32>(model[0].xyz, model[1].xyz, model[2].xyz);\n return transpose(rendererInverseMat3(model3x3));\n}\n\nfn rendererWorldPosition(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n return rendererInstanceModelMatrix(instanceIndex) * vec4(localPosition, 1.0);\n}\n\nfn rendererWorldNormal(localNormal: vec3<f32>, instanceIndex: u32) -> vec3<f32> {\n return normalize(rendererInstanceNormalMatrix(instanceIndex) * localNormal);\n}\n\n${fr("camera"===t?"rendererCamera":"shadowCamera")}\n${mr(n)}\n${s}\n`}var xr=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)}};import{AlwaysCompare as wr,BufferAttribute as br,EqualCompare as yr,GreaterCompare as Sr,GreaterEqualCompare as Cr,LessCompare as Pr,LessEqualCompare as Mr,MirroredRepeatWrapping as Br,NearestFilter as Dr,NearestMipmapLinearFilter as Tr,NearestMipmapNearestFilter as Ir,NeverCompare as Rr,NotEqualCompare as Gr,Object3D as Vr,RepeatWrapping as zr,Vector3 as Ur}from"three";import{Matrix4 as Lr,Sphere as Ar,Vector3 as Fr}from"three";var Er=40,kr=12,Or=new Float32Array(Er),jr=new Float32Array([1,1,1,1]),$r="rgba16float",Nr=(new Lr).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),Wr=[new Fr(0,-1,0),new Fr(0,-1,0),new Fr(0,0,1),new Fr(0,0,-1),new Fr(0,-1,0),new Fr(0,-1,0)],_r=[new Fr(1,0,0),new Fr(-1,0,0),new Fr(0,1,0),new Fr(0,-1,0),new Fr(0,0,1),new Fr(0,0,-1)],Hr=[{name:"position",shaderLocation:0,format:"float32x3"}],qr=[{name:"position",shaderLocation:0,format:"float32x3"},{name:"skinIndex",shaderLocation:1,format:"uint32x4"},{name:"skinWeight",shaderLocation:2,format:"float32x4"}],Kr=new Lr,Zr=new Lr,Yr=(new Lr,new Lr,new Ar),Xr=new Fr,Jr=new Fr,Qr=new Fr,ei=(new Fr,new Fr,new Fr,new Fr,new WeakMap),ti=1;function ri(e){return e?"version"in e?e.version:e.data.version:0}function ii(e){const t=Object.keys(e.attributes).sort().map(t=>{const r=e.getAttribute(t);return[t,ri(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 ni(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 ai(e){return 4*ni(e)}function si(e,t){switch(t){case"uint32":return new Uint32Array(e);case"sint32":return new Int32Array(e);default:return new Float32Array(e)}}function oi(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 li(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 ci(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 ui(e){switch(e){case"vertex":return GPUShaderStage.VERTEX;case"vertex-fragment":return GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT;default:return GPUShaderStage.FRAGMENT}}function di(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 hi(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 pi(e,t,r){try{return e.beginComputePass({timestampWrites:{querySet:t,...r}}).end(),!0}catch{return!1}}function fi(e,t,r,i){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 mi(e,t,r,i,n=0){const a=ni(r),s=(o=r).startsWith("uint32")?"uint32":o.startsWith("sint32")?"sint32":"float32";var o;if(!e)return function(e,t,r,i,n,a){const s=si(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)oi(s,l+o,a,e&&o<t?e[r+o]??n[o]??0:n[o]??0)}return s}(void 0,0,t,a,i,s);if(0===n&&e instanceof br&&!e.normalized&&e.itemSize===a&&e.count===t){const t=e.array;if("float32"===s&&t instanceof Float32Array||"uint32"===s&&t instanceof Uint32Array||"sint32"===s&&t instanceof Int32Array)return t}const l=si(t*a,s);for(let r=0;r<t;r+=1){const t=r*a,o=r-n,c=o>=0&&o<e.count;for(let r=0;r<a;r+=1){oi(l,t+r,s,c&&r<e.itemSize?e.getComponent(o,r):i[r]??0)}}return l}function gi(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 vi(e,t){return{start:e.drawRange.start,count:gi(e,t,e.drawRange.start,e.drawRange.count)}}function xi(e){return e===zr?"repeat":e===Br?"mirror-repeat":"clamp-to-edge"}function wi(e){return e===Dr||e===Ir||e===Tr?"nearest":"linear"}function bi(e){return e instanceof HTMLCanvasElement||e instanceof HTMLImageElement||e instanceof ImageBitmap||e instanceof OffscreenCanvas||e instanceof HTMLVideoElement?e:null}function yi(e){return e}function Si(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 Ci(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 Pi(e,t,r){const i=e.elements;for(let e=0;e<16;e+=1)i[e]=t[r+e]??0;return e}function Mi(e){const t=ei.get(e);if(void 0!==t)return t;const r=ti+=1;return ei.set(e,r),r}function Bi(e,t,r,i,n,a){return[Mi(e),Mi(t),r?1:0,i,n,a?Mi(a):0].join(":")}function Di(e,t,r,i,n,a){let s=2166136261;return s=Gi(s,e),s=Gi(s,t),s=Gi(s,r?1:0),s=Gi(s,i),s=Gi(s,n),s=Gi(s,a),s}function Ti(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 Ii(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:Ti(e,t)}function Ri(e){for(let t=0;t<e.length;t+=1)if(e[t].hasRenderCallbacks)return!0;return!1}function Gi(e,t){let r=Math.imul((e^t)>>>0,16777619);return r^=r>>>13,r>>>0}function Vi(e,t){return e.renderOrder===t.renderOrder&&!e.hasRenderCallbacks&&!t.hasRenderCallbacks&&e.castShadow===t.castShadow&&e.receiveShadow===t.receiveShadow&&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 zi(e,t){return e.renderOrder===t.renderOrder&&!e.hasRenderCallbacks&&!t.hasRenderCallbacks&&e.castShadow===t.castShadow&&e.receiveShadow===t.receiveShadow&&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 Ui(e,t){for(let r=0;r<16;r+=1)t[r]=e[r]??0}function Li(e,t){for(let r=0;r<16;r+=1)if((e[r]??0)!==(t[r]??0))return!1;return!0}function Ai(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 Fi(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 Ei(e,t){return t.multiplyMatrices(Zr.multiplyMatrices(Nr,e.projectionMatrix),e.matrixWorldInverse)}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 Oi(e){return null===e.boundingSphere&&e.computeBoundingSphere(),e.boundingSphere?{center:e.boundingSphere.center.clone(),radius:e.boundingSphere.radius}:{center:new Ur,radius:1}}function ji(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 $i(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 Ni(e){return Math.floor(Math.max(0,e.count)/3)*Math.max(0,e.instanceCount)}function Wi(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 _i(e){const t=e.customDepthMaterial;return t&&Wt(t)?t:null}function Hi(e,t){e.latestFrameProfile=Zi(t.profile),(t.pendingGpuRead||t.pendingVisibilityRead)&&Promise.all([t.pendingGpuRead?qi(t.profile,t.pendingGpuRead):Promise.resolve(),t.pendingVisibilityRead?Ki(t.profile,t.pendingVisibilityRead):Promise.resolve()]).then(()=>{const r=Zi(t.profile);e.latestFrameProfile=r,e.latestCompletedFrameProfile=r})}async function qi(e,t){try{await t.readBuffer.mapAsync(GPUMapMode.READ);const r=t.readBuffer.getMappedRange(),i=new BigUint64Array(r.slice(0));let n=0;const a=t.profile.passes.map((e,t)=>{const r=Number(i[2*t]??0n),a=Number(i[2*t+1]??0n),s=Math.max(0,a-r)/1e6;return n+=s,{...e,gpuTimeMs:s}});e.gpuTimeMs=n,e.gpuProfilingReason=null,e.passes=a}catch{e.timestampQueryActive=!1,e.gpuTimeMs=null,e.gpuProfilingReason="timestamp readback failed after submission",e.passes=e.passes.map(e=>({...e,gpuTimeMs:null}))}finally{"mapped"===t.readBuffer.mapState&&t.readBuffer.unmap(),t.querySet.destroy(),t.resolveBuffer.destroy(),t.readBuffer.destroy()}}async function Ki(e,t){try{await t.readBuffer.mapAsync(GPUMapMode.READ);const r=new Uint32Array(t.readBuffer.getMappedRange());let i=0,n=0,a=0,s=0;for(const e of t.regions){let t=0;const o=e.byteOffset/Uint32Array.BYTES_PER_ELEMENT;for(let i=0;i<e.drawCount;i+=1)t+=r[o+5*i+1]??0;"dynamic"===e.kind?(i+=e.totalInstances,n+=t):(a+=e.totalInstances,s+=t)}const o=i+a,l=n+s;e.visibility={totalInstances:o,visibleInstances:l,culledInstances:Math.max(0,o-l),dynamicTotalInstances:i,dynamicVisibleInstances:n,staticTotalInstances:a,staticVisibleInstances:s}}catch{e.visibility=null}finally{"mapped"===t.readBuffer.mapState&&t.readBuffer.unmap(),t.readBuffer.destroy()}}function Zi(e){return{...e,cpuPhases:{...e.cpuPhases},passes:e.passes.map(e=>({...e})),visibility:e.visibility?{...e.visibility}:null}}function Yi(e){return e.usesBatching}function Xi(e){return!e.wireframe&&e.material.primitiveTopology.startsWith("triangle")}function Ji(e,t){return"pointShadow"===t?null!==e.material.pointShadowVertexShader&&null!==e.material.pointShadowFragmentShader:null!==e.material.depthVertexShader}function Qi(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 en(e,t){if(this.state.staticVisibilityClearKernel&&this.state.staticVisibilityCullKernel&&this.state.staticVisibilityIndirectBuildKernel&&this.getHiZOcclusionCullingActive())for(const r of this.staticDrawSets){if(!r.publicSet.enabled||0===r.drawMetadataResource.count)continue;if("postpass"===t&&r.lastPreVisibilityFrameToken!==this.staticFrameToken)continue;if(!this.state.device)continue;const i="prepass"===t?r.visibilityParamsUpload:r.postVisibilityParamsUpload,n="prepass"===t?r.visibilityParamsBuffer:r.postVisibilityParamsBuffer;i[1]=this.state.hizMipCount,i[3]="prepass"===t?this.state.temporalHiZHistoryValid?3:0:5,this.state.device.queue.writeBuffer(n,0,yi(i),0,4);const a=this.getOrCreateStaticVisibilityBindGroup(r,t);if(!a)continue;if("prepass"!==t||r.visibilityClearBindGroup&&r.visibilityIndirectBuildBindGroup&&r.postVisibilityIndirectBuildBindGroup||(r.visibilityClearBindGroup=this.state.staticVisibilityClearKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:r.visibilityParamsBuffer}},{binding:1,resource:{buffer:r.instanceVisibilityResource.visibleCountsBuffer}},{binding:2,resource:{buffer:r.instanceVisibilityResource.postVisibleCountsBuffer}},{binding:3,resource:{buffer:r.instanceVisibilityResource.visibleInstanceMaskBuffer}}],`${r.label}-visibility-clear-bind-group`),r.visibilityIndirectBuildBindGroup=this.state.staticVisibilityIndirectBuildKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:r.visibilityParamsBuffer}},{binding:1,resource:{buffer:r.instanceVisibilityResource.visibleCountsBuffer}},{binding:2,resource:{buffer:r.instanceVisibilityResource.postVisibleCountsBuffer}},{binding:3,resource:{buffer:r.drawMetadataResource.indirectBuffer}},{binding:4,resource:{buffer:r.drawMetadataResource.postIndirectBuffer}}],`${r.label}-visibility-indirect-build-bind-group`),r.postVisibilityIndirectBuildBindGroup=this.state.staticVisibilityIndirectBuildKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:r.postVisibilityParamsBuffer}},{binding:1,resource:{buffer:r.instanceVisibilityResource.visibleCountsBuffer}},{binding:2,resource:{buffer:r.instanceVisibilityResource.postVisibleCountsBuffer}},{binding:3,resource:{buffer:r.drawMetadataResource.indirectBuffer}},{binding:4,resource:{buffer:r.drawMetadataResource.postIndirectBuffer}}],`${r.label}-post-visibility-indirect-build-bind-group`)),"prepass"===t){const t=e.beginComputePass({label:`${r.label}-temporal-visibility-clear-pass`});t.setPipeline(this.state.staticVisibilityClearKernel.pipeline),t.setBindGroup(0,r.visibilityClearBindGroup),t.dispatchWorkgroups(Math.ceil(Math.max(r.drawMetadataResource.count,r.instanceVisibilityResource.instanceCount)/64)),t.end()}const s=e.beginComputePass({label:`${r.label}-temporal-visibility-${t}-cull-pass`});s.setPipeline(this.state.staticVisibilityCullKernel.pipeline),s.setBindGroup(0,a),s.dispatchWorkgroups(Math.ceil(r.instanceVisibilityResource.instanceCount/64)),s.end();const o=e.beginComputePass({label:`${r.label}-temporal-visibility-${t}-indirect-build-pass`});o.setPipeline(this.state.staticVisibilityIndirectBuildKernel.pipeline),o.setBindGroup(0,"prepass"===t?r.visibilityIndirectBuildBindGroup:r.postVisibilityIndirectBuildBindGroup),o.dispatchWorkgroups(Math.ceil(r.drawMetadataResource.count/64)),o.end(),"prepass"===t?r.lastPreVisibilityFrameToken=this.staticFrameToken:r.lastVisibilityFrameToken=this.staticFrameToken}}function tn(e,t){if(!(this.state.device&&this.state.staticVisibilityCullKernel&&this.state.hizTexture&&this.state.temporalVisibilityBuffer&&this.state.nearestClampSampler))return null;const r="prepass"===t?e.visibilityBindGroup:e.postVisibilityBindGroup;if(r&&e.visibilityBindGroupHizVersion===this.hizResourceVersion)return r;const i=this.state.staticVisibilityCullKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:this.state.temporalVisibilityBuffer}},{binding:1,resource:{buffer:"prepass"===t?e.visibilityParamsBuffer:e.postVisibilityParamsBuffer}},{binding:2,resource:this.state.nearestClampSampler},{binding:3,resource:this.state.hizTexture.createView()},{binding:4,resource:{buffer:e.instanceVisibilityResource.instanceMetadataBuffer}},{binding:5,resource:{buffer:e.drawMetadataResource.metadataBuffer}},{binding:6,resource:{buffer:e.instanceVisibilityResource.visibleCountsBuffer}},{binding:7,resource:{buffer:e.instanceVisibilityResource.visibleInstanceIndicesBuffer}},{binding:8,resource:{buffer:e.instanceVisibilityResource.visibleInstanceMaskBuffer}},{binding:9,resource:{buffer:e.instanceVisibilityResource.postVisibleCountsBuffer}}],`${e.label}-temporal-visibility-${t}-bind-group`);return"prepass"===t?e.visibilityBindGroup=i:e.postVisibilityBindGroup=i,e.visibilityBindGroupHizVersion=this.hizResourceVersion,i}function rn(e,t,r,i){if(!this.state.shadowDepthPipeline||0===this.state.directionalShadowLayerViews.length)return void this.clearDirectionalShadow(e);let n=!1;for(let t=0;t<r.lights.directionals.length;t+=1){const a=r.lights.directionals[t],s=this.state.directionalShadowLayerViews[t];if(!a.castShadow||!s)continue;n=!0;const o=this.directionalShadowCameras[t];o.left=a.shadowCameraLeft,o.right=a.shadowCameraRight,o.top=a.shadowCameraTop,o.bottom=a.shadowCameraBottom,o.near=a.shadowCameraNear,o.far=a.shadowCameraFar,o.position.copy(a.position),o.lookAt(a.target),o.updateMatrixWorld(!0),o.updateProjectionMatrix();const l=this.getShadowCameraBuffer(t);this.writeShadowCameraBuffer(Ei(o,this.shadowViewProjScratch),0,0,0,1,l,o);const c=this.getSharedShadowBindGroupForCameraBuffer(l),u=e.beginRenderPass({label:`renderer-directional-shadow-pass-${t}`,colorAttachments:[],depthStencilAttachment:{view:s,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});u.setPipeline(this.state.shadowDepthPipeline),u.setBindGroup(0,c),this.drawDepthLike(u,r.gpuOpaqueDraws,i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"}),this.drawDepthLike(u,r.directOpaqueDraws,i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"});for(const e of this.staticDrawSets)e.publicSet.enabled&&0!==e.draws.length&&(this.renderBundleScratch[0]=pn.call(this,e,c,l,"directionalShadow",this.state.shadowDepthPipeline,this.state.shadowDepthPipelineDirect),u.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(e,i));u.end()}n||this.clearDirectionalShadow(e)}function nn(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),Xr.copy(a.position).add(_r[n]),o.up.copy(Wr[n]),o.lookAt(Xr),o.updateMatrixWorld(!0),o.updateProjectionMatrix();const l=this.getShadowCameraBuffer(4+s);this.writeShadowCameraBuffer(Ei(o,this.shadowViewProjScratch),a.position.x,a.position.y,a.position.z,a.range,l,o);const c=this.getSharedShadowBindGroupForCameraBuffer(l),u=e.beginRenderPass({label:`renderer-point-shadow-pass-${t}-${n}`,colorAttachments:[{view:this.state.pointShadowFaceViews[s],clearValue:{r:1,g:1,b:1,a:1},loadOp:"clear",storeOp:"store"}],depthStencilAttachment:{view:this.state.pointShadowDepthFaceViews[s],depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});u.setPipeline(this.state.pointShadowPipeline),u.setBindGroup(0,c),this.drawDepthLike(u,r.gpuOpaqueDraws,i,{fallbackPipeline:this.state.pointShadowPipeline,fallbackPipelineDirect:this.state.pointShadowPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedPointShadowPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"pointShadow",customDepthMode:"use"}),this.drawDepthLike(u,r.directOpaqueDraws,i,{fallbackPipeline:this.state.pointShadowPipeline,fallbackPipelineDirect:this.state.pointShadowPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedPointShadowPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"pointShadow",customDepthMode:"use"});for(const e of this.staticDrawSets)e.publicSet.enabled&&0!==e.draws.length&&(this.renderBundleScratch[0]=pn.call(this,e,c,l,"pointShadow",this.state.pointShadowPipeline,this.state.pointShadowPipelineDirect),u.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(e,i));u.end()}}}n||this.clearPointShadow(e)}function an(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),Xr.copy(a.position).add(a.direction),o.lookAt(Xr),o.updateMatrixWorld(!0),o.updateProjectionMatrix();const l=this.getShadowCameraBuffer(28+t);this.writeShadowCameraBuffer(Ei(o,this.shadowViewProjScratch),0,0,0,1,l,o);const c=this.getSharedShadowBindGroupForCameraBuffer(l),u=e.beginRenderPass({label:`renderer-spot-shadow-pass-${t}`,colorAttachments:[],depthStencilAttachment:{view:s,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});u.setPipeline(this.state.shadowDepthPipeline),u.setBindGroup(0,c),this.drawDepthLike(u,r.gpuOpaqueDraws,i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"}),this.drawDepthLike(u,r.directOpaqueDraws,i,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"});for(const e of this.staticDrawSets)e.publicSet.enabled&&0!==e.draws.length&&(this.renderBundleScratch[0]=pn.call(this,e,c,l,"directionalShadow",this.state.shadowDepthPipeline,this.state.shadowDepthPipelineDirect),u.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(e,i));u.end()}n||this.clearSpotShadow(e)}function sn(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 on(e,t,r){for(const i of this.staticDrawSets){if(!i.publicSet.enabled||0===i.draws.length)continue;if(this.getHiZOcclusionCullingActive()&&i.lastPreVisibilityFrameToken===this.staticFrameToken&&un(i)){const e=this.getOrCreateStaticVisibleDepthSceneBindGroup(i);this.renderBundleScratch[0]=ln.call(this,i,e)}else this.renderBundleScratch[0]=this.getOrCreateStaticDepthPrepassBundle(i,t);e.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(i,r)}}function ln(e,t,r=e.drawMetadataResource.indirectBuffer,i="prepass"){if(!this.state.device||!this.state.depthPrepassPipelineVisible)throw new Error("Renderer visible depth prepass resources are not initialized.");const n=e.indirectDepthPrepassBundles[i];if(n?.sceneBindGroup===t&&n.indirectBuffer===r)return n.bundle;const a=`${e.label}-static-temporal-depth-${i}-bundle-${e.id}`,s=this.state.device.createRenderBundleEncoder({label:a,colorFormats:[],depthStencilFormat:"depth32float",sampleCount:1});s.setPipeline(this.state.depthPrepassPipelineVisible),s.setBindGroup(0,t);let o=null;for(let t=0;t<e.draws.length;t+=1){const i=e.draws[t];i.customDepthMaterial||Ji(i,"prepass")||Tn(i.material)||!Xi(i)||(o!==i.geometryKey&&(o=i.geometryKey,this.bindGeometryVertexBuffers(s,i.geometry,i.geometryResource,Hr,0,1,i.wireframe)),s.drawIndexedIndirect(r,5*t*Uint32Array.BYTES_PER_ELEMENT))}const l=s.finish({label:a});return e.indirectDepthPrepassBundles[i]={sceneBindGroup:t,indirectBuffer:r,bundle:l},l}function cn(e){if(this.sampleCount<=1||!this.state.mainDepthView||!this.getHiZOcclusionCullingActive())return;let t=null;for(const r of this.staticDrawSets){if(!r.publicSet.enabled||0===r.draws.length||r.lastVisibilityFrameToken!==this.staticFrameToken||!un(r))continue;t||(t=e.beginRenderPass({label:"renderer-static-temporal-depth-resolve",colorAttachments:[],depthStencilAttachment:{view:this.state.mainDepthView,depthLoadOp:"load",depthStoreOp:"store"}}));const i=this.getOrCreateStaticVisibleDepthSceneBindGroup(r);this.renderBundleScratch[0]=ln.call(this,r,i,r.drawMetadataResource.postIndirectBuffer,"postpass"),t.executeBundles(this.renderBundleScratch)}t?.end()}function un(e){for(const t of e.draws)if(t.customDepthMaterial||Ji(t,"prepass")||Tn(t.material)||!Xi(t))return!1;return!0}function dn(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=hn.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&&(Tn(r.material)||!Xi(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??Hr,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 hn(e,t){const r=t,i=e.depthMaterialResources.get(r);if(i)return i;const n=e.draws.map(e=>{const r=Ji(e,t);if(e.customDepthMaterial||!r)return null;return this.getDepthPassMaterialResourceForDraw(e.material,t,e)});return e.depthMaterialResources.set(r,n),n}function pn(e,t,r,i,n,a){if(!this.state.device)throw new Error("Renderer is not initialized.");const s=this.resolveShadowBindGroupForDraw(e.draws[0],t,r),o=e.shadowBundles.get(s),l=o?.[i];if(l)return l;const c=hn.call(this,e,i),u=`${e.label}-static-${i}-bundle-${e.id}`,d=this.state.device.createRenderBundleEncoder({label:u,colorFormats:"pointShadow"===i?["rgba16float"]:[],depthStencilFormat:"depth32float",sampleCount:1});d.setBindGroup(0,s);let h=null,p=null,f=null;for(let t=0;t<e.draws.length;t+=1){const r=e.draws[t];if(!r.castShadow)continue;const i=c[t],s=i?.pipeline??("instanced-direct"===this.getDrawInstanceAccessMode(r)&&a?a:n);h!==s&&(h=s,p=null,f=null,d.setPipeline(s)),i&&p!==i.bindGroup&&(p=i.bindGroup,d.setBindGroup(1,p)),f!==r.geometryKey&&(f=r.geometryKey,this.bindGeometryVertexBuffers(d,r.geometry,r.geometryResource,i?.vertexAttributes??Hr,r.instanceStart,r.instanceCount,r.wireframe)),d.drawIndexed(r.count,r.instanceCount,r.start,0,r.instanceStart)}const m=d.finish({label:u});return e.shadowBundles.set(s,{...o,[i]:m}),m}function fn(e,t=!1){if(!(this.state.device&&this.state.hizTexture&&this.state.mainDepthTexture&&this.state.mainDepthView&&this.state.hizCopyKernel&&this.state.hizReduceKernel))return;let r=this.state.hizCopyBindGroup;r||(r=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=r);const i=e.beginComputePass({label:"renderer-hiz-copy-pass"});i.setPipeline(this.state.hizCopyKernel.pipeline),i.setBindGroup(0,r),i.dispatchWorkgroups(Math.ceil(this.state.width/8),Math.ceil(this.state.height/8)),i.end();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 mn(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,[$r],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("late"!==o&&this.executeStaticForwardPass(p,i,a),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=Ri(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||Ri(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 gn(e,t,r){for(const i of this.staticDrawSets)if(i.publicSet.enabled&&0!==i.draws.length){if(this.getHiZOcclusionCullingActive()&&i.lastVisibilityFrameToken===this.staticFrameToken){const t=this.getOrCreateStaticVisibleSceneBindGroup(i),n=this.getOrCreateStaticIndirectSubmissionStreams(i,t);for(const t of n)if(this.getMultiDrawIndirectActive()){if(e.setPipeline(t.materialResource.pipeline),this.bindGeometryVertexBuffers(e,t.geometry,t.geometryResource,t.materialResource.vertexAttributes,0,1,t.material.wireframe),e.setBindGroup(0,t.sceneBindGroup),e.setBindGroup(1,t.materialResource.bindGroup),!t.materialResource.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");e.setBindGroup(3,this.createGraphTextureBindGroup(t.material,t.materialResource.graphTextureBindGroupLayout)),e.multiDrawIndexedIndirect(i.drawMetadataResource.indirectBuffer,5*t.indirectStartIndex*Uint32Array.BYTES_PER_ELEMENT,t.indirectCount),r.drawCallCount+=t.drawCallCount,r.triangleCount+=t.triangleCount}else this.renderBundleScratch[0]=this.getOrCreateIndirectForwardBundle(t,i.drawMetadataResource,i.indirectForwardBundleCache,`${i.label}-static-indirect-forward-bundle`),e.executeBundles(this.renderBundleScratch),r.drawCallCount+=t.drawCallCount,r.triangleCount+=t.triangleCount;continue}this.renderBundleScratch[0]=this.getOrCreateStaticDirectForwardBundle(i,t),e.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(i,r)}}function vn(e,t){if(!this.state.device||!this.state.format)throw new Error("Renderer is not initialized.");const r=this.resolveSceneBindGroupForDraw(e.draws[0],t);if(e.directForwardBundle&&e.directForwardBundleSceneBindGroup===r)return e.directForwardBundle;null==e.draws[0]?.materialResource&&(this.refreshStaticDrawMaterialResources(e.draws),this.syncStaticVisibleMaterialBindingCaches(e));const i=`${e.label}-static-forward-direct-bundle-${e.id}`,n=this.state.device.createRenderBundleEncoder({label:i,colorFormats:[$r],depthStencilFormat:"depth32float",sampleCount:this.sampleCount});let a=null,s=null,o=null;n.setBindGroup(0,r);for(const t of e.draws){const e=t.materialResource??this.getMaterialResource(t.material,this.getDrawInstanceAccessMode(t),t.receiveShadow,void 0,null!==t.skinning,Yi(t));if(a!==e.pipeline&&(a=e.pipeline,o=null,n.setPipeline(a)),o!==t.geometryKey&&(o=t.geometryKey,this.bindGeometryVertexBuffers(n,t.geometry,t.geometryResource,e.vertexAttributes,t.instanceStart,t.instanceCount,t.wireframe)),s!==e.bindGroup){if(s=e.bindGroup,n.setBindGroup(1,s),!e.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");n.setBindGroup(3,this.createGraphTextureBindGroup(t.material,e.graphTextureBindGroupLayout))}n.drawIndexed(t.count,t.instanceCount,t.start,0,t.instanceStart)}const l=n.finish({label:i});return e.directForwardBundle=l,e.directForwardBundleSceneBindGroup=r,l}function xn(e){for(const t of e.visibleMaterialBindings){const r=t.drawIndices[0];t.resource=e.draws[r]?.materialResource??e.visibleDrawMaterialResources[r]??null}}function wn(e){for(const t of e)t.materialResource=this.getMaterialResource(t.material,this.getDrawInstanceAccessMode(t),t.receiveShadow,void 0,null!==t.skinning,Yi(t))}function bn(e,t){t.drawCallCount+=e.drawCallCount,t.triangleCount+=e.triangleCount}function yn(){return this.staticDrawSets.some(e=>e.publicSet.enabled&&e.draws.length>0)}function Sn(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 Cn(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 Pn(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 Mn(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 Bn(e,t,r,i){let n=null,a=null,s=null,o=null,l=null;for(const c of t){if("prepass"!==i.passKind&&!c.castShadow)continue;if("prepass"===i.passKind&&null===c.material.depthVertexShader&&Tn(c.material))continue;if("skip"===i.customDepthMode&&c.customDepthMaterial)continue;const t=Ji(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&&!Xi(c))continue;const h=null!==c.skinning,p=d?.pipeline??(h&&i.fallbackSkinnedPipeline?i.fallbackSkinnedPipeline:"instanced-direct"===this.getDrawInstanceAccessMode(c)&&i.fallbackPipelineDirect?i.fallbackPipelineDirect:i.fallbackPipeline);a!==p&&(a=p,s=null,o=null,l=null,n=null,e.setPipeline(p));const f="prepass"===i.passKind?this.resolveSceneBindGroupForDraw(c,i.fallbackBindGroup):this.resolveShadowBindGroupForDraw(c,i.fallbackBindGroup,i.shadowCameraBuffer);s!==f&&(s=f,e.setBindGroup(0,f)),d?o!==d.bindGroup&&(o=d.bindGroup,e.setBindGroup(1,d.bindGroup)):o=null,(d?.usesSkinning??h)&&c.skinning&&l!==c.skinning.bindGroup&&(l=c.skinning.bindGroup,e.setBindGroup(2,l));const m=c.geometryResource;n!==c.geometryKey&&(n=c.geometryKey,this.bindGeometryVertexBuffers(e,c.geometry,m,d?.vertexAttributes??(h?qr:Hr),c.instanceStart,c.instanceCount,c.wireframe)),c.indexed&&(c.wireframe?m.wireframeIndex:m.index)?e.drawIndexed(c.count,c.instanceCount,c.start,0,c.instanceStart):e.draw(c.count,c.instanceCount,c.start,c.instanceStart),this.recordDraw(c,r)}}var Dn=new WeakMap;function Tn(e){if(e.transparent)return!0;let t=Dn.get(e);return null==t&&(t=e.transparent||e.alphaTest>0||/\bdiscard\b/.test(e.fragmentShader),Dn.set(e,t)),t}import{Vector3 as In}from"three";var Rn=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/Er}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+Er);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+=Er,u}appendRange(e,t,r){if(r<=0)return;const i=t*Er,n=i+r*Er;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*Er;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}},Gn=class{constructor(e,t,r,i,n){this.state=e,this.staticDrawSets=t,this.getGeometryResourceForGeometry=r,this.resolveMaterial=i,this.ensureWireframeIndex=n}state;staticDrawSets;getGeometryResourceForGeometry;resolveMaterial;ensureWireframeIndex;nextStaticDrawSetId=1;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=[],a=new Rn(4096),s=(e,t)=>{if("skip"!==i)throw new Error(`StaticDrawSet "${r}" does not support ${e.type||"Object3D"} "${e.name||e.uuid}": ${t}.`)};e.updateMatrixWorld(!0);const o=new Map;this.activeMaterialSnapshots=o;try{e.traverseVisible(e=>{e.isSkinnedMesh?s(e,"skinned meshes are dynamic"):e.isBatchedMesh?this.collectStaticBatchedMesh(e,a,n,r,s):e.isInstancedMesh?this.collectStaticInstancedMesh(e,a,n,r,s):e.isMesh&&this.collectStaticMesh(e,a,n,r,s)})}catch(e){for(const e of o.values())e.dispose();throw e}finally{this.activeMaterialSnapshots=null}const{draws:l,instanceData:c}=this.mergeStaticDraws(n,a),u=this.createVisibleMaterialBindings(l),d=Math.max(4,c.byteLength),h=this.state.device.createBuffer({label:`${r}-static-instance-buffer`,size:256*Math.ceil(d/256),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});c.floatLength>0?this.state.device.queue.writeBuffer(h,0,c.rawData.buffer,0,c.byteLength):this.state.device.queue.writeBuffer(h,0,Or,0,Er);const p={mode:"packed",buffer:h,colorBuffer:null,sceneBindGroup:null,shadowBindGroup:null,shadowBindGroups:new Map,sceneBindGroupVersion:0,shadowBindGroupVersion:0};for(const e of l)e.residentInstanceBinding=p;const f=this.createStaticDrawMetadataResource(r,l),m=this.createStaticInstanceVisibilityResource(r,l,c),g=new Uint32Array([l.length,this.state.hizMipCount,c.instanceCount,0]),v=this.state.device.createBuffer({label:`${r}-visibility-params-buffer`,size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),x=new Uint32Array([l.length,this.state.hizMipCount,c.instanceCount,0]),w=this.state.device.createBuffer({label:`${r}-post-visibility-params-buffer`,size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});this.state.device.queue.writeBuffer(v,0,g,0,4),this.state.device.queue.writeBuffer(w,0,x,0,4);const b={id:this.nextStaticDrawSetId++,label:r,publicSet:null,ownedMaterials:[...o.values()],draws:l,drawCallCount:l.length,triangleCount:l.reduce((e,t)=>e+Math.floor(Math.max(0,t.count)/3)*Math.max(0,t.instanceCount),0),instanceCount:c.instanceCount,instanceBuffer:h,residentInstanceBinding:p,drawMetadataResource:f,instanceVisibilityResource:m,visibilityParamsBuffer:v,visibilityParamsUpload:g,postVisibilityParamsBuffer:w,postVisibilityParamsUpload:x,visibilityBindGroup:null,postVisibilityBindGroup:null,visibilityClearBindGroup:null,visibilityIndirectBuildBindGroup:null,postVisibilityIndirectBuildBindGroup:null,visibleSceneBindGroup:null,visibleSceneBindGroupVersion:0,visibleDepthSceneBindGroup:null,visibleDepthSceneBindGroupVersion:0,visibleMaterialBindings:u,visibleDrawMaterialResources:new Array(l.length),visibleIndirectSubmissionStreams:null,visibleIndirectStreamsSceneBindGroup:null,visibleIndirectStreamsSampleCount:-1,visibleIndirectStreamsColorFormatsKey:"",visibilityBindGroupHizVersion:0,lastPreVisibilityFrameToken:0,lastVisibilityFrameToken:0,indirectForwardBundleCache:new Map,directForwardBundle:null,directForwardBundleSceneBindGroup:null,depthPrepassBundle:null,depthPrepassBundleSceneBindGroup:null,indirectDepthPrepassBundles:{prepass:null,postpass:null},shadowBundles:new WeakMap,depthMaterialResources:new Map},y={label:r,enabled:!0,get drawCount(){return b.draws.length},get instanceCount(){return b.instanceCount},dispose:()=>{this.disposeStaticDrawSetResource(b)}};return b.publicSet=y,this.staticDrawSets.push(b),y}createVisibleMaterialBindings(e){const t=new Map;for(let r=0;r<e.length;r+=1){const i=e[r],n=`${Mi(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()]}mergeStaticDraws(e,t){e.sort(Ti);const r=[],i=new Rn(Math.max(1024,t.floatLength));for(let n=0;n<e.length;){const a=e[n],s=i.instanceCount;i.appendRange(t,a.instanceStart,a.instanceCount);let o=a.instanceCount,l=a.boundsCenter.x-a.boundsRadius,c=a.boundsCenter.y-a.boundsRadius,u=a.boundsCenter.z-a.boundsRadius,d=a.boundsCenter.x+a.boundsRadius,h=a.boundsCenter.y+a.boundsRadius,p=a.boundsCenter.z+a.boundsRadius,f=n+1;for(;f<e.length&&zi(a,e[f]);){const r=e[f];i.appendRange(t,r.instanceStart,r.instanceCount),o+=r.instanceCount;const n=r.boundsCenter.x-r.boundsRadius,a=r.boundsCenter.y-r.boundsRadius,s=r.boundsCenter.z-r.boundsRadius,m=r.boundsCenter.x+r.boundsRadius,g=r.boundsCenter.y+r.boundsRadius,v=r.boundsCenter.z+r.boundsRadius;n<l&&(l=n),a<c&&(c=a),s<u&&(u=s),m>d&&(d=m),g>h&&(h=g),v>p&&(p=v),f+=1}const m=.5*(l+d),g=.5*(c+h),v=.5*(u+p),x=d-m,w=h-g,b=p-v;a.instanceStart=s,a.instanceCount=o,a.boundsCenter.set(m,g,v),a.boundsRadius=Math.sqrt(x*x+w*w+b*b),r.push(a),n=f}return{draws:r,instanceData:i}}collectStaticMesh(e,t,r,i,n){if(!(null!==e.geometry.index))return void n(e,"non-indexed geometry cannot use the v1 indirect static path");if(_i(e))return void n(e,"custom depth materials are not supported by StaticDrawSet v1");const a=this.getGeometryResource(e.geometry),s=Oi(e.geometry),o=Xr.copy(s.center).applyMatrix4(e.matrixWorld),l=s.radius*ji(e.matrixWorld),c=Ci(t,e.matrixWorld,1,1,1,1),u=Array.isArray(e.material)?e.material:null,d=Array.isArray(e.material)?null:e.material;if(e.geometry.groups.length>0){for(const t of e.geometry.groups){const i=u?u[t.materialIndex??0]??u[0]:d,h=this.resolveStaticMaterial(i);if(!h){n(e,"all static mesh materials must be WGSLShaderMaterial");continue}if(h.transparent){n(e,"transparent materials are not supported by StaticDrawSet v1");continue}if(Object.keys(h.getGraphTextureInputs()).length>0){n(e,"scene-texture materials are not supported by StaticDrawSet v1");continue}const p=gi(e.geometry,!0,t.start,t.count);p<=0||r.push(this.createStaticDrawRecord(e.geometry,e.geometry,a,h,!1,t.start,p,c,1,o.x,o.y,o.z,l,s.center,s.radius))}return}const h=d??u?.[0]??null,p=this.resolveStaticMaterial(h);if(!p)return void n(e,"all static mesh materials must be WGSLShaderMaterial");if(p.transparent)return void n(e,"transparent materials are not supported by StaticDrawSet v1");if(Object.keys(p.getGraphTextureInputs()).length>0)return void n(e,"scene-texture materials are not supported by StaticDrawSet v1");const f=vi(e.geometry,!0);f.count<=0||r.push(this.createStaticDrawRecord(e.geometry,e.geometry,a,p,!1,f.start,f.count,c,1,o.x,o.y,o.z,l,s.center,s.radius))}collectStaticInstancedMesh(e,t,r,i,n){const a=this.resolveStaticMaterial(e.material);if(!a)return void n(e,"static instanced meshes must use WGSLShaderMaterial");if(a.transparent)return void n(e,"transparent materials are not supported by StaticDrawSet v1");if(Object.keys(a.getGraphTextureInputs()).length>0)return void n(e,"scene-texture materials are not supported by StaticDrawSet v1");if(_i(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 s=vi(e.geometry,!0);if(s.count<=0||e.count<=0)return;const o=Oi(e.geometry),l=Xr.set(1/0,1/0,1/0),c=Jr.set(-1/0,-1/0,-1/0),u=this.getGeometryResource(e.geometry),d=t.instanceCount;for(let r=0;r<e.count;r+=1){e.getMatrixAt(r,Kr),Zr.multiplyMatrices(e.matrixWorld,Kr);const i=e.instanceColor?e.instanceColor.getComponent(r,0):1,n=e.instanceColor&&e.instanceColor.itemSize>1?e.instanceColor.getComponent(r,1):1,a=e.instanceColor&&e.instanceColor.itemSize>2?e.instanceColor.getComponent(r,2):1,s=e.instanceColor&&e.instanceColor.itemSize>3?e.instanceColor.getComponent(r,3):1;Ci(t,Zr,i,n,a,s);$i(l,c,Qr.copy(o.center).applyMatrix4(Zr),o.radius*ji(Zr))}const h=.5*(l.x+c.x),p=.5*(l.y+c.y),f=.5*(l.z+c.z),m=c.x-h,g=c.y-p,v=c.z-f,x=Math.sqrt(m*m+g*g+v*v);r.push(this.createStaticDrawRecord(e.geometry,e.geometry,u,a,!1,s.start,s.count,d,e.count,h,p,f,x,o.center,o.radius))}collectStaticBatchedMesh(e,t,r,i,n){const a=this.resolveStaticMaterial(e.material);if(!a)return void n(e,"static batched meshes must use WGSLShaderMaterial");if(a.transparent)return void n(e,"transparent materials are not supported by StaticDrawSet v1");if(Object.keys(a.getGraphTextureInputs()).length>0)return void n(e,"scene-texture materials are not supported by StaticDrawSet v1");if(_i(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 s=e,o=this.getGeometryResource(e.geometry),l=s._geometryCount??0,c=[],u=new Map;for(let t=0;t<l;t+=1){const r=e.getGeometryRangeAt(t);if(!r||r.count<=0)continue;const i=gi(e.geometry,!0,r.start,r.count);if(i<=0)continue;const n=e.getBoundingSphereAt(t,Yr),a={geometryId:t,start:r.start,count:i,localBoundsCenter:n?n.center.clone():new In,localBoundsRadius:n?.radius??1,instances:[]};u.set(t,a),c.push(a)}const d=s._instanceInfo??s._drawInfo??[],h=s._matricesTexture?.image.data,p=s._colorsTexture?.image.data;for(let t=0;t<d.length;t+=1){const r=d[t];if(!r?.active||!r.visible)continue;const i=u.get(r.geometryIndex);if(!i)continue;h?Pi(Kr,h,16*t):e.getMatrixAt(t,Kr),Zr.multiplyMatrices(e.matrixWorld,Kr);const n=4*t,a=p?p[n+0]??1:1,s=p?p[n+1]??1:1,o=p?p[n+2]??1:1,l=p?p[n+3]??1:1,c=Qr.copy(i.localBoundsCenter).applyMatrix4(Zr),f=i.localBoundsRadius*ji(Zr);i.instances.push({matrix:new Float32Array(Zr.elements),color0:a,color1:s,color2:o,color3:l,batchingId:t,boundsCenter:c.clone(),boundsRadius:f})}for(const i of c){if(0===i.instances.length)continue;const n=Xr.set(1/0,1/0,1/0),s=Jr.set(-1/0,-1/0,-1/0),l=t.instanceCount;for(const e of i.instances)t.appendMatrixAndColorValues(e.matrix,e.color0,e.color1,e.color2,e.color3,e.batchingId),$i(n,s,e.boundsCenter,e.boundsRadius);const c=.5*(n.x+s.x),u=.5*(n.y+s.y),d=.5*(n.z+s.z),h=s.x-c,p=s.y-u,f=s.z-d,m=Math.sqrt(h*h+p*p+f*f);r.push(this.createStaticDrawRecord(e.geometry,e.geometry,o,a,!0,i.start,i.count,l,i.instances.length,c,u,d,m,i.localBoundsCenter,i.localBoundsRadius))}}createStaticDrawRecord(e,t,r,i,n,a,s,o,l,c,u,d,h,p,f){const m=Mi(i),g=i.wireframe&&"triangle-list"===i.primitiveTopology;g&&this.ensureWireframeIndex(e,r);const v=Mi(t);return{geometry:e,geometryKey:g?r.wireframeIndex:t,geometryResource:r,material:i,customDepthMaterial:null,residentInstanceBinding:null,sourceObject:null,usesBatching:n,geometryGroup:null,batchKey:Bi(i,t,!0,a,s,null),batchHash:Di(m,v,!0,a,s,0),indexed:!0,wireframe:g,start:g?2*a:a,count:g?2*s:s,transparent:!1,renderOrder:0,hasRenderCallbacks:!1,castShadow:!0,receiveShadow:!0,sortMaterialId:m,sortGeometryId:v,sortCustomDepthMaterialId:0,skinning:null,materialResource:null,instanceStart:o,instanceCount:l,boundsCenter:new In(c,u,d),boundsRadius:h,sortDepth:0,transparentSortGroup:0,transparentSortOrder:0,staticLocalBoundsCenter:p.clone(),staticLocalBoundsRadius:f}}createStaticDrawMetadataResource(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=Math.max(1,t.length),i=new Float32Array(r*kr),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*kr;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*kr*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??Oi(i.geometry).center,a=i.staticLocalBoundsRadius??Oi(i.geometry).radius;for(let t=0;t<i.instanceCount;t+=1){const l=i.instanceStart+t,c=l*Er,u=8*l;Kr.fromArray(r.rawData,c);const d=Xr.copy(n).applyMatrix4(Kr),h=a*ji(Kr);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,o[u+6]=0,o[u+7]=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),{instanceMetadataBuffer:l,visibleInstanceIndicesBuffer:c,visibleCountsBuffer:u,postVisibleCountsBuffer:d,visibleInstanceMaskBuffer:h,instanceCount:i}}disposeStaticDrawSetResource(e){const t=this.staticDrawSets.indexOf(e);if(t<0)return;this.staticDrawSets.splice(t,1);const r=new Set;for(const t of e.draws)t.materialResource&&r.add(t.materialResource);for(const t of e.visibleMaterialBindings)t.resource&&r.add(t.resource);for(const t of e.visibleDrawMaterialResources)t&&r.add(t);for(const t of e.depthMaterialResources.values())for(const e of t)e&&r.add(e);for(const e of r)e.uniformBuffer?.destroy();e.instanceBuffer.destroy(),e.drawMetadataResource.metadataBuffer.destroy(),e.drawMetadataResource.indirectBuffer.destroy(),e.drawMetadataResource.postIndirectBuffer.destroy(),e.instanceVisibilityResource.instanceMetadataBuffer.destroy(),e.instanceVisibilityResource.visibleInstanceIndicesBuffer.destroy(),e.instanceVisibilityResource.visibleCountsBuffer.destroy(),e.instanceVisibilityResource.postVisibleCountsBuffer.destroy(),e.instanceVisibilityResource.visibleInstanceMaskBuffer.destroy(),e.visibilityParamsBuffer.destroy(),e.postVisibilityParamsBuffer.destroy();for(const t of e.ownedMaterials)t.dispose();e.ownedMaterials.length=0,e.residentInstanceBinding.buffer=null,e.residentInstanceBinding.colorBuffer=null,e.residentInstanceBinding.sceneBindGroup=null,e.residentInstanceBinding.shadowBindGroup=null,e.residentInstanceBinding.shadowBindGroups.clear(),e.visibilityBindGroup=null,e.postVisibilityBindGroup=null,e.visibilityClearBindGroup=null,e.visibilityIndirectBuildBindGroup=null,e.postVisibilityIndirectBuildBindGroup=null,e.visibleSceneBindGroup=null,e.visibleDepthSceneBindGroup=null,e.visibleMaterialBindings.length=0,e.visibleDrawMaterialResources.length=0,e.visibleIndirectSubmissionStreams=null,e.visibleIndirectStreamsSceneBindGroup=null,e.visibleIndirectStreamsSampleCount=-1,e.visibleIndirectStreamsColorFormatsKey="",e.indirectForwardBundleCache.clear(),e.directForwardBundle=null,e.directForwardBundleSceneBindGroup=null,e.depthPrepassBundle=null,e.depthPrepassBundleSceneBindGroup=null,e.indirectDepthPrepassBundles.prepass=null,e.indirectDepthPrepassBundles.postpass=null,e.shadowBundles=new WeakMap,e.depthMaterialResources.clear()}},Vn=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":wi(e.magFilter),n=r?"nearest":wi(e.minFilter),a=r?"nearest":wi(e.minFilter),s="comparison"===t?function(e){switch(e){case Rr:return"never";case Pr:return"less";case yr:return"equal";case Mr:return"less-equal";case Sr:return"greater";case Gr:return"not-equal";case Cr:return"greater-equal";case wr: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:xi(e.wrapS),addressModeV:xi(e.wrapT),addressModeW:xi(e.wrapR??e.wrapT),magFilter:i,minFilter:n,mipmapFilter:a,maxAnisotropy:o,compare:s})}uploadDataTextureResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const i=function(e){switch(e){case"r8unorm":case"r8snorm":case"r8uint":case"r8sint":return 1;case"r16uint":case"r16sint":case"r16float":case"rg8unorm":case"rg8snorm":case"rg8uint":case"rg8sint":case"depth16unorm":return 2;case"r32uint":case"r32sint":case"r32float":case"rg16uint":case"rg16sint":case"rg16float":case"rgba8unorm":case"rgba8unorm-srgb":case"rgba8snorm":case"rgba8uint":case"rgba8sint":case"bgra8unorm":case"bgra8unorm-srgb":case"rgb9e5ufloat":case"rgb10a2unorm":case"rg11b10ufloat":case"depth32float":return 4;case"rg32uint":case"rg32sint":case"rg32float":case"rgba16uint":case"rgba16sint":case"rgba16float":return 8;case"rgba32uint":case"rgba32sint":case"rgba32float":return 16;default:return null}}(r.format);if(null===i)throw new Error(`Texture format "${r.format}" from "${e.constructor.name}" cannot be uploaded with queue.writeTexture.`);const n=e.mipmaps;if(n&&n.length>0){for(let e=0;e<n.length;e+=1){const a=n[e];if(!a?.data)continue;const s=a.width??Math.max(1,r.width>>e),o=a.height??Math.max(1,r.height>>e),l=a.depth??r.depthOrArrayLayers;this.state.device.queue.writeTexture({texture:t,mipLevel:e},yi(a.data),{bytesPerRow:s*i,rowsPerImage:o},{width:s,height:o,depthOrArrayLayers:l})}return}const a=e.image;a?.data&&this.state.device.queue.writeTexture({texture:t},a.data,{bytesPerRow:r.width*i,rowsPerImage:r.height},{width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers})}uploadCompressedTextureResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const i="bc1-rgba-unorm"===(n=r.format)||"bc1-rgba-unorm-srgb"===n?{byteLength:8,width:4,height:4}:"bc2-rgba-unorm"===n||"bc2-rgba-unorm-srgb"===n||"bc3-rgba-unorm"===n||"bc3-rgba-unorm-srgb"===n?{byteLength:16,width:4,height:4}:"bc4-r-unorm"===n||"bc4-r-snorm"===n?{byteLength:8,width:4,height:4}:"bc5-rg-unorm"===n||"bc5-rg-snorm"===n||"bc6h-rgb-ufloat"===n||"bc6h-rgb-float"===n||"bc7-rgba-unorm"===n||"bc7-rgba-unorm-srgb"===n?{byteLength:16,width:4,height:4}:"etc2-rgb8unorm"===n||"etc2-rgb8unorm-srgb"===n||"etc2-rgb8a1unorm"===n||"etc2-rgb8a1unorm-srgb"===n?{byteLength:8,width:4,height:4}:"etc2-rgba8unorm"===n||"etc2-rgba8unorm-srgb"===n?{byteLength:16,width:4,height:4}:"eac-r11unorm"===n||"eac-r11snorm"===n?{byteLength:8,width:4,height:4}:"eac-rg11unorm"===n||"eac-rg11snorm"===n||"astc-4x4-unorm"===n||"astc-4x4-unorm-srgb"===n?{byteLength:16,width:4,height:4}:"astc-5x4-unorm"===n||"astc-5x4-unorm-srgb"===n?{byteLength:16,width:5,height:4}:"astc-5x5-unorm"===n||"astc-5x5-unorm-srgb"===n?{byteLength:16,width:5,height:5}:"astc-6x5-unorm"===n||"astc-6x5-unorm-srgb"===n?{byteLength:16,width:6,height:5}:"astc-6x6-unorm"===n||"astc-6x6-unorm-srgb"===n?{byteLength:16,width:6,height:6}:"astc-8x5-unorm"===n||"astc-8x5-unorm-srgb"===n?{byteLength:16,width:8,height:5}:"astc-8x6-unorm"===n||"astc-8x6-unorm-srgb"===n?{byteLength:16,width:8,height:6}:"astc-8x8-unorm"===n||"astc-8x8-unorm-srgb"===n?{byteLength:16,width:8,height:8}:"astc-10x5-unorm"===n||"astc-10x5-unorm-srgb"===n?{byteLength:16,width:10,height:5}:"astc-10x6-unorm"===n||"astc-10x6-unorm-srgb"===n?{byteLength:16,width:10,height:6}:"astc-10x8-unorm"===n||"astc-10x8-unorm-srgb"===n?{byteLength:16,width:10,height:8}:"astc-10x10-unorm"===n||"astc-10x10-unorm-srgb"===n?{byteLength:16,width:10,height:10}:"astc-12x10-unorm"===n||"astc-12x10-unorm-srgb"===n?{byteLength:16,width:12,height:10}:"astc-12x12-unorm"===n||"astc-12x12-unorm-srgb"===n?{byteLength:16,width:12,height:12}:null;var n;if(!i)throw new Error(`Compressed texture format "${r.format}" is not supported for upload.`);if(!0===e.isCompressedCubeTexture){const n=e.image;for(let e=0;e<n.length;e+=1){const a=n[e]?.mipmaps??[];for(let n=0;n<a.length;n+=1){const s=a[n];if(!s?.data)continue;const o=s.width??Math.max(1,r.width>>n),l=s.height??Math.max(1,r.height>>n),c=Math.max(1,Math.ceil(o/i.width)),u=Math.max(1,Math.ceil(l/i.height));this.state.device.queue.writeTexture({texture:t,mipLevel:n,origin:{x:0,y:0,z:e}},yi(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},yi(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: ${zn(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: ${zn(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=Se(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 zn(e){return e instanceof Error?e.message:String(e)}var Un="\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",Ln="\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",An="\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",Fn=`\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${An}\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`,En=`\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${An}\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`,kn=`\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${An}\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`,On="\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 jn(e){if(e.transparent)switch(e.blending){case it:return{color:{srcFactor:"src-alpha",dstFactor:"one",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one",operation:"add"}};case vt:return{color:{srcFactor:"zero",dstFactor:"one-minus-src",operation:"subtract"},alpha:{srcFactor:"one",dstFactor:"one",operation:"subtract"}};case dt: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 $n(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 Nn(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=$n(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=$n(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 Wn(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 _n(e){const t=Number(e.userData.motionBlurScale??1);return Number.isFinite(t)?Math.max(0,Math.min(t,8)):1}var Hn="chromium-experimental-multi-draw-indirect",qn=[$r],Kn=[{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 Zn(e){return e.wireframe&&"triangle-list"===e.primitiveTopology?"line-list":e.primitiveTopology}function Yn(e,t,r){if(!Zn(e).startsWith("triangle"))return"none";if("directionalShadow"===t){if(r&&null===e.shadowSide)return"none";const t=e.shadowSide??(e.side===nt?ct:e.side===lt?lt:nt);return t===lt?"none":t===nt?"front":"back"}return e.side===lt?"none":e.side===nt?"front":"back"}function Xn(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 Jn=class{canvas;clearColor;powerPreference;shadowMapSize;pointShadowMapSize;fallbackMaterial;materialResolver;toonOutlineMaterialCache=new WeakMap;fallbackSkinnedMaterial;invokeObjectRenderCallbacks;sampleCount;renderScale;hiZOcclusionCullingEnabled;multiDrawIndirectEnabled;dynamicBatchingEnabled;multiDrawIndirectSupported=!1;renderGraphProfilingEnabled;indirectFirstInstanceSupported=!1;timestampQuerySupported=!1;geometryCache=new WeakMap;skinnedGeometryCache=new Map;skinPaletteCache=new WeakMap;skinPaletteResources=new Set;meshExtractionCache=new WeakMap;resolvedMaterialFrameCache=new WeakMap;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:[],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,pixelRatio:1,width:1,height:1,presentationWidth:1,presentationHeight:1,frameTimeSeconds:0,frameIndex:0,directionalShadowTextureSize:1,pointShadowTextureSize:1,spotShadowTextureSize:1,latestFrameProfile:null,latestCompletedFrameProfile:null,residentSceneBindGroupVersion:0,residentShadowBindGroupVersion:0,initialized:!1}}();textureCache=new WeakMap;graphTextureBindGroupCache=new WeakMap;materialGraphTextureReadCache=new WeakMap;defaultInstanceAttributeBuffers=new Map;textureManager=new Vn(this.state,this.textureCache);renderGraph=new Yt;directionalShadowCameras=Array.from({length:4},()=>new ft(-10,10,10,-10,.1,80));pointShadowCameras=Array.from({length:4},()=>_r.map(()=>new mt(90,1,.1,25)));spotShadowCameras=Array.from({length:4},()=>new mt(60,1,.5,500));colorTargetCache=new Map;msaaColorTargetCache=new Map;msaaDepthTargetCache=new Map;sourceInstanceDataScratch=new Rn(4096);opaqueInstanceDataScratch=new Rn(4096);finalInstanceDataScratch=new Rn(4096);residentInstanceUploadsScratch=[];gpuOpaqueDrawsScratch=[];directOpaqueDrawsScratch=[];stagedOpaqueDrawsScratch=[];residentOpaqueDrawsScratch=[];retiredGeometryResources=[];retiredGeometryBuffers=[];vertexAttributeBufferKeyCache=new WeakMap;standardVertexAttributeCache=new WeakMap;geometryVertexBufferFastCache=new WeakMap;vertexAttributeGroupCache=new WeakMap;vertexAttributeGroupBufferKeyCache=new WeakMap;compileDrawScratch=[];dynamicIndirectSubmissionCache=new WeakMap;indirectStreamKeyCache=new WeakMap;nextIndirectStreamKey=1;indirectBundleInvalidationVersion=0;colorFormatsIdentityCache=new WeakMap;colorFormatsValueCache=new Map([[$r,1]]);nextColorFormatsId=2;renderBundleScratch=[];indirectMaterialResourcesScratch=[];directBundleDrawStatsScratch={drawCallCount:0,triangleCount:0};sortedOpaqueBatchesScratch=[];opaqueBatchPool=[];opaqueBatchPoolCount=0;drawCallPool=[];drawCallPoolCount=0;staticDrawSets=[];materialPassStaticBundleCache=new WeakMap;staticDrawSetManager=new Gn(this.state,this.staticDrawSets,e=>this.getGeometryResource(e),e=>this.resolveMaterial(e),(e,t)=>this.ensureWireframeIndex(e,t));staticFrameToken=0;hizResourceVersion=0;graphTextureResourceVersion=0;visibilityParamsUpload=new Uint32Array(4);drawMetadataUpload=new Float32Array(0);indirectDrawUpload=new Uint32Array(0);extractedAmbientScratch=new bt;extractedHemisphereScratch=this.createExtractedHemisphereLightScratch();extractedBoundsMinScratch=new wt;extractedBoundsMaxScratch=new wt;extractedDirectionalLightsScratch=Array.from({length:4},()=>this.createExtractedDirectionalLightScratch());extractedPointLightsScratch=Array.from({length:4},()=>this.createExtractedPointLightScratch());extractedSpotLightsScratch=Array.from({length:4},()=>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(396);csmCascadeRanges=Array.from({length:4},()=>new xt);csmCascadeCount=0;csmCascadeLights=[];shadowCameraUniformScratch=new Float32Array(64);cameraViewProjScratch=new ht;cameraProjectionScratch=new ht;projectionJitterPixels=new xt;temporalVisibilityCurrentViewProj=new ht;temporalVisibilityPreviousViewProj=new ht;motionVectorProjection=new ht;motionVectorCurrentViewProj=new ht;motionVectorPreviousViewProj=new ht;motionVectorProjectionPending=!1;motionVectorHistoryValid=!1;motionVectorHistoryGeneration=1;lastMotionVectorTimeSeconds=Number.NaN;objectMotionHistory=new WeakMap;cameraFrustumPlanesScratch=new Float32Array(24);objectTraversalStackScratch=[];isSphereVisibleScratch=(e,t,r,i,n)=>!n||function(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}(this.cameraFrustumPlanesScratch,e,t,r,i);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 wt;transparentSortCameraForwardScratch=new wt;temporalVisibilityCurrentCameraPosition=new wt;temporalVisibilityPreviousCameraPosition=new wt;shadowViewProjScratch=new ht;extractionVersion=0;graphBuilder=(e,t)=>{t.addDirectionalShadowPass(),t.addPointShadowPass(),t.addSpotShadowPass(),t.addDepthPrepass(),t.addHiZPasses(),t.addVisibilityPass(),t.addForwardPass(),t.addPresentPass()};createExtractedDirectionalLightScratch(){return{sourceLight:null,position:new wt,target:new wt,direction:new wt,color:new wt,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 wt(0,1,0),skyColor:new wt,groundColor:new wt,intensity:0}}createExtractedPointLightScratch(){return{position:new wt,color:new wt,intensity:0,volumetricIntensity:1,range:25,decay:2,castShadow:!1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowIntensity:1,shadowMapSize:this.pointShadowMapSize,shadowCameraNear:.5,shadowCameraFar:500}}createExtractedSpotLightScratch(){return{position:new wt,direction:new wt(0,-1,0),color:new wt,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}}constructor(e){this.canvas=e.canvas,this.clearColor=[...e.clearColor??[0,0,0,1]],this.powerPreference=e.powerPreference,this.shadowMapSize=e.shadowMapSize??2048,this.pointShadowMapSize=e.pointShadowMapSize??1024,this.fallbackMaterial=e.fallbackMaterial??null,this.materialResolver=e.materialResolver,this.fallbackSkinnedMaterial=e.fallbackSkinnedMaterial??new Nt({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:Kn}),this.invokeObjectRenderCallbacks=e.invokeObjectRenderCallbacks??!0,this.state.directionalShadowTextureSize=this.shadowMapSize,this.state.pointShadowTextureSize=this.pointShadowMapSize,this.state.spotShadowTextureSize=this.shadowMapSize,this.sampleCount=Wi(e.sampleCount),this.renderScale=Xn(e.renderScale),this.hiZOcclusionCullingEnabled=e.hiZOcclusionCulling??!1,this.multiDrawIndirectEnabled=e.multiDrawIndirect??!0,this.dynamicBatchingEnabled=e.dynamicBatching??!0,this.renderGraphProfilingEnabled=e.renderGraphProfiling??!1}resolveMaterial(e){if(!1===e?.visible)return null;if(e&&Wt(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)return!0;if(e instanceof yt)return null!=e.uniforms.hology_depth_map||null!=e.uniforms.hology_scene_map;if(e instanceof Nt)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 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 Nt({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 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 ot(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:lt,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 Nt({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 ot(1,1,1),opacity:1},primitiveTopology:t,depthTest:e.depthTest,depthWrite:e.depthWrite}),r.set(t,i));const n=e;return n.color&&i.uniforms.color.value.copy(n.color),i.uniforms.opacity.value=n.opacity??1,i.transparent=e.transparent||(n.opacity??1)<1,i.depthTest=e.depthTest,i.depthWrite=e.depthWrite,i}resolveSkinnedMaterial(e){const t=this.resolveMaterial(e);return null===t?null:function(e){const t=e.vertexAttributes.find(e=>"skinIndex"===e.name),r=e.vertexAttributes.find(e=>"skinWeight"===e.name);return e.vertexShader.includes("USE_SKINNING")||"uint32x4"===t?.format&&"float32x4"===r?.format&&e.vertexShader.includes("rendererSkinPosition(")}(t)?t:this.fallbackSkinnedMaterial}hasRenderCallbacks(e){return null!==e&&this.invokeObjectRenderCallbacks&&function(e){return null!==e&&(e.onBeforeRender!==Vr.prototype.onBeforeRender||e.onAfterRender!==Vr.prototype.onAfterRender)}(e)}async initialize(){if(!("gpu"in navigator))throw new Error("WebGPU is not available in this browser.");const e=await navigator.gpu.requestAdapter({powerPreference:this.powerPreference});if(!e)throw new Error("A WebGPU adapter could not be created.");const t=[];e.features.has("indirect-first-instance")&&t.push("indirect-first-instance"),e.features.has("timestamp-query")&&t.push("timestamp-query"),e.features.has("texture-compression-bc")&&t.push("texture-compression-bc"),e.features.has("texture-compression-etc2")&&t.push("texture-compression-etc2"),e.features.has("texture-compression-astc")&&t.push("texture-compression-astc"),e.features.has("float32-filterable")&&t.push("float32-filterable"),e.features.has(Hn)&&t.push(Hn);const r=e.limits;if(this.state.device=await e.requestDevice({requiredFeatures:t,requiredLimits:{maxTextureArrayLayers:r.maxTextureArrayLayers,maxBufferSize:r.maxBufferSize,maxStorageBufferBindingSize:r.maxStorageBufferBindingSize}}),this.state.device.addEventListener("uncapturederror",e=>{console.error("Uncaptured WebGPU device error",e)}),this.indirectFirstInstanceSupported=t.includes("indirect-first-instance"),this.timestampQuerySupported=t.includes("timestamp-query"),this.multiDrawIndirectSupported=t.includes(Hn),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:1584,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),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"}}]}),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"}}]}),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"}}]}),this.state.visibleDepthSceneBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-visible-depth-scene-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),this.state.shadowBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-shadow-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),this.state.directShadowBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-direct-shadow-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),this.state.emptyBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-empty-layout",entries:[]}),this.state.skinningBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-skinning-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),this.state.sceneTextureBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-scene-texture-layout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"non-filtering"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth"}}]}),this.state.residentSceneBindGroupVersion+=1,this.state.residentShadowBindGroupVersion+=1,this.state.fullscreenTextureBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-fullscreen-texture-layout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}}]}),this.state.shadowComparisonSampler=this.state.device.createSampler({label:"renderer-shadow-comparison-sampler",compare:"less-equal",magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),this.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"}),this.state.hizCopyKernel=this.createComputeKernel({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"}}]}),this.state.hizReduceKernel=this.createComputeKernel({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"}}]}),this.state.visibilityKernel=this.createComputeKernel({label:"renderer-visibility-cull",code:"\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\nstruct RendererVisibilityParams {\n drawCount: u32,\n hizMipCount: u32,\n reserved0: u32,\n reserved1: u32,\n};\n\nstruct DrawMetadata {\n centerRadius: vec4<f32>,\n args0: vec4<f32>,\n extra: vec4<f32>,\n};\n\nstruct IndirectIndexedArgs {\n indexCount: u32,\n instanceCount: u32,\n firstIndex: u32,\n baseVertex: i32,\n firstInstance: u32,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> visibilityParams: RendererVisibilityParams;\n@group(0) @binding(2) var drawMetaTextureSampler: sampler;\n@group(0) @binding(3) var hizTexture: texture_2d<f32>;\n@group(0) @binding(4) var<storage, read> drawMetadata: array<DrawMetadata>;\n@group(0) @binding(5) var<storage, read_write> indirectArgs: array<IndirectIndexedArgs>;\n\nfn saturate(value: f32) -> f32 {\n return clamp(value, 0.0, 1.0);\n}\n\nfn projectedSphereRadius(\n viewProj: mat4x4<f32>,\n ndc: vec3<f32>,\n clipW: f32,\n radius: f32,\n) -> vec2<f32> {\n // Account for both numerator and perspective-denominator variation over the\n // sphere. Offsetting along world X/Y is not conservative once the camera is\n // rotated because those axes can also change clip W.\n let rowX = vec3(viewProj[0].x, viewProj[1].x, viewProj[2].x);\n let rowY = vec3(viewProj[0].y, viewProj[1].y, viewProj[2].y);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let denominator = max(clipW - radius * length(rowW), 0.0001);\n return radius * vec2(\n length(rowX) + abs(ndc.x) * length(rowW),\n length(rowY) + abs(ndc.y) * length(rowW),\n ) / denominator;\n}\n\nfn spherePlaneRadius(viewProj: mat4x4<f32>, plane: vec4<f32>, radius: f32) -> f32 {\n let worldNormal = vec3(\n dot(viewProj[0], plane),\n dot(viewProj[1], plane),\n dot(viewProj[2], plane),\n );\n return radius * length(worldNormal);\n}\n\nfn isSphereInFrustum(viewProj: mat4x4<f32>, center: vec3<f32>, radius: f32) -> bool {\n let clip = viewProj * vec4(center, 1.0);\n return\n clip.w + clip.x >= -spherePlaneRadius(viewProj, vec4( 1.0, 0.0, 0.0, 1.0), radius) &&\n clip.w - clip.x >= -spherePlaneRadius(viewProj, vec4(-1.0, 0.0, 0.0, 1.0), radius) &&\n clip.w + clip.y >= -spherePlaneRadius(viewProj, vec4( 0.0, 1.0, 0.0, 1.0), radius) &&\n clip.w - clip.y >= -spherePlaneRadius(viewProj, vec4( 0.0, -1.0, 0.0, 1.0), radius) &&\n clip.z >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, 1.0, 0.0), radius) &&\n clip.w - clip.z >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, -1.0, 1.0), radius);\n}\n\nfn nearestSphereDepth(viewProj: mat4x4<f32>, clip: vec4<f32>, radius: f32) -> f32 {\n let rowZ = vec3(viewProj[0].z, viewProj[1].z, viewProj[2].z);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let minClipZ = clip.z - radius * length(rowZ);\n let maxClipW = clip.w + radius * length(rowW);\n return max(0.0, minClipZ / max(maxClipW, 0.0001));\n}\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let drawIndex = globalId.x;\n if (drawIndex >= visibilityParams.drawCount) {\n return;\n }\n\n let drawData = drawMetadata[drawIndex];\n let center = vec4(drawData.centerRadius.xyz, 1.0);\n let radius = drawData.centerRadius.w;\n var visible = isSphereInFrustum(\n rendererCamera.viewProj,\n drawData.centerRadius.xyz,\n radius,\n );\n\n let clip = rendererCamera.viewProj * center;\n let cameraDistance = distance(drawData.centerRadius.xyz, rendererCamera.cameraPosition.xyz);\n // A sphere that intersects the near plane, surrounds the camera, or has a\n // very large projected extent cannot be safely represented by its center.\n // Keep it rather than allowing a false negative to remove large terrain or\n // nearby geometry.\n let clipWRadius = radius * length(vec3(\n rendererCamera.viewProj[0].w,\n rendererCamera.viewProj[1].w,\n rendererCamera.viewProj[2].w,\n ));\n let needsConservativeVisibility =\n clip.w - clipWRadius <= 0.0001 || radius >= cameraDistance * 0.1;\n\n if (!needsConservativeVisibility) {\n let ndc = clip.xyz / clip.w;\n let projectedRadius = projectedSphereRadius(rendererCamera.viewProj, ndc, clip.w, radius);\n let clipRadiusX = projectedRadius.x;\n let clipRadiusY = projectedRadius.y;\n\n if (\n visible &&\n ndc.x - clipRadiusX >= -1.0 && ndc.x + clipRadiusX <= 1.0 &&\n ndc.y - clipRadiusY >= -1.0 && ndc.y + clipRadiusY <= 1.0\n ) {\n let uvCenter = ndc.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n let uvRadius = vec2(clipRadiusX, clipRadiusY) * 0.5;\n let viewport = rendererCamera.viewportAndTime.xy;\n let screenDiameter = max(\n max(clipRadiusX * viewport.x * 0.5, clipRadiusY * viewport.y * 0.5),\n 1.0,\n ) * 2.0;\n let maxMipLevel = max(f32(visibilityParams.hizMipCount) - 1.0, 0.0);\n // Round up from the full diameter. Using floor(log2(radius)) leaves\n // unsampled texels between the corner probes, especially for small\n // objects, and can turn partial coverage into a false occlusion.\n let mipLevel = clamp(ceil(log2(screenDiameter)), 0.0, maxMipLevel);\n // Cover the projected bounds rather than testing only their center. The\n // max-reduced pyramid makes background or a gap at any corner retain the\n // draw, avoiding false occlusion for partially covered objects.\n let hizDepth = max(\n max(\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2(-uvRadius.x, -uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2( uvRadius.x, -uvRadius.y), mipLevel).r,\n ),\n max(\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2(-uvRadius.x, uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2( uvRadius.x, uvRadius.y), mipLevel).r,\n ),\n );\n let conservativeDepth = nearestSphereDepth(rendererCamera.viewProj, clip, radius);\n visible = conservativeDepth <= hizDepth + 0.0005;\n }\n }\n\n let baseVertex = i32(round(drawData.extra.y));\n indirectArgs[drawIndex].indexCount = u32(round(drawData.args0.x));\n indirectArgs[drawIndex].instanceCount = select(0u, u32(round(drawData.args0.w)), visible);\n indirectArgs[drawIndex].firstIndex = u32(round(drawData.args0.y));\n indirectArgs[drawIndex].baseVertex = baseVertex;\n indirectArgs[drawIndex].firstInstance = u32(round(drawData.args0.z));\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.COMPUTE,sampler:{type:"non-filtering"}},{binding:3,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:5,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}),this.state.staticVisibilityClearKernel=this.createComputeKernel({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 atomicStore(&visibleInstanceMask[index], 0u);\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"}}]}),this.state.staticVisibilityCullKernel=this.createComputeKernel({label:"renderer-static-visibility-cull",code:"\nstruct RendererTemporalVisibilityUniforms {\n currentViewProj: mat4x4<f32>,\n previousViewProj: mat4x4<f32>,\n currentCameraPosition: vec4<f32>,\n previousCameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\nstruct RendererVisibilityParams {\n drawCount: u32,\n hizMipCount: u32,\n instanceCount: u32,\n flags: u32,\n};\n\nstruct DrawMetadata {\n centerRadius: vec4<f32>,\n args0: vec4<f32>,\n extra: vec4<f32>,\n};\n\nstruct StaticInstanceMetadata {\n centerRadius: vec4<f32>,\n drawAndSourceIndex: vec4<u32>,\n};\n\n@group(0) @binding(0) var<uniform> temporalVisibility: RendererTemporalVisibilityUniforms;\n@group(0) @binding(1) var<uniform> visibilityParams: RendererVisibilityParams;\n@group(0) @binding(2) var hizSampler: sampler;\n@group(0) @binding(3) var hizTexture: texture_2d<f32>;\n@group(0) @binding(4) var<storage, read> instanceMetadata: array<StaticInstanceMetadata>;\n@group(0) @binding(5) var<storage, read> drawMetadata: array<DrawMetadata>;\n@group(0) @binding(6) var<storage, read_write> visibleCounts: array<atomic<u32>>;\n@group(0) @binding(7) var<storage, read_write> visibleInstanceIndices: array<u32>;\n@group(0) @binding(8) var<storage, read_write> visibleInstanceMask: array<atomic<u32>>;\n@group(0) @binding(9) var<storage, read_write> postVisibleCounts: array<atomic<u32>>;\n\nfn spherePlaneRadius(viewProj: mat4x4<f32>, plane: vec4<f32>, radius: f32) -> f32 {\n let worldNormal = vec3(\n dot(viewProj[0], plane),\n dot(viewProj[1], plane),\n dot(viewProj[2], plane),\n );\n return radius * length(worldNormal);\n}\n\nfn projectedSphereRadius(\n viewProj: mat4x4<f32>,\n ndc: vec3<f32>,\n clipW: f32,\n radius: f32,\n) -> vec2<f32> {\n let rowX = vec3(viewProj[0].x, viewProj[1].x, viewProj[2].x);\n let rowY = vec3(viewProj[0].y, viewProj[1].y, viewProj[2].y);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let denominator = max(clipW - radius * length(rowW), 0.0001);\n return radius * vec2(\n length(rowX) + abs(ndc.x) * length(rowW),\n length(rowY) + abs(ndc.y) * length(rowW),\n ) / denominator;\n}\n\nfn nearestSphereDepth(viewProj: mat4x4<f32>, clip: vec4<f32>, radius: f32) -> f32 {\n let rowZ = vec3(viewProj[0].z, viewProj[1].z, viewProj[2].z);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let minClipZ = clip.z - radius * length(rowZ);\n let maxClipW = clip.w + radius * length(rowW);\n return max(0.0, minClipZ / max(maxClipW, 0.0001));\n}\n\nfn isSphereInFrustum(\n viewProj: mat4x4<f32>,\n center: vec3<f32>,\n radius: f32,\n) -> bool {\n let clip = viewProj * vec4(center, 1.0);\n let left = clip.w + clip.x;\n let right = clip.w - clip.x;\n let bottom = clip.w + clip.y;\n let top = clip.w - clip.y;\n let near = clip.z;\n let far = clip.w - clip.z;\n\n return\n left >= -spherePlaneRadius(viewProj, vec4(1.0, 0.0, 0.0, 1.0), radius) &&\n right >= -spherePlaneRadius(viewProj, vec4(-1.0, 0.0, 0.0, 1.0), radius) &&\n bottom >= -spherePlaneRadius(viewProj, vec4(0.0, 1.0, 0.0, 1.0), radius) &&\n top >= -spherePlaneRadius(viewProj, vec4(0.0, -1.0, 0.0, 1.0), radius) &&\n near >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, 1.0, 0.0), radius) &&\n far >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, -1.0, 1.0), radius);\n}\n\nfn isSphereNearFrustumBoundary(\n viewProj: mat4x4<f32>,\n center: vec3<f32>,\n radius: f32,\n) -> bool {\n let clip = viewProj * vec4(center, 1.0);\n return\n clip.w + clip.x <= spherePlaneRadius(viewProj, vec4(1.0, 0.0, 0.0, 1.0), radius) ||\n clip.w - clip.x <= spherePlaneRadius(viewProj, vec4(-1.0, 0.0, 0.0, 1.0), radius) ||\n clip.w + clip.y <= spherePlaneRadius(viewProj, vec4(0.0, 1.0, 0.0, 1.0), radius) ||\n clip.w - clip.y <= spherePlaneRadius(viewProj, vec4(0.0, -1.0, 0.0, 1.0), radius) ||\n clip.z <= spherePlaneRadius(viewProj, vec4(0.0, 0.0, 1.0, 0.0), radius) ||\n clip.w - clip.z <= spherePlaneRadius(viewProj, vec4(0.0, 0.0, -1.0, 1.0), radius);\n}\n\nfn isSphereVisible(center: vec3<f32>, radius: f32) -> bool {\n let currentViewProj = temporalVisibility.currentViewProj;\n if (!isSphereInFrustum(currentViewProj, center, radius)) {\n return false;\n }\n\n let clip = currentViewProj * vec4(center, 1.0);\n // Near-plane intersections are deliberately kept. A false negative here would\n // incorrectly remove geometry surrounding the camera.\n if (clip.w <= 0.0001) {\n return true;\n }\n\n if ((visibilityParams.flags & 1u) == 0u) {\n return true;\n }\n\n let usesPreviousHiZ = (visibilityParams.flags & 2u) != 0u;\n var hizViewProj = temporalVisibility.currentViewProj;\n var hizCameraPosition = temporalVisibility.currentCameraPosition.xyz;\n if (usesPreviousHiZ) {\n hizViewProj = temporalVisibility.previousViewProj;\n hizCameraPosition = temporalVisibility.previousCameraPosition.xyz;\n }\n\n let hizClip = hizViewProj * vec4(center, 1.0);\n let hizClipWRadius = radius * length(vec3(\n hizViewProj[0].w,\n hizViewProj[1].w,\n hizViewProj[2].w,\n ));\n if (hizClip.w - hizClipWRadius <= 0.0001) {\n return true;\n }\n let hizNdc = hizClip.xyz / hizClip.w;\n let hizProjectedRadius = projectedSphereRadius(\n hizViewProj,\n hizNdc,\n hizClip.w,\n radius,\n );\n let hizClipRadiusX = hizProjectedRadius.x;\n let hizClipRadiusY = hizProjectedRadius.y;\n let hizClipRadiusZ = radius / max(distance(center, hizCameraPosition), 0.001);\n\n // Samples close to the viewport boundary cannot cover the whole projected\n // sphere. This also retains newly revealed regions during camera motion.\n if (\n isSphereNearFrustumBoundary(hizViewProj, center, radius) ||\n hizNdc.x - hizClipRadiusX < -1.0 || hizNdc.x + hizClipRadiusX > 1.0 ||\n hizNdc.y - hizClipRadiusY < -1.0 || hizNdc.y + hizClipRadiusY > 1.0 ||\n hizNdc.z < -hizClipRadiusZ || hizNdc.z > 1.0 + hizClipRadiusZ\n ) {\n return true;\n }\n\n let viewport = temporalVisibility.viewportAndTime.xy;\n let screenDiameter = max(\n max(hizClipRadiusX * viewport.x * 0.5, hizClipRadiusY * viewport.y * 0.5),\n 1.0,\n ) * 2.0;\n let maxMipLevel = max(f32(visibilityParams.hizMipCount) - 1.0, 0.0);\n let mipLevel = clamp(ceil(log2(screenDiameter)), 0.0, maxMipLevel);\n let uvCenter = hizNdc.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n let uvRadius = vec2(hizClipRadiusX, hizClipRadiusY) * 0.5;\n let hizDepth = max(\n max(\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2(-uvRadius.x, -uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2( uvRadius.x, -uvRadius.y), mipLevel).r,\n ),\n max(\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2(-uvRadius.x, uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2( uvRadius.x, uvRadius.y), mipLevel).r,\n ),\n );\n let conservativeNearestDepth = nearestSphereDepth(hizViewProj, hizClip, radius);\n return conservativeNearestDepth <= hizDepth + 0.001;\n}\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let instanceIndex = globalId.x;\n if (instanceIndex >= visibilityParams.instanceCount) {\n return;\n }\n\n let instance = instanceMetadata[instanceIndex];\n if ((visibilityParams.flags & 4u) != 0u && atomicLoad(&visibleInstanceMask[instanceIndex]) != 0u) {\n return;\n }\n let drawIndex = instance.drawAndSourceIndex.x;\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 atomicStore(&visibleInstanceMask[instanceIndex], 1u);\n }\n let firstInstance = u32(round(drawMetadata[drawIndex].args0.z));\n if (isPostpass) {\n let primaryVisibleCount = atomicLoad(&visibleCounts[drawIndex]);\n let postVisibleIndex = atomicAdd(&postVisibleCounts[drawIndex], 1u);\n visibleInstanceIndices[firstInstance + primaryVisibleCount + postVisibleIndex] = instance.drawAndSourceIndex.y;\n } else {\n let visibleIndex = atomicAdd(&visibleCounts[drawIndex], 1u);\n visibleInstanceIndices[firstInstance + visibleIndex] = instance.drawAndSourceIndex.y;\n }\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.COMPUTE,sampler:{type:"non-filtering"}},{binding:3,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:5,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:6,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:7,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:8,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:9,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}),this.state.staticVisibilityIndirectBuildKernel=this.createComputeKernel({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"}}]}),this.state.visibilityParamsBuffer=this.state.device.createBuffer({label:"renderer-visibility-params-buffer",size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.createStaticPipelines(),this.setSize(this.canvas.clientWidth||this.canvas.width||1,this.canvas.clientHeight||this.canvas.height||1),this.state.initialized=!0}createComputeKernel(t){if(!this.state.device)throw new Error("WebGpuRenderer.initialize() must complete before creating compute kernels.");return new e(this.state.device,t)}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)}setRenderGraphProfilingEnabled(e){this.renderGraphProfilingEnabled=e}getRenderGraphProfilingEnabled(){return this.renderGraphProfilingEnabled}getTimestampQuerySupported(){return this.timestampQuerySupported}getSampleCount(){return this.sampleCount}setSampleCount(e){const t=Wi(e);t!==this.sampleCount&&(this.sampleCount=t,this.destroyMsaaResources(),this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches())}setRenderScale(e){const t=Xn(e);if(t===this.renderScale)return;this.renderScale=t;const r=this.state.pixelRatio;this.setSize(this.state.presentationWidth/r,this.state.presentationHeight/r,r)}getRenderScale(){return this.renderScale}setProjectionJitter(e,t){if(!Number.isFinite(e)||!Number.isFinite(t))throw new RangeError("Projection jitter must contain finite pixel offsets.");this.projectionJitterPixels.set(e,t)}clearProjectionJitter(){this.projectionJitterPixels.set(0,0)}setMotionVectorProjection(e){this.motionVectorProjection.copy(e),this.motionVectorProjectionPending=!0}invalidateObjectMotion(e){this.objectMotionHistory.delete(e)}getLastFrameProfile(){const e=this.state.latestFrameProfile?.timestampQueryActive&&null===this.state.latestFrameProfile.gpuTimeMs&&this.state.latestCompletedFrameProfile?this.state.latestCompletedFrameProfile:this.state.latestFrameProfile;return e?{...e,cpuPhases:{...e.cpuPhases},passes:e.passes.map(e=>({...e})),visibility:e.visibility?{...e.visibility}:null}:null}resetViewHistory(){this.state.temporalHiZHistoryValid=!1,this.motionVectorHistoryValid=!1,this.motionVectorHistoryGeneration+=1}setHiZOcclusionCullingEnabled(e){this.hiZOcclusionCullingEnabled!==e&&(this.state.temporalHiZHistoryValid=!1),this.hiZOcclusionCullingEnabled=e}getHiZOcclusionCullingEnabled(){return this.hiZOcclusionCullingEnabled}getHiZOcclusionCullingActive(){return this.hiZOcclusionCullingEnabled&&this.indirectFirstInstanceSupported}setMultiDrawIndirectEnabled(e){this.multiDrawIndirectEnabled=e}getMultiDrawIndirectEnabled(){return this.multiDrawIndirectEnabled}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:$r,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:$r,usage:GPUTextureUsage.COPY_DST|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:$r,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),this.state.postProcessColorView=this.state.postProcessColorTexture.createView(),this.state.sceneTextureBindGroupLayout&&this.state.linearClampSampler&&this.state.nearestClampSampler&&(this.state.sceneTextureBindGroup=this.state.device.createBindGroup({label:"renderer-scene-texture-bind-group",layout:this.state.sceneTextureBindGroupLayout,entries:[{binding:0,resource:this.state.linearClampSampler},{binding:1,resource:this.state.sceneColorSnapshotView},{binding:2,resource:this.state.nearestClampSampler},{binding:3,resource:this.state.sceneDepthSnapshotView}]})),this.state.hizTexture?.destroy(),this.state.hizMipCount=Math.max(1,Math.floor(Math.log2(Math.max(this.state.width,this.state.height)))+1),this.state.hizTexture=this.state.device.createTexture({label:"renderer-hiz-pyramid",size:{width:this.state.width,height:this.state.height},format:"r32float",mipLevelCount:this.state.hizMipCount,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING}),this.state.hizView=this.state.hizTexture.createView(),this.state.hizMipViews=[],this.state.hizCopyBindGroup=null,this.state.hizReduceBindGroups=[],this.state.visibilityBindGroup=null,this.state.visibilityBindGroupMetadataResource=null;for(let e=0;e<this.state.hizMipCount;e+=1)this.state.hizMipViews.push(this.state.hizTexture.createView({baseMipLevel:e,mipLevelCount:1}));this.hizResourceVersion+=1,this.graphTextureResourceVersion+=1,this.state.temporalHiZHistoryValid=!1,this.motionVectorHistoryValid=!1,this.motionVectorHistoryGeneration+=1;for(const e of this.staticDrawSets)e.visibilityBindGroup=null,e.postVisibilityBindGroup=null,e.visibilityBindGroupHizVersion=0;this.recreateShadowResources()}}setClearColor(e){this.clearColor[0]=e[0],this.clearColor[1]=e[1],this.clearColor[2]=e[2],this.clearColor[3]=e[3]}render(e,t,r=.001*performance.now()){this.renderFrame(e,t,r,!1)}async renderAsync(e,t,r=.001*performance.now()){await this.renderFrame(e,t,r,!0)}compile(e,t){this.prepareSceneForCompilation(e,t,!1)}async compileAsync(e,t){this.state.initialized||await this.initialize(),await this.prepareSceneForCompilation(e,t,!0)}createPMREMGenerator(e=20){if(!this.state.device)throw new Error("WebGpuRenderer.initialize() must complete before creating a PMREM generator.");return new sr({device:this.state.device,getTextureResource:e=>this.getTextureResource(e),registerTextureResource:(e,t)=>this.textureCache.set(e,t)},e)}initTexture(e){this.textureManager.getTextureResource(e)}createStaticDrawSet(e,t={}){return this.staticDrawSetManager.createStaticDrawSet(e,t)}disposeStaticDrawSetResource(e){this.staticDrawSetManager.disposeStaticDrawSetResource(e)}renderFrame(e,t,r,i){if(!(this.state.initialized&&this.state.device&&this.state.context&&this.state.mainDepthView&&this.state.sceneColorView&&this.state.postProcessColorView&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.shadowCameraBuffer&&this.state.sceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.shadowComparisonSampler&&this.state.linearClampSampler&&this.state.nearestClampSampler&&this.state.visibilityParamsBuffer&&this.state.directionalShadowView&&this.state.pointShadowArrayView&&this.state.spotShadowView&&this.state.hizCopyKernel&&this.state.hizReduceKernel&&this.state.visibilityKernel&&this.state.presentPipeline))throw new Error("WebGpuRenderer.initialize() must complete before render().");const n=r-this.lastMotionVectorTimeSeconds;Number.isFinite(this.lastMotionVectorTimeSeconds)&&(!Number.isFinite(n)||n<=0||n>.25)&&(this.motionVectorHistoryValid=!1,this.motionVectorHistoryGeneration+=1),this.lastMotionVectorTimeSeconds=r,this.state.frameTimeSeconds=r,this.staticFrameToken+=1,e.matrixWorldAutoUpdate&&e.updateMatrixWorld(),null===t.parent&&t.matrixWorldAutoUpdate&&t.updateMatrixWorld();const a=performance.now(),s=this.extractScene(e,t);this.ensureShadowTextureSizes(s);const o=performance.now()-a,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.updateCameraUniforms(t,e),this.updateTemporalVisibilityUniforms(t),this.updateLightUniforms(s);const d=performance.now()-c,h=this.state.device.createCommandEncoder({label:"renderer-command-encoder"}),p=this.state.context.getCurrentTexture().createView(),f=this.getSharedSceneBindGroup(),m=this.getSharedShadowBindGroup();let g=null;const v=this.state.drawMetadataResource;u&&v&&v.count>0&&this.state.hizView&&(this.state.visibilityBindGroup&&this.state.visibilityBindGroupMetadataResource===v||(this.state.visibilityBindGroup=this.state.visibilityKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:1,resource:{buffer:this.state.visibilityParamsBuffer}},{binding:2,resource:this.state.nearestClampSampler},{binding:3,resource:this.state.hizView},{binding:4,resource:{buffer:v.metadataBuffer}},{binding:5,resource:{buffer:v.indirectBuffer}}],"renderer-visibility-bind-group"),this.state.visibilityBindGroupMetadataResource=v),g=this.state.visibilityBindGroup),this.renderGraph.reset();const x=this.createGraphBuilderContext(this.renderGraph,h,f,m,g,p,s,l);this.graphBuilder(this.renderGraph,x);const w={device:this.state.device,encoder:h},b=function(e,t,r,i,n){if(!t.renderGraphProfilingEnabled||!e.device)return null;const a={frameIndex:e.frameIndex+=1,cpuTimeMs:0,gpuTimeMs:null,drawCallCount:i.drawCallCount,triangleCount:i.triangleCount,cpuPhases:{extractSceneMs:n.extractSceneMs,uploadMs:n.uploadMs,renderGraphMs:0},passes:[],timestampQuerySupported:t.timestampQuerySupported,timestampQueryActive:t.timestampQuerySupported,gpuProfilingReason:null,hiZOcclusionCullingEnabled:t.hiZOcclusionCullingEnabled,hiZOcclusionCullingActive:r,visibility:null};let s=null;const o={begin:(e,r)=>{if(a.passes=e.map(e=>({name:e.name,cpuTimeMs:0,gpuTimeMs:null})),!t.timestampQuerySupported)return a.timestampQueryActive=!1,void(a.gpuProfilingReason="timestamp-query is not supported by this adapter/device");if(0===e.length)return a.timestampQueryActive=!1,void(a.gpuProfilingReason="no render graph passes were recorded");const i=2*e.length,n=Math.max(8,8*i),o=r.device.createQuerySet({label:`renderer-frame-profile-${a.frameIndex}`,type:"timestamp",count:i}),l=r.device.createBuffer({label:`renderer-frame-profile-resolve-${a.frameIndex}`,size:n,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),c=r.device.createBuffer({label:`renderer-frame-profile-read-${a.frameIndex}`,size:n,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});s={profile:a,querySet:o,resolveBuffer:l,readBuffer:c,queryCount:i}},beforePass:(e,t,r)=>{s&&(pi(r.encoder,s.querySet,{endOfPassWriteIndex:2*t})||(a.timestampQueryActive=!1,a.gpuProfilingReason="timestampWrites marker pass is not available on this browser/runtime",s.querySet.destroy(),s.resolveBuffer.destroy(),s.readBuffer.destroy(),s=null))},afterPass:(e,t,r,i)=>{a.passes[t].cpuTimeMs=r,s&&(pi(i.encoder,s.querySet,{beginningOfPassWriteIndex:2*t+1})||(a.timestampQueryActive=!1,a.gpuProfilingReason="timestampWrites marker pass is not available on this browser/runtime",s.querySet.destroy(),s.resolveBuffer.destroy(),s.readBuffer.destroy(),s=null))},end:(t,r,n)=>{if(a.cpuPhases.renderGraphMs=r,a.cpuTimeMs=a.cpuPhases.extractSceneMs+a.cpuPhases.uploadMs+a.cpuPhases.renderGraphMs,a.drawCallCount=i.drawCallCount,a.triangleCount=i.triangleCount,!s){const t=Zi(a);return e.latestFrameProfile=t,void(e.latestCompletedFrameProfile=t)}n.encoder.resolveQuerySet(s.querySet,0,s.queryCount,s.resolveBuffer,0),n.encoder.copyBufferToBuffer(s.resolveBuffer,0,s.readBuffer,0,8*s.queryCount),e.latestFrameProfile=Zi(a)}};return{profile:a,observer:o,pendingVisibilityRead:null,get pendingGpuRead(){return s},set pendingGpuRead(e){s=e}}}(this.state,{renderGraphProfilingEnabled:this.renderGraphProfilingEnabled,timestampQuerySupported:this.timestampQuerySupported,hiZOcclusionCullingEnabled:this.hiZOcclusionCullingEnabled},u,l,{extractSceneMs:o,uploadMs:d}),y=()=>{if(!b||!u)return;const e=[];v&&v.count>0&&e.push({buffer:v.indirectBuffer,drawCount:v.count,totalInstances:s.gpuOpaqueDraws.reduce((e,t)=>e+Math.max(0,t.instanceCount),0),kind:"dynamic"});for(const t of this.staticDrawSets)t.publicSet.enabled&&t.lastVisibilityFrameToken===this.staticFrameToken&&e.push({buffer:t.drawMetadataResource.indirectBuffer,drawCount:t.drawMetadataResource.count,totalInstances:t.instanceCount,kind:"static"});!function(e,t,r,i){const n=i.filter(e=>e.drawCount>0);if(0===n.length)return void(e.profile.visibility={totalInstances:0,visibleInstances:0,culledInstances:0,dynamicTotalInstances:0,dynamicVisibleInstances:0,staticTotalInstances:0,staticVisibleInstances:0});let a=0;const s=n.map(e=>{const t={byteOffset:a,drawCount:e.drawCount,totalInstances:e.totalInstances,kind:e.kind};return a+=5*e.drawCount*Uint32Array.BYTES_PER_ELEMENT,t}),o=t.createBuffer({label:`renderer-visibility-profile-read-${e.profile.frameIndex}`,size:Math.max(4,a),usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});for(let e=0;e<n.length;e+=1){const t=n[e];r.copyBufferToBuffer(t.buffer,0,o,s[e].byteOffset,5*t.drawCount*Uint32Array.BYTES_PER_ELEMENT)}e.pendingVisibilityRead={readBuffer:o,regions:s}}(b,this.state.device,h,e)};if(i)return this.renderGraph.executeAsync(w,b?.observer).then(()=>{y(),this.state.device.queue.submit([h.finish()]),this.commitTemporalHiZHistory(),this.releaseRetiredGeometryResourcesAfterSubmit(),b&&Hi(this.state,b)});this.renderGraph.execute(w,b?.observer),y(),this.state.device.queue.submit([h.finish()]),this.commitTemporalHiZHistory(),this.releaseRetiredGeometryResourcesAfterSubmit(),b&&Hi(this.state,b)}destroy(){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.state.sceneDepthSnapshotTexture?.destroy(),this.state.postProcessColorTexture?.destroy(),this.state.directionalShadowTexture?.destroy(),this.state.pointShadowTexture?.destroy(),this.state.pointShadowDepthTexture?.destroy(),this.state.spotShadowTexture?.destroy(),this.state.hizTexture?.destroy(),this.state.cameraBuffer?.destroy(),this.state.temporalVisibilityBuffer?.destroy(),this.state.lightBuffer?.destroy(),this.state.shadowCameraBuffer?.destroy();for(const e of this.state.shadowCameraBufferPool)e.destroy();this.state.shadowCameraBufferPool.length=0,this.state.sharedShadowBindGroupByCameraBuffer.clear(),this.state.instanceBuffer?.destroy();for(const e of this.defaultInstanceAttributeBuffers.values())for(const t of e.values())t.destroy();this.defaultInstanceAttributeBuffers.clear(),this.state.visibilityParamsBuffer?.destroy(),this.state.drawMetadataResource?.metadataBuffer.destroy(),this.state.drawMetadataResource?.indirectBuffer.destroy(),this.state.drawMetadataResource?.postIndirectBuffer.destroy(),this.state.initialized=!1,this.state.device?.destroy(),this.state.device=null}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=this.state.device.createPipelineLayout({label:"renderer-depth-prepass-layout",bindGroupLayouts:[this.state.sceneBindGroupLayout]});this.state.depthPrepassPipeline=this.state.device.createRenderPipeline({label:"renderer-depth-prepass-pipeline",layout:e,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"}});const t=this.state.device.createPipelineLayout({label:"renderer-depth-prepass-visible-layout",bindGroupLayouts:[this.state.visibleDepthSceneBindGroupLayout]});this.state.depthPrepassPipelineVisible=this.state.device.createRenderPipeline({label:"renderer-depth-prepass-visible-pipeline",layout:t,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"}});const r=this.state.device.createPipelineLayout({label:"renderer-depth-prepass-direct-layout",bindGroupLayouts:[this.state.directSceneBindGroupLayout]});this.state.depthPrepassPipelineDirect=this.state.device.createRenderPipeline({label:"renderer-depth-prepass-direct-pipeline",layout:r,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"}});const i=this.state.device.createPipelineLayout({label:"renderer-skinned-depth-prepass-layout",bindGroupLayouts:[this.state.sceneBindGroupLayout,this.state.emptyBindGroupLayout,this.state.skinningBindGroupLayout]});this.state.skinnedDepthPrepassPipeline=this.state.device.createRenderPipeline({label:"renderer-skinned-depth-prepass-pipeline",layout:i,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-depth-prepass-module",code:Fn}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(qr)},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}});const n=this.state.device.createPipelineLayout({label:"renderer-shadow-layout",bindGroupLayouts:[this.state.shadowBindGroupLayout]}),a=this.state.device.createPipelineLayout({label:"renderer-direct-shadow-pipeline-layout",bindGroupLayouts:[this.state.directShadowBindGroupLayout]});this.state.shadowDepthPipeline=this.state.device.createRenderPipeline({label:"renderer-directional-shadow-pipeline",layout:n,vertex:{module:this.state.device.createShaderModule({label:"renderer-directional-shadow-module",code:"\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> @builtin(position) @invariant vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n return shadowCamera.viewProj * world;\n}\n"}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"front",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}}),this.state.shadowDepthPipelineDirect=this.state.device.createRenderPipeline({label:"renderer-directional-shadow-direct-pipeline",layout:a,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}});const s=this.state.device.createPipelineLayout({label:"renderer-skinned-shadow-layout",bindGroupLayouts:[this.state.shadowBindGroupLayout,this.state.emptyBindGroupLayout,this.state.skinningBindGroupLayout]});this.state.skinnedShadowDepthPipeline=this.state.device.createRenderPipeline({label:"renderer-skinned-directional-shadow-pipeline",layout:s,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-directional-shadow-module",code:En}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(qr)},primitive:{topology:"triangle-list",cullMode:"front",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}}),this.state.pointShadowPipeline=this.state.device.createRenderPipeline({label:"renderer-point-shadow-pipeline",layout:n,vertex:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-module",code:Un}),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:Un}),entryPoint:"fsMain",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}),this.state.pointShadowPipelineDirect=this.state.device.createRenderPipeline({label:"renderer-point-shadow-direct-pipeline",layout:a,vertex:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-direct-module",code:Ln}),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:Ln}),entryPoint:"fsMain",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}),this.state.skinnedPointShadowPipeline=this.state.device.createRenderPipeline({label:"renderer-skinned-point-shadow-pipeline",layout:s,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-point-shadow-module",code:kn}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(qr)},fragment:{module:this.state.device.createShaderModule({label:"renderer-skinned-point-shadow-fragment-module",code:kn}),entryPoint:"fsMain",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}});const o=this.state.device.createPipelineLayout({label:"renderer-present-layout",bindGroupLayouts:[this.state.fullscreenTextureBindGroupLayout]});this.state.presentPipeline=this.state.device.createRenderPipeline({label:"renderer-present-pipeline",layout:o,vertex:{module:this.state.device.createShaderModule({label:"renderer-present-module",code:On}),entryPoint:"vsMain"},fragment:{module:this.state.device.createShaderModule({label:"renderer-present-fragment-module",code:On}),entryPoint:"fsMain",targets:[{format:this.state.format}]},primitive:{topology:"triangle-list"}})}recreateShadowResources(){if(this.state.device){this.state.residentSceneBindGroupVersion+=1,this.state.sharedSceneBindGroup=null,this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches(),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}));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}))}}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.shadowMapSize,...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??$r,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??$r,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 $r;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,u=!1;const d=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)},h={device:this.state.device,encoder:t,camera:s.camera,sceneColorView:this.state.sceneColorView,postProcessColorView:this.state.postProcessColorView,presentationColorView:a,depthView:this.state.mainDepthView,colorFormat:$r,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}},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:s.lights.points.length,activeLayerCount:6*s.lights.points.length},spot:{view:this.state.spotShadowView,size:this.state.spotShadowTextureSize,layerCount:4,activeLightCount:s.lights.spots.length,activeLayerCount:s.lights.spots.length}}),getSceneLightingResources:()=>{if(!(this.state.lightBuffer&&this.state.directionalShadowView&&this.state.pointShadowArrayView&&this.state.spotShadowView))throw new Error("Renderer scene lighting resources are not initialized.");return{lightBuffer:this.state.lightBuffer,directionalShadowView:this.state.directionalShadowView,pointShadowView:this.state.pointShadowArrayView,spotShadowView:this.state.spotShadowView}}};return{fogVolumeObjects:s.fogVolumeObjects,extractedLights:s.lights,addDirectionalShadowPass:()=>{e.addPass(new xr("DirectionalShadowPass",()=>{this.executeDirectionalShadowPass(t,i,s,o)},{writes:["directionalShadow"]}))},addPointShadowPass:()=>{s.lights.points.some(e=>e.castShadow)&&e.addPass(new xr("PointShadowPass",()=>{this.executePointShadowPass(t,i,s,o)},{writes:["pointShadow"]}))},addSpotShadowPass:()=>{s.lights.spots.some(e=>e.castShadow)&&e.addPass(new xr("SpotShadowPass",()=>{this.executeSpotShadowPass(t,i,s,o)},{writes:["spotShadow"]}))},addDepthPrepass:()=>{c=!0,this.getHiZOcclusionCullingActive()&&this.hasEnabledStaticDrawSets()&&e.addPass(new xr("TemporalStaticVisibilityPrepass",()=>{this.executeStaticVisibilityPasses(t,"prepass")},{reads:["hiz"],writes:["staticIndirectArgs"]})),e.addPass(new xr("DepthPrepass",()=>{this.executeDepthPrepass(t,r,s,o)},{writes:["mainDepth"]}))},addHiZPasses:()=>{this.getHiZOcclusionCullingActive()&&e.addPass(new xr("HiZPasses",()=>{this.executeHiZPasses(t)},{reads:["mainDepth"],writes:["hiz"]}))},addVisibilityPass:()=>{this.getHiZOcclusionCullingActive()&&(n||this.hasEnabledStaticDrawSets())&&(e.addPass(new xr("VisibilityPass",()=>{n&&this.executeVisibilityPass(t,n),this.executeStaticVisibilityPasses(t,"postpass")},{reads:["hiz"],writes:["indirectArgs","staticIndirectArgs"]})),this.sampleCount>1&&this.hasEnabledStaticDrawSets()&&e.addPass(new xr("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")=>{const n=!c,a=[...s.gpuOpaqueDraws,...s.directOpaqueDraws,...s.transparentDraws],h=d(a);if(l?.push({draws:a,colorTargetFormats:[this.getColorTargetFormat(i)],sampleCount:this.sampleCount}),h.includes("mainDepth")){if(!c)throw new Error("Materials that sample mainDepth require a depth prepass.");e.addPass(new xr("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"]})),u=!0}e.addPass(new xr("ForwardPass",()=>{this.executeForwardPass(t,i,this.getColorTargetView(i),r,s,o,n)},{reads:["directionalShadow","pointShadow","spotShadow","mainDepth","indirectArgs",...h.map(e=>"mainDepth"===e?"sceneDepthSnapshot":e)],writes:[i]})),this.getHiZOcclusionCullingActive()&&this.hasEnabledStaticDrawSets()&&e.addPass(new xr("TemporalHiZHistoryPass",()=>{this.executeHiZPasses(t,!0)},{reads:["mainDepth"],writes:["hiz"],dependsOn:["ForwardPass"]}))},addOpaquePass:(i="sceneColor")=>{const n=!c,a=[...s.gpuOpaqueDraws,...s.directOpaqueDraws],h=d(a);if(l?.push({draws:a,colorTargetFormats:[this.getColorTargetFormat(i)],sampleCount:this.sampleCount}),h.includes("mainDepth")){if(!c)throw new Error("Materials that sample mainDepth require a depth prepass.");e.addPass(new xr("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"]})),u=!0}e.addPass(new xr("OpaquePass",()=>{this.executeForwardPass(t,i,this.getColorTargetView(i),r,s,o,n,"opaque")},{reads:["directionalShadow","pointShadow","spotShadow","mainDepth","indirectArgs",...h.map(e=>"mainDepth"===e?"sceneDepthSnapshot":e)],writes:[i]}))},addSceneTextureCopyPass:(r="sceneColor")=>{if(!(s.transparentDraws.some(e=>e.material.usesSceneTextures())||d(s.transparentDraws).includes("mainDepth")))return;const i=this.getColorTargetDimensions(r);if(i.width!==this.state.width||i.height!==this.state.height||this.getColorTargetFormat(r)!==$r)throw new Error("Scene texture snapshots currently require a full-resolution rgba16float source.");e.addPass(new xr("SceneTextureCopyPass",()=>{this.state.sceneColorSnapshotTexture&&this.state.sceneDepthSnapshotTexture&&this.state.mainDepthTexture&&(t.copyTextureToTexture({texture:this.getColorTargetTexture(r)},{texture:this.state.sceneColorSnapshotTexture},{width:this.state.width,height:this.state.height}),t.copyTextureToTexture({texture:this.state.mainDepthTexture},{texture:this.state.sceneDepthSnapshotTexture},{width:this.state.width,height:this.state.height}))},{reads:[r,"mainDepth"],writes:["sceneColorSnapshot","sceneDepthSnapshot"]})),u=!0},addLatePass:(i="sceneColor")=>{if(0===s.transparentDraws.length)return;l?.push({draws:s.transparentDraws,colorTargetFormats:[this.getColorTargetFormat(i)],sampleCount:1});const n=[i,"mainDepth",...d(s.transparentDraws)];s.transparentDraws.some(e=>e.material.usesSceneTextures())&&n.push("sceneColorSnapshot","sceneDepthSnapshot"),e.addPass(new xr("LatePass",()=>{this.executeForwardPass(t,i,this.getColorTargetView(i),r,s,o,!1,"late",!0,1)},{reads:n,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 xr("TemporalHiZHistoryPass",()=>{this.executeHiZPasses(t,!0)},{reads:["mainDepth"],writes:["hiz"],dependsOn:[i]}))},addMaterialPass:(i={})=>{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],u=i.objectFilter?c.filter(e=>i.objectFilter(e.sourceObject)||!0===e.sourceRanges?.some(e=>i.objectFilter(e.sourceObject))):c,d=e=>"function"==typeof i.overrideMaterial?i.overrideMaterial(e.material,null!==e.skinning):i.overrideMaterial,h=i.overrideMaterial?u.map(e=>({...e,material:d(e)})):u;l?.push({draws:h,colorTargetFormats:n.map(e=>this.getColorTargetFormat(e)),sampleCount:this.sampleCount}),e.addPass(new xr(i.name??"MaterialPass",()=>{this.executeMaterialPass(t,n,r,s,o,i)},{reads:["directionalShadow","pointShadow","spotShadow",...i.loadDepth?["mainDepth"]:[],...i.loadColor?n:[]],writes:this.sampleCount>1?n:[...n,"mainDepth"]}))},addCustomPass:t=>{e.addPass(new xr(t.name,()=>{t.execute(h)},{reads:t.reads,writes:t.writes,dependsOn:t.dependsOn}))},addPresentPass:(r="sceneColor")=>{e.addPass(new xr("PresentPass",()=>{const e=this.getColorTargetView(r);this.executePresentPass(t,e,a)},{reads:[r],writes:["mainColor"]}))}}}transparentDraws=[];opaqueBatches=new Map;acquireDrawCall(){const e=this.drawCallPoolCount;this.drawCallPoolCount+=1;let t=this.drawCallPool[e];return t||(t={geometry:null,geometryKey:{},geometryResource:null,material:null,customDepthMaterial:null,residentInstanceBinding:null,sourceObject:null,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 wt,boundsRadius:0,sortDepth:0,transparentSortGroup:0,transparentSortOrder:0},this.drawCallPool[e]=t),t}acquireOpaqueBatchBuilder(){const e=this.opaqueBatchPoolCount;this.opaqueBatchPoolCount+=1;let t=this.opaqueBatchPool[e];return t||(t={template:null,totalInstanceCount:0,rangePairCount:0,firstInstanceStart:0,firstInstanceCount:0,sourceRanges:[],boundsMin:new wt,boundsMax:new wt},this.opaqueBatchPool[e]=t),t}populateDrawCall(e,t,r,i,n,a,s,o){const l=t.wireframe;l&&this.ensureWireframeIndex(t.geometry,t.geometryResource);const c=t.sourceObject?Boolean(t.sourceObject.receiveShadow):t.receiveShadow;return this.shouldInvalidateDrawMaterialResource(e,t.material,c,t.usesBatching,null)&&(e.materialResource=null),e.geometry=t.geometry,e.geometryKey=l?t.geometryResource.wireframeIndex:t.geometryKey,e.geometryResource=t.geometryResource,e.material=t.material,e.customDepthMaterial=t.customDepthMaterial,e.residentInstanceBinding=t.residentInstanceBinding,e.sourceObject=t.sourceObject,e.usesBatching=t.usesBatching,e.geometryGroup=t.geometryGroup,e.batchKey=t.batchKey,e.batchHash=t.batchHash,e.indexed=l||t.indexed,e.wireframe=l,e.start=l?2*t.start:t.start,e.count=l?2*t.count:t.count,e.transparent=t.transparent,e.renderOrder=t.sourceObject?.renderOrder??t.renderOrder,e.hasRenderCallbacks=this.hasRenderCallbacks(t.sourceObject),e.castShadow=t.sourceObject?Boolean(t.sourceObject.castShadow):t.castShadow,e.receiveShadow=c,e.sortMaterialId=t.sortMaterialId,e.sortGeometryId=t.sortGeometryId,e.sortCustomDepthMaterialId=t.sortCustomDepthMaterialId,e.skinning=null,e.instanceStart=r,e.instanceCount=i,e.boundsCenter.set(n,a,s),e.boundsRadius=o,e.sortDepth=0,e.transparentSortGroup=0,e.transparentSortOrder=0,e.sourceRanges=void 0,e}populateDynamicDrawCall(e,t,r,i,n,a,s,o,l,c,u,d,h,p,f,m,g,v,x,w,b,y,S,C,P,M,B,D,T=null){const I=!0===o?.isBatchedMesh,R=n.wireframe&&"triangle-list"===n.primitiveTopology;return R&&this.ensureWireframeIndex(t,i),this.shouldInvalidateDrawMaterialResource(e,n,x,I,T)&&(e.materialResource=null),e.geometry=t,e.geometryKey=R?i.wireframeIndex:r,e.geometryResource=i,e.material=n,e.customDepthMaterial=a,e.residentInstanceBinding=s,e.sourceObject=o,e.usesBatching=I,e.geometryGroup=l,e.batchKey=c,e.batchHash=u,e.indexed=R||d,e.wireframe=R,e.start=R?2*h:h,e.count=R?2*p:p,e.transparent=f,e.renderOrder=m,e.hasRenderCallbacks=g,e.castShadow=v,e.receiveShadow=x,e.sortMaterialId=w,e.sortGeometryId=b,e.sortCustomDepthMaterialId=y,e.skinning=T,e.instanceStart=S,e.instanceCount=C,e.boundsCenter.set(P,M,B),e.boundsRadius=D,e.sortDepth=0,e.transparentSortGroup=0,e.transparentSortOrder=0,e.sourceRanges=void 0,e}pushOpaqueDrawTemplate(e,t,r,i,n,a,s){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(Vi(r.template,e)){c=r;break}}else Vi(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;let i=this.toonOutlineMaterialCache.get(e);if(!i){const t=t=>new Nt({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?Kn:[{name:"position",shaderLocation:0,format:"float32x3"},{name:"normal",shaderLocation:1,format:"float32x3",defaultValue:[0,0,1]}],uniforms:{outlineThickness:r.thickness??.003,outlineColor:(new ot).fromArray(r.color??[0,0,0]),outlineAlpha:r.alpha??e.opacity},side:nt,depthTest:!0,depthWrite:!0,transparent:!0});i={regular:t(!1),skinned:t(!0)},this.toonOutlineMaterialCache.set(e,i)}const n=t?i.skinned:i.regular;return n.uniforms.outlineThickness.value=r.thickness??.003,n.uniforms.outlineColor.value.fromArray(r.color??[0,0,0]),n.uniforms.outlineAlpha.value=r.alpha??e.opacity,n}pushToonOutlineDraw(e,t){const r=t?this.getToonOutlineMaterial(t,null!==e.skinning):null;if(!r||e.usesBatching)return;const i=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e.geometryKey,e.geometryResource,r,null,e.residentInstanceBinding,e.sourceObject,e.geometryGroup,`toon-outline:${e.batchKey}`,Di(Mi(r),Mi(e.geometryKey),e.indexed,e.start,e.count,0),e.indexed,e.start,e.count,!0,e.renderOrder,!1,!1,!1,Mi(r),e.sortGeometryId,0,e.instanceStart,e.instanceCount,e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius,e.skinning);this.transparentDraws.push(i)}updateTransparentDrawSortDepths(e,t,r){for(let i=0;i<e.length;i+=1){const n=e[i];0===n.transparentSortGroup&&(n.sortDepth=(n.boundsCenter.x-t.x)*r.x+(n.boundsCenter.y-t.y)*r.y+(n.boundsCenter.z-t.z)*r.z)}}extractScene(e,t){this.extractionVersion+=1,this.drawCallPoolCount=0,this.opaqueBatchPoolCount=0;this.opaqueBatches.clear();const r=this.transparentDraws;r.length=0;const i=this.residentInstanceUploadsScratch;i.length=0;const n=this.sourceInstanceDataScratch;n.reset();const a=this.gpuOpaqueDrawsScratch;a.length=0;const s=this.directOpaqueDrawsScratch;s.length=0;const o=this.stagedOpaqueDrawsScratch;o.length=0;const l=this.residentOpaqueDrawsScratch;l.length=0;const c=this.opaqueInstanceDataScratch;c.reset();const u=this.finalInstanceDataScratch;u.reset();const d=this.extractedAmbientScratch;d.set(0,0,0,0);let h=null;const p=this.activeDirectionalLightsScratch,f=this.activePointLightsScratch,m=this.activeSpotLightsScratch,g=this.fogVolumeObjectsScratch;p.length=0,f.length=0,m.length=0,g.length=0;const v=this.extractedBoundsMinScratch;v.set(1/0,1/0,1/0);const x=this.extractedBoundsMaxScratch;x.set(-1/0,-1/0,-1/0),function(e,t){const r=e.elements,i=r[0],n=r[1],a=r[2],s=r[3],o=r[4],l=r[5],c=r[6],u=r[7],d=r[8],h=r[9],p=r[10],f=r[11],m=r[12],g=r[13],v=r[14],x=r[15];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)}(Ei(t,this.cameraViewProjScratch),this.cameraFrustumPlanesScratch);const w=this.transparentSortCameraPositionScratch,b=this.transparentSortCameraForwardScratch;t.getWorldPosition(w),t.getWorldDirection(b);const y=this.isSphereVisibleScratch,S=this.updateExtractedBoundsFromMatrixScratch,C=this.objectTraversalStackScratch;C.length=0,C.push(e);for(let e=this.csmCascadeLights.length-1;e>=0;e-=1)C.push(this.csmCascadeLights[e]);for(;C.length>0;){const e=C.pop();if(!e.visible)continue;const r=0!==(e.layers.mask&t.layers.mask);if(!0===e.isFogVolumeObject&&null!=e.volume)g.push(e);else if(e.isAmbientLight){if(r){const t=e;d.x+=t.color.r*t.intensity,d.y+=t.color.g*t.intensity,d.z+=t.color.b*t.intensity,d.w=1}}else if(e.isHemisphereLight){if(r&&null==h){const t=e,r=this.extractedHemisphereScratch;Xr.setFromMatrixPosition(t.matrixWorld),r.direction.copy(Xr),r.direction.lengthSq()<=1e-10?r.direction.set(0,1,0):r.direction.normalize(),r.skyColor.set(t.color.r,t.color.g,t.color.b),r.groundColor.set(t.groundColor.r,t.groundColor.g,t.groundColor.b),r.intensity=t.intensity,h=r}}else if(e.isDirectionalLight){if(r&&p.length<4&&!this.hasExtractedDirectionalLight(p,e)){const t=e,r=t.shadow,i=r.camera,n=this.extractedDirectionalLightsScratch[p.length];n.sourceLight=t,t.target.matrixWorldAutoUpdate&&t.target.updateMatrixWorld(!0),Xr.setFromMatrixPosition(t.matrixWorld),Jr.setFromMatrixPosition(t.target.matrixWorld),n.position.copy(Xr),n.target.copy(Jr),n.direction.copy(Jr).sub(Xr).normalize(),n.color.set(t.color.r,t.color.g,t.color.b),n.intensity=t.intensity,n.volumetricIntensity=t.userData?.volumetricIntensity??1,n.castShadow=t.castShadow,n.shadowBias=r.bias,n.shadowNormalBias=r.normalBias,n.shadowRadius=r.radius,n.shadowIntensity=r.intensity,n.shadowMapSize=Math.max(1,r.mapSize.width,r.mapSize.height),n.shadowCameraLeft=i.left,n.shadowCameraRight=i.right,n.shadowCameraTop=i.top,n.shadowCameraBottom=i.bottom,n.shadowCameraNear=i.near,n.shadowCameraFar=i.far,p.push(n)}}else if(e.isPointLight){if(r&&f.length<4){const t=e,r=t.shadow,i=r.camera,n=this.extractedPointLightsScratch[f.length];Xr.setFromMatrixPosition(t.matrixWorld),n.position.copy(Xr),n.color.set(t.color.r,t.color.g,t.color.b),n.intensity=t.intensity,n.volumetricIntensity=t.userData?.volumetricIntensity??1,n.range=t.distance>0?t.distance:Math.max(i.far,25),n.decay=t.decay,n.castShadow=t.castShadow,n.shadowBias=r.bias,n.shadowNormalBias=r.normalBias,n.shadowRadius=r.radius,n.shadowIntensity=r.intensity,n.shadowMapSize=Math.max(1,r.mapSize.width,r.mapSize.height),n.shadowCameraNear=i.near,n.shadowCameraFar=t.distance>0?t.distance:i.far,f.push(n)}}else if(e.isSpotLight){if(r&&m.length<4){const t=e,r=t.shadow,i=r.camera,n=this.extractedSpotLightsScratch[m.length];t.target.matrixWorldAutoUpdate&&t.target.updateMatrixWorld(!0),Xr.setFromMatrixPosition(t.matrixWorld),Jr.setFromMatrixPosition(t.target.matrixWorld),n.position.copy(Xr),n.direction.copy(Jr).sub(Xr).normalize(),n.color.set(t.color.r,t.color.g,t.color.b),n.intensity=t.intensity,n.volumetricIntensity=t.userData?.volumetricIntensity??1,n.range=t.distance>0?t.distance:i.far,n.angle=t.angle,n.penumbra=t.penumbra,n.decay=t.decay,n.castShadow=t.castShadow,n.shadowBias=r.bias,n.shadowNormalBias=r.normalBias,n.shadowRadius=r.radius,n.shadowIntensity=r.intensity,n.shadowMapSize=Math.max(1,r.mapSize.width,r.mapSize.height),n.shadowCameraNear=i.near,n.shadowCameraFar=t.distance>0?t.distance:i.far,n.shadowCameraFov=i.fov,m.push(n)}}else r&&e.isBatchedMesh?this.collectBatchedMesh(e,n,S,y,t,w,b):r&&e.isInstancedMesh?this.collectInstancedMesh(e,n,S,y):r&&e.isSkinnedMesh?this.collectSkinnedMesh(e,n,S,y):r&&e.isLine?this.collectLine(e,n,S,y):r&&e.isSprite?this.collectSprite(e,n,S,y):r&&e.isMesh&&this.collectMesh(e,n,S,y);const i=e.children;for(let e=i.length-1;e>=0;e-=1)C.push(i[e])}if(this.csmCascadeLights.length>0){const e=new Map;for(let t=0;t<this.csmCascadeLights.length;t+=1)e.set(this.csmCascadeLights[t],t);p.sort((t,r)=>((null==t.sourceLight?void 0:e.get(t.sourceLight))??4)-((null==r.sourceLight?void 0:e.get(r.sourceLight))??4))}const P=s.length;this.updateTransparentDrawSortDepths(r,w,b),r.sort(Ii),Number.isFinite(v.x)||(v.set(-6,-6,-6),x.set(6,6,6)),o.sort(Ti);for(let e=0;e<o.length;){const t=o[e],r=c.instanceCount;c.appendRange(n,t.instanceStart,t.instanceCount);let i,l=t.instanceCount,u=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<o.length&&zi(t,o[g]);){const e=o[g];c.appendRange(n,e.instanceStart,e.instanceCount),i??=[{sourceObject:t.sourceObject,instanceStart:r,instanceCount:t.instanceCount}],i.push({sourceObject:e.sourceObject,instanceStart:r+l,instanceCount:e.instanceCount}),l+=e.instanceCount;const a=e.boundsCenter.x-e.boundsRadius,s=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;a<u&&(u=a),s<d&&(d=s),v<h&&(h=v),x>p&&(p=x),w>f&&(f=w),b>m&&(m=b),g+=1}const v=.5*(u+p),x=.5*(d+f),w=.5*(h+m),b=p-v,y=f-x,S=m-w;t.instanceStart=r,t.instanceCount=l,t.sourceRanges=i,t.boundsCenter.set(v,x,w),t.boundsRadius=Math.sqrt(b*b+y*y+S*S),t.indexed&&!t.hasRenderCallbacks?a.push(t):s.push(t),e=g}l.sort(Ti);for(let e=0;e<l.length;e+=1){const t=l[e];t.indexed&&!t.hasRenderCallbacks?a.push(t):s.push(t)}u.appendBuilder(c);for(let e=0;e<P;e+=1){const t=s[e];if(t.residentInstanceBinding)continue;const r=u.instanceCount;u.appendRange(n,t.instanceStart,t.instanceCount),t.instanceStart=r}a.sort(Ti),s.sort(Ti);for(let e=0;e<r.length;e+=1){const t=r[e];if(t.residentInstanceBinding)continue;const i=u.instanceCount;u.appendRange(n,t.instanceStart,t.instanceCount),t.instanceStart=i}const M=this.extractedLightsScratch;M.hemisphere=h,M.directional=p[0]??null,M.point=f[0]??null,M.spot=m[0]??null;const B=this.extractedFrameScratch;return B.scene=e,B.camera=t,B.fogVolumeObjects=g,B.transparentDraws=r,B.instanceData=u,B.residentInstanceUploads=i,B}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=`${ii(n)}:${s}`;let c=this.lineProxyCache.get(e);c&&c.signature===l||(c={signature:l,mesh:new pt(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=ii(n);let o=this.lineProxyCache.get(e);if(!o||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 st;f.setIndex([0,2,1,2,3,1,2,4,3,4,5,3,4,6,5,6,7,5]),f.setAttribute("position",new at(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 ut(new Float32Array(d),3)),f.setAttribute("instanceEnd",new ut(new Float32Array(h),3)),f.instanceCount=d.length/3;const m=Oi(n);f.boundingSphere=new gt(m.center.clone(),m.radius),o={signature:s,mesh:new pt(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 pt(t,e.material),centerX:Number.NaN,centerY:Number.NaN},this.spriteProxyCache.set(e,n)}if(n.centerX!==e.center.x||n.centerY!==e.center.y){const t=n.mesh.geometry.getAttribute("position"),r=e.geometry.getAttribute("position");for(let i=0;i<t.count;i+=1)t.setXYZ(i,r.getX(i)+.5-e.center.x,r.getY(i)+.5-e.center.y,r.getZ(i));t.needsUpdate=!0,n.mesh.geometry.computeBoundingSphere(),n.centerX=e.center.x,n.centerY=e.center.y}const a=n.mesh;a.material=e.material,a.matrixWorld.copy(e.matrixWorld),a.frustumCulled=e.frustumCulled,a.renderOrder=e.renderOrder,a.castShadow=e.castShadow,a.receiveShadow=e.receiveShadow,a.onBeforeRender=(...t)=>e.onBeforeRender(...t),a.onAfterRender=(...t)=>e.onAfterRender(...t),this.collectMesh(a,t,r,i)}hasExtractedDirectionalLight(e,t){for(let r=0;r<e.length;r+=1)if(e[r].sourceLight===t)return!0;return!1}getObjectMotionHistory(e,t){let r=this.objectMotionHistory.get(e);if(!r)return r={matrix:new Float32Array(16),generation:this.motionVectorHistoryGeneration,lastExtractionVersion:-1,valid:!1},r.matrix.set(t),this.objectMotionHistory.set(e,r),r;const i=!0===e.userData.motionBlurTeleported;i&&(e.userData.motionBlurTeleported=!1);const n=(t[12]??0)-r.matrix[12],a=(t[13]??0)-r.matrix[13],s=(t[14]??0)-r.matrix[14],o=Math.max(0,Number(e.userData.motionBlurTeleportDistance??10));return r.valid=this.motionVectorHistoryValid&&r.generation===this.motionVectorHistoryGeneration&&r.lastExtractionVersion===this.extractionVersion-1&&!i&&n*n+a*a+s*s<=o*o,r}commitObjectMotionHistory(e,t){e.matrix.set(t),e.generation=this.motionVectorHistoryGeneration,e.lastExtractionVersion=this.extractionVersion}collectMesh(e,t,r,i){const n=e.geometry;if(void 0===n.attributes.position)return;const a=e.material,s=Array.isArray(a);if(!s&&!1===a.visible||s&&a.every(e=>!1===e.visible))return;const o=this.getGeometryResource(n),l=this.meshExtractionCache.get(e),c=l?.geometryResource===o?l:null,u=c?null:Oi(n),d=c?c.localBoundsCenter:u.center,h=c?c.localBoundsRadius:u.radius,p=e.matrixWorld.elements,f=d.x,m=d.y,g=d.z,v=p[0]*f+p[4]*m+p[8]*g+p[12],x=p[1]*f+p[5]*m+p[9]*g+p[13],w=p[2]*f+p[6]*m+p[10]*g+p[14],b=p[0]*p[0]+p[1]*p[1]+p[2]*p[2],y=p[4]*p[4]+p[5]*p[5]+p[6]*p[6],S=p[8]*p[8]+p[9]*p[9]+p[10]*p[10],C=h*Math.sqrt(Math.max(b,y,S,1e-10));if(!i(v,x,w,C,e.frustumCulled))return;const P=this.resolvedMeshMaterialsScratch;P.length=0;let M=null;if(s)for(let e=0;e<a.length;e+=1)P[e]=this.resolveMaterial(a[e]);else{if(!a.visible)return;M=this.resolveMaterial(a)}const B=_i(e),D=l&&l.customDepthMaterial===B&&l.geometryResource.lastValidatedExtractionVersion===this.extractionVersion&&(!s&&l.material===a&&l.resolvedMaterial===M||s&&null!==l.materials&&null!==l.resolvedMaterials&&li(l.materials,a)&&di(l.resolvedMaterials,P))?l:this.getMeshExtractionCacheEntry(e,a,M,P,B,o),T=D.templates.length;if(0===T)return;const I=function(e){const t=e.attributes;let r=!1,i=1/0;for(const e in t){const n=t[e];!0!==n.isInstancedBufferAttribute&&!0!==n.data?.isInstancedInterleavedBuffer||(r=!0,n.count<i&&(i=n.count))}if(!r)return 1;const n=e.instanceCount;return Number.isFinite(n)?Math.max(0,Math.floor(n)):Math.max(0,i)}(n),R=this.getObjectMotionHistory(e,p),G=Wn(e),V=_n(e);let z=0;for(let e=0;e<I;e+=1){const r=Si(t,p,1,1,1,1,void 0,R.matrix,G,V,R.valid?1:0);0===e&&(z=r)}this.commitObjectMotionHistory(R,p),r(p);for(let e=0;e<T;e+=1){const t=D.templates[e],r=this.populateDrawCall(this.acquireDrawCall(),t,z,I,v,x,w,C);t.transparent?this.transparentDraws.push(r):this.pushDraw(r);const i=s?a[t.geometryGroup?.materialIndex??0]:a;this.pushToonOutlineDraw(r,i)}}prepareSceneForCompilation(e,t,r){if(!(this.state.initialized&&this.state.device&&this.state.context&&this.state.mainDepthView&&this.state.sceneColorView&&this.state.postProcessColorView&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.shadowCameraBuffer&&this.state.sceneBindGroupLayout&&this.state.shadowBindGroupLayout&&this.state.shadowComparisonSampler&&this.state.linearClampSampler&&this.state.nearestClampSampler&&this.state.visibilityParamsBuffer&&this.state.directionalShadowView&&this.state.pointShadowArrayView&&this.state.spotShadowView&&this.state.hizCopyKernel&&this.state.hizReduceKernel&&this.state.visibilityKernel&&this.state.presentPipeline))throw new Error("WebGpuRenderer.initialize() must complete before compile().");e.matrixWorldAutoUpdate&&e.updateMatrixWorld(),null===t.parent&&t.matrixWorldAutoUpdate&&t.updateMatrixWorld();const i=this.extractScene(e,t);this.ensureShadowTextureSizes(i),this.uploadInstanceData(i.instanceData),this.uploadResidentInstanceData(i.residentInstanceUploads),this.uploadDrawMetadata(this.getHiZOcclusionCullingActive()?i.gpuOpaqueDraws:[]),this.updateCameraUniforms(t,e),this.updateLightUniforms(i);const n=this.compileDrawScratch;if(n.length=0,n.push(...i.gpuOpaqueDraws,...i.directOpaqueDraws,...i.transparentDraws),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,i,{drawCallCount:0,triangleCount:0},e);return this.graphBuilder(this.renderGraph,r),Promise.all([...e.map(e=>this.compileDrawMaterialsAsync(e.draws,e.colorTargetFormats,e.sampleCount)),...e.map(e=>this.compileStaticDrawMaterialsAsync(e.colorTargetFormats,e.sampleCount))]).then(async()=>{await(this.state.device?.queue.onSubmittedWorkDone())})}this.compileDrawMaterials(n)}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=_i(e),l=this.getGeometryResource(e.geometry),c=this.getInstancedMeshExtractionCacheEntry(e,s,o,l),u=e.instanceMatrix.array,d=e.instanceMatrix.version,h=e.instanceColor?.array,p=e.instanceColor?.itemSize??0,f=e.instanceColor?.version??-1,m=c.cacheValid&&c.cachedCount===e.count&&c.cachedInstanceMatrixVersion===d&&c.cachedInstanceColorVersion===f&&Li(c.cachedMatrixWorld,e.matrixWorld.elements),g=Ai(e.matrixWorld.elements),v=g&&!e.frustumCulled;if(!m){const t=c.cachedInstanceMatrixVersion!==d||c.cachedCount!==e.count,r=c.cachedInstanceColorVersion!==f||c.cachedCount!==e.count;if(v){const i=e.matrixWorld.elements,n=i[12]??0,a=i[13]??0,s=i[14]??0;c.cachedDrawBoundsCenter.set(n,a,s),c.cachedDrawBoundsRadius=0,c.cachedBoundsMin.set(n,a,s),c.cachedBoundsMax.set(n,a,s),c.cachedInstanceMatrixVersion=d,c.cachedInstanceColorVersion=f,c.cachedCount=e.count,c.cachedDefaultColorData=null,Ui(e.matrixWorld.elements,c.cachedMatrixWorld),c.residentBufferDirty||=t,c.residentColorBufferDirty||=r,c.cacheValid=!0}else{const t=c.cachedInstanceData.beginWriteInstances(e.count),r=c.cachedBoundsMin,i=c.cachedBoundsMax;r.set(1/0,1/0,1/0),i.set(-1/0,-1/0,-1/0);const n=c.localBoundsCenter,a=c.localBoundsRadius,s=e.matrixWorld.elements,o=Ai(s),l=n.x,m=n.y,g=n.z,v=s[0],x=s[4],w=s[8],b=s[12],y=s[1],S=s[5],C=s[9],P=s[13],M=s[2],B=s[6],D=s[10],T=s[14],I=s[3],R=s[7],G=s[11],V=s[15];for(let n=0;n<e.count;n+=1){const e=16*n,s=n*Er,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,L=u[e+5]??0,A=u[e+6]??0,F=u[e+7]??0,E=u[e+8]??0,k=u[e+9]??0,O=u[e+10]??0,j=u[e+11]??0,$=u[e+12]??0,N=u[e+13]??0,W=u[e+14]??0,_=u[e+15]??0;let H,q,K,Z,Y,X,J,Q,ee,te,re,ie,ne,ae,se,oe;o?(H=c,q=d,K=f,Z=z,Y=U,X=L,J=A,Q=F,ee=E,te=k,re=O,ie=j,ne=$,ae=N,se=W,oe=_):(H=v*c+x*d+w*f+b*z,Y=v*U+x*L+w*A+b*F,ee=v*E+x*k+w*O+b*j,ne=v*$+x*N+w*W+b*_,q=y*c+S*d+C*f+P*z,X=y*U+S*L+C*A+P*F,te=y*E+S*k+C*O+P*j,ae=y*$+S*N+C*W+P*_,K=M*c+B*d+D*f+T*z,J=M*U+B*L+D*A+T*F,re=M*E+B*k+D*O+T*j,se=M*$+B*N+D*W+T*_,Z=I*c+R*d+G*f+V*z,Q=I*U+R*L+G*A+V*F,ie=I*E+R*k+G*O+V*j,oe=I*$+R*N+G*W+V*_),t[s+0]=H,t[s+1]=q,t[s+2]=K,t[s+3]=Z,t[s+4]=Y,t[s+5]=X,t[s+6]=J,t[s+7]=Q,t[s+8]=ee,t[s+9]=te,t[s+10]=re,t[s+11]=ie,t[s+12]=ne,t[s+13]=ae,t[s+14]=se,t[s+15]=oe;const le=n*p;t[s+16]=h?h[le+0]??1:1,t[s+17]=h?h[le+1]??1:1,t[s+18]=h?h[le+2]??1:1,t[s+19]=h&&p>=4?h[le+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 ce=H*l+Y*m+ee*g+ne,ue=q*l+X*m+te*g+ae,de=K*l+J*m+re*g+se,he=Math.sqrt(H*H+q*q+K*K),pe=Math.sqrt(Y*Y+X*X+J*J),fe=Math.sqrt(ee*ee+te*te+re*re),me=a*Math.max(he,pe,fe,1e-5);$i(r,i,Xr.set(ce,ue,de),me)}c.cachedDrawBoundsCenter.copy(r).add(i).multiplyScalar(.5);const z=i.x-c.cachedDrawBoundsCenter.x,U=i.y-c.cachedDrawBoundsCenter.y,L=i.z-c.cachedDrawBoundsCenter.z;c.cachedDrawBoundsRadius=Math.sqrt(z*z+U*U+L*L),c.cachedInstanceMatrixVersion=d,c.cachedInstanceColorVersion=f,c.cachedCount=e.count,c.cachedDefaultColorData=null,Ui(e.matrixWorld.elements,c.cachedMatrixWorld),c.residentBufferDirty=!0,c.residentColorBufferDirty=!0,c.cacheValid=!0}}if(!i(c.cachedDrawBoundsCenter.x,c.cachedDrawBoundsCenter.y,c.cachedDrawBoundsCenter.z,c.cachedDrawBoundsRadius,e.frustumCulled))return;c.residentInstanceBinding&&c.residentInstanceBinding.mode!==(g?"instanced-direct":"packed")&&(c.residentInstanceBinding.mode=g?"instanced-direct":"packed",c.residentInstanceBinding.sceneBindGroup=null,c.residentInstanceBinding.shadowBindGroup=null,c.residentInstanceBinding.shadowBindGroups.clear(),c.residentInstanceBinding.sceneBindGroupVersion=0,c.residentInstanceBinding.shadowBindGroupVersion=0,c.residentBufferDirty=!0,c.residentColorBufferDirty=!0),(c.residentBufferDirty||c.residentColorBufferDirty||!c.residentInstanceBinding)&&this.residentInstanceUploadsScratch.push(c),Fi(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;if(e.frustumCulled&&null!==n){const t=n.center,r=e.matrixWorld.elements;if(!i(r[0]*t.x+r[4]*t.y+r[8]*t.z+r[12],r[1]*t.x+r[5]*t.y+r[9]*t.z+r[13],r[2]*t.x+r[6]*t.y+r[10]*t.z+r[14],n.radius*ji(e.matrixWorld),!0))return}const a=Array.isArray(e.material)?e.material:[e.material],s=_i(e),o=null!==e.geometry.index,l=this.getSkinnedGeometryResource(e);this.refreshSkinningPalette(l.skinning.palette),this.refreshSkinningBindMatrices(e,l.skinning),this.updateSkinnedBounds(e,l);const c=Xr.copy(l.localBoundsCenter).applyMatrix4(e.matrixWorld),u=l.localBoundsRadius*ji(e.matrixWorld);if(!i(c.x,c.y,c.z,u,e.frustumCulled))return;this.uploadSkinningResources(l.skinning);const d=this.getObjectMotionHistory(e,e.matrixWorld.elements),h=Ci(t,e.matrixWorld,1,1,1,1,void 0,d.matrix,Wn(e),_n(e),d.valid?1:0);if(this.commitObjectMotionHistory(d,e.matrixWorld.elements),r(e.matrixWorld.elements),e.geometry.groups.length>0&&a.length>0){for(const t of e.geometry.groups){const r=a[t.materialIndex??0]??a[0],i=this.resolveSkinnedMaterial(r);if(!i)continue;const n=Bi(i,e,o,t.start,gi(e.geometry,o,t.start,t.count),s),d=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e,l.resource,i,s,null,e,t,n,Di(Mi(i),Mi(e),o,t.start,gi(e.geometry,o,t.start,t.count),s?Mi(s):0),o,t.start,gi(e.geometry,o,t.start,t.count),i.transparent,e.renderOrder,this.hasRenderCallbacks(e),e.castShadow,e.receiveShadow,Mi(i),Mi(e),s?Mi(s):0,h,1,c.x,c.y,c.z,u,l.skinning);this.pushDraw(d),this.pushToonOutlineDraw(d,r)}return}const p=this.resolveSkinnedMaterial(a[0]);if(!p)return;const f=vi(e.geometry,o),m=Bi(p,e,o,f.start,f.count,s),g=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e,l.resource,p,s,null,e,null,m,Di(Mi(p),Mi(e),o,f.start,f.count,s?Mi(s):0),o,f.start,f.count,p.transparent,e.renderOrder,this.hasRenderCallbacks(e),e.castShadow,e.receiveShadow,Mi(p),Mi(e),s?Mi(s):0,h,1,c.x,c.y,c.z,u,l.skinning);this.pushDraw(g),this.pushToonOutlineDraw(g,a[0])}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=_i(e),c=(e.geometry.index,this.getGeometryResource(e.geometry)),u=e,d=u._instanceInfo??u._drawInfo??[],h=d.length,p=u._matricesTexture?.image.data,f=u._colorsTexture?.image.data,m=this.getBatchedMeshExtractionCacheEntry(e,o,l,c,u),g=e.matrixWorld.elements,v=u._matricesTexture?.version??0,x=u._colorsTexture?.version??-1;if(m.cacheValid&&!o.transparent&&m.cachedMatricesVersion===v&&m.cachedColorsVersion===x&&m.cachedInstanceInfoLength===d.length&&m.cachedGeometryCount===(u._geometryCount??0)&&Li(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 Fi(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?Kr.fromArray(p,16*n):e.getMatrixAt(n,Kr),Zr.multiplyMatrices(e.matrixWorld,Kr);const h=u.localBoundsCenter,g=Zr.elements,v=g[0]*h.x+g[4]*h.y+g[8]*h.z+g[12],x=g[1]*h.x+g[5]*h.y+g[9]*h.z+g[13],w=g[2]*h.x+g[6]*h.y+g[10]*h.z+g[14],b=Math.sqrt(g[0]*g[0]+g[1]*g[1]+g[2]*g[2]),y=Math.sqrt(g[4]*g[4]+g[5]*g[5]+g[6]*g[6]),S=Math.sqrt(g[8]*g[8]+g[9]*g[9]+g[10]*g[10]),C=u.localBoundsRadius*Math.max(b,y,S,1e-5);if(!i(v,x,w,C,e.frustumCulled&&e.perObjectFrustumCulled))continue;const P=f?f[4*n+0]??1:1,M=f?f[4*n+1]??1:1,B=f?f[4*n+2]??1:1,D=f?f[4*n+3]??1:1,T=Ci(t,Zr,P,M,B,D,n);r(Zr.elements);const I=this.populateDrawCall(this.acquireDrawCall(),u,T,1,v,x,w,C),R=(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:R,index:n,draw:I}):(I.sortDepth=R,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=Mi(e);for(let e=0;e<o.length;e+=1){const i=o[e].draw;i.sortDepth=t,i.transparentSortGroup=r,i.transparentSortOrder=e,this.transparentDraws.push(i)}}return}const w=m.activeGroups;for(let e=0;e<w.length;e+=1){const t=w[e];t.activeInFrame=!1,t.activeCount=0}w.length=0;const b=m.cachedBoundsMin,y=m.cachedBoundsMax;b.set(1/0,1/0,1/0),y.set(-1/0,-1/0,-1/0),m.geometryIdsSnapshot.length!==d.length&&(m.geometryIdsSnapshot=new Int32Array(d.length));let S=0;for(let e=0;e<h;e+=1){const t=d[e];if(!t?.active||!t.visible){m.geometryIdsSnapshot[e]=-1;continue}const r=m.groups[t.geometryIndex];r?(m.geometryIdsSnapshot[e]=t.geometryIndex,r.activeInFrame||(r.activeInFrame=!0,r.activeCount=0,r.boundsMin.set(1/0,1/0,1/0),r.boundsMax.set(-1/0,-1/0,-1/0),w.push(r)),r.activeCount+=1,S+=1):m.geometryIdsSnapshot[e]=-1}const C=m.cachedInstanceData.beginWriteInstances(S);let P=0;for(let e=0;e<w.length;e+=1){const t=w[e];t.instanceStart=P,t.writeOffset=P*Er,P+=t.activeCount}const M=Ai(g),B=g[0],D=g[4],T=g[8],I=g[12],R=g[1],G=g[5],V=g[9],z=g[13],U=g[2],L=g[6],A=g[10],F=g[14],E=g[3],k=g[7],O=g[11],j=g[15];for(let t=0;t<h;t+=1){const r=m.geometryIdsSnapshot[t]??-1;if(r<0)continue;const i=m.groups[r];if(!i)continue;let n,a,s,o,l,c,u,d,h,g,v,x,w,S,P,$,N,W,_,H,q,K,Z,Y,X,J,Q,ee,te,re,ie,ne;if(p){const e=16*t;n=p[e+0]??0,a=p[e+1]??0,s=p[e+2]??0,o=p[e+3]??0,l=p[e+4]??0,c=p[e+5]??0,u=p[e+6]??0,d=p[e+7]??0,h=p[e+8]??0,g=p[e+9]??0,v=p[e+10]??0,x=p[e+11]??0,w=p[e+12]??0,S=p[e+13]??0,P=p[e+14]??0,$=p[e+15]??0}else{e.getMatrixAt(t,Kr);const r=Kr.elements;n=r[0]??0,a=r[1]??0,s=r[2]??0,o=r[3]??0,l=r[4]??0,c=r[5]??0,u=r[6]??0,d=r[7]??0,h=r[8]??0,g=r[9]??0,v=r[10]??0,x=r[11]??0,w=r[12]??0,S=r[13]??0,P=r[14]??0,$=r[15]??0}M?(N=n,W=a,_=s,H=o,q=l,K=c,Z=u,Y=d,X=h,J=g,Q=v,ee=x,te=w,re=S,ie=P,ne=$):(N=B*n+D*a+T*s+I*o,q=B*l+D*c+T*u+I*d,X=B*h+D*g+T*v+I*x,te=B*w+D*S+T*P+I*$,W=R*n+G*a+V*s+z*o,K=R*l+G*c+V*u+z*d,J=R*h+G*g+V*v+z*x,re=R*w+G*S+V*P+z*$,_=U*n+L*a+A*s+F*o,Z=U*l+L*c+A*u+F*d,Q=U*h+L*g+A*v+F*x,ie=U*w+L*S+A*P+F*$,H=E*n+k*a+O*s+j*o,Y=E*l+k*c+O*u+j*d,ee=E*h+k*g+O*v+j*x,ne=E*w+k*S+O*P+j*$);const ae=f?f[4*t+0]??1:1,se=f?f[4*t+1]??1:1,oe=f?f[4*t+2]??1:1,le=f?f[4*t+3]??1:1,ce=i.writeOffset;C[ce+0]=N,C[ce+1]=W,C[ce+2]=_,C[ce+3]=H,C[ce+4]=q,C[ce+5]=K,C[ce+6]=Z,C[ce+7]=Y,C[ce+8]=X,C[ce+9]=J,C[ce+10]=Q,C[ce+11]=ee,C[ce+12]=te,C[ce+13]=re,C[ce+14]=ie,C[ce+15]=ne,C[ce+16]=ae,C[ce+17]=se,C[ce+18]=oe,C[ce+19]=le,C[ce+20]=t,C[ce+21]=1,C[ce+22]=1,C[ce+23]=0;for(let e=0;e<16;e+=1)C[ce+24+e]=C[ce+e];i.writeOffset+=Er;const ue=i.template.localBoundsCenter,de=N*ue.x+q*ue.y+X*ue.z+te,he=W*ue.x+K*ue.y+J*ue.z+re,pe=_*ue.x+Z*ue.y+Q*ue.z+ie,fe=Math.sqrt(N*N+W*W+_*_),me=Math.sqrt(q*q+K*K+Z*Z),ge=Math.sqrt(X*X+J*J+Q*Q),ve=i.template.localBoundsRadius*Math.max(fe,me,ge,1e-5),xe=de-ve,we=he-ve,be=pe-ve,ye=de+ve,Se=he+ve,Ce=pe+ve;xe<i.boundsMin.x&&(i.boundsMin.x=xe),we<i.boundsMin.y&&(i.boundsMin.y=we),be<i.boundsMin.z&&(i.boundsMin.z=be),ye>i.boundsMax.x&&(i.boundsMax.x=ye),Se>i.boundsMax.y&&(i.boundsMax.y=Se),Ce>i.boundsMax.z&&(i.boundsMax.z=Ce),xe<b.x&&(b.x=xe),we<b.y&&(b.y=we),be<b.z&&(b.z=be),ye>y.x&&(y.x=ye),Se>y.y&&(y.y=Se),Ce>y.z&&(y.z=Ce)}const $=m.cachedDraws;let N=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=$[N];c||(c={template:t.template,instanceStart:0,instanceCount:0,boundsCenter:new wt,boundsRadius:0},$[N]=c),c.template=t.template,c.instanceStart=t.instanceStart,c.instanceCount=t.activeCount,c.boundsCenter.set(r,i,n),c.boundsRadius=l,N+=1}$.length=N,m.cachedMatricesVersion=v,m.cachedColorsVersion=x,m.cachedInstanceInfoLength=d.length,m.cachedGeometryCount=u._geometryCount??0,Ui(g,m.cachedMatrixWorld),m.residentBufferDirty=!0,m.cacheValid=!0;let W=!1;for(let t=0;t<$.length;t+=1){const r=$[t];i(r.boundsCenter.x,r.boundsCenter.y,r.boundsCenter.z,r.boundsRadius,e.frustumCulled)&&(W=!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)))}W&&(this.residentInstanceUploadsScratch.push(m),Fi(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,Or,0,Er)}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,yi(n),0,16*t.count):this.state.device.queue.writeBuffer(i.buffer,0,jr,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,yi(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,yi(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,Or,0,Er),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,e.depthMaterialResources.clear()}}getViewport(e){return e.set(0,0,this.state.width,this.state.height)}getSharedSceneBindGroup(){if(!(this.state.device&&this.state.sceneBindGroupLayout&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.instanceBuffer&&this.state.shadowComparisonSampler&&this.state.directionalShadowView&&this.state.linearClampSampler&&this.state.pointShadowArrayView&&this.state.spotShadowView))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}]})),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=Ni(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=qn){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=qn,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=Gi(i,e.key),i=Gi(i,Mi(e.geometryResource.position)),i=Gi(i,e.geometryResource.index?Mi(e.geometryResource.index):0),i=Gi(i,Mi(t.indirectBuffer)),i=Gi(i,e.indirectStartIndex),i=Gi(i,e.indirectCount),i=Gi(i,this.sampleCount),i=Gi(i,e.material.version),i=Gi(i,this.graphTextureResourceVersion),i=Gi(i,r),i>>>0}getColorFormatsId(e){if(e===qn)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=Gi(i,e.length),i=Gi(i,this.sampleCount),i=Gi(i,Mi(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=Gi(i,Mi(a.material)),i=Gi(i,a.receiveShadow?1:0),i=Gi(i,a.material.version??0),i=Gi(i,Mi(s.pipeline)),i=Gi(i,Mi(s.bindGroup)),i=Gi(i,Mi(o)),i=Gi(i,Mi(a.geometryKey)),i=Gi(i,Mi(a.geometryResource.position)),i=Gi(i,Mi(a.geometryResource.normal)),i=Gi(i,Mi(a.geometryResource.uv)),i=Gi(i,Mi(a.geometryResource.color)),i=Gi(i,a.geometryResource.index?Mi(a.geometryResource.index):0);for(const e of a.geometryResource.extraAttributeBuffers.values())i=Gi(i,Mi(e));i=Gi(i,a.indexed?1:0),i=Gi(i,a.start),i=Gi(i,a.count),i=Gi(i,a.instanceStart),i=Gi(i,a.instanceCount);const l=a.material.getTexturesList();i=Gi(i,l.length);for(let e=0;e<l.length;e+=1){const t=l[e];i=Gi(i,Mi(t)),i=Gi(i,t.version)}}return`forward-direct:${i}:${e.length}:samples=${this.sampleCount}:formats=${r.join("|")}`}getOrCreateDirectForwardBundle(e,t,r,i=qn){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=`${Mi(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}]}:{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}]}),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*kr;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*kr;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*kr*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+=Ni(e)}executeVisibilityPass(e,t){Qi.call(this,e,t)}executeStaticVisibilityPasses(e,t){en.call(this,e,t)}getOrCreateStaticVisibilityBindGroup(e,t){return tn.call(this,e,t)}executeDirectionalShadowPass(e,t,r,i){rn.call(this,e,t,r,i)}executePointShadowPass(e,t,r,i){nn.call(this,e,t,r,i)}executeSpotShadowPass(e,t,r,i){an.call(this,e,t,r,i)}executeDepthPrepass(e,t,r,i){sn.call(this,e,t,r,i)}executeStaticDepthPrepass(e,t,r){on.call(this,e,t,r)}executeStaticTemporalDepthResolvePass(e){cn.call(this,e)}getOrCreateStaticDepthPrepassBundle(e,t){return dn.call(this,e,t)}executeHiZPasses(e,t=!1){fn.call(this,e,t)}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))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}}]}),e.visibleSceneBindGroupVersion=this.state.residentSceneBindGroupVersion),e.visibleSceneBindGroup}getOrCreateStaticVisibleDepthSceneBindGroup(e){if(!this.state.device||!this.state.visibleDepthSceneBindGroupLayout||!this.state.cameraBuffer)throw new Error("Renderer visible depth scene bind group resources are not initialized.");return e.visibleDepthSceneBindGroup&&e.visibleDepthSceneBindGroupVersion===this.state.residentSceneBindGroupVersion||(e.visibleDepthSceneBindGroup=this.state.device.createBindGroup({label:`${e.label}-static-visible-depth-scene-bind-group`,layout:this.state.visibleDepthSceneBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:2,resource:{buffer:e.instanceBuffer}},{binding:3,resource:{buffer:e.instanceVisibilityResource.visibleInstanceIndicesBuffer}}]}),e.visibleDepthSceneBindGroupVersion=this.state.residentSceneBindGroupVersion),e.visibleDepthSceneBindGroup}executeMaterialPass(e,t,r,i,n,a={}){if(!this.state.mainDepthView||0===t.length)return;const s=t.map(e=>this.getColorTargetFormat(e)),o=this.getColorFormatsId(s),l=t.map(e=>this.getColorTargetView(e)),c=this.sampleCount>1,u=c?t.map(e=>this.ensureMsaaColorTarget(e)):[],d=this.getColorTargetDimensions(t[0]),h=c?this.ensureMsaaDepthTarget(d.width,d.height):null,p=e.beginRenderPass({label:"renderer-material-pass",colorAttachments:t.map((e,t)=>({view:u[t]?.view??l[t],resolveTarget:u[t]?l[t]:void 0,clearValue:1===t?{r:.5,g:.5,b:1,a:1}:t>=2?{r:0,g:0,b:0,a:1}:{r:this.clearColor[0],g:this.clearColor[1],b:this.clearColor[2],a:this.clearColor[3]},loadOp:a.loadColor?"load":"clear",storeOp:u[t]?"discard":"store"})),depthStencilAttachment:{view:h?.view??this.state.mainDepthView,depthClearValue:1,depthLoadOp:h?"clear":a.loadDepth?"load":"clear",depthStoreOp:h?"discard":"store"}});let f=null,m=null,g=null,v=null,x=null;const w=e=>{e.sourceObject&&e.hasRenderCallbacks&&e.sourceObject.onBeforeRender(this,i.scene,i.camera,e.geometry,e.material,e.geometryGroup);const t=e.geometryResource;let a=e.material;const o=this.getMaterialResourceForDraw(e,s),l=this.resolveSceneBindGroupForDraw(e,r);if(f!==o.pipeline&&(f=o.pipeline,g=null,x=null,p.setPipeline(f)),g!==e.geometryKey&&(g=e.geometryKey,this.bindGeometryVertexBuffers(p,e.geometry,t,o.vertexAttributes,e.instanceStart,e.instanceCount,e.wireframe)),v!==l&&(v=l,p.setBindGroup(0,l)),m!==a){if(m=a,p.setBindGroup(1,o.bindGroup),!o.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");p.setBindGroup(3,this.createGraphTextureBindGroup(a,o.graphTextureBindGroupLayout))}o.usesSkinning&&e.skinning&&x!==e.skinning.bindGroup&&(x=e.skinning.bindGroup,p.setBindGroup(2,x)),e.indexed&&(e.wireframe?t.wireframeIndex:t.index)?p.drawIndexed(e.count,e.instanceCount,e.start,0,e.instanceStart):p.draw(e.count,e.instanceCount,e.start,e.instanceStart),this.recordDraw(e,n),e.sourceObject&&e.hasRenderCallbacks&&e.sourceObject.onAfterRender(this,i.scene,i.camera,e.geometry,e.material,e.geometryGroup)},b=a.drawStage??"all";if(a.objectFilter||a.overrideMaterial){const e=e=>{if(a.objectFilter){const t=e.sourceRanges?.filter(e=>a.objectFilter(e.sourceObject));if(null!=t&&t.length>0){const r="function"==typeof a.overrideMaterial?a.overrideMaterial(e.material,null!==e.skinning):a.overrideMaterial;for(const i of t)w({...e,sourceObject:i.sourceObject,instanceStart:i.instanceStart,instanceCount:i.instanceCount,material:r??e.material,sourceRanges:void 0});return}if(!a.objectFilter(e.sourceObject))return}const t="function"==typeof a.overrideMaterial?a.overrideMaterial(e.material,null!==e.skinning):a.overrideMaterial;w(t?{...e,material:t}:e)};if("late"!==b){for(const t of this.staticDrawSets)if(t.publicSet.enabled)for(const r of t.draws)e(r);for(const t of i.gpuOpaqueDraws)e(t);for(const t of i.directOpaqueDraws)e(t)}if("opaque"!==b)for(const t of i.transparentDraws)e(t);return void p.end()}if("late"!==b){for(const e of this.staticDrawSets){if(!e.publicSet.enabled||0===e.draws.length)continue;if(this.getHiZOcclusionCullingActive()&&e.lastVisibilityFrameToken===this.staticFrameToken){const t=this.getOrCreateStaticVisibleSceneBindGroup(e),r=this.getOrCreateStaticIndirectSubmissionStreams(e,t,s);for(const t of r){if(this.getMultiDrawIndirectActive()){if(p.setPipeline(t.materialResource.pipeline),this.bindGeometryVertexBuffers(p,t.geometry,t.geometryResource,t.materialResource.vertexAttributes,0,1,t.material.wireframe),p.setBindGroup(0,t.sceneBindGroup),p.setBindGroup(1,t.materialResource.bindGroup),!t.materialResource.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");p.setBindGroup(3,this.createGraphTextureBindGroup(t.material,t.materialResource.graphTextureBindGroupLayout)),p.multiDrawIndexedIndirect(e.drawMetadataResource.indirectBuffer,5*t.indirectStartIndex*Uint32Array.BYTES_PER_ELEMENT,t.indirectCount)}else this.renderBundleScratch[0]=this.getOrCreateIndirectForwardBundle(t,e.drawMetadataResource,e.indirectForwardBundleCache,`${e.label}-static-indirect-material-bundle`,s,!1,o),p.executeBundles(this.renderBundleScratch);n.drawCallCount+=t.drawCallCount,n.triangleCount+=t.triangleCount}continue}const t=this.getOrCreateStaticMaterialBundle(e,r,n,s);t&&(this.renderBundleScratch[0]=t,p.executeBundles(this.renderBundleScratch))}if(this.getHiZOcclusionCullingActive()&&this.state.drawMetadataResource){const e=this.indirectMaterialResourcesScratch;e.length=i.gpuOpaqueDraws.length;for(let t=0;t<i.gpuOpaqueDraws.length;t+=1)e[t]=this.getMaterialResourceForDraw(i.gpuOpaqueDraws[t],s);const t=this.buildIndirectSubmissionStreams(i.gpuOpaqueDraws,r,void 0,e);for(const e of t){const t=this.getOrCreateIndirectForwardBundle(e,this.state.drawMetadataResource,this.state.indirectForwardBundleCache,"renderer-indirect-material-bundle",s,!0,o);t?(this.renderBundleScratch[0]=t,p.executeBundles(this.renderBundleScratch)):this.submitIndirectStreamDirect(p,e,this.state.drawMetadataResource),n.drawCallCount+=e.drawCallCount,n.triangleCount+=e.triangleCount}}else{const e=Ri(i.gpuOpaqueDraws)||i.gpuOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(i.gpuOpaqueDraws,r,n,s);if(e)this.renderBundleScratch[0]=e,p.executeBundles(this.renderBundleScratch);else for(const e of i.gpuOpaqueDraws)w(e)}const e=Ri(i.directOpaqueDraws)||i.directOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(i.directOpaqueDraws,r,n,s);if(e)this.renderBundleScratch[0]=e,p.executeBundles(this.renderBundleScratch);else for(const e of i.directOpaqueDraws)w(e)}if("opaque"!==b)for(const e of i.transparentDraws)w(e);p.end()}executeForwardPass(e,t,r,i,n,a,s=!1,o="all",l=!1,c=this.sampleCount){mn.call(this,e,t,r,i,n,a,s,o,l,c)}executeStaticForwardPass(e,t,r){gn.call(this,e,t,r)}getOrCreateStaticDirectForwardBundle(e,t){return vn.call(this,e,t)}refreshStaticDrawMaterialResources(e){wn.call(this,e)}syncStaticVisibleMaterialBindingCaches(e){xn.call(this,e)}recordStaticDrawStats(e,t){bn.call(this,e,t)}hasEnabledStaticDrawSets(){return yn.call(this)}executePresentPass(e,t,r){Sn.call(this,e,t,r)}clearDirectionalShadow(e){Cn.call(this,e)}clearPointShadow(e){Pn.call(this,e)}clearSpotShadow(e){Mn.call(this,e)}drawDepthLike(e,t,r,i){Bn.call(this,e,t,r,i)}getGeometryResource(e){if(!this.state.device)throw new Error("Renderer is not initialized.");const t=this.geometryCache.get(e);if(t&&t.lastValidatedExtractionVersion===this.extractionVersion)return t;if(t&&function(e,t){if(t.indexVersion!==(e.index?.version??0)||t.drawRangeStart!==e.drawRange.start||t.drawRangeCount!==e.drawRange.count)return!1;if(t.groups.length!==e.groups.length)return!1;for(let r=0;r<t.groups.length;r+=1){const i=t.groups[r],n=e.groups[r];if(i.start!==n?.start||i.count!==n?.count||i.materialIndex!==(n?.materialIndex??0))return!1}for(let r=0;r<t.attributes.length;r+=1){const i=t.attributes[r],n=e.getAttribute(i.name);if(n?ri(n)!==i.version||n.itemSize!==i.itemSize||n.count!==i.count:0!==i.version||0!==i.itemSize||0!==i.count)return!1}return!0}(e,t))return t.lastValidatedExtractionVersion=this.extractionVersion,t;t&&(this.clearIndirectBundleCache(),this.retireGeometryResource(t));const r=e.getAttribute("position");if(!r)throw new Error("BufferGeometry is missing the required position attribute.");const i=r.count,n=fi(r,i,3,[0,0,0]),a=fi(e.getAttribute("normal"),i,3,[0,0,1]),s=fi(e.getAttribute("uv"),i,2,[0,0]),o=fi(e.getAttribute("color"),i,4,[1,1,1,1]);let l=null,c=null;if(e.index){const t=e.index.array,r=t instanceof Uint32Array?t:new Uint16Array(t);c=t instanceof Uint32Array?"uint32":"uint16",l=ci(this.state.device,r,GPUBufferUsage.INDEX,`${e.uuid}-index`)}const u={signature:ii(e),indexVersion:e.index?.version??0,drawRangeStart:e.drawRange.start,drawRangeCount:e.drawRange.count,vertexCount:i,attributes:["position","normal","uv","color"].map(t=>{const r=e.getAttribute(t);return{name:t,version:ri(r),itemSize:r?.itemSize??0,count:r?.count??0}}),lastValidatedExtractionVersion:this.extractionVersion,groups:e.groups.map(e=>({start:e.start,count:e.count,materialIndex:e.materialIndex??0})),...this.createGeometryBuffers(e.uuid,n,a,s,o,e.index?.array),extraAttributeBuffers:new Map,extraAttributeBufferVersions:new Map,wireframeIndex:null,wireframeIndexFormat:null};return this.geometryCache.set(e,u),u}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=function(e){return[ii(e.geometry),ri(e.geometry.getAttribute("skinIndex")),ri(e.geometry.getAttribute("skinWeight")),e.skeleton.bones.length].join(";")}(e);let a=this.skinnedGeometryCache.get(e);if(!a||a.sourceSignature!==n||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={sourceSignature:n,resource:this.getGeometryResource(e.geometry),skinning:c,boneBounds:this.createSkinningBoneBounds(e,i,t,r),localBoundsMin:new wt,localBoundsMax:new wt,localBoundsCenter:new wt,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)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;e.update();const i=new Float32Array(e.boneMatrices),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,lastRefreshExtractionVersion:-1};return this.skinPaletteCache.set(e,n),this.skinPaletteResources.add(n),n}refreshSkinningPalette(e){if(e.lastRefreshExtractionVersion===this.extractionVersion)return;e.lastRefreshExtractionVersion=this.extractionVersion;const{skeleton:t}=e;t.update(),e.dirty=!0}refreshSkinningBindMatrices(e,t){const r=t.bindMatrices;let i=!1;for(let t=0;t<16;t+=1){const n=e.bindMatrix.elements[t],a=e.bindMatrixInverse.elements[t];r[t]===n&&r[t+16]===a||(i=!0),r[t]=n,r[t+16]=a}t.bindUniformDirty||=i}uploadSkinningResources(e){if(this.state.device){if(e.palette.dirty){const t=e.palette.skeleton.boneMatrices;this.state.device.queue.writeBuffer(e.palette.previousMatrixBuffer,0,e.palette.previousMatrices.buffer,e.palette.previousMatrices.byteOffset,e.palette.previousMatrices.byteLength),this.state.device.queue.writeBuffer(e.palette.matrixBuffer,0,t.buffer,t.byteOffset,16*e.palette.skeleton.bones.length*Float32Array.BYTES_PER_ELEMENT),e.palette.previousMatrices.set(t),e.palette.dirty=!1}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 wt(1/0,1/0,1/0)),a=Array.from({length:e.skeleton.bones.length},()=>new wt(-1/0,-1/0,-1/0));for(let e=0;e<t.count;e+=1){Xr.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(Xr),l.max(Xr))}}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=Oi(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;Kr.fromArray(t.skinning.palette.skeleton.boneMatrices,16*n),Zr.multiplyMatrices(e.bindMatrixInverse,Kr).multiply(e.bindMatrix),Xr.copy(a.center).applyMatrix4(Zr);const s=a.radius*ji(Zr);r.min(Jr.copy(Xr).addScalar(-s)),i.max(Jr.copy(Xr).addScalar(s))}t.localBoundsCenter.copy(r).add(i).multiplyScalar(.5),t.localBoundsRadius=i.distanceTo(t.localBoundsCenter)}createGeometryBuffers(e,t,r,i,n,a,s=GPUBufferUsage.VERTEX,o=GPUBufferUsage.VERTEX){if(!this.state.device)throw new Error("Renderer is not initialized.");let l=null,c=null;if(a){const t=a instanceof Uint32Array?a:new Uint16Array(a);c=a instanceof Uint32Array?"uint32":"uint16",l=ci(this.state.device,t,GPUBufferUsage.INDEX,`${e}-index`)}return{position:ci(this.state.device,t,s,`${e}-position`),normal:ci(this.state.device,r,o,`${e}-normal`),uv:ci(this.state.device,i,GPUBufferUsage.VERTEX,`${e}-uv`),color:ci(this.state.device,n,GPUBufferUsage.VERTEX,`${e}-color`),index:l,indexFormat:c}}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+=ai(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){const r=e.vertexAttributes.slice();if(!t)return r;const i=[{name:"skinIndex",shaderLocation:4,format:"uint32x4"},{name:"skinWeight",shaderLocation:5,format:"float32x4"}];for(const e of i){const t=r.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 i=r.find(t=>t.shaderLocation===e.shaderLocation);if(i)throw new Error(`Skinned material requires location ${e.shaderLocation} for "${e.name}", but it is used by "${i.name}".`);r.push(e)}return r}getGeometryVertexBuffer(e,t,r,i=0,n=1){if(!this.state.device)throw new Error("Renderer is not initialized.");let a=this.standardVertexAttributeCache.get(r);if(void 0===a&&(a="position"===r.name&&"float32x3"===r.format?"position":"normal"!==r.name||"float32x3"!==r.format||void 0!==r.defaultValue&&!hi(r.defaultValue,[0,0,1])?"uv"!==r.name||"float32x2"!==r.format||void 0!==r.defaultValue&&!hi(r.defaultValue,[0,0])?"color"!==r.name||"float32x4"!==r.format||void 0!==r.defaultValue&&!hi(r.defaultValue,[1,1,1,1])?null:"color":"uv":"normal",this.standardVertexAttributeCache.set(r,a)),a)return t[a];const s=e.getAttribute(r.name),o="instance"===r.stepMode,l=o?Math.max(0,Math.trunc(i)):0;if(o&&!s)return this.getDefaultInstanceAttributeBuffer(r,l+Math.max(1,n));const c=ri(s),u=this.geometryVertexBufferFastCache.get(t),d=u?.get(r),h=d?.get(l);if(h&&h.source===s&&h.version===c&&h.itemSize===(s?.itemSize??0)&&h.count===(s?.count??0))return h.buffer;const p=`${this.getGeometryAttributeBufferKey(r)}${o?`:instance-start=${l}`:""}`,f=s?`${c}:${s.itemSize}:${s.count}`:"default",m=t.extraAttributeBuffers.get(p);if(m&&t.extraAttributeBufferVersions.get(p)===f)return this.cacheGeometryVertexBufferFast(t,r,l,s,c,m),m;if(!s&&!r.defaultValue)throw new Error(`Geometry "${e.uuid}" is missing required vertex attribute "${r.name}".`);const g=mi(s,o?l+Math.max(1,s?.count??1,n):t.vertexCount,r.format,r.defaultValue??[],o?l:0);if(m&&m.size>=Math.max(4,g.byteLength))return this.state.device.queue.writeBuffer(m,0,g.buffer,g.byteOffset,g.byteLength),t.extraAttributeBufferVersions.set(p,f),this.cacheGeometryVertexBufferFast(t,r,l,s,c,m),m;const v=ci(this.state.device,g,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e.uuid}-${r.name}-${r.format}`);return m&&(this.clearIndirectBundleCache(),this.retiredGeometryBuffers.push(m)),t.extraAttributeBuffers.set(p,v),t.extraAttributeBufferVersions.set(p,f),this.cacheGeometryVertexBufferFast(t,r,l,s,c,v),v}cacheGeometryVertexBufferFast(e,t,r,i,n,a){let s=this.geometryVertexBufferFastCache.get(e);s||(s=new WeakMap,this.geometryVertexBufferFastCache.set(e,s));let o=s.get(t);o||(o=new Map,s.set(t,o));const l=i;o.set(r,{source:i,version:n,itemSize:l?.itemSize??0,count:l?.count??0,buffer:a})}getInterleavedGeometryVertexBuffer(e,t,r,i,n){if(!this.state.device)throw new Error("Renderer is not initialized.");const a=r[0].stepMode??"vertex",s=Math.max(0,Math.trunc(i)),o="instance"===a?s+Math.max(1,n,...r.map(t=>e.getAttribute(t.name)?.count??1)):t.vertexCount,l=`interleaved:${this.getGeometryAttributeGroupBufferKey(r)}:instance-start=${"instance"===a?s:0}`,c=r.map(t=>{const r=e.getAttribute(t.name);return r?`${ri(r)}:${r.itemSize}:${r.count}`:"default"}).join("|"),u=t.extraAttributeBuffers.get(l);if(u&&t.extraAttributeBufferVersions.get(l)===c)return u;const d=[];let h=0;for(const e of r)d.push(h),h+=ai(e.format);const p=new Uint8Array(o*h);for(let t=0;t<r.length;t+=1){const i=r[t],n=mi(e.getAttribute(i.name),o,i.format,i.defaultValue??[],"instance"===a?s:0),l=new Uint8Array(n.buffer,n.byteOffset,n.byteLength),c=ai(i.format);for(let e=0;e<o;e+=1)p.set(l.subarray(e*c,(e+1)*c),e*h+d[t])}if(u&&u.size>=Math.max(4,p.byteLength))return this.state.device.queue.writeBuffer(u,0,p.buffer,p.byteOffset,p.byteLength),t.extraAttributeBufferVersions.set(l,c),u;const f=ci(this.state.device,p,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e.uuid}-interleaved-${a}`);return u&&(this.clearIndirectBundleCache(),this.retiredGeometryBuffers.push(u)),t.extraAttributeBuffers.set(l,f),t.extraAttributeBufferVersions.set(l,c),f}ensureWireframeIndex(e,t){if(t.wireframeIndex)return;if(!this.state.device)throw new Error("Renderer is not initialized.");const r=e.index?.array,i=r?.length??t.vertexCount,n=Math.floor(i/3),a=t.vertexCount>65535,s=a?new Uint32Array(6*n):new Uint16Array(6*n);for(let e=0;e<n;e+=1){const t=3*e,i=6*e,n=r?r[t]:t,a=r?r[t+1]:t+1,o=r?r[t+2]:t+2;s[i]=n,s[i+1]=a,s[i+2]=a,s[i+3]=o,s[i+4]=o,s[i+5]=n}t.wireframeIndexFormat=a?"uint32":"uint16",t.wireframeIndex=ci(this.state.device,s,GPUBufferUsage.INDEX,`${e.uuid}-wireframe-index`)}bindGeometryVertexBuffers(e,t,r,i,n=0,a=1,s=!1){const o=this.getVertexAttributeGroups(i);for(let i=0;i<o.length;i+=1){const s=o[i];e.setVertexBuffer(i,1===s.length?this.getGeometryVertexBuffer(t,r,s[0],n,a):this.getInterleavedGeometryVertexBuffer(t,r,s,n,a))}s&&r.wireframeIndex&&r.wireframeIndexFormat?e.setIndexBuffer(r.wireframeIndex,r.wireframeIndexFormat):r.index&&r.indexFormat&&e.setIndexBuffer(r.index,r.indexFormat)}getDefaultInstanceAttributeBuffer(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=Math.max(1,t,Math.ceil(this.state.instanceBufferSize/(Float32Array.BYTES_PER_ELEMENT*Er))),i=2**Math.ceil(Math.log2(r)),n=`${e.format}:${(e.defaultValue??[]).join(",")}`;let a=this.defaultInstanceAttributeBuffers.get(n);a||(a=new Map,this.defaultInstanceAttributeBuffers.set(n,a));const s=a.get(i);if(s)return s;const o=ci(this.state.device,mi(void 0,i,e.format,e.defaultValue??[]),GPUBufferUsage.VERTEX,`renderer-default-instance-${e.format}`);return a.set(i,o),o}getMeshExtractionCacheEntry(e,t,r,i,n,a){const s=this.meshExtractionCache.get(e),o=Array.isArray(t)?t:null,l=Array.isArray(t)?null:t;if(s&&s.geometryResource===a&&s.customDepthMaterial===n&&(null!==l&&s.material===l&&s.resolvedMaterial===r||null!==o&&null!==s.materials&&null!==s.resolvedMaterials&&li(s.materials,o)&&di(s.resolvedMaterials,i)))return s;const c=null!==e.geometry.index,u=Oi(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=gi(e.geometry,c,t.start,t.count),u=Bi(s,e.geometry,c,t.start,l,n),h=Mi(s),p=Mi(e.geometry),f=n?Mi(n):0;d.push({geometry:e.geometry,geometryKey:e.geometry,geometryResource:a,material:s,customDepthMaterial:n,residentInstanceBinding:null,sourceObject:e,usesBatching:!1,geometryGroup:t,batchKey:u,batchHash:Di(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=vi(e.geometry,c),i=Bi(t,e.geometry,c,r.start,r.count,n),s=Mi(t),o=Mi(e.geometry),l=n?Mi(n):0;d.push({geometry:e.geometry,geometryKey:e.geometry,geometryResource:a,material:t,customDepthMaterial:n,residentInstanceBinding:null,sourceObject:e,usesBatching:!1,geometryGroup:null,batchKey:i,batchHash:Di(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=vi(e.geometry,n),s=Oi(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=Mi(t),c=Mi(e.geometry),u=r?Mi(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:Bi(t,e,n,a.start,a.count,r),batchHash:Di(l,c,n,a.start,a.count,u),sortMaterialId:l,sortGeometryId:c,sortCustomDepthMaterialId:u,localBoundsCenter:s.center.clone(),localBoundsRadius:s.radius,cachedInstanceData:new Rn(1024),cachedBoundsMin:new wt,cachedBoundsMax:new wt,cachedDrawBoundsCenter:new wt,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=gi(e.geometry,o,a.start,a.count),u=Bi(t,e.geometry,o,a.start,s,r),d=Mi(t),h=Mi(e.geometry),p=r?Mi(r):0,f=e.getBoundingSphereAt(n,Yr),m={geometry:e.geometry,geometryKey:e.geometry,geometryResource:i,material:t,customDepthMaterial:r,residentInstanceBinding:null,sourceObject:e,usesBatching:!0,geometryGroup:null,batchKey:u,batchHash:Di(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 wt,localBoundsRadius:f?.radius??1};l[n]=m,c[n]={template:m,boundsMin:new wt,boundsMax:new wt,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 Rn(1024),cachedDraws:[],cachedBoundsMin:new wt,cachedBoundsMax:new wt,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();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=qe(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=di(e.textures,t.getTexturesList())&&hi(e.textureVersions,t.getTextureVersionsList())&&di(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=[],n=[],a=Array.from(e.getTexturesList()),s=Array.from(e.getTextureVersionsList()),o=e.getStorageBufferBindingList();let l=null;if(Object.keys(e.uniforms).length>0){const r=qe(e.uniforms,e.getUniformLayout());l=this.state.device.createBuffer({label:`${t}-uniforms`,size:r.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.state.device.queue.writeBuffer(l,0,r),i.push({binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}),n.push({binding:0,resource:{buffer:l}})}for(const[e,t]of a.entries()){const a=1+2*e,s=this.getTextureResource(t);i.push({binding:a,visibility:r,sampler:{type:s.samplerBindingType}},{binding:a+1,visibility:r,texture:{sampleType:s.sampleType,viewDimension:s.viewDimension}}),n.push({binding:a,resource:s.sampler},{binding:a+1,resource:s.view})}const c=1+2*a.length,u=Array.from(e.getStorageBufferList());for(const[e,t]of o.entries()){const r=c+e;i.push({binding:r,visibility:ui(t.visibility),buffer:{type:"read-only-storage"}}),n.push({binding:r,resource:{buffer:t.buffer}})}return{bindGroupLayoutEntries:i,bindGroupEntries:n,uniformBuffer:l,textures:a,textureVersions:s,storageBuffers:u}}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: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"mainDepth"===e?this.state.mainDepthView:"sceneColorSnapshot"===e?this.state.sceneColorSnapshotView:"sceneDepthSnapshot"===e?this.state.sceneDepthSnapshotView: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=qn,r=this.sampleCount){const i=new Set,n=new Set,a=[];for(const s of e){const e=this.getDrawInstanceAccessMode(s),o=null!==s.skinning,l=this.drawUsesBatching(s),c=`${s.material.uuid}:${e}:receiveShadow=${s.receiveShadow?1:0}:skinning=${o?1:0}:batching=${l?1:0}`;if(i.has(c)||(a.push(this.getMaterialResourceAsync(s.material,e,s.receiveShadow,t,o,l,r).then(e=>(s.materialResource=e,e))),i.add(c)),s.customDepthMaterial){const t=`${s.customDepthMaterial.uuid}:${e}:skinning=${o?1:0}`;n.has(t)||(a.push(this.getDepthPassMaterialResourceAsyncForDraw(s.customDepthMaterial,"directionalShadow",s)),n.add(t))}if(null!==s.material.depthVertexShader||l){const t=null!==s.material.depthVertexShader?["prepass","directionalShadow","pointShadow"]:["prepass","directionalShadow"];for(const r of t){const t=`${s.material.uuid}:${r}:${e}:skinning=${o?1:0}:batching=${l?1:0}`;n.has(t)||(a.push(this.getDepthPassMaterialResourceAsyncForDraw(s.material,r,s)),n.add(t))}}}await Promise.all(a)}async compileStaticDrawMaterialsAsync(e,t=this.sampleCount){const r=[],i=new Set;for(const n of this.staticDrawSets)if(n.publicSet.enabled){r.push(this.compileDrawMaterialsAsync(n.draws,e,t));for(const a of n.visibleMaterialBindings){const n=`${a.material.uuid}:receiveShadow=${a.receiveShadow?1:0}:batching=${a.usesBatching?1:0}`;i.has(n)||(i.add(n),r.push(this.getMaterialResourceAsync(a.material,"packed-visible",a.receiveShadow,e,!1,a.usesBatching,t)))}}await Promise.all(r)}getDepthPassMaterialKey(e,t,r,i,n){if(!this.state.device)throw new Error("Renderer is not initialized.");return`${e.customProgramCacheKey()}:${t}:instance=${r}:skinning=${i?1:0}:batching=${n?1:0}:textures=${e.getTextureLayoutKey(this.state.device)}`}getForwardMaterialKey(e,t,r,i,n,a,s=this.sampleCount){return`${e.customProgramCacheKey()}:instance=${t}:receiveShadow=${r?1:0}:skinning=${n?1:0}:batching=${a?1:0}:textures=${e.getTextureLayoutKey(this.state.device)}:samples=${s}:targets=${i.join("|")}`}getInstanceAccessModeIndex(e){return"packed"===e?0:"packed-visible"===e?1:2}getForwardMaterialFastCacheIndex(e,t,r,i){return this.getInstanceAccessModeIndex(e)|(t?4:0)|(r?8:0)|(i?16:0)}getDepthMaterialFastCacheIndex(e,t,r,i){return("prepass"===e?0:"directionalShadow"===e?1:2)+3*this.getInstanceAccessModeIndex(t)+(r?9:0)+(i?18: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=Ct(`${t}\n${r}`,this.createMaterialPreprocessorDefines(e,i,n,a),{sourceName:i});return i.includes("vertex")?function(e){return e.replace(/@builtin\s*\(\s*position\s*\)(?!\s*@invariant)\s+(?=[A-Za-z_]\w*\s*:)/g,"@builtin(position) @invariant ").replace(/@builtin\s*\(\s*position\s*\)(?!\s*@invariant)\s+(?=vec4(?:\s*<\s*f32\s*>|f)\b)/g,"@builtin(position) @invariant ")}(s):s}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:4,NUM_SPOT_LIGHTS:4,NUM_DIR_LIGHT_SHADOWS:4,NUM_POINT_LIGHT_SHADOWS:4,NUM_SPOT_LIGHT_SHADOWS:4,NUM_CLIPPING_PLANES:0,UNION_CLIPPING_PLANES:0,USE_SKINNING:r,RENDERER_MOTION_VECTORS:!t.includes("shared-depth"),...this.createTexturePreprocessorDefines(e)};return e.side===lt?n.DOUBLE_SIDED=!0:e.side===nt&&(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.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=qn,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);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))}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))}}getDepthPassMaterialResourceForDraw(e,t,r){return this.getDepthPassMaterialResource(e,t,this.getDrawInstanceAccessMode(r),null!==r.skinning,this.drawUsesBatching(r))}getDepthPassMaterialResourceAsyncForDraw(e,t,r){return this.getDepthPassMaterialResourceAsync(e,t,this.getDrawInstanceAccessMode(r),null!==r.skinning,this.drawUsesBatching(r))}getOrCreateSharedDepthPipeline(e,t,r,i,n,a,s){if(!(this.state.device&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&this.state.skinningBindGroupLayout))throw new Error("Renderer is not initialized.");const o=this.sharedDepthPipelineCache.get(e);if(o)return o;const l=this.state.device.createBindGroupLayout({label:`${e}-shared-depth-material-layout`,entries:n}),c="prepass"===r?"instanced-direct"===i?this.state.directSceneBindGroupLayout:this.state.sceneBindGroupLayout:"instanced-direct"===i?this.state.directShadowBindGroupLayout:this.state.shadowBindGroupLayout,u=this.state.device.createPipelineLayout({label:`${e}-shared-depth-pipeline-layout`,bindGroupLayouts:[c,l,...a?[this.state.skinningBindGroupLayout]:[]]}),d=vr(t,"prepass"===r?"camera":"shadow",this.state.device,i,a),h=this.buildMaterialShaderCode(t,d,"pointShadow"===r?t.pointShadowVertexShader??t.vertexShader:t.depthVertexShader??t.vertexShader,`${e}-shared-depth-vertex`,a,s),p="pointShadow"===r?t.pointShadowFragmentShader:t.depthFragmentShader,f=p?this.buildMaterialShaderCode(t,d,p,`${e}-shared-depth-fragment`,a,s):null,m={bindGroupLayout:l,pipeline:this.state.device.createRenderPipeline({label:`${e}-shared-depth-pipeline`,layout:u,vertex:{module:this.state.device.createShaderModule({label:`${e}-shared-depth-vertex`,code:h}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,a))},...f?{fragment:{module:this.state.device.createShaderModule({label:`${e}-shared-depth-fragment`,code:f}),entryPoint:"fsMain",targets:"pointShadow"===r?[{format:"rgba16float"}]:[]}}:{},primitive:{topology:Zn(t),cullMode:Yn(t,r,s),frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",..."directionalShadow"===r?{depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}:{}}})};return this.sharedDepthPipelineCache.set(e,m),m}async getOrCreateSharedDepthPipelineAsync(e,t,r,i,n,a,s){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 o=this.sharedDepthPipelineCache.get(e);if(o)return o;const l=this.sharedDepthPipelinePromiseCache.get(e);if(l)return l;const c=(async()=>{const o=this.state.device.createBindGroupLayout({label:`${e}-shared-depth-material-layout`,entries:n}),l="prepass"===r?"instanced-direct"===i?this.state.directSceneBindGroupLayout:this.state.sceneBindGroupLayout:"instanced-direct"===i?this.state.directShadowBindGroupLayout:this.state.shadowBindGroupLayout,c=this.state.device.createPipelineLayout({label:`${e}-shared-depth-pipeline-layout`,bindGroupLayouts:[l,o,...a?[this.state.skinningBindGroupLayout]:[]]}),u=vr(t,"prepass"===r?"camera":"shadow",this.state.device,i,a),d=this.buildMaterialShaderCode(t,u,"pointShadow"===r?t.pointShadowVertexShader??t.vertexShader:t.depthVertexShader??t.vertexShader,`${e}-shared-depth-vertex`,a,s),h="pointShadow"===r?t.pointShadowFragmentShader:t.depthFragmentShader,p=h?this.buildMaterialShaderCode(t,u,h,`${e}-shared-depth-fragment`,a,s):null,f={bindGroupLayout:o,pipeline:await this.state.device.createRenderPipelineAsync({label:`${e}-shared-depth-pipeline`,layout:c,vertex:{module:this.state.device.createShaderModule({label:`${e}-shared-depth-vertex`,code:d}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,a))},...p?{fragment:{module:this.state.device.createShaderModule({label:`${e}-shared-depth-fragment`,code:p}),entryPoint:"fsMain",targets:"pointShadow"===r?[{format:"rgba16float"}]:[]}}:{},primitive:{topology:Zn(t),cullMode:Yn(t,r,s),frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",..."directionalShadow"===r?{depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}:{}}})};return this.sharedDepthPipelineCache.set(e,f),this.sharedDepthPipelinePromiseCache.delete(e),f})();return this.sharedDepthPipelinePromiseCache.set(e,c),c}getOrCreateSharedForwardPipeline(e,t,r,i,n,a,s,o,l=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 c=this.sharedForwardPipelineCache.get(e);if(c)return c;const u=this.state.device.createBindGroupLayout({label:`${e}-shared-forward-material-layout`,entries:i}),d=this.createGraphTextureBindGroupLayout(t),h=this.state.device.createPipelineLayout({label:`${e}-shared-forward-pipeline-layout`,bindGroupLayouts:["instanced-direct"===r?this.state.directSceneBindGroupLayout:"packed-visible"===r?this.state.visibleSceneBindGroupLayout:this.state.sceneBindGroupLayout,u,s?this.state.skinningBindGroupLayout:this.state.emptyBindGroupLayout,d]}),p=gr(t,this.state.device,r,n,s),f=this.buildMaterialShaderCode(t,p,t.vertexShader,`${e}-shared-forward-vertex`,s,o),m=this.buildMaterialShaderCode(t,p,t.fragmentShader,`${e}-shared-forward-fragment`,s,o),g={bindGroupLayout:u,graphTextureBindGroupLayout:d,pipeline:this.state.device.createRenderPipeline({label:`${e}-shared-forward-pipeline`,layout:h,vertex:{module:this.state.device.createShaderModule({label:`${e}-shared-forward-vertex`,code:f}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,s))},fragment:{module:this.state.device.createShaderModule({label:`${e}-shared-forward-fragment`,code:m}),entryPoint:"fsMain",targets:Nn(m,a,jn(t))},primitive:{topology:Zn(t),cullMode:Zn(t).startsWith("triangle")&&t.side!==lt?t.side===nt?"front":"back":"none",frontFace:"ccw"},multisample:{count:l},depthStencil:{format:"depth32float",depthWriteEnabled:t.depthWrite,depthCompare:t.depthTest?"less-equal":"always"}})};return this.sharedForwardPipelineCache.set(e,g),g}async getOrCreateSharedForwardPipelineAsync(e,t,r,i,n,a,s,o,l=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 c=this.sharedForwardPipelineCache.get(e);if(c)return c;const u=this.sharedForwardPipelinePromiseCache.get(e);if(u)return u;const d=(async()=>{const c=this.state.device.createBindGroupLayout({label:`${e}-shared-forward-material-layout`,entries:i}),u=this.createGraphTextureBindGroupLayout(t),d=this.state.device.createPipelineLayout({label:`${e}-shared-forward-pipeline-layout`,bindGroupLayouts:["instanced-direct"===r?this.state.directSceneBindGroupLayout:"packed-visible"===r?this.state.visibleSceneBindGroupLayout:this.state.sceneBindGroupLayout,c,s?this.state.skinningBindGroupLayout:this.state.emptyBindGroupLayout,u]}),h=gr(t,this.state.device,r,n,s),p=this.buildMaterialShaderCode(t,h,t.vertexShader,`${e}-shared-forward-vertex`,s,o),f=this.buildMaterialShaderCode(t,h,t.fragmentShader,`${e}-shared-forward-fragment`,s,o),m={bindGroupLayout:c,graphTextureBindGroupLayout:u,pipeline:await this.state.device.createRenderPipelineAsync({label:`${e}-shared-forward-pipeline`,layout:d,vertex:{module:this.state.device.createShaderModule({label:`${e}-shared-forward-vertex`,code:p}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,s))},fragment:{module:this.state.device.createShaderModule({label:`${e}-shared-forward-fragment`,code:f}),entryPoint:"fsMain",targets:Nn(f,a,jn(t))},primitive:{topology:Zn(t),cullMode:Zn(t).startsWith("triangle")&&t.side!==lt?t.side===nt?"front":"back":"none",frontFace:"ccw"},multisample:{count:l},depthStencil:{format:"depth32float",depthWriteEnabled:t.depthWrite,depthCompare:t.depthTest?"less-equal":"always"}})};return this.sharedForwardPipelineCache.set(e,m),this.sharedForwardPipelinePromiseCache.delete(e),m})();return this.sharedForwardPipelinePromiseCache.set(e,d),d}getDepthPassMaterialResource(e,t,r,i,n){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 a=this.getDepthMaterialFastCacheIndex(t,r,i,n),s=this.depthMaterialFrameCache.get(e)?.[a];if(s?.extractionVersion===this.extractionVersion)return s.resource;const o=this.depthMaterialFastCache.get(e)?.[a];if(o&&this.fastMaterialResourceMatches(o,e))return this.updateMaterialUniformBuffer(e,o),this.setDepthMaterialFrameCache(e,a,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),u=l.get(e),d=u?.get(c);if(d&&this.materialResourceMatches(d,e,c))return this.setDepthMaterialFastCache(e,a,d),this.updateMaterialUniformBuffer(e,d),this.setDepthMaterialFrameCache(e,a,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=this.getOrCreateSharedDepthPipeline(c,e,t,r,h,i,n),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,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,a,b),this.setDepthMaterialFrameCache(e,a,b),b}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){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 a=this.getDepthMaterialFastCacheIndex(t,r,i,n),s=this.depthMaterialFastCache.get(e)?.[a];if(s&&this.fastMaterialResourceMatches(s,e))return this.updateMaterialUniformBuffer(e,s),s;const o="prepass"===t?this.depthPrepassMaterialCache:i?this.skinnedDirectionalShadowMaterialCache:"instanced-direct"===r?this.directionalShadowMaterialCacheDirect:this.directionalShadowMaterialCache,l=this.getDepthPassMaterialKey(e,t,r,i,n),c=o.get(e),u=c?.get(l);if(u&&this.materialResourceMatches(u,e,l))return this.setDepthMaterialFastCache(e,a,u),this.updateMaterialUniformBuffer(e,u),u;this.destroyMaterialResource(u),c&&c.delete(l);const{bindGroupLayoutEntries:d,bindGroupEntries:h,uniformBuffer:p,textures:f,textureVersions:m,storageBuffers:g}=this.createMaterialBindGroupData(e,`${e.uuid}-${t}-${r}-material`,GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT),v=await this.getOrCreateSharedDepthPipelineAsync(l,e,t,r,d,i,n),x=this.state.device.createBindGroup({label:`${e.uuid}-${t}-${r}-material-bind-group`,layout:v.bindGroupLayout,entries:h}),w={key:l,materialVersion:e.version,textureVersionHash:e.getTextureVersionHash(),rendererSampleCount:this.sampleCount,instanceAccessMode:r,receiveShadow:!0,useBatching:n,colorTargetFormatsId:0,pipeline:v.pipeline,graphTextureBindGroupLayout:v.graphTextureBindGroupLayout,bindGroup:x,uniformBuffer:p,uniformBufferSize:p?.size??0,uniformValueHash:e.uniformValuesAutoUpdate?e.getUniformValueHash():0,uniformValuesAutoVersion:e.uniformValuesAutoVersion,textures:f,textureVersions:m,storageBuffers:g,vertexAttributes:this.getMaterialVertexAttributes(e,i),usesSkinning:i};let b=o.get(e);return b||(b=new Map,o.set(e,b)),b.set(l,w),this.setDepthMaterialFastCache(e,a,w),w}getMaterialResource(e,t,r=!0,i,n=!1,a=!1,s=this.sampleCount){if(!(this.state.device&&this.state.format&&this.state.sceneBindGroupLayout&&this.state.visibleSceneBindGroupLayout&&this.state.directSceneBindGroupLayout))throw new Error("Renderer is not initialized.");const o=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,l=i??qn,c=void 0===i||1===i.length&&i[0]===$r,u=this.getForwardMaterialFastCacheIndex(t,r,n,a),d=c?null:this.getForwardMaterialTargetFastCacheKey(l,u);if(c){const t=this.forwardMaterialFrameCache.get(e)?.[u];if(t?.extractionVersion===this.extractionVersion&&t.resource.rendererSampleCount===s)return t.resource;const r=this.forwardMaterialFastCache.get(e)?.[u];if(r&&this.fastMaterialResourceMatches(r,e,s))return this.updateMaterialUniformBuffer(e,r),this.setForwardMaterialFrameCache(e,u,r),r}else{const t=this.forwardMaterialTargetFastCache.get(e)?.get(d);if(t&&this.fastMaterialResourceMatches(t,e,s))return this.updateMaterialUniformBuffer(e,t),t}const h=this.getForwardMaterialKey(e,t,r,l,n,a,s),p=o.get(e),f=p?.get(h);if(f&&this.materialResourceMatches(f,e,h,s))return c?(this.setForwardMaterialFastCache(e,u,f),this.setForwardMaterialFrameCache(e,u,f)):this.setForwardMaterialTargetFastCache(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=this.getOrCreateSharedForwardPipeline(h,e,t,m,r,l,n,a,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,colorTargetFormatsId:this.getColorFormatsId(l),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 P=o.get(e);return P||(P=new Map,o.set(e,P)),P.set(h,C),c?(this.setForwardMaterialFastCache(e,u,C),this.setForwardMaterialFrameCache(e,u,C)):this.setForwardMaterialTargetFastCache(e,d,C),C}async getMaterialResourceAsync(e,t,r=!0,i,n=!1,a=!1,s=this.sampleCount){if(!(this.state.device&&this.state.format&&this.state.sceneBindGroupLayout&&this.state.visibleSceneBindGroupLayout&&this.state.directSceneBindGroupLayout))throw new Error("Renderer is not initialized.");const o=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,l=i??qn,c=void 0===i||1===i.length&&i[0]===$r,u=this.getForwardMaterialFastCacheIndex(t,r,n,a);if(c){const t=this.forwardMaterialFrameCache.get(e)?.[u];if(t?.extractionVersion===this.extractionVersion&&t.resource.rendererSampleCount===s)return t.resource;const r=this.forwardMaterialFastCache.get(e)?.[u];if(r&&this.fastMaterialResourceMatches(r,e,s))return this.updateMaterialUniformBuffer(e,r),this.setForwardMaterialFrameCache(e,u,r),r}const d=this.getForwardMaterialKey(e,t,r,l,n,a,s),h=o.get(e),p=h?.get(d);if(p&&this.materialResourceMatches(p,e,d,s))return c&&(this.setForwardMaterialFastCache(e,u,p),this.setForwardMaterialFrameCache(e,u,p)),this.updateMaterialUniformBuffer(e,p),p;this.destroyMaterialResource(p),h&&h.delete(d);const{bindGroupLayoutEntries:f,bindGroupEntries:m,uniformBuffer:g,textures:v,textureVersions:x,storageBuffers:w}=this.createMaterialBindGroupData(e,`${e.uuid}-${t}-material`,GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT),b=await this.getOrCreateSharedForwardPipelineAsync(d,e,t,f,r,l,n,a,s),y=this.state.device.createBindGroup({label:`${e.uuid}-${t}-material-bind-group`,layout:b.bindGroupLayout,entries:m}),S={key:d,materialVersion:e.version,textureVersionHash:e.getTextureVersionHash(),rendererSampleCount:s,instanceAccessMode:t,receiveShadow:r,useBatching:a,colorTargetFormatsId:this.getColorFormatsId(l),pipeline:b.pipeline,graphTextureBindGroupLayout:b.graphTextureBindGroupLayout,bindGroup:y,uniformBuffer:g,uniformBufferSize:g?.size??0,uniformValueHash:e.uniformValuesAutoUpdate?e.getUniformValueHash():0,uniformValuesAutoVersion:e.uniformValuesAutoVersion,textures:v,textureVersions:x,storageBuffers:w,vertexAttributes:this.getMaterialVertexAttributes(e,n),usesSkinning:n};let C=o.get(e);return C||(C=new Map,o.set(e,C)),C.set(d,S),c&&(this.setForwardMaterialFastCache(e,u,S),this.setForwardMaterialFrameCache(e,u,S)),S}updateCameraUniforms(e,t){if(!this.state.device||!this.state.cameraBuffer)return;const r=this.cameraProjectionScratch.copy(e.projectionMatrix);r.elements[8]-=2*this.projectionJitterPixels.x/this.state.width,r.elements[9]-=2*this.projectionJitterPixels.y/this.state.height;const i=this.cameraViewProjScratch.copy(Nr).multiply(r).multiply(e.matrixWorldInverse);e.getWorldPosition(Xr);const n=this.cameraUniformScratch;n.set(i.elements,0),n[16]=Xr.x,n[17]=Xr.y,n[18]=Xr.z,n[19]=1,n[20]=this.state.width,n[21]=this.state.height,n[22]=this.state.pixelRatio,n[23]=this.state.frameTimeSeconds,n.set(e.matrixWorldInverse.elements,24),n.set(Zr.multiplyMatrices(Nr,r).elements,40),n[56]=e.near,n[57]=e.far,n[58]=1/Math.max(e.far-e.near,1e-4),n[59]=0;const a=t.fog;null!=a?(n[60]=a.color.r,n[61]=a.color.g,n[62]=a.color.b,n[63]=1,"density"in a?(n[64]=0,n[65]=0,n[66]=a.density,n[67]=1):(n[64]=a.near,n[65]=a.far,n[66]=0,n[67]=0)):(n.fill(0,60,68),n[67]=-1);const s=this.motionVectorProjectionPending?this.motionVectorProjection:e.projectionMatrix,o=this.motionVectorCurrentViewProj.copy(Nr).multiply(s).multiply(e.matrixWorldInverse);n.set(o.elements,68),n.set((this.motionVectorHistoryValid?this.motionVectorPreviousViewProj:o).elements,84),n[100]=this.motionVectorHistoryValid?1:0,n[101]=this.state.width,n[102]=this.state.height,n[103]=0,this.motionVectorProjectionPending=!1,this.state.device.queue.writeBuffer(this.state.cameraBuffer,0,n,0,104)}updateTemporalVisibilityUniforms(e){if(!this.state.device||!this.state.temporalVisibilityBuffer)return;const t=Ei(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;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=360+4*e;t[i+0]=r.x,t[i+1]=r.y}const r=e.lights.hemisphere;null!=r&&(t[376]=r.skyColor.x,t[377]=r.skyColor.y,t[378]=r.skyColor.z,t[379]=r.intensity,t[380]=r.groundColor.x,t[381]=r.groundColor.y,t[382]=r.groundColor.z,t[383]=r.intensity,t[384]=r.direction.x,t[385]=r.direction.y,t[386]=r.direction.z,t[387]=1);for(let r=0;r<e.lights.directionals.length;r+=1){const i=e.lights.directionals[r],n=this.directionalShadowCameras[r];n.left=i.shadowCameraLeft,n.right=i.shadowCameraRight,n.top=i.shadowCameraTop,n.bottom=i.shadowCameraBottom,n.near=i.shadowCameraNear,n.far=i.shadowCameraFar,n.position.copy(i.position),n.lookAt(i.target),n.updateMatrixWorld(!0),n.updateProjectionMatrix();const 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,t.set(Ei(n,this.shadowViewProjScratch).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=152+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=168+4*r;t[s+0]=i.shadowBias,t[s+1]=i.castShadow?1:0,t[s+2]=this.state.pointShadowTextureSize,t[s+3]=i.shadowNormalBias;const o=184+4*r;t[o+0]=i.shadowRadius,t[o+1]=i.shadowIntensity,t[o+2]=i.shadowCameraNear,t[o+3]=i.shadowCameraFar}for(let r=0;r<e.lights.spots.length;r+=1){const i=e.lights.spots[r],n=this.spotShadowCameras[r];n.near=i.shadowCameraNear,n.far=i.shadowCameraFar,n.fov=i.shadowCameraFov,n.aspect=1,n.position.copy(i.position),Jr.copy(i.position).add(i.direction),n.lookAt(Jr),n.updateMatrixWorld(!0),n.updateProjectionMatrix();const a=200+4*r;t[a+0]=i.position.x,t[a+1]=i.position.y,t[a+2]=i.position.z,t[a+3]=i.range;const s=216+4*r;t[s+0]=i.direction.x,t[s+1]=i.direction.y,t[s+2]=i.direction.z,t[s+3]=Math.cos(i.angle);const o=232+4*r;t[o+0]=i.color.x,t[o+1]=i.color.y,t[o+2]=i.color.z,t[o+3]=i.intensity;const l=248+4*r;t[l+0]=i.shadowBias,t[l+1]=i.castShadow?1:0,t[l+2]=this.state.spotShadowTextureSize,t[l+3]=i.shadowNormalBias;const c=264+4*r;t[c+0]=i.shadowRadius,t[c+1]=i.shadowIntensity;const u=280+4*r;t[u+0]=i.range,t[u+1]=Math.cos(i.angle*(1-i.penumbra)),t[u+2]=i.decay,t.set(Ei(n,this.shadowViewProjScratch).elements,296+16*r)}this.state.device.queue.writeBuffer(this.state.lightBuffer,0,t,0,396)}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]=0,o[62]=0,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)}};import{DataTexture as Qn,Matrix4 as ea,RepeatWrapping as ta}from"three";var ra={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}}},ia=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 Qn(i,5,5);return n.wrapS=ta,n.wrapT=ta,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=ua(e)}get enabled(){return this.options.enabled}get temporalEnabled(){return!1!==this.options.temporal}setOptions(e){Object.assign(this.options,ua({...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(ra[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 na(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 aa(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 sa(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??.6),s=Math.max(1e-4,i.power??1),o=`${t}:${r}:${n}:${a}:${s}`;let l=this.compositePasses.get(o);return l||(l=new oa(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}},na=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 ea;webGpuProjectionInverse=new ea;frameIndex=0;updateUniforms=e=>(this.webGpuProjection.copy(la).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)},aa=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=ca;uniforms=new Float32Array(this.uniformBufferSize/4);inverseProjection=new ea;updateUniforms=e=>(this.inverseProjection.copy(la).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)},sa=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 ea;updateUniforms=e=>(this.webGpuProjectionInverse.copy(la).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)},oa=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"},la=(new ea).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);var ca="\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 ua(e){return{enabled:e.enabled??!0,radius:Math.max(.001,e.radius??.25),resolutionScale:ha(e.resolutionScale??1,.25,1),thickness:Math.max(.001,e.thickness??1),distanceExponent:Math.max(.01,e.distanceExponent??1),distanceFalloff:ha(e.distanceFalloff??1,0,1),directions:pa(e.directions??3,1,8),steps:pa(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:da(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:ha(e.temporal?.historyWeight??.9,0,.98),depthRejection:ha(e.temporal?.depthRejection??.08,.001,1),neighborhoodClamp:e.temporal?.neighborhoodClamp??!0}}}function da(e){return e<=4?4:e<=8?8:e<=12?12:16}function ha(e,t,r){return Math.min(r,Math.max(t,e))}function pa(e,t,r){return Math.floor(ha(e,t,r))}import{Matrix4 as fa}from"three";var ma=class{options;passes=new Map;constructor(e={}){var t,r,i;this.options={resolutionScale:ba(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:ba(e.maxRoughness??.8,.01,1),steps:(t=e.steps??2048,r=8,i=2048,Math.round(ba(t,r,i))),pixelStride:ba(e.pixelStride??1,1,4),normalSpace:e.normalSpace??"world",blur:e.blur??!0,blurRadius:ba(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 ga(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 va(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 xa(t.sceneColor,a,s,this.options.intensity),this.passes.set(o,l)),e.addFullscreenPass(l),s}},ga=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 fa;inverseProjection=new fa;updateUniforms=e=>(this.projection.copy(wa).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)},va=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}"},xa=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 wa=(new fa).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);function ba(e,t,r){return Math.min(r,Math.max(t,e))}import{Matrix4 as ya,Vector2 as Sa}from"three";var Ca=(new ya).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),Pa=class{renderScale;sampleCount;minCurrentWeight;motionWeightScale;depthThreshold;relativeDepthThreshold;targetPrefix;writeIndex=0;historyValid=!1;frameIndex=0;renderWidth=1;renderHeight=1;outputWidth=1;outputHeight=1;jitter=new Sa;unjitteredProjection=new ya;previousJitterUv=new Sa;currentJitterUv=new Sa;previousViewProjection=new ya;resolvePasses=new Map;constructor(e={}){this.renderScale=Da(e.renderScale??1,.25,1),this.sampleCount=Math.max(1,Math.floor(e.sampleCount??32)),this.minCurrentWeight=Da(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(Ba(this.frameIndex%this.sampleCount+1,2)-.5,Ba(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 Ma(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=Da(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(Ca).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}},Ma=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 ya;currentViewProjectionInverse=new ya;updateUniforms=e=>(this.state.updateResolveUniforms(this.uniforms,this.currentViewProjection,this.currentViewProjectionInverse,e),this.uniforms)};function Ba(e,t){let r=1,i=0;for(;e>0;)r/=t,i+=r*(e%t),e=Math.floor(e/t);return i}function Da(e,t,r){return Math.min(r,Math.max(t,e))}var Ta=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=Ra(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 Ia(t,i,this),this.passes.set(n,a)),e.addFullscreenPass(a),i}},Ia=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),Ra(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 Ra(e,t,r){return Math.min(r,Math.max(t,e))}import{ClampToEdgeWrapping as Ga,DataTexture as Va,LinearFilter as za,NoColorSpace as Ua,RGFormat as La,UnsignedByteType as Aa}from"three";var Fa={low:{searchSteps:4,diagonalSteps:0},medium:{searchSteps:8,diagonalSteps:0},high:{searchSteps:16,diagonalSteps:8},ultra:{searchSteps:32,diagonalSteps:16}},Ea=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=Ya(e.cornerRounding??.25,0,1),this.sharpness=Ya(e.sharpness??0,0,1),this.quality=Fa[e.quality??"high"],this.targetPrefix=e.targetPrefix??"smaa",this.areaTexture=function(){const e=new Va(function(){if($a)return $a;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){Na(e,16*n+r,16*a+t,Wa(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){Na(e,80+20*s+r,20*o+t,qa(i,r,t))}}return $a=e,e}(),160,80,La,Aa);return e.name="SMAA-Area-Lookup",e.colorSpace=Ua,e.minFilter=za,e.magFilter=za,e.wrapS=Ga,e.wrapT=Ga,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 ka(t,i,this),this.edgePasses.set(s,o));const l=`${i}:${n}`;let c=this.weightPasses.get(l);c||(c=new Oa(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 ja(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}},ka=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"},Oa=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,Ya(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"},ja=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([Ya(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 $a=null;function Na(e,t,r,i){const n=2*(160*r+t);e[n]=Math.floor(255*Ya(i[0],0,1)),e[n+1]=Math.floor(255*Ya(i[1],0,1))}function Wa(e,t,r){const i=t+r+1,n=.5,a=-.5,s=()=>_a([0,a],[i/2,0],t),o=()=>_a([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 Ha(i,s(),o());case 4:return t<=r?_a([0,n],[i/2,0],t):[0,0];case 6:case 14:case 7:return _a([0,n],[i,a],t);case 8:return t>=r?_a([i/2,0],[i,n],t):[0,0];case 9:case 11:case 13:return _a([0,a],[i,n],t);case 12:return Ha(i,_a([0,n],[i/2,0],t),_a([i/2,0],[i,n],t))}}function _a(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 Ha(e,t,r){const i=e=>[.5*Math.sqrt(2*e[0]),.5*Math.sqrt(2*e[1])],n=Ya(e/32,0,1),a=i(t),s=i(r);return[Za(a[0],t[0],n)+Za(s[0],r[0],n),Za(a[1],t[1],n)+Za(s[1],r[1],n)]}function qa(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 Ka(o(1,1),o(0,0));case 1:return Ka(s([1,0],[i,i]),o(0,0));case 2:return Ka(s([0,0],[1+i,i]),o(0,0));case 3:return o(0,0);case 4:return Ka(s([1,1],[i,i]),s([1,1],[1+i,i]));case 5:return Ka(s([1,1],[i,i]),o(0,0));case 6:return s([1,1],[1+i,i]);case 7:return Ka(s([1,1],[1+i,i]),o(0,0));case 8:return Ka(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 Ka(s([0,0],[1+i,1+i]),o(0,0));case 11:return Ka(s([1,0],[1+i,1+i]),o(0,0));case 12:return s([1,1],[1+i,1+i]);case 13:return Ka(s([1,1],[1+i,1+i]),s([1,0],[1+i,1+i]));case 14:return Ka(s([1,1],[1+i,1+i]),s([1,1],[1+i,i]));case 15:return Ka(s([1,1],[1+i,1+i]),o(0,0));default:return[0,0]}}function Ka(e,t){return[.5*(e[0]+t[0]),.5*(e[1]+t[1])]}function Za(e,t,r){return e+(t-e)*r}function Ya(e,t,r){return Math.min(r,Math.max(t,e))}var Xa=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=ts(e.radius??.2,0,1),this.levels=(t=e.levels??5,r=1,i=5,Math.floor(ts(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 Ja(o,a,this):new Qa(`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 Qa(`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 es(t,s,a,this,this.levels),this.passes.set(o,l)),e.addFullscreenPass(l),a}},Ja=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}"},Qa=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},es=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,ts(this.state.radius,0,1),0,0]),this.uniforms);fragmentShader};function ts(e,t,r){return Math.min(r,Math.max(t,e))}var rs=[1,1,1],is=[0,0,0],ns=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 as(t,r,this.options),this.passes.set(i,n)),e.addFullscreenPass(n),r}},as=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,rs),t(e?.contrast,rs),t(e?.gamma,rs),t(e?.gain,rs),t(e?.offset,is)};return t(this.state.whiteBalance,rs),t(this.state.tint,rs),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 ss}from"three";var os=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 ls(t,r,i,this.options),this.passes.set(n,a)),e.addFullscreenPass(a),i}},ls=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 ss;updateUniforms=e=>(this.inverseProjection.copy(cs).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); }"},cs=(new ss).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);import{Matrix4 as us,Vector2 as ds,Vector3 as hs}from"three";var ps=(new us).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),fs=(e=>(e[e.Disabled=0]="Disabled",e[e.CameraOnly=1]="CameraOnly",e[e.ObjectAndCamera=2]="ObjectAndCamera",e[e.ForceObjectBlur=3]="ForceObjectBlur",e))(fs||{}),ms={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}},gs=class{options;targetPrefix;currentViewProjection=new us;currentInverseViewProjection=new us;currentInverseProjection=new us;previousViewProjection=new us;pendingViewProjection=new us;previousProjection=new us;previousCameraWorld=new us;previousCameraPosition=new hs;currentCameraPosition=new hs;currentJitterUv=new ds;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:xs(e.sampleCount??8),shutterScale:ws(e.shutterScale??.75,0,4),maxBlurPixels:ws(e.maxBlurPixels??18,0,128),cameraBlurScale:ws(e.cameraBlurScale??.1,0,4),objectBlurScale:ws(e.objectBlurScale??1,0,8),depthRejectionStrength:ws(e.depthRejectionStrength??24,0,200),velocityThresholdPixels:ws(e.velocityThresholdPixels??.6,0,16),dilation:e.dilation??!0,debugVelocity:e.debugVelocity??!1,targetFrameRate:ws(e.targetFrameRate??60,15,240),maxFrameTime:ws(e.maxFrameTime??.1,1/240,1),cameraCutDistance:ws(e.cameraCutDistance??8,0,1e3),cameraCutRotationThreshold:ws(e.cameraCutRotationThreshold??.75,0,2),projectionCutThreshold:ws(e.projectionCutThreshold??.25,0,4)},this.targetPrefix=e.targetPrefix??"motionBlur"}applyPreset(e){Object.assign(this.options,ms[e]),this.options.sampleCount=xs(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(ps).multiply(e.projectionMatrix).multiply(e.matrixWorldInverse),this.currentViewProjection.copy(this.pendingViewProjection),this.currentInverseViewProjection.copy(this.currentViewProjection).invert(),this.currentInverseProjection.copy(ps).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=xs(n.sampleCount),o=`${t}:${r}:${i}:${a}:${s}`;let l=this.passes.get(o);return l||(l=new vs(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,xs(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}},vs=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 xs(e){return e<=0?0:e<=4?4:e<=8?8:e<=12?12:16}function ws(e,t,r){return Math.min(r,Math.max(t,e))}var bs=class{enabled;visibleEdgeColor;edgeStrength;edgeThickness;selectedObjects=new Set;selectedInstances=[];targetPrefix;maskMaterial;skinnedMaskMaterial;instanceMaskMaterials=new Map;passes=new Map;constructor(e={}){this.enabled=e.enabled??!0,this.visibleEdgeColor=[...e.visibleEdgeColor??[1,1,1]],this.edgeStrength=Math.max(0,e.edgeStrength??5),this.edgeThickness=Math.max(0,e.edgeThickness??1.5),this.targetPrefix=e.targetPrefix??"outline",this.maskMaterial=ys(!1),this.skinnedMaskMaterial=ys(!0)}setSelectedObjects(e){this.selectedObjects.clear();for(const t of e)this.selectedObjects.add(t)}setSelectedInstances(e){this.selectedInstances.length=0;for(const t of e)Number.isInteger(t.instanceIndex)&&t.instanceIndex>=0&&this.selectedInstances.push(t)}addPass(e,t){if(!this.enabled||0===this.selectedObjects.size&&0===this.selectedInstances.length)return t;const r=e.createColorTarget(`${this.targetPrefix}Mask`,{format:"rgba8unorm"}),i=this.selectedObjects;e.addMaterialPass({name:"OutlineMask",outputs:r,loadDepth:!0,objectFilter:e=>null!==e&&function(e,t){for(let r=e;null!==r;r=r.parent)if(t.has(r))return!0;return!1}(e,i),overrideMaterial:(e,t)=>t?this.skinnedMaskMaterial:this.maskMaterial});for(let t=0;t<this.selectedInstances.length;t+=1){const i=this.selectedInstances[t];let n=this.instanceMaskMaterials.get(i.instanceIndex);n||(n=[ys(!1,i.instanceIndex),ys(!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}Color`,{format:"rgba16float"}),a=`${t}:${r}:${n}`;let s=this.passes.get(a);return s||(s=new Ss(t,r,n,this),this.passes.set(a,s)),e.addFullscreenPass(s),n}dispose(){this.maskMaterial.dispose(),this.skinnedMaskMaterial.dispose();for(const e of this.instanceMaskMaterials.values())e[0].dispose(),e[1].dispose();this.instanceMaskMaterials.clear(),this.passes.clear()}};function ys(e,t=-1){return new Nt({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:!0})}var Ss=class{constructor(e,t,r,i){this.state=i,this.inputs={source:e,mask:t},this.outputs=r}state;name="OutlineComposite";sampler="linear";uniformBufferSize=32;inputs;outputs;uniforms=new Float32Array(8);updateUniforms=()=>(this.uniforms.set([this.state.visibleEdgeColor[0],this.state.visibleEdgeColor[1],this.state.visibleEdgeColor[2],this.state.edgeStrength,this.state.edgeThickness,0,0,0]),this.uniforms);fragmentShader="\n@fragment fn fsMain(input: FullscreenVertexOutput) -> @location(0) vec4<f32> {\n let scene = textureSample(sourceTexture, fullscreenSampler, input.uv);\n let texel = 1.0 / vec2<f32>(textureDimensions(maskTexture));\n let radius = max(fullscreenUniforms[1].x, 0.5);\n let center = textureSample(maskTexture, fullscreenSampler, input.uv).r;\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 around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv + texel * radius).r);\n around = max(around, textureSample(maskTexture, fullscreenSampler, input.uv - texel * radius).r);\n let edge = clamp(around - center, 0.0, 1.0);\n let color = fullscreenUniforms[0].rgb * fullscreenUniforms[0].a;\n return vec4(scene.rgb + color * edge, scene.a);\n}"};import{AmbientLight as Cs,BackSide as Ps,Bone as Ms,BatchedMesh as Bs,BoxGeometry as Ds,BufferAttribute as Ts,BufferGeometry as Is,CanvasTexture as Rs,Color as Gs,CompressedArrayTexture as Vs,CompressedArrayTexture as zs,CompressedCubeTexture as Us,CompressedTexture as Ls,CubeTexture as As,Data3DTexture as Fs,DataArrayTexture as Es,DataTexture as ks,DepthTexture as Os,DirectionalLight as js,DoubleSide as $s,FrontSide as Ns,Group as Ws,HemisphereLight as _s,InstancedMesh as Hs,MathUtils as qs,Matrix4 as Ks,Mesh as Zs,Object3D as Ys,OrthographicCamera as Xs,PerspectiveCamera as Js,PlaneGeometry as Qs,PointLight as eo,RepeatWrapping as to,Scene as ro,Skeleton as io,SkinnedMesh as no,SphereGeometry as ao,SpotLight as so,Texture as oo,Vector2 as lo,Vector3 as co,Vector4 as uo}from"three";export{Cs as AmbientLight,Ps as BackSide,Bs as BatchedMesh,Xa as BloomEffect,Ms as Bone,Ds as BoxGeometry,Ts as BufferAttribute,Is as BufferGeometry,Rs as CanvasTexture,Gs as Color,ns as ColorGradingEffect,Vs as CompressedArrayTexture,Us as CompressedCubeTexture,Ls as CompressedTexture,zs as CompressedTextureArray,e as ComputeKernel,As as CubeTexture,$t as DEFAULT_WGSL_VERTEX_ATTRIBUTES,Fs as Data3DTexture,Es as DataArrayTexture,ks as DataTexture,os as DepthOfFieldEffect,Os as DepthTexture,js as DirectionalLight,$s as DoubleSide,Ta as FXAAEffect,rt as FrameGraphBuilder,Ns as FrontSide,ia as GTAOEffect,ra as GTAO_PRESETS,Ws as Group,_s as HemisphereLight,Hs as InstancedMesh,ms as MOTION_BLUR_PRESETS,qs as MathUtils,Ks as Matrix4,Zs as Mesh,gs as MotionBlurEffect,fs as MotionBlurMode,Ys as Object3D,Xs as OrthographicCamera,bs as OutlineEffect,Js as PerspectiveCamera,Qs as PlaneGeometry,eo as PointLight,Yt as RenderGraph,to as RepeatWrapping,Ea as SMAAEffect,ma as SSREffect,ro as Scene,io as Skeleton,no as SkinnedMesh,ao as SphereGeometry,so as SpotLight,Pa as TemporalAAEffect,oo as Texture,C as VOLUMETRIC_FOG_MATERIAL_WGSL,u as VOLUMETRIC_FOG_PRESETS,lo as Vector2,co as Vector3,uo as Vector4,g as VolumetricFogEffect,c as VolumetricFogVolumeObject,Nt as WGSLShaderMaterial,sr as WebGpuPMREMGenerator,Jn as WebGpuRenderer,P as configureVolumetricFogMaterial};
|
|
1
|
+
var e=class{layout;pipeline;constructor(e,t){this.layout=e.createBindGroupLayout({label:t.label?`${t.label}-layout`:void 0,entries:t.bindGroupLayoutEntries});const r=e.createPipelineLayout({label:t.label?`${t.label}-pipeline-layout`:void 0,bindGroupLayouts:[this.layout]});this.pipeline=e.createComputePipeline({label:t.label,layout:r,compute:{module:e.createShaderModule({label:t.label?`${t.label}-module`:void 0,code:t.code}),entryPoint:t.entryPoint??"main"}})}createBindGroup(e,t,r){return e.createBindGroup({label:r,layout:this.layout,entries:t})}};import{Color as t,DirectionalLight as r,Matrix4 as n,Object3D as i,PointLight as a,Scene as s,SpotLight as o,Vector3 as l}from"three";var c=class extends i{constructor(e){super(),this.volume=e}volume;isFogVolumeObject=!0},u={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:48,integrationSubsteps:1,shadowFilterTaps:1,temporalJitter:!0,temporal:{historyWeight:.94,depthRejection:.04,neighborhoodClamp:!0},blur:{scale:.5,radius:3,depthSigma:.05,spatialSigma:2,depthAwareUpsample:!0}}},d=16,h=(new n).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),p=new l,f=new l,m=new l,g={label:"VolumetricFogFroxelPass"};function v(e,t,r,n,i,a){e[t]=r,e[t+1]=n,e[t+2]=i,e[t+3]=a}var x=class{constructor(e=new s,t={}){this.scene=e,this.options=w(t),this.integratedVolume=`${this.options.targetPrefix}Integrated`,this.columnDepthBounds=`${this.options.targetPrefix}DepthBounds`,this.volumeData=new Float32Array(20*this.options.maxVolumes);const r=this.options.maxDirectionalLights+this.options.maxPointLights+this.options.maxSpotLights;this.lightData=new Float32Array(r*d),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;options;resources=new WeakMap;uniformStorage=new ArrayBuffer(160);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 r&&e.layers.test(t.layers)&&!this.collectedDirectionals.includes(e)?this.collectedDirectionals.push(e):e instanceof a&&e.layers.test(t.layers)?this.collectedPoints.push(e):e instanceof o&&e.layers.test(t.layers)&&this.collectedSpots.push(e)};executeFroxelPass=e=>{this.executeFroxels(e)};projectionInverse=new n;viewProjectionInverse=new n;previousTemporalViewProjection=new n;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=w({...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(u[e])}reset(){this.frameIndex=0,this.temporalWriteIndex=0,this.temporalHistoryValid=!1,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}),e.addPass({name:"VolumetricFogFroxelPass",inputs:{sceneDepth:t.depth},outputs:[this.integratedVolume,this.columnDepthBounds],execute:this.executeFroxelPass});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 b(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 n=this.options.blur;if(!1===n)return r;const i=e.createColorTarget(`${this.options.targetPrefix}Resolved`,{format:"rgba16float",scale:n.scale}),a=e.createColorTarget(`${this.options.targetPrefix}BlurTemporary`,{format:"rgba16float",scale:n.scale}),s=e.createColorTarget(`${this.options.targetPrefix}Blurred`,{format:"rgba16float",scale:n.scale}),o=`resolve:${t.depth}:${i}`;let l=this.blurPassCache.get(o);l||(l=new y(t.depth,this.integratedVolume,this.columnDepthBounds,i,this.options.maxDistance,this.options.fogDitherStrength),this.blurPassCache.set(o,l)),l.setFrameIndex(this.frameIndex),e.addFullscreenPass(l);const c=this.addTemporalPass(e,t,i,n.scale);for(const[r,i,o]of[[c,a,[1,0]],[a,s,[0,1]]]){const a=`blur:${r}:${i}:${o[0]}:${n.radius}:${n.depthSigma}:${n.spatialSigma}`;let s=this.blurPassCache.get(a);s||(s=new C(r,t.depth,i,o,n),this.blurPassCache.set(a,s)),e.addFullscreenPass(s)}const u=`blurComposite:${t.sceneColor}:${t.depth}:${s}:${r}:${n.depthAwareUpsample}`;let d=this.blurPassCache.get(u);return d||(d=new P(t.sceneColor,t.depth,s,this.integratedVolume,this.columnDepthBounds,r,n.depthAwareUpsample),this.blurPassCache.set(u,d)),e.addFullscreenPass(d),r}addTemporalPass(e,t,r,n){const i=this.options.temporal;if(!1===i)return r;const a=e.createColorTarget(`${this.options.targetPrefix}TemporalA`,{format:"rgba16float",scale:n}),s=e.createColorTarget(`${this.options.targetPrefix}TemporalB`,{format:"rgba16float",scale:n}),o=e.createColorTarget(`${this.options.targetPrefix}TemporalDepthA`,{format:"r16float",scale:n}),l=e.createColorTarget(`${this.options.targetPrefix}TemporalDepthB`,{format:"r16float",scale:n}),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 S(r,t.depth,t.velocity,c,d,u,h,i,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,n,i){t.copy(h).multiply(i.camera.projectionMatrix).multiply(i.camera.matrixWorldInverse),r.copy(t).invert();const a=this.consumeTemporalHistoryValid();e.set(r.elements,0),e.set((a?this.previousTemporalViewProjection:t).elements,16),v(e,32,n.historyWeight,n.depthRejection,n.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),n=Math.max(r+.01,Math.min(e.camera.far,this.options.maxDistance)),i=Math.max(1,Math.floor(e.width/this.options.froxelPixelSize)),a=Math.max(1,Math.floor(e.height/this.options.froxelPixelSize));this.viewProjectionInverse.copy(h).multiply(e.camera.projectionMatrix).multiply(e.camera.matrixWorldInverse).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,v(this.uniforms,20,i,a,this.options.depthSlices,n),this.uniformIntegers[24]=this.volumeCount,this.uniformIntegers[25]=this.directionalCount,this.uniformIntegers[26]=this.pointCount,this.uniformIntegers[27]=this.spotCount,v(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(f),v(this.uniforms,32,f.x,f.y,f.z,Math.max(e.camera.far-r,1e-4)),v(this.uniforms,36,this.options.scatteringIntensity,this.options.spatialJitter?1:0,0,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,20*this.volumeCount*4);const s=this.directionalCount+this.pointCount+this.spotCount;s>0&&e.device.queue.writeBuffer(t.lightBuffer,0,this.lightData.buffer,this.lightData.byteOffset,s*d*4);const o=e.getSceneLightingResources(),l=e.getTextureView(this.integratedVolume),c=e.getTextureView(this.columnDepthBounds),u=e.depthView,p=t.bindGroupResources;t.bindGroup&&p&&p.integratedVolumeView===l&&p.lightBuffer===o.lightBuffer&&p.comparisonSampler===e.comparisonSampler&&p.directionalShadowView===o.directionalShadowView&&p.pointShadowView===o.pointShadowView&&p.spotShadowView===o.spotShadowView&&p.depthView===u&&p.columnDepthBoundsView===c||(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:l},{binding:4,resource:{buffer:o.lightBuffer}},{binding:5,resource:e.comparisonSampler},{binding:6,resource:o.directionalShadowView},{binding:7,resource:o.pointShadowView},{binding:8,resource:o.spotShadowView},{binding:9,resource:u},{binding:10,resource:c}]}),t.bindGroupResources={integratedVolumeView:l,lightBuffer:o.lightBuffer,comparisonSampler:e.comparisonSampler,directionalShadowView:o.directionalShadowView,pointShadowView:o.pointShadowView,spotShadowView:o.spotShadowView,depthView:u,columnDepthBoundsView:c});const m=e.encoder.beginComputePass(g);m.setPipeline(t.pipeline),m.setBindGroup(0,t.bindGroup),m.dispatchWorkgroups(Math.ceil(i/8),Math.ceil(a/8)),m.end()}collectSceneData(e){const t=this.collectedVolumes,r=this.collectedDirectionals,n=this.collectedPoints,i=this.collectedSpots;t.length=0,r.length=0,n.length=0,i.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,20*a);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??n,e,this.selectedPointIndices,this.selectedPointScores),u=this.selectClosestLights(l??i,e,this.selectedSpotIndices,this.selectedSpotScores);this.lightData.fill(0,0,(s+c+u)*d);let h=0;for(let e=0;e<s;e++){const t=this.extractedLights?.directionals[e];t?this.writeExtractedDirectional(h++,t):this.writeDirectional(h++,r[e])}for(let e=0;e<c;e++){const t=this.selectedPointIndices[e];o?this.writeExtractedPoint(h++,o[t],t):this.writePoint(h++,n[t])}for(let e=0;e<u;e++){const t=this.selectedSpotIndices[e];l?this.writeExtractedSpot(h++,l[t],t):this.writeSpot(h++,i[t])}this.volumeCount=a,this.directionalCount=s,this.pointCount=c,this.spotCount=u}selectClosestLights(e,t,r,n){const a=r.length;if(0===a)return 0;t.getWorldPosition(f);let s=0;for(let t=0;t<e.length;t+=1){const o=e[t],l=Number(o instanceof i?o.userData?.volumetricIntensity??0:o.volumetricIntensity);if(!Number.isFinite(l)||l<=0)continue;const c=o instanceof i?o.getWorldPosition(p):o.position,u=f.distanceToSquared(c);if(s===a&&u>=n[a-1])continue;let d=Math.min(s,a-1);for(;d>0&&u<n[d-1];)d<a&&(n[d]=n[d-1],r[d]=r[d-1]),d-=1;n[d]=u,r[d]=t,s<a&&(s+=1)}return s}writeVolume(e,t){const r=20*e;t.object.getWorldPosition(p),t.object.getWorldScale(m),v(this.volumeData,r,p.x,p.y,p.z,5*Math.max(m.x,m.y,m.z)),v(this.volumeData,r+4,t.albedo.r,t.albedo.g,t.albedo.b,Math.max(0,t.baseDensity)),v(this.volumeData,r+8,t.heightFalloff,t.heightOffset,t.startDistance??3,-Math.max(-.99,Math.min(.99,t.scatteringDistribution))),v(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*d;t.getWorldPosition(p),t.target.getWorldPosition(f),f.sub(p).normalize(),v(this.lightData,r,f.x,f.y,f.z,0);const n=t.intensity*(t.userData?.volumetricIntensity??1);v(this.lightData,r+4,t.color.r*n,t.color.g*n,t.color.b*n,0)}writeExtractedDirectional(e,t){const r=e*d;v(this.lightData,r,t.direction.x,t.direction.y,t.direction.z,0);const n=t.intensity*t.volumetricIntensity;v(this.lightData,r+4,t.color.x*n,t.color.y*n,t.color.z*n,0)}writePoint(e,t,r=e){const n=e*d;t.getWorldPosition(p),v(this.lightData,n,p.x,p.y,p.z,Math.max(.001,t.distance||this.options.maxDistance));const i=t.intensity*(t.userData?.volumetricIntensity??1);v(this.lightData,n+4,t.color.r*i,t.color.g*i,t.color.b*i,Math.max(0,t.decay)),this.lightData[n+13]=r}writeExtractedPoint(e,t,r){const n=e*d;v(this.lightData,n,t.position.x,t.position.y,t.position.z,Math.max(.001,t.range||this.options.maxDistance));const i=t.intensity*t.volumetricIntensity;v(this.lightData,n+4,t.color.x*i,t.color.y*i,t.color.z*i,Math.max(0,t.decay)),this.lightData[n+13]=r,this.lightData[n+14]=1}writeSpot(e,t,r=e){const n=e*d;t.getWorldPosition(p),t.target.getWorldPosition(f),f.sub(p).normalize(),v(this.lightData,n,p.x,p.y,p.z,Math.max(.001,t.distance||this.options.maxDistance));const i=t.intensity*(t.userData?.volumetricIntensity??1);v(this.lightData,n+4,t.color.r*i,t.color.g*i,t.color.b*i,Math.max(0,t.decay)),v(this.lightData,n+8,f.x,f.y,f.z,Math.cos(t.angle)),this.lightData[n+12]=Math.cos(t.angle*(1-t.penumbra)),this.lightData[n+13]=r}writeExtractedSpot(e,t,r){const n=e*d;v(this.lightData,n,t.position.x,t.position.y,t.position.z,Math.max(.001,t.range||this.options.maxDistance));const i=t.intensity*t.volumetricIntensity;v(this.lightData,n+4,t.color.x*i,t.color.y*i,t.color.z*i,Math.max(0,t.decay)),v(this.lightData,n+8,t.direction.x,t.direction.y,t.direction.z,Math.cos(t.angle)),this.lightData[n+12]=Math.cos(t.angle*(1-t.penumbra)),this.lightData[n+13]=r,this.lightData[n+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(":"),n=t.get(r);if(n)return n;const i=e.createBuffer({size:160,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"}}]}),l=e.createShaderModule({label:"volumetric-fog-compute",code:D.replace("__SHADOW_TAPS__",String(this.options.shadowFilterTaps)).replace("__INTEGRATION_SUBSTEPS__",String(this.options.integrationSubsteps))}),c={uniformBuffer:i,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 w(e){return{enabled:e.enabled??!0,froxelPixelSize:Math.max(2,Math.floor(e.froxelPixelSize??8)),depthSlices:Math.max(8,Math.floor(e.depthSlices??48)),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 t(.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 b=class{constructor(e,t,r,n,i,a,s){this.maxDistance=a,this.ditherStrength=s,this.inputs={sceneColor:e,sceneDepth:t,fogVolume:r,fogBounds:n},this.outputs=i}maxDistance;ditherStrength;name="VolumetricFogCompositePass";sampler="linear";uniformBufferSize=80;inputs;inputDimensions={fogVolume:"3d"};outputs;fragmentShader=T;data=new Float32Array(20);inverseProjection=new n;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(h).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),v(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)},y=class{constructor(e,t,r,n,i,a){this.maxDistance=i,this.ditherStrength=a,this.inputs={sceneDepth:e,fogVolume:t,fogBounds:r},this.outputs=n}maxDistance;ditherStrength;name="VolumetricFogResolvePass";sampler="linear";uniformBufferSize=80;inputDimensions={fogVolume:"3d"};inputs;outputs;fragmentShader=I;data=new Float32Array(20);inverseProjection=new n;frameIndex=0;setFrameIndex(e){this.frameIndex=e}updateUniforms=e=>(this.inverseProjection.copy(h).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),v(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)},S=class{constructor(e,t,r,n,i,a,s,o,l){var c;this.temporal=o,this.state=l,this.inputs=null==r?{currentFog:e,sceneDepth:t,historyFog:n,historyDepth:i}:{currentFog:e,sceneDepth:t,historyFog:n,historyDepth:i,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 n;currentViewProjectionInverse=new n;updateUniforms=e=>(this.state.updateTemporalUniforms(this.uniforms,this.currentViewProjection,this.currentViewProjectionInverse,this.temporal,e),v(this.uniforms,36,e.camera.position.x,e.camera.position.y,e.camera.position.z,e.camera.far),this.uniforms)},C=class{name;sampler="linear";uniformBufferSize=80;inputs;outputs;fragmentShader;data=new Float32Array(20);inverseProjection=new n;constructor(e,t,r,n,i){this.name=n[0]?"VolumetricFogBlurHorizontalPass":"VolumetricFogBlurVerticalPass",this.inputs={fogInput:e,sceneDepth:t},this.outputs=r,this.data.set([n[0],n[1],i.depthSigma,i.spatialSigma],16),this.fragmentShader=`\nconst BLUR_RADIUS:i32=${i.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(h).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements,0),this.data)},P=class{name="VolumetricFogBlurCompositePass";sampler="linear";uniformBufferSize=64;inputs;inputDimensions={fogVolume:"3d"};outputs;fragmentShader;data=new Float32Array(16);inverseProjection=new n;constructor(e,t,r,n,i,a,s){this.inputs=s?{sceneColor:e,sceneDepth:t,fogInput:r,fogVolume:n,fogBounds:i}:{sceneColor:e,fogInput:r},this.outputs=a,this.fragmentShader=s?R:V}updateUniforms=e=>(this.inverseProjection.copy(h).multiply(e.camera.projectionMatrix).invert(),this.data.set(this.inverseProjection.elements),this.data)},M="\nfn rendererSampleIntegratedFog(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 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((distance - bounds.x) / max(bounds.y - bounds.x, 0.001), 0.0, 1.0);\n let fog = rendererSampleIntegratedFog(uv, z);\n return vec4<f32>(fog.rgb + color.rgb * fog.a, color.a);\n}";function B(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 D="\nstruct FogUniforms { inverseViewProjection: mat4x4<f32>, cameraNear: vec4<f32>, dimensionsFar: vec4<f32>, counts: vec4<u32>, ambient: vec4<f32>, cameraForwardDepthRange: vec4<f32>, scattering: 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>;\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 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 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 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 let temporal=select(vec2<f32>(0.5),vec2<f32>(hash12(vec2<f32>(id.xy)+uniforms.ambient.w),hash12(vec2<f32>(id.yx)+uniforms.ambient.w+19.19)),uniforms.ambient.w>0.0);\n let rayJitter=hash12(vec2<f32>(id.xy)+vec2<f32>(uniforms.ambient.w*0.754877,uniforms.ambient.w*0.569841));\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 nearPlane = uniforms.cameraNear.w; let farPlane = uniforms.dimensionsFar.w;\n let depthSize=textureDimensions(sceneDepth);\n let cellMin=id.xy*depthSize/dims.xy;\n let cellEnd=((id.xy+vec2<u32>(1u))*depthSize+dims.xy-vec2<u32>(1u))/dims.xy;\n let cellMax=min(cellEnd-vec2<u32>(1u),depthSize-vec2<u32>(1u));\n let cellCenter=(cellMin+cellMax)/vec2<u32>(2u);var columnFar=max(sceneDistanceAt(cellCenter),max(max(sceneDistanceAt(cellMin),sceneDistanceAt(vec2<u32>(cellMax.x,cellMin.y))),max(sceneDistanceAt(vec2<u32>(cellMin.x,cellMax.y)),sceneDistanceAt(cellMax))));\n columnFar=clamp(columnFar,nearPlane,farPlane);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,columnFar);columnFar=max(columnFar,columnNear+0.001);textureStore(outputDepthBounds,vec2<i32>(id.xy),vec4<f32>(columnNear,columnFar,0.0,0.0));\n var previousDirectionalVisibility=array<f32,4>(1.0,1.0,1.0,1.0);var hasPreviousDirectionalVisibility=false;\n var transmittance = 1.0; var scattering = vec3<f32>(0.0); var previousDistance = columnNear;\n for (var z=0u; z<dims.z; z+=1u) {\n let sliceEnd = mix(columnNear,columnFar,f32(z+1u)/f32(dims.z)); let stepSize = sliceEnd-previousDistance;\n let substepSize=stepSize/f32(INTEGRATION_SUBSTEPS);\n for(var substep=0;substep<INTEGRATION_SUBSTEPS;substep+=1){\n // Share one stratified offset across all intervals on a ray. This turns\n // coherent Z terraces into stationary spatial error that blur can remove.\n let sampleOffset=select(0.5,rayJitter,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 // Directional visibility belongs to the integration interval endpoints.\n // Reusing the preceding endpoint gives trapezoidal shadow integration\n // with one new lookup per interval, instead of quantizing a whole slice\n // from a midpoint visibility sample.\n let shadowDistance=previousDistance+(f32(substep)+1.0)*substepSize;\n let shadowP=camera+ray*shadowDistance;\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));}let current=directionalVisibility(d,shadowP)*cascadeWeight;filteredDirectionalVisibility[d]=select(current,0.5*(previousDirectionalVisibility[d]+current),hasPreviousDirectionalVisibility);previousDirectionalVisibility[d]=current;}\n hasPreviousDirectionalVisibility=true;\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 li=0u;\n for (var d=0u; d<uniforms.counts.y; d+=1u) {\n let l=lights[li]; li+=1u;\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=smoothstep(l.directionCone.w,l.penumbra.x,cd); direct += l.colorDecay.rgb*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 sigma += density; source += lighting*volume.albedoDensity.rgb*density;\n }\n }\n if (sigma > 0.000001) { let extinction=exp(-sigma*substepSize); scattering += transmittance*source*((1.0-extinction)/sigma); transmittance*=extinction; }\n }\n textureStore(outputFog, vec3<i32>(i32(id.x),i32(id.y),i32(z)), vec4<f32>(scattering,transmittance)); previousDistance=sliceEnd;\n }\n}",T="\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 sampleIntegratedFog(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}\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((distance-bounds.x)/max(bounds.y-bounds.x,0.001),0.0,1.0);\n let frame=fullscreenUniforms[4].z; let ditherStrength=fullscreenUniforms[4].w;\n // Half a slice of stochastic Z movement hides integration-layer contours;\n // the RGB term removes display-quantization bands. Both converge under TAA.\n let sliceCount=f32(textureDimensions(fogVolumeTexture).z); let noise=fogDither(input.position.xy,max(frame,0.0));\n let zJitter=select(0.0,noise/max(sliceCount,1.0),frame>=0.0);\n let fog=sampleIntegratedFog(input.uv,z+zJitter);\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}",I="\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 sampleIntegratedFog(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}\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((distance-bounds.x)/max(bounds.y-bounds.x,0.001),0.0,1.0); let frame=fullscreenUniforms[4].z; let noise=fogDither(input.position.xy,max(frame,0.0));\n let slices=f32(textureDimensions(fogVolumeTexture).z); let zJitter=select(0.0,noise/max(slices,1.0),frame>=0.0); var fog=sampleIntegratedFog(input.uv,z+zJitter);\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 R="\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);}\nfn inverseProjection()->mat4x4<f32>{return mat4x4<f32>(fullscreenUniforms[0],fullscreenUniforms[1],fullscreenUniforms[2],fullscreenUniforms[3]);}\nfn viewDistance(uv:vec2<f32>)->f32{let depth=loadDepth(uv);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);}\nfn sampleIntegratedFog(uv:vec2<f32>,normalizedDepth:f32)->vec4<f32>{let slices=f32(textureDimensions(fogVolumeTexture).z);let slicePosition=clamp(normalizedDepth,0.0,1.0)*slices;let textureZ=clamp((slicePosition-0.5)/slices,0.0,1.0);let integrated=textureSampleLevel(fogVolumeTexture,fullscreenSampler,vec3<f32>(uv,textureZ),0.0);return mix(vec4<f32>(0.0,0.0,0.0,1.0),integrated,min(slicePosition,1.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 centerDistance=max(viewDistance(input.uv),0.0001);var bestUv=clamp(candidates[0],vec2<f32>(0.0),vec2<f32>(1.0));var bestDifference=abs(log(max(viewDistance(bestUv),0.0001)/centerDistance));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(log(max(viewDistance(uv),0.0001)/centerDistance));maxDifference=max(maxDifference,difference);if(difference<bestDifference){bestDifference=difference;bestUv=uv;}}\n let blurredUv=select(bestUv,input.uv,maxDifference<0.02);let blurredFog=textureSampleLevel(fogInputTexture,fullscreenSampler,blurredUv,0.0);let bounds=textureSampleLevel(fogBoundsTexture,fullscreenSampler,input.uv,0.0).rg;let z=clamp((centerDistance-bounds.x)/max(bounds.y-bounds.x,0.001),0.0,1.0);let directFog=sampleIntegratedFog(input.uv,z);let fog=select(directFog,blurredFog,bestDifference<0.02);return vec4<f32>(fog.rgb+color.rgb*fog.a,color.a);\n}",V="\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 G,DepthFormat as z,DepthStencilFormat as U,FloatType as L,HalfFloatType as A,IntType as F,RED_GREEN_RGTC2_Format as k,RED_RGTC1_Format as E,RGBA_ASTC_10x10_Format as O,RGBA_ASTC_10x5_Format as j,RGBA_ASTC_10x6_Format as $,RGBA_ASTC_10x8_Format as N,RGBA_ASTC_12x10_Format as W,RGBA_ASTC_12x12_Format as _,RGBA_ASTC_4x4_Format as H,RGBA_ASTC_5x4_Format as q,RGBA_ASTC_5x5_Format as K,RGBA_ASTC_6x5_Format as Z,RGBA_ASTC_6x6_Format as Y,RGBA_ASTC_8x5_Format as X,RGBA_ASTC_8x6_Format as J,RGBA_ASTC_8x8_Format as Q,RGBA_BPTC_Format as ee,RGBA_ETC2_EAC_Format as te,RGBA_S3TC_DXT1_Format as re,RGBA_S3TC_DXT3_Format as ne,RGBA_S3TC_DXT5_Format as ie,RGBAFormat as ae,RGBAIntegerFormat as se,RGFormat as oe,RGIntegerFormat as le,RGB_ETC1_Format as ce,RGB_ETC2_Format as ue,RGB_S3TC_DXT1_Format as de,RGBFormat as he,RedFormat as pe,RedIntegerFormat as fe,ShortType as me,SIGNED_RED_GREEN_RGTC2_Format as ge,SIGNED_RED_RGTC1_Format as ve,SRGBColorSpace as xe,UnsignedByteType as we,UnsignedInt248Type as be,UnsignedInt5999Type as ye,UnsignedIntType as Se,UnsignedShortType as Ce}from"three";function Pe(e,t){const r=Ie(e),n=function(e,t){const r=e.format,n=e.type,i=e.colorSpace===xe;let a=null;if(Re(e))switch(r){case de:case re:a=i?"bc1-rgba-unorm-srgb":"bc1-rgba-unorm";break;case ne:a=i?"bc2-rgba-unorm-srgb":"bc2-rgba-unorm";break;case ie:a=i?"bc3-rgba-unorm-srgb":"bc3-rgba-unorm";break;case E:a="bc4-r-unorm";break;case ve:a="bc4-r-snorm";break;case k:a="bc5-rg-unorm";break;case ge:a="bc5-rg-snorm";break;case ee:a=i?"bc7-rgba-unorm-srgb":"bc7-rgba-unorm";break;case ue:case ce:a=i?"etc2-rgb8unorm-srgb":"etc2-rgb8unorm";break;case te:a=i?"etc2-rgba8unorm-srgb":"etc2-rgba8unorm";break;case H:a=i?"astc-4x4-unorm-srgb":"astc-4x4-unorm";break;case q:a=i?"astc-5x4-unorm-srgb":"astc-5x4-unorm";break;case K:a=i?"astc-5x5-unorm-srgb":"astc-5x5-unorm";break;case Z:a=i?"astc-6x5-unorm-srgb":"astc-6x5-unorm";break;case Y:a=i?"astc-6x6-unorm-srgb":"astc-6x6-unorm";break;case X:a=i?"astc-8x5-unorm-srgb":"astc-8x5-unorm";break;case J:a=i?"astc-8x6-unorm-srgb":"astc-8x6-unorm";break;case Q:a=i?"astc-8x8-unorm-srgb":"astc-8x8-unorm";break;case j:a=i?"astc-10x5-unorm-srgb":"astc-10x5-unorm";break;case $:a=i?"astc-10x6-unorm-srgb":"astc-10x6-unorm";break;case N:a=i?"astc-10x8-unorm-srgb":"astc-10x8-unorm";break;case O:a=i?"astc-10x10-unorm-srgb":"astc-10x10-unorm";break;case W:a=i?"astc-12x10-unorm-srgb":"astc-12x10-unorm";break;case _:a=i?"astc-12x12-unorm-srgb":"astc-12x12-unorm";break;case ae:a=i?"rgba8unorm-srgb":"rgba8unorm"}else switch(r){case ae:switch(n){case G:a="rgba8snorm";break;case me:a="rgba16sint";break;case Ce:a="rgba16uint";break;case Se:a="rgba32uint";break;case F:a="rgba32sint";break;case we:a=i?"rgba8unorm-srgb":"rgba8unorm";break;case A:a="rgba16float";break;case L:a="rgba32float"}break;case he:switch(n){case ye:a="rgb9e5ufloat";break;case 35899:a="rg11b10ufloat"}break;case pe:switch(n){case G:a="r8snorm";break;case me:a="r16sint";break;case Ce:a="r16uint";break;case Se:a="r32uint";break;case F:a="r32sint";break;case we:a="r8unorm";break;case A:a="r16float";break;case L:a="r32float"}break;case oe:switch(n){case G:a="rg8snorm";break;case me:a="rg16sint";break;case Ce:a="rg16uint";break;case Se:a="rg32uint";break;case F:a="rg32sint";break;case we:a="rg8unorm";break;case A:a="rg16float";break;case L:a="rg32float"}break;case z:switch(n){case Ce:a="depth16unorm";break;case Se:a="depth24plus";break;case L:a="depth32float"}break;case U:switch(n){case be:a="depth24plus-stencil8";break;case L:Ve("depth32float-stencil8",t,e,"DepthTexture with DepthStencilFormat + FloatType"),a="depth32float-stencil8"}break;case fe:switch(n){case F:a="r32sint";break;case Se:a="r32uint"}break;case le:switch(n){case F:a="rg32sint";break;case Se:a="rg32uint"}break;case se:switch(n){case F:a="rgba32sint";break;case Se:a="rgba32uint"}}if(!a)throw new Error(`Texture format "${r}" with type "${n}" from "${e.constructor.name}" is not supported by this renderer yet.`);const s=function(e){if(e.startsWith("bc"))return"texture-compression-bc";if(e.startsWith("etc2")||e.startsWith("eac"))return"texture-compression-etc2";if(e.startsWith("astc"))return"texture-compression-astc";return null}(a);s&&Ve(s,t,e,`Texture format "${a}"`);return a}(e,t),i=function(e){const t=Te(e);if("cube"===t)return"cube";if("2d-array"===t)return"2d-array";if("3d"===t)return"3d";return"2d"}(e),a=function(e){return"3d"===Te(e)?"3d":"2d"}(e),s=function(e,t,r){if(!0===e.isDepthTexture)return"depth";if(t.endsWith("uint"))return"uint";if(t.endsWith("sint"))return"sint";if(!0===e.isDataTexture||!0===e.isDataArrayTexture||!0===e.isData3DTexture){if(e.type===F)return"sint";if(e.type===Se)return"uint";if(e.type===L&&!Ge(r,"float32-filterable")&&("r32float"===t||"rg32float"===t||"rgba32float"===t))return"unfilterable-float"}return"float"}(e,n,t),o=function(e,t){const r=e.compareFunction;if("depth"===t&&null!=r)return"comparison";if("float"===t)return"filtering";return"non-filtering"}(e,s),l=function(e){if(!0===e.isCompressedCubeTexture){const t=e.image;return Math.max(1,t?.[0]?.mipmaps?.length??1)}const t=e.mipmaps;return Math.max(1,t?.length??1)}(e);return{format:n,textureDimension:a,viewDimension:i,sampleType:s,samplerBindingType:o,wgslTextureType:De(i,s),wgslSamplerType:"comparison"===o?"sampler_comparison":"sampler",width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers,mipLevelCount:l,compressed:Re(e)}}function Me(e,t){const r=Pe(e,t);return[r.format,r.textureDimension,r.viewDimension,r.sampleType,r.samplerBindingType,r.width,r.height,r.depthOrArrayLayers,r.mipLevelCount].join(":")}function Be(e){const t=Ie(e),r=e.compareFunction;return[Te(e),e.format,e.type,e.colorSpace,r??"none",t.depthOrArrayLayers].join(":")}function De(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 Te(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 Ie(e){if(!0===e.isCubeTexture){const t=e.image,r=t?.[0],n=r?.image??r;return{width:n?.width??1,height:n?.height??1,depthOrArrayLayers:6}}const t=e.image;return{width:t?.width??1,height:t?.height??1,depthOrArrayLayers:t?.depth??1}}function Re(e){return!0===e.isCompressedTexture||!0===e.isCompressedArrayTexture}function Ve(e,t,r,n){if(!Ge(t,e))throw new Error(`${n} for "${r.name||r.uuid}" requires the WebGPU feature "${e}", which is not enabled on this device.`)}function Ge(e,t){return!!e&&(e instanceof Set?e.has(t):"features"in e?e.features.has(t):e.has(t))}import{Color as ze,Matrix3 as Ue,Matrix4 as Le,Vector2 as Ae,Vector3 as Fe,Vector4 as ke}from"three";var Ee=new ArrayBuffer(8),Oe=new Float64Array(Ee),je=new Uint32Array(Ee),$e={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 Ne(e,t){return Math.ceil(e/t)*t}function We(e,t){return"number"==typeof e||"boolean"==typeof e?[Number(e)]:Array.isArray(e)?Array.from(e.slice(0,t)):e instanceof ze?t>=4?[e.r,e.g,e.b,1]:[e.r,e.g,e.b]:e instanceof Ae?[e.x,e.y]:e instanceof Fe?[e.x,e.y,e.z]:e instanceof ke?[e.x,e.y,e.z,e.w]:e instanceof Ue||e instanceof Le?Array.from(e.elements):[]}function _e(e,t,r,n){const i="boolean"==typeof n?n?1:0:Number(n);"i32"!==r?"u32"!==r?e.setFloat32(t,i,!0):e.setUint32(t,i,!0):e.setInt32(t,i,!0)}function He(e,t,r,n){const i=We(r,n);for(let r=0;r<n;r+=1)e[t+r]=i[r]??0}function qe(e,t,r){const n=r instanceof Ue?r.elements:Array.isArray(r)?Array.from(r):We(r,9);for(let r=0;r<3;r+=1){const i=3*r,a=t+4*r;e[a+0]=n[i+0]??0,e[a+1]=n[i+1]??0,e[a+2]=n[i+2]??0,e[a+3]=0}}function Ke(e){let t=0;const r=[];for(const[n,i]of Object.entries(e)){const e=$e[i.type];t=Ne(t,e.alignment),r.push({name:n,offset:t,type:i.type}),t+=e.size}return{byteLength:Ne(t,16),entries:r}}function Ze(e,t){const r=new ArrayBuffer(t.byteLength),n=new DataView(r),i=new Float32Array(r);for(const r of t.entries){const t=e[r.name],a=r.offset/4;switch(r.type){case"f32":case"i32":case"u32":_e(n,r.offset,r.type,t.value);break;case"vec2<f32>":He(i,a,t.value,2);break;case"vec3<f32>":He(i,a,t.value,3);break;case"vec4<f32>":He(i,a,t.value,4);break;case"mat3x3<f32>":qe(i,a,t.value);break;case"mat4x4<f32>":if(t.value instanceof Le)i.set(t.value.elements,a);else{const e=We(t.value,16);i.set(e,a)}}}return r}function Ye(e,t){let r=Math.imul(e^t,16777619);return r^=r>>>13,r>>>0}function Xe(e,t){return Oe[0]=t,e=Ye(e,je[0]??0),e=Ye(e,je[1]??0)}function Je(e,t,r){const n=We(t,r);e=Ye(e,n.length);for(let t=0;t<n.length;t+=1)e=Xe(e,n[t]??0);return e}var Qe="\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",et=new WeakMap,tt=new WeakMap;function rt(e){return e?"string"==typeof e?[e]:Array.from(e):[]}function nt(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}var it=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=rt(e.outputs),n={name:e.name,reads:t,writes:r.length>0?r:void 0,dependsOn:e.dependsOn,execute:e.execute};this.context.addCustomPass(n)}addFullscreenPass(e){const t=rt(e.outputs),r=Object.entries(e.inputs),n=Object.entries(e.textures??{});for(const[t]of n)if(t in e.inputs)throw new Error(`Fullscreen pass "${e.name}" cannot use "${t}" as both an input and an external texture.`);const i=r.map(([,e])=>e===this.mainDepth?"depth":"color");this.addPass({name:e.name,inputs:e.inputs,outputs:t,execute:a=>{const s=t.map(e=>a.getColorFormat(e)),o=n.map(([,e])=>Pe(e,a.device)),l=n.map(([,e])=>Me(e,a.device)).join("|"),c=r.map(([t])=>e.inputDimensions?.[t]??"2d"),u=`${s.join("|")}:${i.map((e,t)=>`${e}-${c[t]}`).join("|")}:${l}:${e.uniformBufferSize??0}`,d=function(e,t){let r=et.get(e);r||(r=new WeakMap,et.set(e,r));let n=r.get(t);return n||(n=new Map,r.set(t,n)),n}(e,a.device);let h=d.get(u);if(!h){const t=[Qe,"@group(0) @binding(0) var fullscreenSampler: sampler;",r.map(([e],t)=>`@group(0) @binding(${t+1}) var ${e}Texture: ${"depth"===i[t]?"texture_depth_2d":"3d"===c[t]?"texture_3d<f32>":"texture_2d<f32>"};`).join("\n"),n.map(([e],t)=>{const n=r.length+1+2*t,i=o[t];return`@group(0) @binding(${n}) var ${e}Sampler: ${i.wgslSamplerType};\n@group(0) @binding(${n+1}) var ${e}Texture: ${i.wgslTextureType};`}).join("\n"),e.uniformBufferSize?`@group(0) @binding(${r.length+1+2*n.length}) var<uniform> fullscreenUniforms: array<vec4<f32>, ${Math.max(1,Math.ceil(e.uniformBufferSize/16))}>;`:"",e.fragmentShader].filter(Boolean).join("\n\n"),l=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"===i[t]?"depth":"float",viewDimension:"3d"===c[t]?"3d":"2d"}})),...o.flatMap((e,t)=>{const n=r.length+1+2*t;return[{binding:n,visibility:GPUShaderStage.FRAGMENT,sampler:{type:e.samplerBindingType}},{binding:n+1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:e.sampleType,viewDimension:e.viewDimension}}]}),...e.uniformBufferSize?[{binding:r.length+1+2*n.length,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]:[]]}),p=a.device.createPipelineLayout({label:`${e.name}-pipeline-layout`,bindGroupLayouts:[l]});h={bindGroupLayout:l,pipeline:a.device.createRenderPipeline({label:`${e.name}-pipeline`,layout:p,vertex:{module:a.device.createShaderModule({label:`${e.name}-vertex-module`,code:t}),entryPoint:"vsMain"},fragment:{module:a.device.createShaderModule({label:`${e.name}-fragment-module`,code:t}),entryPoint:"fsMain",targets:s.map(e=>({format:e}))},primitive:{topology:"triangle-list"}}),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},d.set(u,h)}const{bindGroupLayout:p,pipeline:f,uniformBuffer:m}=h,g=e.updateUniforms?.(a)??null;m&&g&&a.device.queue.writeBuffer(m,0,g.buffer,g.byteOffset,g.byteLength);const v=[{binding:0,resource:"nearest"===e.sampler||"linear"!==e.sampler&&i.includes("depth")?a.nearestClampSampler:a.linearClampSampler},...r.map(([,e],t)=>({binding:t+1,resource:"depth"===i[t]?a.depthView:a.getColorView(e)}))];for(let e=0;e<n.length;e+=1){const t=a.getExternalTexture(n[e][1]),i=r.length+1+2*e;v.push({binding:i,resource:t.sampler},{binding:i+1,resource:t.view})}m&&v.push({binding:r.length+1+2*n.length,resource:{buffer:m}});const x=a.device.createBindGroup({label:`${e.name}-bind-group`,layout:p,entries:v}),w=a.encoder.beginRenderPass({label:e.name,colorAttachments:t.map(e=>({view:a.getColorView(e),clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}))});w.setPipeline(f),w.setBindGroup(0,x),w.draw(3),w.end()}})}addNodeFullscreenPass(e){const t=rt(e.outputs),r=Object.entries(function(e){const t={};for(const[r,n]of Object.entries(e.sceneTextures??{}))t[r]="sceneDepth"===n?{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??{}),i=Object.fromEntries(r.map(([e,t])=>[e,t.resource])),a=Ke(e.shader.uniforms);this.addPass({name:e.name,inputs:i,outputs:t,execute:i=>{const s=t.map(e=>i.getColorFormat(e)),o=r.map(([e,t])=>`${e}:${t.dimension}:${t.sampleType}:${t.sampler??"filtering"}`).join("|"),l=n.map(([,e])=>Pe(e,i.device)),c=n.map(([,e])=>Me(e,i.device)).join("|"),u=a.entries.map(e=>`${e.name}:${e.type}:${e.offset}`).join("|"),d=`${s.join("|")}:${o}:${c}:${u}`,h=function(e,t){let r=tt.get(e);r||(r=new WeakMap,tt.set(e,r));let n=r.get(t);return n||(n=new Map,r.set(t,n)),n}(e.shader,i.device);let p=h.get(d);if(!p){const t=[];for(const[,e]of r){const r=t.length;t.push({binding:r,visibility:GPUShaderStage.FRAGMENT,sampler:{type:e.sampler??("depth-2d"===e.dimension?"non-filtering":"filtering")}},{binding:r+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 l.entries()){const e=t.length;t.push({binding:e,visibility:GPUShaderStage.FRAGMENT,sampler:{type:r.samplerBindingType}},{binding:e+1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:r.sampleType,viewDimension:r.viewDimension}})}const o=2*(r.length+n.length);a.byteLength>0&&t.push({binding:o,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}});const c=i.device.createBindGroupLayout({label:`${e.name}-node-layout`,entries:t}),u=i.device.createPipelineLayout({label:`${e.name}-node-pipeline-layout`,bindGroupLayouts:[c]}),f=r.map(([e,t],r)=>{const n=nt(e);return`@group(0) @binding(${2*r}) var ${n}Sampler: ${"comparison"===t.sampler?"sampler_comparison":"sampler"};\n@group(0) @binding(${2*r+1}) var ${n}Texture: ${"depth-2d"===t.dimension?"texture_depth_2d":"3d"===t.dimension?"texture_3d<f32>":"texture_2d<f32>"};`}).join("\n"),m=n.map(([e],t)=>{const n=2*(r.length+t),i=l[t],a=nt(e);return`@group(0) @binding(${n}) var ${a}Sampler: ${i.wgslSamplerType};\n@group(0) @binding(${n+1}) var ${a}Texture: ${i.wgslTextureType};`}).join("\n"),g=a.entries.map(e=>` ${nt(e.name)}: ${e.type},`).join("\n"),v=a.byteLength>0?`struct MaterialUniforms {\n${g}\n};\n@group(0) @binding(${o}) var<uniform> materialUniforms: MaterialUniforms;`:"",x=[Qe,f,m,v,e.shader.fragmentShader].filter(Boolean).join("\n\n");p={bindGroupLayout:c,pipeline:i.device.createRenderPipeline({label:`${e.name}-node-pipeline`,layout:u,vertex:{module:i.device.createShaderModule({label:`${e.name}-node-vertex-module`,code:x}),entryPoint:"vsMain"},fragment:{module:i.device.createShaderModule({label:`${e.name}-node-fragment-module`,code:x}),entryPoint:"fsMain",targets:s.map(e=>({format:e}))},primitive:{topology:"triangle-list"}}),uniformBuffer:a.byteLength>0?i.device.createBuffer({label:`${e.name}-node-uniforms`,size:a.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}):null},h.set(d,p)}const{pipeline:f,bindGroupLayout:m,uniformBuffer:g}=p;e.shader.syncLiveUniforms(e.shader.uniforms),g&&i.device.queue.writeBuffer(g,0,Ze(e.shader.uniforms,a));const v=[];for(const[,e]of r){const t=v.length,r="comparison"===e.sampler?i.comparisonSampler:"non-filtering"===e.sampler||"depth-2d"===e.dimension?i.nearestClampSampler:i.linearClampSampler;v.push({binding:t,resource:r},{binding:t+1,resource:i.getTextureView(e.resource)})}for(const[,e]of n){const t=v.length,r=i.getExternalTexture(e);v.push({binding:t,resource:r.sampler},{binding:t+1,resource:r.view})}g&&v.push({binding:2*(r.length+n.length),resource:{buffer:g}});const x=i.device.createBindGroup({label:`${e.name}-node-bind-group`,layout:m,entries:v}),w=i.encoder.beginRenderPass({label:e.name,colorAttachments:t.map(e=>({view:i.getColorView(e),clearValue:{r:0,g:0,b:0,a:1},loadOp:"clear",storeOp:"store"}))});w.setPipeline(f),w.setBindGroup(0,x),w.draw(3),w.end()}})}present(e=this.sceneColor){this.context.addPresentPass(e)}};import{AdditiveBlending as at,BackSide as st,BufferAttribute as ot,BufferGeometry as lt,Color as ct,DoubleSide as ut,FrontSide as dt,InstancedBufferAttribute as ht,MultiplyBlending as pt,Matrix4 as ft,Mesh as mt,OrthographicCamera as gt,PerspectiveCamera as vt,Sphere as xt,SubtractiveBlending as wt,Vector2 as bt,Vector3 as yt,Vector4 as St,ShaderMaterial as Ct}from"three";var Pt=/^[A-Za-z_][A-Za-z0-9_]*$/;function Mt(e,t={},r={}){const n=function(e){const t=new Map;for(const[r,n]of Object.entries(e))Pt.test(r)&&!1!==n&&null!=n&&t.set(r,{name:r,parameters:null,body:Bt(n)});return t}(t),i=[],a=[],s=e.split(/\r?\n/),o=r.sourceName??"shader";for(let e=0;e<s.length;e+=1){const t=s[e],r=Dt(t),l=It(i);if(!r){a.push(l?Vt(t,n):"");continue}const{name:c,rest:u}=r;switch(c){case"define":l&&Tt(u,n,o,e+1),a.push("");break;case"undef":l&&n.delete(u.trim()),a.push("");break;case"ifdef":{const e=l,t=e&&n.has(u.trim());i.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),a.push("");break}case"ifndef":{const e=l,t=e&&!n.has(u.trim());i.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),a.push("");break}case"if":{const e=l,t=e&&Et(u,n);i.push({parentActive:e,active:t,branchTaken:t,elseSeen:!1}),a.push("");break}case"elif":{const t=Rt(i,o,e+1,c);if(t.elseSeen)throw new Error(`${o}:${e+1}: #elif after #else`);const r=t.parentActive&&!t.branchTaken&&Et(u,n);t.active=r,t.branchTaken=t.branchTaken||r,a.push("");break}case"else":{const t=Rt(i,o,e+1,c);if(t.elseSeen)throw new Error(`${o}:${e+1}: duplicate #else`);t.active=t.parentActive&&!t.branchTaken,t.branchTaken=!0,t.elseSeen=!0,a.push("");break}case"endif":Rt(i,o,e+1,c),i.pop(),a.push("");break;case"error":if(l)throw new Error(`${o}:${e+1}: ${u.trim()||"#error"}`);a.push("");break;case"warning":case"line":case"version":case"pragma":a.push("");break;default:if(l)throw new Error(`${o}:${e+1}: unsupported preprocessor directive #${c}`);a.push("")}}if(i.length>0)throw new Error(`${o}: unterminated preprocessor conditional`);return a.join("\n")}function Bt(e){return"boolean"==typeof e?e?"1":"0":String(e)}function Dt(e){const t=/^\s*#\s*([A-Za-z_][A-Za-z0-9_]*)(.*)$/.exec(e);return t?{name:t[1],rest:t[2]??""}:null}function Tt(e,t,r,n){const i=/^\s*([A-Za-z_][A-Za-z0-9_]*)(.*)$/.exec(e);if(!i)throw new Error(`${r}:${n}: invalid #define`);const a=i[1],s=i[2]??"";if(s.startsWith("(")){const e=kt(s,0);if(e<0)throw new Error(`${r}:${n}: invalid function-like #define ${a}`);const i=s.slice(1,e).trim(),o=0===i.length?[]:i.split(",").map(e=>e.trim());for(const e of o)if(!Pt.test(e))throw new Error(`${r}:${n}: invalid macro parameter "${e}"`);return void t.set(a,{name:a,parameters:o,body:jt(s.slice(e+1)).trim()||"1"})}t.set(a,{name:a,parameters:null,body:jt(s).trim()||"1"})}function It(e){for(const t of e)if(!t.active)return!1;return!0}function Rt(e,t,r,n){const i=e[e.length-1];if(!i)throw new Error(`${t}:${r}: #${n} without matching #if`);return i}function Vt(e,t){let r=e;for(let e=0;e<8;e+=1){const e=r;if(r=zt(r,t),r=Gt(r,t),r===e)return r}return r}function Gt(e,t){return e.replace(/\b[A-Za-z_][A-Za-z0-9_]*\b/g,e=>{const r=t.get(e);return r&&null===r.parameters?r.body:e})}function zt(e,t){let r=e;for(const e of t.values())null!==e.parameters&&(r=Ut(r,e));return r}function Ut(e,t){let r="",n=0;for(;n<e.length;){const i=Lt(e,t.name,n);if(i<0){r+=e.slice(n);break}let a=i+t.name.length;for(;/\s/.test(e[a]??"");)a+=1;if("("!==e[a]){r+=e.slice(n,i+t.name.length),n=i+t.name.length;continue}const s=kt(e,a);if(s<0){r+=e.slice(n);break}const o=Ft(e.slice(a+1,s));r+=e.slice(n,i),r+=At(t,o),n=s+1}return r}function Lt(e,t,r){let n=e.indexOf(t,r);for(;n>=0;){const r=n>0?e[n-1]:"",i=e[n+t.length]??"";if(!/[A-Za-z0-9_]/.test(r)&&!/[A-Za-z0-9_]/.test(i))return n;n=e.indexOf(t,n+t.length)}return-1}function At(e,t){let r=e.body;const n=e.parameters??[];for(let e=0;e<n.length;e+=1){const i=n[e],a=t[e]?.trim()??"";r=r.replace(new RegExp(`\\b${$t(i)}\\b`,"g"),a)}return r}function Ft(e){const t=[];let r=0,n=0;for(let i=0;i<e.length;i+=1){const a=e[i];"("===a?r+=1:")"===a?r-=1:","===a&&0===r&&(t.push(e.slice(n,i)),n=i+1)}return(e.length>0||n>0)&&t.push(e.slice(n)),t}function kt(e,t){let r=0;for(let n=t;n<e.length;n+=1){const t=e[n];if("("===t)r+=1;else if(")"===t&&(r-=1,0===r))return n}return-1}function Et(e,t){const r=function(e){const t=[];let r=0;for(;r<e.length;){const n=e[r];if(/\s/.test(n)){r+=1;continue}const i=e.slice(r,r+2);if(["&&","||","==","!=","<=",">="].includes(i)){t.push({type:"operator",value:i}),r+=2;continue}if("!<>+-*/%".includes(n)){t.push({type:"operator",value:n}),r+=1;continue}if("("===n||")"===n){t.push({type:"paren",value:n}),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}(jt(e));return 0!==new Ot(r,t).parseExpression()}var Ot=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 jt(e){const t=e.indexOf("//");return t>=0?e.slice(0,t):e}function $t(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}import{Material as Nt}from"three";var Wt=[{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]}],_t=class e extends Nt{isWGSLShaderMaterial=!0;vertexShader;fragmentShader;depthVertexShader;depthFragmentShader;pointShadowVertexShader;pointShadowFragmentShader;defines;uniforms;textures;sceneTextures;graphTextures;storageBuffers;vertexAttributes;primitiveTopology;wireframe;uniformLayoutCache=null;programCacheKeyCache=null;textureListCache=null;textureVersionsCache=[];textureVersionHashCache=0;storageBufferBindingListCache=null;storageBufferListCache=null;textureLayoutKeyDeviceCache=null;textureLayoutKeyCache=null;uniformValuesAutoUpdate=!0;uniformValuesAutoVersion=0;set uniformValuesNeedsUpdate(e){e&&this.uniformValuesAutoVersion++}constructor(e){super();const{vertexShader:t,fragmentShader:r,depthVertexShader:n,depthFragmentShader:i,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={},n={...t};for(const[t,i]of Object.entries(e)){const e=Zt(t,i);"texture"!==e.kind?r[t]=e.uniform:n[t]=e.texture}return{uniforms:r,textures:n}}(l??{},c??{});this.type="WGSLShaderMaterial",this.vertexShader=t,this.fragmentShader=r,this.depthVertexShader=n??null,this.depthFragmentShader=i??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=qt(p??Wt),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=Ke(this.uniforms)),this.uniformLayoutCache}setUniform(e,t){const r=Zt(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=qt(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:Kt(t.value)}])),this.textures={...e.textures},this.sceneTextures={...e.sceneTextures},this.graphTextures={...e.graphTextures},this.storageBuffers={...e.storageBuffers},this.vertexAttributes=qt(e.vertexAttributes),this.primitiveTopology=e.primitiveTopology,this.wireframe=e.wireframe,this.uniformValuesAutoUpdate=e.uniformValuesAutoUpdate,this.uniformValuesAutoVersion=e.uniformValuesAutoVersion,this.uniformLayoutCache=null,this.invalidateBindingCache(),this.invalidateProgramStructureCache(),this}clone(){return new e({vertexShader:this.vertexShader,fragmentShader:this.fragmentShader}).copy(this)}customProgramCacheKey(){if(null!==this.programCacheKeyCache)return this.programCacheKeyCache;const e=Object.keys(this.defines).sort((e,t)=>e.localeCompare(t));let t=`vertex:${this.vertexShader};fragment:${this.fragmentShader};depthVertex:${this.depthVertexShader??""};depthFragment:${this.depthFragmentShader??""};pointShadowVertex:${this.pointShadowVertexShader??""};pointShadowFragment:${this.pointShadowFragmentShader??""};`;for(const r of e)t+=`${r}:${String(this.defines[r])};`;for(const e in this.uniforms)t+=`uniform:${e}:${this.uniforms[e].type};`;for(const[e,r]of Object.entries(this.textures))t+=`texture:${e}:${Be(r)};`;for(const[e,r]of Object.entries(this.sceneTextures))t+=`sceneTexture:${e}:${r};`;for(const[e,r]of Object.entries(this.getGraphTextureInputs()))t+=`graphTexture:${e}:${r.resource}:${r.dimension}:${r.sampleType??"float"}:${r.sampler??"filtering"}:${Number(r.requiresLatePass??!1)};`;for(const[e,r]of Object.entries(this.storageBuffers))t+=`storage:${e}:${r.type}:${r.visibility??"fragment"};`;for(const e of this.vertexAttributes){const r=e.defaultValue?e.defaultValue.join(","):"";t+=`attribute:${e.name}:${e.shaderLocation}:${e.format}:${e.stepMode??"vertex"}:${r};`}return t+=`topology:${this.primitiveTopology};wireframe:${Number(this.wireframe)};transparent:${Number(this.transparent)};blending:${this.blending};premultipliedAlpha:${Number(this.premultipliedAlpha)};blendSrc:${this.blendSrc};blendDst:${this.blendDst};blendEquation:${this.blendEquation};blendSrcAlpha:${this.blendSrcAlpha};blendDstAlpha:${this.blendDstAlpha};blendEquationAlpha:${this.blendEquationAlpha};depthWrite:${Number(this.depthWrite)};depthTest:${Number(this.depthTest)};side:${String(this.side)};shadowSide:${String(this.shadowSide)};`,this.programCacheKeyCache=t,this.programCacheKeyCache}getTexturesList(){return null===this.textureListCache&&(this.textureListCache=Object.values(this.textures)),this.textureListCache}usesSceneTextures(){return this.usesSceneColor()||this.usesSceneDepth()}usesSceneColor(){return Object.values(this.sceneTextures).includes("sceneColor")||Object.values(this.graphTextures).some(e=>"sceneColorSnapshot"===e.resource)}usesSceneDepth(){return Object.values(this.sceneTextures).includes("sceneDepth")||Object.values(this.graphTextures).some(e=>"sceneDepthSnapshot"===e.resource)}getGraphTextureInputs(){const e={...this.graphTextures};for(const[t,r]of Object.entries(this.sceneTextures))e[t]="sceneDepth"===r?{resource:"sceneDepthSnapshot",dimension:"2d",sampleType:"unfilterable-float",sampler:"non-filtering",requiresLatePass:!0}:{resource:"sceneColorSnapshot",dimension:"2d",sampleType:"float",sampler:"filtering",requiresLatePass:!0};return e}requiresLatePass(){return Object.values(this.getGraphTextureInputs()).some(e=>!0===e.requiresLatePass)}getUniformValueHash(){return function(e,t){let r=2166136261;for(let n=0;n<t.entries.length;n+=1){const i=t.entries[n],a=e[i.name];if(a)switch(r=Ye(r,i.offset),i.type){case"f32":case"i32":case"u32":r=Xe(r,"boolean"==typeof a.value?a.value?1:0:Number(a.value));break;case"vec2<f32>":r=Je(r,a.value,2);break;case"vec3<f32>":r=Je(r,a.value,3);break;case"vec4<f32>":r=Je(r,a.value,4);break;case"mat3x3<f32>":r=Je(r,a.value,9);break;case"mat4x4<f32>":r=Je(r,a.value,16);break;default:r=Ye(r,n+17)}else r=Ye(r,n+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 n=0;n<e.length;n+=1){const i=e[n].version;t[n]=i,r=Math.imul((r^i)>>>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=>Me(t,e)).join("|")),this.textureLayoutKeyCache}invalidateProgramStructureCache(){this.programCacheKeyCache=null}invalidateBindingCache(){this.textureListCache=null,this.textureVersionsCache.length=0,this.textureVersionHashCache=0,this.storageBufferBindingListCache=null,this.storageBufferListCache=null,this.textureLayoutKeyDeviceCache=null,this.textureLayoutKeyCache=null}};function Ht(e){return!0===e.isWGSLShaderMaterial}function qt(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 Kt(e){return Array.isArray(e)?Array.from(e):"number"==typeof e||"boolean"==typeof e?e:e.clone()}function Zt(e,t){const r=Xt(t)?t:null,n=null!==r&&"value"in r?r.value:t;if(function(e){return Yt(e,"isTexture")}(n))return{kind:"texture",texture:n};if(!function(e){return"number"==typeof e||"boolean"==typeof e||Array.isArray(e)||Yt(e,"isColor")||Yt(e,"isVector2")||Yt(e,"isVector3")||Yt(e,"isVector4")||Yt(e,"isMatrix3")||Yt(e,"isMatrix4")}(n))throw new Error(`Unsupported WGSLShaderMaterial uniform "${e}". Use a number, boolean, vector, color, matrix, numeric array, or Texture.`);const i=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}(i)?i: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(Yt(t,"isColor"))return"vec3<f32>";if(Yt(t,"isVector2"))return"vec2<f32>";if(Yt(t,"isVector3"))return"vec3<f32>";if(Yt(t,"isVector4"))return"vec4<f32>";if(Yt(t,"isMatrix3"))return"mat3x3<f32>";if(Yt(t,"isMatrix4"))return"mat4x4<f32>";throw new Error(`Cannot infer WGSL type for uniform "${e}". Provide an explicit type.`)}(e,n);return{kind:"uniform",uniform:{type:a,value:n}}}function Yt(e,t){return Xt(e)&&!0===e[t]}function Xt(e){return"object"==typeof e&&null!==e}var Jt=class{passes=[];addPass(e){this.passes.push(e)}async executeAsync(e,t){const r=this.resolveExecutionOrder(),n=performance.now();t?.begin?.(r,e);for(let n=0;n<r.length;n+=1){const i=r[n];t?.beforePass?.(i,n,e);const a=performance.now();await(i.prepare?.(e)),i.execute(e),t?.afterPass?.(i,n,performance.now()-a,e)}t?.end?.(r,performance.now()-n,e)}execute(e,t){const r=this.resolveExecutionOrder(),n=performance.now();t?.begin?.(r,e);for(let n=0;n<r.length;n+=1){const i=r[n];t?.beforePass?.(i,n,e);const a=performance.now();i.execute(e),t?.afterPass?.(i,n,performance.now()-a,e)}t?.end?.(r,performance.now()-n,e)}reset(){this.passes.length=0}resolveExecutionOrder(){const e=new Map,t=new Map,r=new Map,n=new Map;for(const n of this.passes)e.set(n.name,n),t.set(n.name,new Set(n.dependsOn??[])),r.set(n.name,new Set);for(const e of this.passes){const r=t.get(e.name);for(const t of e.reads??[]){const i=n.get(t);i&&i!==e.name&&r.add(i)}for(const t of e.writes??[]){const i=n.get(t);i&&i!==e.name&&r.add(i),n.set(t,e.name)}}for(const[e,n]of t)for(const t of n){const n=r.get(t);if(!n)throw new Error(`RenderGraph dependency "${t}" for pass "${e}" is missing.`);n.add(e)}const i=Array.from(t.entries()).filter(([,e])=>0===e.size).map(([e])=>e),a=[];for(;i.length>0;){const n=i.shift();a.push(e.get(n));for(const e of r.get(n)??[]){const r=t.get(e);r.delete(n),0===r.size&&i.push(e)}}if(a.length!==this.passes.length)throw new Error("RenderGraph contains a dependency cycle.");return a}};import{CubeUVReflectionMapping as Qt,HalfFloatType as er,LinearFilter as tr,LinearSRGBColorSpace as rr,RGBAFormat as nr,Texture as ir}from"three";var ar=[.125,.215,.35,.446,.526,.582],sr=20,or=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]]}(),lr=class{constructor(e,t=20){this.context=e;const{device:r}=e,n=Math.max(1,Math.min(20,Math.floor(t)));this.maxBlurSamples=n,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=cr(r,this.equirectBindGroupLayout,hr,"pmrem-equirectangular"),this.blurPipeline=cr(r,this.blurBindGroupLayout,pr.replaceAll("PMREM_MAX_SAMPLES",String(n)),"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)))),n=Math.floor(Math.log2(r)),i=function(e){const t=[];for(let r=e;r>=4;r-=1){const n=2**r;t.push({mip:r,size:n,sigma:r===e?0:1/n})}for(let e=0;e<ar.length;e+=1)t.push({mip:4-e-1,size:16,sigma:ar[e]});return t}(n),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=ur(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<i.length;e+=1){const t=i[e-1],r=i[e],o=Math.sqrt(r.sigma*r.sigma-t.sigma*t.sigma),l=or[(i.length-e-1)%or.length];this.encodeBlurPass({encoder:h,source:c,target:u,sampler:d,atlasWidth:a,atlasHeight:s,maxMip:n,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:n,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 ir;return v.image={width:a,height:s},v.name="PMREM.cubeUv",v.mapping=Qt,v.format=nr,v.type=er,v.colorSpace=rr,v.minFilter=tr,v.magFilter=tr,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:n,sampler:i,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(sr);let n=0;for(let i=0;i<sr;i+=1){const a=i/e,s=Math.exp(-a*a/2);r[i]=s,0===i?n+=s:i<t&&(n+=2*s)}for(let e=0;e<r.length;e+=1)r[e]/=n;return r}(v,x),b=ur(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,sr).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:i}]}),S=3*c.size*Math.max(0,4-c.mip),C=4*(2**o-c.size),P=t.beginRenderPass({colorAttachments:[{view:n.createView(),loadOp:p?"clear":"load",storeOp:"store",clearValue:[0,0,0,1]}]});P.setViewport(S,C,3*c.size,2*c.size,0,1),P.setScissorRect(S,C,3*c.size,2*c.size),P.setPipeline(this.blurPipeline),P.setBindGroup(0,y),P.draw(36),P.end()}};function cr(e,t,r,n){const i=e.createShaderModule({code:r,label:`${n}-shader`});return i.getCompilationInfo().then(e=>{const t=e.messages.filter(e=>"error"===e.type);t.length>0&&console.error(`[WebGpuPMREMGenerator] ${n} WGSL compilation failed.`,t)}),e.createRenderPipeline({label:n,layout:e.createPipelineLayout({bindGroupLayouts:[t]}),vertex:{module:i,entryPoint:"vs"},fragment:{module:i,entryPoint:"fs",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list"}})}function ur(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 dr="\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",hr=`${dr}\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`,pr=`${dr}\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 fr(e){return e.replace(/[^A-Za-z0-9_]/g,"_")}function mr(e,t){const r=Object.entries(e.uniforms).map(([e,t])=>` ${fr(e)}: ${t.type},`).join("\n"),n=r?`\nstruct MaterialUniforms {\n${r}\n};\n\n@group(1) @binding(0) var<uniform> materialUniforms: MaterialUniforms;\n`:"",i=Object.entries(e.textures).map(([e,r],n)=>{const i=1+2*n,a=fr(e),s=Pe(r,t);return[`@group(1) @binding(${i}) var ${a}Sampler: ${s.wgslSamplerType};`,`@group(1) @binding(${i+1}) var ${a}Texture: ${s.wgslTextureType};`].join("\n")}).join("\n"),a=1+2*Object.keys(e.textures).length;return`${n}\n${i}\n${Object.entries(e.storageBuffers).map(([e,t],r)=>{const n=fr(e);return`@group(1) @binding(${a+r}) var<storage, read> ${n}: ${t.type};`}).join("\n")}`}function gr(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 vr(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 xr(e,t,r="packed",n=!0,i=!1,a){const s=mr(e,t),o=function(e){return Object.entries(e.getGraphTextureInputs()).map(([e,t],r)=>{const n=fr(e);return`@group(3) @binding(${2*r}) var ${n}Sampler: ${"comparison"===t.sampler?"sampler_comparison":"sampler"};\n@group(3) @binding(${2*r+1}) var ${n}Texture: ${"depth-2d"===t.dimension?"texture_depth_2d":"3d"===t.dimension?"texture_3d<f32>":"texture_2d<f32>"};`}).join("\n")}(e),l="packed-visible"===r,c=n?"\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 return vec3<f32>(uv * 0.5 + vec2(0.5, 0.5), 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\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\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${l?"@group(0) @binding(8) var<storage, read> rendererVisibleInstanceIndices: array<u32>;":""}\n\nfn rendererResolveInstanceIndex(instanceIndex: u32) -> u32 {\n ${l?"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\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${gr("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\n${c}\n${vr(i)}\n${s}\n${o}\n`}function wr(e=!0,t){return xr({uniforms:{},textures:{},storageBuffers:{},getGraphTextureInputs:()=>({})},void 0,"particle",e,!1,t)}function br(e,t,r,n="packed",i=!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"===n?"@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"===n?"@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=mr(e,r);return`\n${a}\n\n${"instanced-direct"===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 rendererObjectColor(instanceIndex: u32) -> vec4<f32> {\n return rendererInstanceColors[instanceIndex];\n}\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 {\n return instanceIndex;\n}\n":"\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\nfn rendererObjectColor(instanceIndex: u32) -> vec4<f32> {\n return rendererInstances[instanceIndex].color;\n}\n\nfn rendererBatchingId(instanceIndex: u32) -> u32 {\n return u32(round(rendererInstances[instanceIndex].batching.x));\n}\n"}\n\nfn rendererInverseMat3(m: mat3x3<f32>) -> mat3x3<f32> {\n let a = m[0];\n let b = m[1];\n let c = m[2];\n let r0 = cross(b, c);\n let r1 = cross(c, a);\n let r2 = cross(a, b);\n let det = dot(r2, c);\n let safeDet = select(det, select(-1e-8, 1e-8, det >= 0.0), abs(det) < 1e-8);\n let invDet = 1.0 / safeDet;\n return transpose(mat3x3<f32>(r0 * invDet, r1 * invDet, r2 * invDet));\n}\n\nfn rendererInstanceNormalMatrix(instanceIndex: u32) -> mat3x3<f32> {\n let model = rendererInstanceModelMatrix(instanceIndex);\n let model3x3 = mat3x3<f32>(model[0].xyz, model[1].xyz, model[2].xyz);\n return transpose(rendererInverseMat3(model3x3));\n}\n\nfn rendererWorldPosition(localPosition: vec3<f32>, instanceIndex: u32) -> vec4<f32> {\n return rendererInstanceModelMatrix(instanceIndex) * vec4(localPosition, 1.0);\n}\n\nfn rendererWorldNormal(localNormal: vec3<f32>, instanceIndex: u32) -> vec3<f32> {\n return normalize(rendererInstanceNormalMatrix(instanceIndex) * localNormal);\n}\n\n${gr("camera"===t?"rendererCamera":"shadowCamera")}\n${vr(i)}\n${s}\n`}var yr=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)}};import{AlwaysCompare as Sr,BufferAttribute as Cr,EqualCompare as Pr,GreaterCompare as Mr,GreaterEqualCompare as Br,LessCompare as Dr,LessEqualCompare as Tr,MirroredRepeatWrapping as Ir,NearestFilter as Rr,NearestMipmapLinearFilter as Vr,NearestMipmapNearestFilter as Gr,NeverCompare as zr,NotEqualCompare as Ur,Object3D as Lr,RepeatWrapping as Ar,Vector3 as Fr}from"three";import{Matrix4 as kr,Sphere as Er,Vector3 as Or}from"three";var jr=64,$r=64,Nr=40,Wr=12,_r=new Float32Array(Nr),Hr=new Float32Array([1,1,1,1]),qr="rgba16float",Kr="rgba8unorm",Zr=(new kr).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),Yr=[new Or(0,-1,0),new Or(0,-1,0),new Or(0,0,1),new Or(0,0,-1),new Or(0,-1,0),new Or(0,-1,0)],Xr=[new Or(1,0,0),new Or(-1,0,0),new Or(0,1,0),new Or(0,-1,0),new Or(0,0,1),new Or(0,0,-1)],Jr=4004,Qr=[{name:"position",shaderLocation:0,format:"float32x3"}],en=[{name:"position",shaderLocation:0,format:"float32x3"},{name:"skinIndex",shaderLocation:1,format:"uint32x4"},{name:"skinWeight",shaderLocation:2,format:"float32x4"}],tn=new kr,rn=new kr,nn=(new kr,new kr,new Er),an=new Or,sn=new Or,on=new Or,ln=(new Or,new Or,new Or,new Or,new WeakMap),cn=1;function un(e){return e?"version"in e?e.version:e.data.version:0}function dn(e){const t=Object.keys(e.attributes).sort().map(t=>{const r=e.getAttribute(t);return[t,un(r),r?.itemSize??0,r?.count??0].join(":")}).join("|"),r=e.index?.version??0,n=e.groups.map(e=>`${e.start}:${e.count}:${e.materialIndex??0}`).join("|");return[t,r,e.drawRange.start,e.drawRange.count,n].join(";")}function hn(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 pn(e){return 4*hn(e)}function fn(e,t){switch(t){case"uint32":return new Uint32Array(e);case"sint32":return new Int32Array(e);default:return new Float32Array(e)}}function mn(e,t,r,n){switch(r){case"uint32":e[t]=Math.max(0,Math.round(n));break;case"sint32":e[t]=Math.trunc(n);break;default:e[t]=n}}function gn(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 vn(e,t,r,n){const i=Math.max(4,t.byteLength),a=e.createBuffer({label:n,size:4*Math.ceil(i/4),usage:r,mappedAtCreation:!0});return new Uint8Array(a.getMappedRange()).set(new Uint8Array(t.buffer,t.byteOffset,t.byteLength)),a.unmap(),a}function xn(e){switch(e){case"vertex":return GPUShaderStage.VERTEX;case"vertex-fragment":return GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT;default:return GPUShaderStage.FRAGMENT}}function wn(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 bn(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 yn(e,t,r){try{return e.beginComputePass({timestampWrites:{querySet:t,...r}}).end(),!0}catch{return!1}}function Sn(e,t,r,n){const i=new Float32Array(t*r);if(!e){for(let e=0;e<t;e+=1)i.set(n,e*r);return i}for(let a=0;a<t;a+=1){for(let t=0;t<r;t+=1)t<e.itemSize?i[a*r+t]=e.getComponent(a,t):i[a*r+t]=n[t]??0;3===e.itemSize&&4===r&&(i[a*r+3]=n[3]??1)}return i}function Cn(e,t,r,n,i=0){const a=hn(r),s=(o=r).startsWith("uint32")?"uint32":o.startsWith("sint32")?"sint32":"float32";var o;if(!e)return function(e,t,r,n,i,a){const s=fn(r*n,a);for(let o=0;o<r;o+=1){const r=o*t,l=o*n;for(let o=0;o<n;o+=1)mn(s,l+o,a,e&&o<t?e[r+o]??i[o]??0:i[o]??0)}return s}(void 0,0,t,a,n,s);if(0===i&&e instanceof Cr&&!e.normalized&&e.itemSize===a&&e.count===t){const t=e.array;if("float32"===s&&t instanceof Float32Array||"uint32"===s&&t instanceof Uint32Array||"sint32"===s&&t instanceof Int32Array)return t}const l=fn(t*a,s);for(let r=0;r<t;r+=1){const t=r*a,o=r-i,c=o>=0&&o<e.count;for(let r=0;r<a;r+=1){mn(l,t+r,s,c&&r<e.itemSize?e.getComponent(o,r):n[r]??0)}}return l}function Pn(e,t,r,n){return Number.isFinite(n)&&n>0?n:t?Math.max(0,(e.index?.count??0)-r):Math.max(0,e.getAttribute("position").count-r)}function Mn(e,t){return{start:e.drawRange.start,count:Pn(e,t,e.drawRange.start,e.drawRange.count)}}function Bn(e){return e===Ar?"repeat":e===Ir?"mirror-repeat":"clamp-to-edge"}function Dn(e){return e===Rr||e===Gr||e===Vr?"nearest":"linear"}function Tn(e){return e instanceof HTMLCanvasElement||e instanceof HTMLImageElement||e instanceof ImageBitmap||e instanceof OffscreenCanvas||e instanceof HTMLVideoElement?e:null}function In(e){return e}function Rn(e,t,r,n,i,a,s,o,l,c,u){return e.appendMatrixAndColorValues(t,r,n,i,a,s,o,l,c,u)}function Vn(e,t,r,n,i,a,s,o,l,c,u){return e.appendMatrixAndColorValues(t.elements,r,n,i,a,s,o,l,c,u)}function Gn(e,t,r){const n=e.elements;for(let e=0;e<16;e+=1)n[e]=t[r+e]??0;return e}function zn(e){const t=ln.get(e);if(void 0!==t)return t;const r=cn+=1;return ln.set(e,r),r}function Un(e,t,r,n,i,a){return[zn(e),zn(t),r?1:0,n,i,a?zn(a):0].join(":")}function Ln(e,t,r,n,i,a){let s=2166136261;return s=En(s,e),s=En(s,t),s=En(s,r?1:0),s=En(s,n),s=En(s,i),s=En(s,a),s}function An(e,t){return e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:(r=e.sortMaterialId,n=e.sortGeometryId,i=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:n!==c?n-c:i!==u?i?-1:1:a!==d?a-d:s!==h?s-h:o-p);var r,n,i,a,s,o,l,c,u,d,h,p}function Fn(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:An(e,t)}function kn(e){for(let t=0;t<e.length;t+=1)if(e[t].hasRenderCallbacks)return!0;return!1}function En(e,t){let r=Math.imul((e^t)>>>0,16777619);return r^=r>>>13,r>>>0}function On(e,t){return e.renderOrder===t.renderOrder&&!e.hasRenderCallbacks&&!t.hasRenderCallbacks&&e.castShadow===t.castShadow&&e.receiveShadow===t.receiveShadow&&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 jn(e,t){return e.renderOrder===t.renderOrder&&!e.hasRenderCallbacks&&!t.hasRenderCallbacks&&e.castShadow===t.castShadow&&e.receiveShadow===t.receiveShadow&&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 $n(e,t){for(let r=0;r<16;r+=1)t[r]=e[r]??0}function Nn(e,t){for(let r=0;r<16;r+=1)if((e[r]??0)!==(t[r]??0))return!1;return!0}function Wn(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 _n(e,t,r,n){r.x<e.x&&(e.x=r.x),r.y<e.y&&(e.y=r.y),r.z<e.z&&(e.z=r.z),n.x>t.x&&(t.x=n.x),n.y>t.y&&(t.y=n.y),n.z>t.z&&(t.z=n.z)}function Hn(e,t){return t.multiplyMatrices(rn.multiplyMatrices(Zr,e.projectionMatrix),e.matrixWorldInverse)}function qn(e,t,r,n,i,a){const s=Math.hypot(r,n,i)||1;e[t+0]=r/s,e[t+1]=n/s,e[t+2]=i/s,e[t+3]=a/s}function Kn(e,t,r,n,i){const a=-i;for(let i=0;i<24;i+=4){if(e[i+0]*t+e[i+1]*r+e[i+2]*n+e[i+3]<a)return!1}return!0}function Zn(e){return null===e.boundingSphere&&e.computeBoundingSphere(),e.boundingSphere?{center:e.boundingSphere.center.clone(),radius:e.boundingSphere.radius}:{center:new Fr,radius:1}}function Yn(e){const t=e.elements,r=Math.hypot(t[0],t[1],t[2]),n=Math.hypot(t[4],t[5],t[6]),i=Math.hypot(t[8],t[9],t[10]);return Math.max(r,n,i,1e-5)}function Xn(e,t,r,n,i,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=n[i]*h+n[i+4]*p+n[i+8]*f+n[i+12],g=n[i+1]*h+n[i+5]*p+n[i+9]*f+n[i+13],v=n[i+2]*h+n[i+6]*p+n[i+10]*f+n[i+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=n[i],w=n[i+4],b=n[i+8],y=n[i+1],S=n[i+5],C=n[i+9],P=n[i+2],M=n[i+6],B=n[i+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],R=y*o[0]+S*o[1]+C*o[2],V=y*o[4]+S*o[5]+C*o[6],G=y*o[8]+S*o[9]+C*o[10],z=P*o[0]+M*o[1]+B*o[2],U=P*o[4]+M*o[5]+B*o[6],L=P*o[8]+M*o[9]+B*o[10],A=l[0]*D+l[4]*R+l[8]*z,F=l[0]*T+l[4]*V+l[8]*U,k=l[0]*I+l[4]*G+l[8]*L,E=l[1]*D+l[5]*R+l[9]*z,O=l[1]*T+l[5]*V+l[9]*U,j=l[1]*I+l[5]*G+l[9]*L,$=l[2]*D+l[6]*R+l[10]*z,N=l[2]*T+l[6]*V+l[10]*U,W=l[2]*I+l[6]*G+l[10]*L,_=Math.hypot(A,E,$),H=Math.hypot(F,O,N),q=Math.hypot(k,j,W);return t*Math.max(_,H,q,1e-5)}function Jn(e){const t=e.bones,r=e.boneInverses,n=e.boneMatrices;for(let e=0;e<t.length;e+=1){const i=t[e],a=i?.matrixWorld.elements,s=r[e].elements,o=16*e;if(!a){n.set(s,o);continue}const l=a[0],c=a[4],u=a[8],d=a[12],h=a[1],p=a[5],f=a[9],m=a[13],g=a[2],v=a[6],x=a[10],w=a[14],b=a[3],y=a[7],S=a[11],C=a[15],P=s[0],M=s[4],B=s[8],D=s[12],T=s[1],I=s[5],R=s[9],V=s[13],G=s[2],z=s[6],U=s[10],L=s[14],A=s[3],F=s[7],k=s[11],E=s[15];n[o]=l*P+c*T+u*G+d*A,n[o+4]=l*M+c*I+u*z+d*F,n[o+8]=l*B+c*R+u*U+d*k,n[o+12]=l*D+c*V+u*L+d*E,n[o+1]=h*P+p*T+f*G+m*A,n[o+5]=h*M+p*I+f*z+m*F,n[o+9]=h*B+p*R+f*U+m*k,n[o+13]=h*D+p*V+f*L+m*E,n[o+2]=g*P+v*T+x*G+w*A,n[o+6]=g*M+v*I+x*z+w*F,n[o+10]=g*B+v*R+x*U+w*k,n[o+14]=g*D+v*V+x*L+w*E,n[o+3]=b*P+y*T+S*G+C*A,n[o+7]=b*M+y*I+S*z+C*F,n[o+11]=b*B+y*R+S*U+C*k,n[o+15]=b*D+y*V+S*L+C*E}null!==e.boneTexture&&(e.boneTexture.needsUpdate=!0)}function Qn(e,t,r,n){const i=r.x-n,a=r.y-n,s=r.z-n,o=r.x+n,l=r.y+n,c=r.z+n;i<e.x&&(e.x=i),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 ei(e){return Math.floor(Math.max(0,e.count)/3)*Math.max(0,e.instanceCount)}function ti(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 ri(e){const t=e.customDepthMaterial;return t&&Ht(t)?t:null}function ni(e,t){e.latestFrameProfile=si(t.profile),(t.pendingGpuRead||t.pendingVisibilityRead)&&Promise.all([t.pendingGpuRead?ii(t.profile,t.pendingGpuRead):Promise.resolve(),t.pendingVisibilityRead?ai(t.profile,t.pendingVisibilityRead):Promise.resolve()]).then(()=>{const r=si(t.profile);e.latestFrameProfile=r,e.latestCompletedFrameProfile=r})}async function ii(e,t){try{await t.readBuffer.mapAsync(GPUMapMode.READ);const r=t.readBuffer.getMappedRange(),n=new BigUint64Array(r.slice(0));let i=0;const a=t.profile.passes.map((e,t)=>{const r=Number(n[2*t]??0n),a=Number(n[2*t+1]??0n),s=Math.max(0,a-r)/1e6;return i+=s,{...e,gpuTimeMs:s}});e.gpuTimeMs=i,e.gpuProfilingReason=null,e.passes=a}catch{e.timestampQueryActive=!1,e.gpuTimeMs=null,e.gpuProfilingReason="timestamp readback failed after submission",e.passes=e.passes.map(e=>({...e,gpuTimeMs:null}))}finally{"mapped"===t.readBuffer.mapState&&t.readBuffer.unmap(),t.querySet.destroy(),t.resolveBuffer.destroy(),t.readBuffer.destroy()}}async function ai(e,t){try{await t.readBuffer.mapAsync(GPUMapMode.READ);const r=new Uint32Array(t.readBuffer.getMappedRange());let n=0,i=0,a=0,s=0;for(const e of t.regions){let t=0;const o=e.byteOffset/Uint32Array.BYTES_PER_ELEMENT;for(let n=0;n<e.drawCount;n+=1)t+=r[o+5*n+1]??0;"dynamic"===e.kind?(n+=e.totalInstances,i+=t):(a+=e.totalInstances,s+=t)}const o=n+a,l=i+s;e.visibility={totalInstances:o,visibleInstances:l,culledInstances:Math.max(0,o-l),dynamicTotalInstances:n,dynamicVisibleInstances:i,staticTotalInstances:a,staticVisibleInstances:s}}catch{e.visibility=null}finally{"mapped"===t.readBuffer.mapState&&t.readBuffer.unmap(),t.readBuffer.destroy()}}function si(e){return{...e,cpuPhases:{...e.cpuPhases},passes:e.passes.map(e=>({...e})),visibility:e.visibility?{...e.visibility}:null}}function oi(e){return e.usesBatching}function li(e){return!e.wireframe&&e.material.primitiveTopology.startsWith("triangle")}function ci(e,t){return"pointShadow"===t?null!==e.material.pointShadowVertexShader&&null!==e.material.pointShadowFragmentShader:null!==e.material.depthVertexShader}function ui(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 di(e,t){if(this.state.staticVisibilityClearKernel&&this.state.staticVisibilityCullKernel&&this.state.staticVisibilityIndirectBuildKernel&&this.getHiZOcclusionCullingActive())for(const r of this.staticDrawSets){if(!r.publicSet.enabled||0===r.drawMetadataResource.count)continue;if("postpass"===t&&r.lastPreVisibilityFrameToken!==this.staticFrameToken)continue;if(!this.state.device)continue;const n="prepass"===t?r.visibilityParamsUpload:r.postVisibilityParamsUpload,i="prepass"===t?r.visibilityParamsBuffer:r.postVisibilityParamsBuffer;n[1]=this.state.hizMipCount,n[3]="prepass"===t?this.state.temporalHiZHistoryValid?3:0:5,this.state.device.queue.writeBuffer(i,0,In(n),0,4);const a=this.getOrCreateStaticVisibilityBindGroup(r,t);if(!a)continue;if("prepass"!==t||r.visibilityClearBindGroup&&r.visibilityIndirectBuildBindGroup&&r.postVisibilityIndirectBuildBindGroup||(r.visibilityClearBindGroup=this.state.staticVisibilityClearKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:r.visibilityParamsBuffer}},{binding:1,resource:{buffer:r.instanceVisibilityResource.visibleCountsBuffer}},{binding:2,resource:{buffer:r.instanceVisibilityResource.postVisibleCountsBuffer}},{binding:3,resource:{buffer:r.instanceVisibilityResource.visibleInstanceMaskBuffer}}],`${r.label}-visibility-clear-bind-group`),r.visibilityIndirectBuildBindGroup=this.state.staticVisibilityIndirectBuildKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:r.visibilityParamsBuffer}},{binding:1,resource:{buffer:r.instanceVisibilityResource.visibleCountsBuffer}},{binding:2,resource:{buffer:r.instanceVisibilityResource.postVisibleCountsBuffer}},{binding:3,resource:{buffer:r.drawMetadataResource.indirectBuffer}},{binding:4,resource:{buffer:r.drawMetadataResource.postIndirectBuffer}}],`${r.label}-visibility-indirect-build-bind-group`),r.postVisibilityIndirectBuildBindGroup=this.state.staticVisibilityIndirectBuildKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:r.postVisibilityParamsBuffer}},{binding:1,resource:{buffer:r.instanceVisibilityResource.visibleCountsBuffer}},{binding:2,resource:{buffer:r.instanceVisibilityResource.postVisibleCountsBuffer}},{binding:3,resource:{buffer:r.drawMetadataResource.indirectBuffer}},{binding:4,resource:{buffer:r.drawMetadataResource.postIndirectBuffer}}],`${r.label}-post-visibility-indirect-build-bind-group`)),"prepass"===t){const t=e.beginComputePass({label:`${r.label}-temporal-visibility-clear-pass`});t.setPipeline(this.state.staticVisibilityClearKernel.pipeline),t.setBindGroup(0,r.visibilityClearBindGroup),t.dispatchWorkgroups(Math.ceil(Math.max(r.drawMetadataResource.count,r.instanceVisibilityResource.instanceCount)/64)),t.end()}const s=e.beginComputePass({label:`${r.label}-temporal-visibility-${t}-cull-pass`});s.setPipeline(this.state.staticVisibilityCullKernel.pipeline),s.setBindGroup(0,a),s.dispatchWorkgroups(Math.ceil(r.instanceVisibilityResource.instanceCount/64)),s.end();const o=e.beginComputePass({label:`${r.label}-temporal-visibility-${t}-indirect-build-pass`});o.setPipeline(this.state.staticVisibilityIndirectBuildKernel.pipeline),o.setBindGroup(0,"prepass"===t?r.visibilityIndirectBuildBindGroup:r.postVisibilityIndirectBuildBindGroup),o.dispatchWorkgroups(Math.ceil(r.drawMetadataResource.count/64)),o.end(),"prepass"===t?r.lastPreVisibilityFrameToken=this.staticFrameToken:r.lastVisibilityFrameToken=this.staticFrameToken}}function hi(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 n=this.state.staticVisibilityCullKernel.createBindGroup(this.state.device,[{binding:0,resource:{buffer:this.state.temporalVisibilityBuffer}},{binding:1,resource:{buffer:"prepass"===t?e.visibilityParamsBuffer:e.postVisibilityParamsBuffer}},{binding:2,resource:this.state.nearestClampSampler},{binding:3,resource:this.state.hizTexture.createView()},{binding:4,resource:{buffer:e.instanceVisibilityResource.instanceMetadataBuffer}},{binding:5,resource:{buffer:e.drawMetadataResource.metadataBuffer}},{binding:6,resource:{buffer:e.instanceVisibilityResource.visibleCountsBuffer}},{binding:7,resource:{buffer:e.instanceVisibilityResource.visibleInstanceIndicesBuffer}},{binding:8,resource:{buffer:e.instanceVisibilityResource.visibleInstanceMaskBuffer}},{binding:9,resource:{buffer:e.instanceVisibilityResource.postVisibleCountsBuffer}}],`${e.label}-temporal-visibility-${t}-bind-group`);return"prepass"===t?e.visibilityBindGroup=n:e.postVisibilityBindGroup=n,e.visibilityBindGroupHizVersion=this.hizResourceVersion,n}function pi(e,t,r,n){if(!this.state.shadowDepthPipeline||0===this.state.directionalShadowLayerViews.length)return void this.clearDirectionalShadow(e);let i=!1;for(let t=0;t<r.lights.directionals.length;t+=1){const a=r.lights.directionals[t],s=this.state.directionalShadowLayerViews[t];if(!a.castShadow||!s)continue;i=!0;const o=this.directionalShadowCameras[t];o.left=a.shadowCameraLeft,o.right=a.shadowCameraRight,o.top=a.shadowCameraTop,o.bottom=a.shadowCameraBottom,o.near=a.shadowCameraNear,o.far=a.shadowCameraFar,o.position.copy(a.position),o.lookAt(a.target),o.updateMatrixWorld(!0),o.updateProjectionMatrix();const l=this.getShadowCameraBuffer(t);this.writeShadowCameraBuffer(Hn(o,this.shadowViewProjScratch),0,0,0,1,l,o);const c=this.getSharedShadowBindGroupForCameraBuffer(l),u=e.beginRenderPass({label:`renderer-directional-shadow-pass-${t}`,colorAttachments:[],depthStencilAttachment:{view:s,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});u.setPipeline(this.state.shadowDepthPipeline),u.setBindGroup(0,c),this.drawDepthLike(u,r.gpuOpaqueDraws,n,{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,n,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"});for(const e of this.staticDrawSets)e.publicSet.enabled&&0!==e.draws.length&&"late"!==e.drawStage&&(this.renderBundleScratch[0]=Ci.call(this,e,c,l,"directionalShadow",this.state.shadowDepthPipeline,this.state.shadowDepthPipelineDirect),u.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(e,n));u.end()}i||this.clearDirectionalShadow(e)}function fi(e,t,r,n){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 i=!1;for(let t=0;t<r.lights.points.length;t+=1){const a=r.lights.points[t];if(a.castShadow){i=!0;for(let i=0;i<6;i+=1){const s=6*t+i,o=this.pointShadowCameras[t][i];o.near=a.shadowCameraNear,o.far=a.shadowCameraFar,o.position.copy(a.position),an.copy(a.position).add(Xr[i]),o.up.copy(Yr[i]),o.lookAt(an),o.updateMatrixWorld(!0),o.updateProjectionMatrix();const l=this.getShadowCameraBuffer(4+s);this.writeShadowCameraBuffer(Hn(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}-${i}`,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,n,{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,n,{fallbackPipeline:this.state.pointShadowPipeline,fallbackPipelineDirect:this.state.pointShadowPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedPointShadowPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"pointShadow",customDepthMode:"use"});for(const e of this.staticDrawSets)e.publicSet.enabled&&0!==e.draws.length&&"late"!==e.drawStage&&(this.renderBundleScratch[0]=Ci.call(this,e,c,l,"pointShadow",this.state.pointShadowPipeline,this.state.pointShadowPipelineDirect),u.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(e,n));u.end()}}}i||this.clearPointShadow(e)}function mi(e,t,r,n){if(!r.lights.spots.some(e=>e.castShadow))return;if(!this.state.shadowDepthPipeline||0===this.state.spotShadowLayerViews.length)return void this.clearSpotShadow(e);let i=!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;i=!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),an.copy(a.position).add(a.direction),o.lookAt(an),o.updateMatrixWorld(!0),o.updateProjectionMatrix();const l=this.getShadowCameraBuffer(28+t);this.writeShadowCameraBuffer(Hn(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,n,{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,n,{fallbackPipeline:this.state.shadowDepthPipeline,fallbackPipelineDirect:this.state.shadowDepthPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedShadowDepthPipeline,fallbackBindGroup:c,shadowCameraBuffer:l,passKind:"directionalShadow",customDepthMode:"use"});for(const e of this.staticDrawSets)e.publicSet.enabled&&0!==e.draws.length&&"late"!==e.drawStage&&(this.renderBundleScratch[0]=Ci.call(this,e,c,l,"directionalShadow",this.state.shadowDepthPipeline,this.state.shadowDepthPipelineDirect),u.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(e,n));u.end()}i||this.clearSpotShadow(e)}function gi(e,t,r,n){if(!this.state.depthPrepassPipeline||!this.state.mainDepthView)return;const i=e.beginRenderPass({label:"renderer-depth-prepass",colorAttachments:[],depthStencilAttachment:{view:this.state.mainDepthView,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});i.setPipeline(this.state.depthPrepassPipeline),i.setBindGroup(0,t),this.executeStaticDepthPrepass(i,t,n),this.drawDepthLike(i,r.gpuOpaqueDraws,n,{fallbackPipeline:this.state.depthPrepassPipeline,fallbackPipelineDirect:this.state.depthPrepassPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedDepthPrepassPipeline,fallbackBindGroup:t,passKind:"prepass",customDepthMode:"skip"}),this.drawDepthLike(i,r.directOpaqueDraws,n,{fallbackPipeline:this.state.depthPrepassPipeline,fallbackPipelineDirect:this.state.depthPrepassPipelineDirect,fallbackSkinnedPipeline:this.state.skinnedDepthPrepassPipeline,fallbackBindGroup:t,passKind:"prepass",customDepthMode:"skip"}),i.end()}function vi(e,t,r){for(const n of this.staticDrawSets){if(!n.publicSet.enabled||0===n.draws.length||"late"===n.drawStage)continue;if(this.getHiZOcclusionCullingActive()&&n.lastPreVisibilityFrameToken===this.staticFrameToken&&bi(n)){const e=this.getOrCreateStaticVisibleDepthSceneBindGroup(n);this.renderBundleScratch[0]=xi.call(this,n,e)}else this.renderBundleScratch[0]=this.getOrCreateStaticDepthPrepassBundle(n,t);e.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(n,r)}}function xi(e,t,r=e.drawMetadataResource.indirectBuffer,n="prepass"){if(!this.state.device||!this.state.depthPrepassPipelineVisible)throw new Error("Renderer visible depth prepass resources are not initialized.");const i=e.indirectDepthPrepassBundles[n];if(i?.sceneBindGroup===t&&i.indirectBuffer===r)return i.bundle;const a=`${e.label}-static-temporal-depth-${n}-bundle-${e.id}`,s=this.state.device.createRenderBundleEncoder({label:a,colorFormats:[],depthStencilFormat:"depth32float",sampleCount:1});s.setPipeline(this.state.depthPrepassPipelineVisible),s.setBindGroup(0,t);let o=null;for(let t=0;t<e.draws.length;t+=1){const n=e.draws[t];n.customDepthMaterial||ci(n,"prepass")||ki(n.material)||!li(n)||(o!==n.geometryKey&&(o=n.geometryKey,this.bindGeometryVertexBuffers(s,n.geometry,n.geometryResource,Qr,0,1,n.wireframe)),s.drawIndexedIndirect(r,5*t*Uint32Array.BYTES_PER_ELEMENT))}const l=s.finish({label:a});return e.indirectDepthPrepassBundles[n]={sceneBindGroup:t,indirectBuffer:r,bundle:l},l}function wi(e){if(this.sampleCount<=1||!this.state.mainDepthView||!this.getHiZOcclusionCullingActive())return;let t=null;for(const r of this.staticDrawSets){if(!r.publicSet.enabled||0===r.draws.length||"late"===r.drawStage||r.lastVisibilityFrameToken!==this.staticFrameToken||!bi(r))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(r);this.renderBundleScratch[0]=xi.call(this,r,n,r.drawMetadataResource.postIndirectBuffer,"postpass"),t.executeBundles(this.renderBundleScratch)}t?.end()}function bi(e){for(const t of e.draws)if(t.customDepthMaterial||ci(t,"prepass")||ki(t.material)||!li(t))return!1;return!0}function yi(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 n=Si.call(this,e,"prepass"),i=`${e.label}-static-depth-prepass-bundle-${e.id}`,a=this.state.device.createRenderBundleEncoder({label:i,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],i=n[t];if(r.customDepthMaterial||!i&&(ki(r.material)||!li(r)))continue;const c=i?.pipeline??this.state.depthPrepassPipeline;s!==c&&(s=c,o=null,l=null,a.setPipeline(c)),i&&o!==i.bindGroup&&(o=i.bindGroup,a.setBindGroup(1,o)),l!==r.geometryKey&&(l=r.geometryKey,this.bindGeometryVertexBuffers(a,r.geometry,r.geometryResource,i?.vertexAttributes??Qr,r.instanceStart,r.instanceCount,r.wireframe)),a.drawIndexed(r.count,r.instanceCount,r.start,0,r.instanceStart)}const c=a.finish({label:i});return e.depthPrepassBundle=c,e.depthPrepassBundleSceneBindGroup=r,c}function Si(e,t){const r=t,n=e.depthMaterialResources.get(r);if(n)return n;const i=e.draws.map(e=>{const r=ci(e,t);if(e.customDepthMaterial||!r)return null;return this.getDepthPassMaterialResourceForDraw(e.material,t,e)});return e.depthMaterialResources.set(r,i),i}function Ci(e,t,r,n,i,a){if(!this.state.device)throw new Error("Renderer is not initialized.");const s=this.resolveShadowBindGroupForDraw(e.draws[0],t,r),o=e.shadowBundles.get(s),l=o?.[n];if(l)return l;const c=Si.call(this,e,n),u=`${e.label}-static-${n}-bundle-${e.id}`,d=this.state.device.createRenderBundleEncoder({label:u,colorFormats:"pointShadow"===n?["rgba16float"]:[],depthStencilFormat:"depth32float",sampleCount:1});d.setBindGroup(0,s);let h=null,p=null,f=null;for(let t=0;t<e.draws.length;t+=1){const r=e.draws[t];if(!r.castShadow)continue;const n=c[t],s=n?.pipeline??("instanced-direct"===this.getDrawInstanceAccessMode(r)&&a?a:i);h!==s&&(h=s,p=null,f=null,d.setPipeline(s)),n&&p!==n.bindGroup&&(p=n.bindGroup,d.setBindGroup(1,p)),f!==r.geometryKey&&(f=r.geometryKey,this.bindGeometryVertexBuffers(d,r.geometry,r.geometryResource,n?.vertexAttributes??Qr,r.instanceStart,r.instanceCount,r.wireframe)),d.drawIndexed(r.count,r.instanceCount,r.start,0,r.instanceStart)}const m=d.finish({label:u});return e.shadowBundles.set(s,{...o,[n]:m}),m}function Pi(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 n=this.state.hizCopyBindGroup;n||(n=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=n);const i=e.beginComputePass({label:"renderer-hiz-copy-pass"});if(i.setPipeline(this.state.hizCopyKernel.pipeline),i.setBindGroup(0,n),i.dispatchWorkgroups(Math.ceil(this.state.width/8),Math.ceil(this.state.height/8)),i.end(),!r){for(let t=1;t<this.state.hizMipCount;t+=1){const r=Math.max(1,this.state.width>>t),n=Math.max(1,this.state.height>>t);let i=this.state.hizReduceBindGroups[t];i||(i=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]=i);const a=e.beginComputePass({label:`renderer-hiz-reduce-pass-${t}`});a.setPipeline(this.state.hizReduceKernel.pipeline),a.setBindGroup(0,i),a.dispatchWorkgroups(Math.ceil(r/8),Math.ceil(n/8)),a.end()}t&&this.commitTemporalHiZHistory()}}function Mi(e,t,r,n,i,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,i.scene,i.camera,e.geometry,e.material,e.geometryGroup);const t=e.geometryResource,r=this.getMaterialResourceForDraw(e,[qr],c),s=this.resolveSceneBindGroupForDraw(e,n);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,i.scene,i.camera,e.geometry,e.material,e.geometryGroup)};if(this.executeStaticForwardPass(p,n,a,o,c),f=null,m=null,g=null,v=null,x=null,"late"!==o&&this.getHiZOcclusionCullingActive()&&this.state.drawMetadataResource){const e=this.buildIndirectSubmissionStreams(i.gpuOpaqueDraws,n),t=this.renderBundleScratch;t.length=0;for(let r=0;r<e.length;r+=1){const n=e[r];t[0]=this.getOrCreateIndirectForwardBundle(n),p.executeBundles(t),a.drawCallCount+=n.drawCallCount,a.triangleCount+=n.triangleCount}f=null,m=null,g=null,v=null}else if("late"!==o){const e=kn(i.gpuOpaqueDraws)||i.gpuOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(i.gpuOpaqueDraws,n,a);if(e)this.renderBundleScratch[0]=e,p.executeBundles(this.renderBundleScratch);else for(const e of i.gpuOpaqueDraws)w(e)}const b="late"===o||kn(i.directOpaqueDraws)||i.directOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(i.directOpaqueDraws,n,a);if(b)this.renderBundleScratch[0]=b,p.executeBundles(this.renderBundleScratch);else if("late"!==o)for(const e of i.directOpaqueDraws)w(e);if("opaque"!==o)for(const e of i.transparentDraws)w(e);p.end()}function Bi(e,t,r,n="all",i=this.sampleCount){for(const a of this.staticDrawSets)if(a.publicSet.enabled&&0!==a.draws.length&&("all"===n||a.drawStage===n)){if("opaque"===a.drawStage&&this.getHiZOcclusionCullingActive()&&a.lastVisibilityFrameToken===this.staticFrameToken){const t=this.getOrCreateStaticVisibleSceneBindGroup(a),n=this.getOrCreateStaticIndirectSubmissionStreams(a,t);for(const t of n)if(this.getMultiDrawIndirectActive()){if(e.setPipeline(t.materialResource.pipeline),this.bindGeometryVertexBuffers(e,t.geometry,t.geometryResource,t.materialResource.vertexAttributes,0,1,t.material.wireframe),e.setBindGroup(0,t.sceneBindGroup),e.setBindGroup(1,t.materialResource.bindGroup),!t.materialResource.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");e.setBindGroup(3,this.createGraphTextureBindGroup(t.material,t.materialResource.graphTextureBindGroupLayout)),e.multiDrawIndexedIndirect(a.drawMetadataResource.indirectBuffer,5*t.indirectStartIndex*Uint32Array.BYTES_PER_ELEMENT,t.indirectCount),r.drawCallCount+=t.drawCallCount,r.triangleCount+=t.triangleCount}else this.renderBundleScratch[0]=this.getOrCreateIndirectForwardBundle(t,a.drawMetadataResource,a.indirectForwardBundleCache,`${a.label}-static-indirect-forward-bundle`),e.executeBundles(this.renderBundleScratch),r.drawCallCount+=t.drawCallCount,r.triangleCount+=t.triangleCount;continue}this.renderBundleScratch[0]=this.getOrCreateStaticDirectForwardBundle(a,t,i),e.executeBundles(this.renderBundleScratch),this.recordStaticDrawStats(a,r)}}function Di(e,t,r=this.sampleCount){if(!this.state.device||!this.state.format)throw new Error("Renderer is not initialized.");const n=this.resolveSceneBindGroupForDraw(e.draws[0],t);if(e.directForwardBundle&&e.directForwardBundleSceneBindGroup===n&&e.directForwardBundleSampleCount===r)return e.directForwardBundle;null==e.draws[0]?.materialResource&&(this.refreshStaticDrawMaterialResources(e.draws),this.syncStaticVisibleMaterialBindingCaches(e));const i=`${e.label}-static-forward-direct-bundle-${e.id}`,a=this.state.device.createRenderBundleEncoder({label:i,colorFormats:[qr],depthStencilFormat:"depth32float",sampleCount:r});let s=null,o=null,l=null;a.setBindGroup(0,n);for(const t of e.draws){const n=("opaque"===e.drawStage?t.materialResource:null)??this.getMaterialResource(t.material,this.getDrawInstanceAccessMode(t),t.receiveShadow,void 0,null!==t.skinning,oi(t),r);if(s!==n.pipeline&&(s=n.pipeline,l=null,a.setPipeline(s)),l!==t.geometryKey&&(l=t.geometryKey,this.bindGeometryVertexBuffers(a,t.geometry,t.geometryResource,n.vertexAttributes,t.instanceStart,t.instanceCount,t.wireframe)),o!==n.bindGroup){if(o=n.bindGroup,a.setBindGroup(1,o),!n.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");a.setBindGroup(3,this.createGraphTextureBindGroup(t.material,n.graphTextureBindGroupLayout))}a.drawIndexed(t.count,t.instanceCount,t.start,0,t.instanceStart)}const c=a.finish({label:i});return e.directForwardBundle=c,e.directForwardBundleSceneBindGroup=n,e.directForwardBundleSampleCount=r,c}function Ti(e){for(const t of e.visibleMaterialBindings){const r=t.drawIndices[0];t.resource=e.draws[r]?.materialResource??e.visibleDrawMaterialResources[r]??null}}function Ii(e){for(const t of e)t.materialResource=this.getMaterialResource(t.material,this.getDrawInstanceAccessMode(t),t.receiveShadow,void 0,null!==t.skinning,oi(t))}function Ri(e,t){t.drawCallCount+=e.drawCallCount,t.triangleCount+=e.triangleCount}function Vi(){return this.staticDrawSets.some(e=>e.publicSet.enabled&&e.draws.length>0)}function Gi(e,t,r){if(!(this.state.device&&this.state.presentPipeline&&this.state.fullscreenTextureBindGroupLayout&&this.state.linearClampSampler))return;let n=this.state.presentBindGroups.get(t);n||(n=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,n));const i=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"}]});i.setPipeline(this.state.presentPipeline),i.setBindGroup(0,n),i.draw(3),i.end()}function zi(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 Ui(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 Li(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 Ai(e,t,r,n){let i=null,a=null,s=null,o=null,l=null;for(const c of t){if("prepass"!==n.passKind&&!c.castShadow)continue;if("prepass"===n.passKind&&null===c.material.depthVertexShader&&ki(c.material))continue;if("skip"===n.customDepthMode&&c.customDepthMaterial)continue;const t=ci(c,n.passKind),u="use"===n.customDepthMode&&c.customDepthMaterial?c.customDepthMaterial:"ignore"!==n.customDepthMode&&t?c.material:null,d=u?this.getDepthPassMaterialResourceForDraw(u,n.passKind,c):null;if(!d&&!li(c))continue;const h=null!==c.skinning,p=d?.pipeline??(h&&n.fallbackSkinnedPipeline?n.fallbackSkinnedPipeline:"instanced-direct"===this.getDrawInstanceAccessMode(c)&&n.fallbackPipelineDirect?n.fallbackPipelineDirect:n.fallbackPipeline);a!==p&&(a=p,s=null,o=null,l=null,i=null,e.setPipeline(p));const f="prepass"===n.passKind?this.resolveSceneBindGroupForDraw(c,n.fallbackBindGroup):this.resolveShadowBindGroupForDraw(c,n.fallbackBindGroup,n.shadowCameraBuffer);s!==f&&(s=f,e.setBindGroup(0,f)),d?o!==d.bindGroup&&(o=d.bindGroup,e.setBindGroup(1,d.bindGroup)):o=null,(d?.usesSkinning??h)&&c.skinning&&l!==c.skinning.bindGroup&&(l=c.skinning.bindGroup,e.setBindGroup(2,l));const m=c.geometryResource;i!==c.geometryKey&&(i=c.geometryKey,this.bindGeometryVertexBuffers(e,c.geometry,m,d?.vertexAttributes??(h?en:Qr),c.instanceStart,c.instanceCount,c.wireframe)),c.indexed&&(c.wireframe?m.wireframeIndex:m.index)?e.drawIndexed(c.count,c.instanceCount,c.start,0,c.instanceStart):e.draw(c.count,c.instanceCount,c.start,c.instanceStart),this.recordDraw(c,r)}}var Fi=new WeakMap;function ki(e){if(e.transparent)return!0;let t=Fi.get(e);return null==t&&(t=e.transparent||e.alphaTest>0||/\bdiscard\b/.test(e.fragmentShader),Fi.set(e,t)),t}import{Vector3 as Ei}from"three";var Oi=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/Nr}reset(){this.lengthFloats=0}appendMatrixAndColor(e,t,r=e,n=2,i=1,a=0){return this.appendMatrixAndColorValues(e,t[0]??1,t[1]??1,t[2]??1,t[3]??1,void 0,r,n,i,a)}appendMatrixAndColorValues(e,t,r,n,i,a=this.instanceCount,s=e,o=2,l=1,c=0){const u=this.instanceCount;this.ensureCapacity(this.lengthFloats+Nr);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]=n,this.data[d+19]=i,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+=Nr,u}appendRange(e,t,r){if(r<=0)return;const n=t*Nr,i=n+r*Nr;this.ensureCapacity(this.lengthFloats+(i-n)),this.data.set(e.data.subarray(n,i),this.lengthFloats),this.lengthFloats+=i-n}appendBuilder(e){this.appendRange(e,0,e.instanceCount)}beginWriteInstances(e){const t=e*Nr;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}},ji=class{constructor(e,t,r,n,i){this.state=e,this.staticDrawSets=t,this.getGeometryResourceForGeometry=r,this.resolveMaterial=n,this.ensureWireframeIndex=i}state;staticDrawSets;getGeometryResourceForGeometry;resolveMaterial;ensureWireframeIndex;nextStaticDrawSetId=1;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}`,n=t.onUnsupported??"throw",i=t.allowUnsortedLateDraws??!1,a=[],s=new Oi(4096),o=(e,t)=>{if("skip"!==n)throw new Error(`StaticDrawSet "${r}" does not support ${e.type||"Object3D"} "${e.name||e.uuid}": ${t}.`)};e.updateMatrixWorld(!0);const l=new Map;this.activeMaterialSnapshots=l;try{e.traverseVisible(e=>{e.isSkinnedMesh?o(e,"skinned meshes are dynamic"):e.isBatchedMesh?this.collectStaticBatchedMesh(e,s,a,r,o,i):e.isInstancedMesh?this.collectStaticInstancedMesh(e,s,a,r,o,i):e.isMesh&&this.collectStaticMesh(e,s,a,r,o,i)})}catch(e){for(const e of l.values())e.dispose();throw e}finally{this.activeMaterialSnapshots=null}const{draws:c,instanceData:u}=this.mergeStaticDraws(a,s),d=c.some(e=>e.transparent),h=c.some(e=>!e.transparent);if(d&&h)throw new Error(`StaticDrawSet "${r}" cannot mix opaque and late materials; register them as separate sets.`);const p=this.createVisibleMaterialBindings(c),f=Math.max(4,u.byteLength),m=this.state.device.createBuffer({label:`${r}-static-instance-buffer`,size:256*Math.ceil(f/256),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});u.floatLength>0?this.state.device.queue.writeBuffer(m,0,u.rawData.buffer,0,u.byteLength):this.state.device.queue.writeBuffer(m,0,_r,0,Nr);const g={mode:"packed",buffer:m,colorBuffer:null,sceneBindGroup:null,shadowBindGroup:null,shadowBindGroups:new Map,sceneBindGroupVersion:0,shadowBindGroupVersion:0};for(const e of c)e.residentInstanceBinding=g;const v=this.createStaticDrawMetadataResource(r,c),x=this.createStaticInstanceVisibilityResource(r,c,u),w=new Uint32Array([c.length,this.state.hizMipCount,u.instanceCount,0]),b=this.state.device.createBuffer({label:`${r}-visibility-params-buffer`,size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),y=new Uint32Array([c.length,this.state.hizMipCount,u.instanceCount,0]),S=this.state.device.createBuffer({label:`${r}-post-visibility-params-buffer`,size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});this.state.device.queue.writeBuffer(b,0,w,0,4),this.state.device.queue.writeBuffer(S,0,y,0,4);const C={id:this.nextStaticDrawSetId++,label:r,publicSet:null,ownedMaterials:[...l.values()],draws:c,drawStage:d?"late":"opaque",drawCallCount:c.length,triangleCount:c.reduce((e,t)=>e+Math.floor(Math.max(0,t.count)/3)*Math.max(0,t.instanceCount),0),instanceCount:u.instanceCount,instanceBuffer:m,residentInstanceBinding:g,drawMetadataResource:v,instanceVisibilityResource:x,visibilityParamsBuffer:b,visibilityParamsUpload:w,postVisibilityParamsBuffer:S,postVisibilityParamsUpload:y,visibilityBindGroup:null,postVisibilityBindGroup:null,visibilityClearBindGroup:null,visibilityIndirectBuildBindGroup:null,postVisibilityIndirectBuildBindGroup:null,visibleSceneBindGroup:null,visibleSceneBindGroupVersion:0,visibleDepthSceneBindGroup:null,visibleDepthSceneBindGroupVersion:0,visibleMaterialBindings:p,visibleDrawMaterialResources:new Array(c.length),visibleIndirectSubmissionStreams:null,visibleIndirectStreamsSceneBindGroup:null,visibleIndirectStreamsSampleCount:-1,visibleIndirectStreamsColorFormatsKey:"",visibilityBindGroupHizVersion:0,lastPreVisibilityFrameToken:0,lastVisibilityFrameToken:0,indirectForwardBundleCache:new Map,directForwardBundle:null,directForwardBundleSampleCount:-1,directForwardBundleSceneBindGroup:null,depthPrepassBundle:null,depthPrepassBundleSceneBindGroup:null,indirectDepthPrepassBundles:{prepass:null,postpass:null},shadowBundles:new WeakMap,depthMaterialResources:new Map},P={label:r,enabled:!0,get drawCount(){return C.draws.length},get instanceCount(){return C.instanceCount},dispose:()=>{this.disposeStaticDrawSetResource(C)}};return C.publicSet=P,this.staticDrawSets.push(C),P}createVisibleMaterialBindings(e){const t=new Map;for(let r=0;r<e.length;r+=1){const n=e[r],i=`${zn(n.material)}:${n.receiveShadow?1:0}:${n.usesBatching?1:0}`;let a=t.get(i);a||(a={material:n.material,receiveShadow:n.receiveShadow,usesBatching:n.usesBatching,drawIndices:[],resource:null},t.set(i,a)),a.drawIndices.push(r)}return[...t.values()]}mergeStaticDraws(e,t){e.sort(An);const r=[],n=new Oi(Math.max(1024,t.floatLength));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&&jn(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,n,i,a){if(!(null!==e.geometry.index))return void i(e,"non-indexed geometry cannot use the v1 indirect static path");if(ri(e))return void i(e,"custom depth materials are not supported by StaticDrawSet v1");const s=this.getGeometryResource(e.geometry),o=Zn(e.geometry),l=an.copy(o.center).applyMatrix4(e.matrixWorld),c=o.radius*Yn(e.matrixWorld),u=Vn(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 n=d?d[t.materialIndex??0]??d[0]:h,p=this.resolveStaticMaterial(n);if(!p){i(e,"all static mesh materials must be WGSLShaderMaterial");continue}if(p.transparent&&!a){i(e,"transparent materials are not supported by StaticDrawSet v1");continue}if(Object.keys(p.getGraphTextureInputs()).length>0&&!a){i(e,"scene-texture materials are not supported by StaticDrawSet v1");continue}const f=Pn(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))}return}const p=h??d?.[0]??null,f=this.resolveStaticMaterial(p);if(!f)return void i(e,"all static mesh materials must be WGSLShaderMaterial");if(f.transparent&&!a)return void i(e,"transparent materials are not supported by StaticDrawSet v1");if(Object.keys(f.getGraphTextureInputs()).length>0&&!a)return void i(e,"scene-texture materials are not supported by StaticDrawSet v1");const m=Mn(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))}collectStaticInstancedMesh(e,t,r,n,i,a){const s=this.resolveStaticMaterial(e.material);if(!s)return void i(e,"static instanced meshes must use WGSLShaderMaterial");if(s.transparent&&!a)return void i(e,"transparent materials are not supported by StaticDrawSet v1");if(Object.keys(s.getGraphTextureInputs()).length>0&&!a)return void i(e,"scene-texture materials are not supported by StaticDrawSet v1");if(ri(e))return void i(e,"custom depth materials are not supported by StaticDrawSet v1");if(null===e.geometry.index)return void i(e,"non-indexed geometry cannot use the v1 indirect static path");const o=Mn(e.geometry,!0);if(o.count<=0||e.count<=0)return;const l=Zn(e.geometry),c=an.set(1/0,1/0,1/0),u=sn.set(-1/0,-1/0,-1/0),d=this.getGeometryResource(e.geometry),h=t.instanceCount;for(let r=0;r<e.count;r+=1){e.getMatrixAt(r,tn),rn.multiplyMatrices(e.matrixWorld,tn);const n=e.instanceColor?e.instanceColor.getComponent(r,0):1,i=e.instanceColor&&e.instanceColor.itemSize>1?e.instanceColor.getComponent(r,1):1,a=e.instanceColor&&e.instanceColor.itemSize>2?e.instanceColor.getComponent(r,2):1,s=e.instanceColor&&e.instanceColor.itemSize>3?e.instanceColor.getComponent(r,3):1;Vn(t,rn,n,i,a,s);Qn(c,u,on.copy(l.center).applyMatrix4(rn),l.radius*Yn(rn))}const p=.5*(c.x+u.x),f=.5*(c.y+u.y),m=.5*(c.z+u.z),g=u.x-p,v=u.y-f,x=u.z-m,w=Math.sqrt(g*g+v*v+x*x);r.push(this.createStaticDrawRecord(e.geometry,e.geometry,d,s,!1,o.start,o.count,h,e.count,p,f,m,w,l.center,l.radius))}collectStaticBatchedMesh(e,t,r,n,i,a){const s=this.resolveStaticMaterial(e.material);if(!s)return void i(e,"static batched meshes must use WGSLShaderMaterial");if(s.transparent&&!a)return void i(e,"transparent materials are not supported by StaticDrawSet v1");if(Object.keys(s.getGraphTextureInputs()).length>0&&!a)return void i(e,"scene-texture materials are not supported by StaticDrawSet v1");if(ri(e))return void i(e,"custom depth materials are not supported by StaticDrawSet v1");if(null===e.geometry.index)return void i(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 n=Pn(e.geometry,!0,r.start,r.count);if(n<=0)continue;const i=e.getBoundingSphereAt(t,nn),a={geometryId:t,start:r.start,count:n,localBoundsCenter:i?i.center.clone():new Ei,localBoundsRadius:i?.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 n=d.get(r.geometryIndex);if(!n)continue;p?Gn(tn,p,16*t):e.getMatrixAt(t,tn),rn.multiplyMatrices(e.matrixWorld,tn);const i=4*t,a=f?f[i+0]??1:1,s=f?f[i+1]??1:1,o=f?f[i+2]??1:1,l=f?f[i+3]??1:1,c=on.copy(n.localBoundsCenter).applyMatrix4(rn),u=n.localBoundsRadius*Yn(rn);n.instances.push({matrix:new Float32Array(rn.elements),color0:a,color1:s,color2:o,color3:l,batchingId:t,boundsCenter:c.clone(),boundsRadius:u})}for(const n of u){if(0===n.instances.length)continue;const i=an.set(1/0,1/0,1/0),a=sn.set(-1/0,-1/0,-1/0),o=t.instanceCount;for(const e of n.instances)t.appendMatrixAndColorValues(e.matrix,e.color0,e.color1,e.color2,e.color3,e.batchingId),Qn(i,a,e.boundsCenter,e.boundsRadius);const c=.5*(i.x+a.x),u=.5*(i.y+a.y),d=.5*(i.z+a.z),h=a.x-c,p=a.y-u,f=a.z-d,m=Math.sqrt(h*h+p*p+f*f);r.push(this.createStaticDrawRecord(e.geometry,e.geometry,l,s,!0,n.start,n.count,o,n.instances.length,c,u,d,m,n.localBoundsCenter,n.localBoundsRadius))}}createStaticDrawRecord(e,t,r,n,i,a,s,o,l,c,u,d,h,p,f){const m=zn(n),g=n.wireframe&&"triangle-list"===n.primitiveTopology;g&&this.ensureWireframeIndex(e,r);const v=zn(t);return{geometry:e,geometryKey:g?r.wireframeIndex:t,geometryResource:r,material:n,customDepthMaterial:null,residentInstanceBinding:null,sourceObject:null,usesBatching:i,geometryGroup:null,batchKey:Un(n,t,!0,a,s,null),batchHash:Ln(m,v,!0,a,s,0),indexed:!0,wireframe:g,start:g?2*a:a,count:g?2*s:s,transparent:n.transparent||n.requiresLatePass(),renderOrder:0,hasRenderCallbacks:!1,castShadow:!0,receiveShadow:!0,sortMaterialId:m,sortGeometryId:v,sortCustomDepthMaterialId:0,skinning:null,materialResource:null,instanceStart:o,instanceCount:l,boundsCenter:new Ei(c,u,d),boundsRadius:h,sortDepth:0,transparentSortGroup:0,transparentSortOrder:0,staticLocalBoundsCenter:p.clone(),staticLocalBoundsRadius:f}}createStaticDrawMetadataResource(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=Math.max(1,t.length),n=new Float32Array(r*Wr),i=new Uint32Array(5*r),a=new Uint32Array(5*r);for(let e=0;e<t.length;e+=1){const r=t[e],s=e*Wr;n[s+0]=r.boundsCenter.x,n[s+1]=r.boundsCenter.y,n[s+2]=r.boundsCenter.z,n[s+3]=r.boundsRadius,n[s+4]=r.count,n[s+5]=r.start,n[s+6]=r.instanceStart,n[s+7]=r.instanceCount,n[s+8]=1,n[s+9]=0,n[s+10]=0,n[s+11]=0;const o=5*e;i[o+0]=r.count,i[o+1]=r.instanceCount,i[o+2]=r.start,i[o+3]=0,i[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*Wr*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,n,0,n.length),this.state.device.queue.writeBuffer(o,0,i,0,i.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 n=r.instanceCount,i=Math.max(32,32*n),a=new ArrayBuffer(i),s=new Float32Array(a),o=new Uint32Array(a);for(let e=0;e<t.length;e+=1){const n=t[e],i=n.staticLocalBoundsCenter??Zn(n.geometry).center,a=n.staticLocalBoundsRadius??Zn(n.geometry).radius;for(let t=0;t<n.instanceCount;t+=1){const l=n.instanceStart+t,c=l*Nr,u=8*l;tn.fromArray(r.rawData,c);const d=an.copy(i).applyMatrix4(tn),h=a*Yn(tn);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,o[u+6]=0,o[u+7]=0}}const l=this.state.device.createBuffer({label:`${e}-static-instance-visibility-metadata`,size:256*Math.ceil(i/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*n)/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*n)/256),usage:GPUBufferUsage.STORAGE});return n>0&&this.state.device.queue.writeBuffer(l,0,a),{instanceMetadataBuffer:l,visibleInstanceIndicesBuffer:c,visibleCountsBuffer:u,postVisibleCountsBuffer:d,visibleInstanceMaskBuffer:h,instanceCount:n}}disposeStaticDrawSetResource(e){const t=this.staticDrawSets.indexOf(e);if(t<0)return;this.staticDrawSets.splice(t,1);const r=new Set;for(const t of e.draws)t.materialResource&&r.add(t.materialResource);for(const t of e.visibleMaterialBindings)t.resource&&r.add(t.resource);for(const t of e.visibleDrawMaterialResources)t&&r.add(t);for(const t of e.depthMaterialResources.values())for(const e of t)e&&r.add(e);for(const e of r)e.uniformBuffer?.destroy();e.instanceBuffer.destroy(),e.drawMetadataResource.metadataBuffer.destroy(),e.drawMetadataResource.indirectBuffer.destroy(),e.drawMetadataResource.postIndirectBuffer.destroy(),e.instanceVisibilityResource.instanceMetadataBuffer.destroy(),e.instanceVisibilityResource.visibleInstanceIndicesBuffer.destroy(),e.instanceVisibilityResource.visibleCountsBuffer.destroy(),e.instanceVisibilityResource.postVisibleCountsBuffer.destroy(),e.instanceVisibilityResource.visibleInstanceMaskBuffer.destroy(),e.visibilityParamsBuffer.destroy(),e.postVisibilityParamsBuffer.destroy();for(const t of e.ownedMaterials)t.dispose();e.ownedMaterials.length=0,e.residentInstanceBinding.buffer=null,e.residentInstanceBinding.colorBuffer=null,e.residentInstanceBinding.sceneBindGroup=null,e.residentInstanceBinding.shadowBindGroup=null,e.residentInstanceBinding.shadowBindGroups.clear(),e.visibilityBindGroup=null,e.postVisibilityBindGroup=null,e.visibilityClearBindGroup=null,e.visibilityIndirectBuildBindGroup=null,e.postVisibilityIndirectBuildBindGroup=null,e.visibleSceneBindGroup=null,e.visibleDepthSceneBindGroup=null,e.visibleMaterialBindings.length=0,e.visibleDrawMaterialResources.length=0,e.visibleIndirectSubmissionStreams=null,e.visibleIndirectStreamsSceneBindGroup=null,e.visibleIndirectStreamsSampleCount=-1,e.visibleIndirectStreamsColorFormatsKey="",e.indirectForwardBundleCache.clear(),e.directForwardBundle=null,e.directForwardBundleSceneBindGroup=null,e.depthPrepassBundle=null,e.depthPrepassBundleSceneBindGroup=null,e.indirectDepthPrepassBundles.prepass=null,e.indirectDepthPrepassBundles.postpass=null,e.shadowBundles=new WeakMap,e.depthMaterialResources.clear()}},$i=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,n=r?"nearest":Dn(e.magFilter),i=r?"nearest":Dn(e.minFilter),a=r?"nearest":Dn(e.minFilter),s="comparison"===t?function(e){switch(e){case zr:return"never";case Dr:return"less";case Pr:return"equal";case Tr:return"less-equal";case Mr:return"greater";case Ur:return"not-equal";case Br:return"greater-equal";case Sr:return"always";default:return}}(e.compareFunction):void 0,o=r||"linear"!==n||"linear"!==i||"linear"!==a?1:Math.max(1,e.anisotropy);return this.state.device.createSampler({label:`${e.uuid}-sampler`,addressModeU:Bn(e.wrapS),addressModeV:Bn(e.wrapT),addressModeW:Bn(e.wrapR??e.wrapT),magFilter:n,minFilter:i,mipmapFilter:a,maxAnisotropy:o,compare:s})}uploadDataTextureResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const n=function(e){switch(e){case"r8unorm":case"r8snorm":case"r8uint":case"r8sint":return 1;case"r16uint":case"r16sint":case"r16float":case"rg8unorm":case"rg8snorm":case"rg8uint":case"rg8sint":case"depth16unorm":return 2;case"r32uint":case"r32sint":case"r32float":case"rg16uint":case"rg16sint":case"rg16float":case"rgba8unorm":case"rgba8unorm-srgb":case"rgba8snorm":case"rgba8uint":case"rgba8sint":case"bgra8unorm":case"bgra8unorm-srgb":case"rgb9e5ufloat":case"rgb10a2unorm":case"rg11b10ufloat":case"depth32float":return 4;case"rg32uint":case"rg32sint":case"rg32float":case"rgba16uint":case"rgba16sint":case"rgba16float":return 8;case"rgba32uint":case"rgba32sint":case"rgba32float":return 16;default:return null}}(r.format);if(null===n)throw new Error(`Texture format "${r.format}" from "${e.constructor.name}" cannot be uploaded with queue.writeTexture.`);const i=e.mipmaps;if(i&&i.length>0){for(let e=0;e<i.length;e+=1){const a=i[e];if(!a?.data)continue;const s=a.width??Math.max(1,r.width>>e),o=a.height??Math.max(1,r.height>>e),l=a.depth??r.depthOrArrayLayers;this.state.device.queue.writeTexture({texture:t,mipLevel:e},In(a.data),{bytesPerRow:s*n,rowsPerImage:o},{width:s,height:o,depthOrArrayLayers:l})}return}const a=e.image;a?.data&&this.state.device.queue.writeTexture({texture:t},a.data,{bytesPerRow:r.width*n,rowsPerImage:r.height},{width:r.width,height:r.height,depthOrArrayLayers:r.depthOrArrayLayers})}uploadCompressedTextureResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const n="bc1-rgba-unorm"===(i=r.format)||"bc1-rgba-unorm-srgb"===i?{byteLength:8,width:4,height:4}:"bc2-rgba-unorm"===i||"bc2-rgba-unorm-srgb"===i||"bc3-rgba-unorm"===i||"bc3-rgba-unorm-srgb"===i?{byteLength:16,width:4,height:4}:"bc4-r-unorm"===i||"bc4-r-snorm"===i?{byteLength:8,width:4,height:4}:"bc5-rg-unorm"===i||"bc5-rg-snorm"===i||"bc6h-rgb-ufloat"===i||"bc6h-rgb-float"===i||"bc7-rgba-unorm"===i||"bc7-rgba-unorm-srgb"===i?{byteLength:16,width:4,height:4}:"etc2-rgb8unorm"===i||"etc2-rgb8unorm-srgb"===i||"etc2-rgb8a1unorm"===i||"etc2-rgb8a1unorm-srgb"===i?{byteLength:8,width:4,height:4}:"etc2-rgba8unorm"===i||"etc2-rgba8unorm-srgb"===i?{byteLength:16,width:4,height:4}:"eac-r11unorm"===i||"eac-r11snorm"===i?{byteLength:8,width:4,height:4}:"eac-rg11unorm"===i||"eac-rg11snorm"===i||"astc-4x4-unorm"===i||"astc-4x4-unorm-srgb"===i?{byteLength:16,width:4,height:4}:"astc-5x4-unorm"===i||"astc-5x4-unorm-srgb"===i?{byteLength:16,width:5,height:4}:"astc-5x5-unorm"===i||"astc-5x5-unorm-srgb"===i?{byteLength:16,width:5,height:5}:"astc-6x5-unorm"===i||"astc-6x5-unorm-srgb"===i?{byteLength:16,width:6,height:5}:"astc-6x6-unorm"===i||"astc-6x6-unorm-srgb"===i?{byteLength:16,width:6,height:6}:"astc-8x5-unorm"===i||"astc-8x5-unorm-srgb"===i?{byteLength:16,width:8,height:5}:"astc-8x6-unorm"===i||"astc-8x6-unorm-srgb"===i?{byteLength:16,width:8,height:6}:"astc-8x8-unorm"===i||"astc-8x8-unorm-srgb"===i?{byteLength:16,width:8,height:8}:"astc-10x5-unorm"===i||"astc-10x5-unorm-srgb"===i?{byteLength:16,width:10,height:5}:"astc-10x6-unorm"===i||"astc-10x6-unorm-srgb"===i?{byteLength:16,width:10,height:6}:"astc-10x8-unorm"===i||"astc-10x8-unorm-srgb"===i?{byteLength:16,width:10,height:8}:"astc-10x10-unorm"===i||"astc-10x10-unorm-srgb"===i?{byteLength:16,width:10,height:10}:"astc-12x10-unorm"===i||"astc-12x10-unorm-srgb"===i?{byteLength:16,width:12,height:10}:"astc-12x12-unorm"===i||"astc-12x12-unorm-srgb"===i?{byteLength:16,width:12,height:12}:null;var i;if(!n)throw new Error(`Compressed texture format "${r.format}" is not supported for upload.`);if(!0===e.isCompressedCubeTexture){const i=e.image;for(let e=0;e<i.length;e+=1){const a=i[e]?.mipmaps??[];for(let i=0;i<a.length;i+=1){const s=a[i];if(!s?.data)continue;const o=s.width??Math.max(1,r.width>>i),l=s.height??Math.max(1,r.height>>i),c=Math.max(1,Math.ceil(o/n.width)),u=Math.max(1,Math.ceil(l/n.height));this.state.device.queue.writeTexture({texture:t,mipLevel:i,origin:{x:0,y:0,z:e}},In(s.data),{bytesPerRow:c*n.byteLength,rowsPerImage:u},{width:c*n.width,height:u*n.height,depthOrArrayLayers:1})}}return}const a=e.mipmaps;for(let e=0;e<a.length;e+=1){const i=a[e];if(!i?.data)continue;const s=i.width??Math.max(1,r.width>>e),o=i.height??Math.max(1,r.height>>e),l=Math.max(1,Math.ceil(s/n.width)),c=Math.max(1,Math.ceil(o/n.height));this.state.device.queue.writeTexture({texture:t,mipLevel:e},In(i.data),{bytesPerRow:l*n.byteLength,rowsPerImage:c},{width:l*n.width,height:c*n.height,depthOrArrayLayers:r.depthOrArrayLayers})}}uploadExternalTextureResource(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");if(!0===e.isCubeTexture){const n=e.image;if(!Array.isArray(n)||6!==n.length)return void this.warnSkippedExternalTextureUpload(e,r,"CubeTexture must provide exactly six face images.");for(let i=0;i<n.length;i+=1){const a=Tn(n[i]);if(!a)return void this.warnSkippedExternalTextureUpload(e,r,`CubeTexture face ${i} 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:i}},{width:r.width,height:r.height,depthOrArrayLayers:1})}catch(t){return void this.warnSkippedExternalTextureUpload(e,r,`CubeTexture face ${i} could not be copied: ${Ni(t)}`)}}return}const n=function(e){return Tn(e.image)}(e);if(n)try{this.state.device.queue.copyExternalImageToTexture({source:n,flipY:e.flipY},{texture:t},{width:r.width,height:r.height,depthOrArrayLayers:1})}catch(t){this.warnSkippedExternalTextureUpload(e,r,`copyExternalImageToTexture failed: ${Ni(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 n=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:n?.constructor?.name??typeof n,width:n?.width,height:n?.height,depth:n?.depth,src:n?.currentSrc??n?.src,hasData:null!=n?.data,keys:null==n?[]:Object.keys(n).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=Pe(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 n=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,n,r);const i=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:n,view:n.createView("2d"===r.viewDimension?void 0:"2d-array"===r.viewDimension?{dimension:"2d-array",arrayLayerCount:r.depthOrArrayLayers}:{dimension:r.viewDimension}),sampler:i};return this.textureCache.set(e,a),a}};function Ni(e){return e instanceof Error?e.message:String(e)}var Wi="\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",_i="\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",Hi="\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",qi=`\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${Hi}\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`,Ki=`\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${Hi}\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`,Zi=`\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${Hi}\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`,Yi="\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 Xi(e){if(e.transparent)switch(e.blending){case at:return{color:{srcFactor:"src-alpha",dstFactor:"one",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one",operation:"add"}};case wt:return{color:{srcFactor:"zero",dstFactor:"one-minus-src",operation:"subtract"},alpha:{srcFactor:"one",dstFactor:"one",operation:"subtract"}};case pt: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 Ji(e,t,r,n){if(t<0||e[t]!==r)return-1;let i=0;for(let a=t;a<e.length;a+=1)if(e[a]===r&&(i+=1),e[a]===n&&(i-=1,0===i))return a;return-1}function Qi(e,t,r){const n=function(e,t="fsMain"){const r=e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,""),n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=new RegExp(`@fragment\\s+fn\\s+${n}\\s*\\(`).exec(r);if(!i)return null;const a=r.indexOf("(",i.index),s=Ji(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=Ji(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===n||n.has(t)?{format:e,blend:r}:{format:e,writeMask:0})}function ea(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 ta(e){const t=Number(e.userData.motionBlurScale??1);return Number.isFinite(t)?Math.max(0,Math.min(t,8)):1}var ra="chromium-experimental-multi-draw-indirect";function na(e,t){return Number(t.castShadow)-Number(e.castShadow)}var ia=[qr],aa=[{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 sa(e){return e.wireframe&&"triangle-list"===e.primitiveTopology?"line-list":e.primitiveTopology}function oa(e,t,r){if(!sa(e).startsWith("triangle"))return"none";if("directionalShadow"===t){if(r&&null===e.shadowSide)return"none";const t=e.shadowSide??(e.side===st?dt:e.side===ut?ut:st);return t===ut?"none":t===st?"front":"back"}return e.side===ut?"none":e.side===st?"front":"back"}function la(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 ca=class{canvas;clearColor;powerPreference;shadowMapSize;pointShadowMapSize;fallbackMaterial;materialResolver;toonOutlineMaterialCache=new WeakMap;fallbackSkinnedMaterial;invokeObjectRenderCallbacks;sampleCount;renderScale;hiZOcclusionCullingEnabled;multiDrawIndirectEnabled;dynamicBatchingEnabled;multiDrawIndirectSupported=!1;renderGraphProfilingEnabled;indirectFirstInstanceSupported=!1;timestampQuerySupported=!1;geometryCache=new WeakMap;skinnedGeometryCache=new Map;skinPaletteCache=new WeakMap;skinPaletteResources=new Set;meshExtractionCache=new WeakMap;resolvedMaterialFrameCache=new WeakMap;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:[],hizTexture:null,hizView:null,hizMipViews:[],hizCopyBindGroup:null,hizReduceBindGroups:[],visibilityBindGroup:null,visibilityBindGroupMetadataResource:null,presentBindGroups:new WeakMap,hizMipCount:1,temporalHiZHistoryValid:!1,temporalVisibilityBuffer:null,visibilityParamsBuffer:null,hizCopyKernel:null,hizReduceKernel:null,visibilityKernel:null,staticVisibilityClearKernel:null,staticVisibilityCullKernel:null,staticVisibilityIndirectBuildKernel:null,depthPrepassPipeline:null,depthPrepassPipelineVisible:null,depthPrepassPipelineDirect:null,skinnedDepthPrepassPipeline:null,shadowDepthPipeline:null,shadowDepthPipelineDirect:null,skinnedShadowDepthPipeline:null,pointShadowPipeline:null,pointShadowPipelineDirect:null,skinnedPointShadowPipeline:null,presentPipeline:null,sceneColorSnapshotPipeline:null,sceneColorSnapshotBindGroups:new WeakMap,pixelRatio:1,width:1,height:1,presentationWidth:1,presentationHeight:1,frameTimeSeconds:0,frameIndex:0,directionalShadowTextureSize:1,pointShadowTextureSize:1,spotShadowTextureSize:1,latestFrameProfile:null,latestCompletedFrameProfile:null,residentSceneBindGroupVersion:0,residentShadowBindGroupVersion:0,initialized:!1}}();textureCache=new WeakMap;graphTextureBindGroupCache=new WeakMap;materialGraphTextureReadCache=new WeakMap;defaultInstanceAttributeBuffers=new Map;textureManager=new $i(this.state,this.textureCache);renderGraph=new Jt;directionalShadowCameras=Array.from({length:4},()=>new gt(-10,10,10,-10,.1,80));pointShadowCameras=Array.from({length:4},()=>Xr.map(()=>new vt(90,1,.1,25)));spotShadowCameras=Array.from({length:4},()=>new vt(60,1,.5,500));colorTargetCache=new Map;msaaColorTargetCache=new Map;msaaDepthTargetCache=new Map;sourceInstanceDataScratch=new Oi(4096);opaqueInstanceDataScratch=new Oi(4096);finalInstanceDataScratch=new Oi(4096);residentInstanceUploadsScratch=[];gpuOpaqueDrawsScratch=[];directOpaqueDrawsScratch=[];stagedOpaqueDrawsScratch=[];residentOpaqueDrawsScratch=[];retiredGeometryResources=[];retiredGeometryBuffers=[];vertexAttributeBufferKeyCache=new WeakMap;standardVertexAttributeCache=new WeakMap;geometryVertexBufferFastCache=new WeakMap;vertexAttributeGroupCache=new WeakMap;materialVertexAttributeCache=new WeakMap;vertexBufferBindingPlanCache=new WeakMap;vertexAttributeGroupBufferKeyCache=new WeakMap;compileDrawScratch=[];dynamicIndirectSubmissionCache=new WeakMap;indirectStreamKeyCache=new WeakMap;nextIndirectStreamKey=1;indirectBundleInvalidationVersion=0;colorFormatsIdentityCache=new WeakMap;colorFormatsValueCache=new Map([[qr,1]]);nextColorFormatsId=2;renderBundleScratch=[];indirectMaterialResourcesScratch=[];directBundleDrawStatsScratch={drawCallCount:0,triangleCount:0};sortedOpaqueBatchesScratch=[];opaqueBatchPool=[];opaqueBatchPoolCount=0;drawCallPool=[];drawCallPoolCount=0;staticDrawSets=[];materialPassStaticBundleCache=new WeakMap;staticDrawSetManager=new ji(this.state,this.staticDrawSets,e=>this.getGeometryResource(e),e=>this.resolveMaterial(e),(e,t)=>this.ensureWireframeIndex(e,t));staticFrameToken=0;hizResourceVersion=0;graphTextureResourceVersion=0;visibilityParamsUpload=new Uint32Array(4);drawMetadataUpload=new Float32Array(0);indirectDrawUpload=new Uint32Array(0);extractedAmbientScratch=new St;extractedHemisphereScratch=this.createExtractedHemisphereLightScratch();extractedBoundsMinScratch=new yt;extractedBoundsMaxScratch=new yt;extractedDirectionalLightsScratch=Array.from({length:4},()=>this.createExtractedDirectionalLightScratch());extractedPointLightsScratch=Array.from({length:jr},()=>this.createExtractedPointLightScratch());extractedSpotLightsScratch=Array.from({length:$r},()=>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(Jr);csmCascadeRanges=Array.from({length:4},()=>new bt);csmCascadeCount=0;csmCascadeLights=[];shadowCameraUniformScratch=new Float32Array(64);cameraViewProjScratch=new ft;cameraProjectionScratch=new ft;projectionJitterPixels=new bt;temporalVisibilityCurrentViewProj=new ft;temporalVisibilityPreviousViewProj=new ft;motionVectorProjection=new ft;motionVectorCurrentViewProj=new ft;motionVectorPreviousViewProj=new ft;motionVectorProjectionPending=!1;motionVectorHistoryValid=!1;motionVectorHistoryGeneration=1;lastMotionVectorTimeSeconds=Number.NaN;objectMotionHistory=new WeakMap;cameraFrustumPlanesScratch=new Float32Array(24);objectTraversalStackScratch=[];isSphereVisibleScratch=(e,t,r,n,i)=>!i||Kn(this.cameraFrustumPlanesScratch,e,t,r,n);updateExtractedBoundsFromMatrixScratch=e=>{const t=this.extractedBoundsMinScratch,r=this.extractedBoundsMaxScratch,n=e[12],i=e[13],a=e[14];n<t.x&&(t.x=n),i<t.y&&(t.y=i),a<t.z&&(t.z=a),n>r.x&&(r.x=n),i>r.y&&(r.y=i),a>r.z&&(r.z=a)};transparentSortCameraPositionScratch=new yt;transparentSortCameraForwardScratch=new yt;temporalVisibilityCurrentCameraPosition=new yt;temporalVisibilityPreviousCameraPosition=new yt;shadowViewProjScratch=new ft;extractionVersion=0;graphBuilder=(e,t)=>{t.addDirectionalShadowPass(),t.addPointShadowPass(),t.addSpotShadowPass(),t.addDepthPrepass(),t.addHiZPasses(),t.addVisibilityPass(),t.addForwardPass(),t.addPresentPass()};createExtractedDirectionalLightScratch(){return{sourceLight:null,position:new yt,target:new yt,direction:new yt,color:new yt,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 yt(0,1,0),skyColor:new yt,groundColor:new yt,intensity:0}}createExtractedPointLightScratch(){return{sourceLight:null,position:new yt,color:new yt,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 yt,direction:new yt(0,-1,0),color:new yt,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}}constructor(e){this.canvas=e.canvas,this.clearColor=[...e.clearColor??[0,0,0,1]],this.powerPreference=e.powerPreference,this.shadowMapSize=e.shadowMapSize??2048,this.pointShadowMapSize=e.pointShadowMapSize??1024,this.fallbackMaterial=e.fallbackMaterial??null,this.materialResolver=e.materialResolver,this.fallbackSkinnedMaterial=e.fallbackSkinnedMaterial??new _t({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:aa}),this.invokeObjectRenderCallbacks=e.invokeObjectRenderCallbacks??!0,this.state.directionalShadowTextureSize=this.shadowMapSize,this.state.pointShadowTextureSize=this.pointShadowMapSize,this.state.spotShadowTextureSize=this.shadowMapSize,this.sampleCount=ti(e.sampleCount),this.renderScale=la(e.renderScale),this.hiZOcclusionCullingEnabled=e.hiZOcclusionCulling??!1,this.multiDrawIndirectEnabled=e.multiDrawIndirect??!0,this.dynamicBatchingEnabled=e.dynamicBatching??!0,this.renderGraphProfilingEnabled=e.renderGraphProfiling??!1}resolveMaterial(e){if(!1===e?.visible)return null;if(e&&Ht(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)return!0;if(e instanceof Ct)return null!=e.uniforms.hology_depth_map||null!=e.uniforms.hology_scene_map;if(e instanceof _t)return e.requiresLatePass();return!1}(e)?"late":"opaque",n=this.materialResolver?.(e,r);"opaque"===r&&n?.requiresLatePass()&&(r="late",n=this.materialResolver?.(e,r));const i=void 0===n?this.fallbackMaterial:n;return this.resolvedMaterialFrameCache.set(e,{extractionVersion:this.extractionVersion,material:i}),void 0!==n?n:i}resolveLineMaterial(e){let t=this.lineMaterialCache.get(e);t||(t=new _t({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 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 ct(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:ut,depthTest:e.depthTest,depthWrite:e.depthWrite}),this.lineMaterialCache.set(e,t));const r=e,n=r.color;return n&&t.uniforms.color.value.copy(n),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 n=r.get(t);n||(n=new _t({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 ct(1,1,1),opacity:1},primitiveTopology:t,depthTest:e.depthTest,depthWrite:e.depthWrite}),r.set(t,n));const i=e;return i.color&&n.uniforms.color.value.copy(i.color),n.uniforms.opacity.value=i.opacity??1,n.transparent=e.transparent||(i.opacity??1)<1,n.depthTest=e.depthTest,n.depthWrite=e.depthWrite,n}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!==Lr.prototype.onBeforeRender||e.onAfterRender!==Lr.prototype.onAfterRender)}(e)}async initialize(){if(!("gpu"in navigator))throw new Error("WebGPU is not available in this browser.");const e=await navigator.gpu.requestAdapter({powerPreference:this.powerPreference});if(!e)throw new Error("A WebGPU adapter could not be created.");const t=[];e.features.has("indirect-first-instance")&&t.push("indirect-first-instance"),e.features.has("timestamp-query")&&t.push("timestamp-query"),e.features.has("texture-compression-bc")&&t.push("texture-compression-bc"),e.features.has("texture-compression-etc2")&&t.push("texture-compression-etc2"),e.features.has("texture-compression-astc")&&t.push("texture-compression-astc"),e.features.has("float32-filterable")&&t.push("float32-filterable"),e.features.has(ra)&&t.push(ra);const r=e.limits;this.state.device=await e.requestDevice({requiredFeatures:t,requiredLimits:{maxTextureArrayLayers:r.maxTextureArrayLayers,maxBufferSize:r.maxBufferSize,maxStorageBufferBindingSize:r.maxStorageBufferBindingSize,maxStorageBuffersPerShaderStage:r.maxStorageBuffersPerShaderStage}});let n=!1;if(this.state.device.addEventListener("uncapturederror",e=>{n||(console.error("Uncaptured WebGPU device error",e),n=!0)}),this.indirectFirstInstanceSupported=t.includes("indirect-first-instance"),this.timestampQuerySupported=t.includes("timestamp-query"),this.multiDrawIndirectSupported=t.includes(ra),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}),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"}}]}),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"}}]}),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"}}]}),this.state.visibleDepthSceneBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-visible-depth-scene-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),this.state.shadowBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-shadow-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),this.state.directShadowBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-direct-shadow-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),this.state.emptyBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-empty-layout",entries:[]}),this.state.skinningBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-skinning-layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),this.state.sceneTextureBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-scene-texture-layout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"non-filtering"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth"}}]}),this.state.residentSceneBindGroupVersion+=1,this.state.residentShadowBindGroupVersion+=1,this.state.fullscreenTextureBindGroupLayout=this.state.device.createBindGroupLayout({label:"renderer-fullscreen-texture-layout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}}]}),this.state.shadowComparisonSampler=this.state.device.createSampler({label:"renderer-shadow-comparison-sampler",compare:"less-equal",magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),this.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"}),this.state.hizCopyKernel=this.createComputeKernel({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"}}]}),this.state.hizReduceKernel=this.createComputeKernel({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"}}]}),this.state.visibilityKernel=this.createComputeKernel({label:"renderer-visibility-cull",code:"\nstruct RendererCameraUniforms {\n viewProj: mat4x4<f32>,\n cameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\nstruct RendererVisibilityParams {\n drawCount: u32,\n hizMipCount: u32,\n reserved0: u32,\n reserved1: u32,\n};\n\nstruct DrawMetadata {\n centerRadius: vec4<f32>,\n args0: vec4<f32>,\n extra: vec4<f32>,\n};\n\nstruct IndirectIndexedArgs {\n indexCount: u32,\n instanceCount: u32,\n firstIndex: u32,\n baseVertex: i32,\n firstInstance: u32,\n};\n\n@group(0) @binding(0) var<uniform> rendererCamera: RendererCameraUniforms;\n@group(0) @binding(1) var<uniform> visibilityParams: RendererVisibilityParams;\n@group(0) @binding(2) var drawMetaTextureSampler: sampler;\n@group(0) @binding(3) var hizTexture: texture_2d<f32>;\n@group(0) @binding(4) var<storage, read> drawMetadata: array<DrawMetadata>;\n@group(0) @binding(5) var<storage, read_write> indirectArgs: array<IndirectIndexedArgs>;\n\nfn saturate(value: f32) -> f32 {\n return clamp(value, 0.0, 1.0);\n}\n\nfn projectedSphereRadius(\n viewProj: mat4x4<f32>,\n ndc: vec3<f32>,\n clipW: f32,\n radius: f32,\n) -> vec2<f32> {\n // Account for both numerator and perspective-denominator variation over the\n // sphere. Offsetting along world X/Y is not conservative once the camera is\n // rotated because those axes can also change clip W.\n let rowX = vec3(viewProj[0].x, viewProj[1].x, viewProj[2].x);\n let rowY = vec3(viewProj[0].y, viewProj[1].y, viewProj[2].y);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let denominator = max(clipW - radius * length(rowW), 0.0001);\n return radius * vec2(\n length(rowX) + abs(ndc.x) * length(rowW),\n length(rowY) + abs(ndc.y) * length(rowW),\n ) / denominator;\n}\n\nfn spherePlaneRadius(viewProj: mat4x4<f32>, plane: vec4<f32>, radius: f32) -> f32 {\n let worldNormal = vec3(\n dot(viewProj[0], plane),\n dot(viewProj[1], plane),\n dot(viewProj[2], plane),\n );\n return radius * length(worldNormal);\n}\n\nfn isSphereInFrustum(viewProj: mat4x4<f32>, center: vec3<f32>, radius: f32) -> bool {\n let clip = viewProj * vec4(center, 1.0);\n return\n clip.w + clip.x >= -spherePlaneRadius(viewProj, vec4( 1.0, 0.0, 0.0, 1.0), radius) &&\n clip.w - clip.x >= -spherePlaneRadius(viewProj, vec4(-1.0, 0.0, 0.0, 1.0), radius) &&\n clip.w + clip.y >= -spherePlaneRadius(viewProj, vec4( 0.0, 1.0, 0.0, 1.0), radius) &&\n clip.w - clip.y >= -spherePlaneRadius(viewProj, vec4( 0.0, -1.0, 0.0, 1.0), radius) &&\n clip.z >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, 1.0, 0.0), radius) &&\n clip.w - clip.z >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, -1.0, 1.0), radius);\n}\n\nfn nearestSphereDepth(viewProj: mat4x4<f32>, clip: vec4<f32>, radius: f32) -> f32 {\n let rowZ = vec3(viewProj[0].z, viewProj[1].z, viewProj[2].z);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let minClipZ = clip.z - radius * length(rowZ);\n let maxClipW = clip.w + radius * length(rowW);\n return max(0.0, minClipZ / max(maxClipW, 0.0001));\n}\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let drawIndex = globalId.x;\n if (drawIndex >= visibilityParams.drawCount) {\n return;\n }\n\n let drawData = drawMetadata[drawIndex];\n let center = vec4(drawData.centerRadius.xyz, 1.0);\n let radius = drawData.centerRadius.w;\n var visible = isSphereInFrustum(\n rendererCamera.viewProj,\n drawData.centerRadius.xyz,\n radius,\n );\n\n let clip = rendererCamera.viewProj * center;\n let cameraDistance = distance(drawData.centerRadius.xyz, rendererCamera.cameraPosition.xyz);\n // A sphere that intersects the near plane, surrounds the camera, or has a\n // very large projected extent cannot be safely represented by its center.\n // Keep it rather than allowing a false negative to remove large terrain or\n // nearby geometry.\n let clipWRadius = radius * length(vec3(\n rendererCamera.viewProj[0].w,\n rendererCamera.viewProj[1].w,\n rendererCamera.viewProj[2].w,\n ));\n let needsConservativeVisibility =\n clip.w - clipWRadius <= 0.0001 || radius >= cameraDistance * 0.1;\n\n if (!needsConservativeVisibility) {\n let ndc = clip.xyz / clip.w;\n let projectedRadius = projectedSphereRadius(rendererCamera.viewProj, ndc, clip.w, radius);\n let clipRadiusX = projectedRadius.x;\n let clipRadiusY = projectedRadius.y;\n\n if (\n visible &&\n ndc.x - clipRadiusX >= -1.0 && ndc.x + clipRadiusX <= 1.0 &&\n ndc.y - clipRadiusY >= -1.0 && ndc.y + clipRadiusY <= 1.0\n ) {\n let uvCenter = ndc.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n let uvRadius = vec2(clipRadiusX, clipRadiusY) * 0.5;\n let viewport = rendererCamera.viewportAndTime.xy;\n let screenDiameter = max(\n max(clipRadiusX * viewport.x * 0.5, clipRadiusY * viewport.y * 0.5),\n 1.0,\n ) * 2.0;\n let maxMipLevel = max(f32(visibilityParams.hizMipCount) - 1.0, 0.0);\n // Round up from the full diameter. Using floor(log2(radius)) leaves\n // unsampled texels between the corner probes, especially for small\n // objects, and can turn partial coverage into a false occlusion.\n let mipLevel = clamp(ceil(log2(screenDiameter)), 0.0, maxMipLevel);\n // Cover the projected bounds rather than testing only their center. The\n // max-reduced pyramid makes background or a gap at any corner retain the\n // draw, avoiding false occlusion for partially covered objects.\n let hizDepth = max(\n max(\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2(-uvRadius.x, -uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2( uvRadius.x, -uvRadius.y), mipLevel).r,\n ),\n max(\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2(-uvRadius.x, uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, drawMetaTextureSampler, uvCenter + vec2( uvRadius.x, uvRadius.y), mipLevel).r,\n ),\n );\n let conservativeDepth = nearestSphereDepth(rendererCamera.viewProj, clip, radius);\n visible = conservativeDepth <= hizDepth + 0.0005;\n }\n }\n\n let baseVertex = i32(round(drawData.extra.y));\n indirectArgs[drawIndex].indexCount = u32(round(drawData.args0.x));\n indirectArgs[drawIndex].instanceCount = select(0u, u32(round(drawData.args0.w)), visible);\n indirectArgs[drawIndex].firstIndex = u32(round(drawData.args0.y));\n indirectArgs[drawIndex].baseVertex = baseVertex;\n indirectArgs[drawIndex].firstInstance = u32(round(drawData.args0.z));\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.COMPUTE,sampler:{type:"non-filtering"}},{binding:3,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:5,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}),this.state.staticVisibilityClearKernel=this.createComputeKernel({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 atomicStore(&visibleInstanceMask[index], 0u);\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"}}]}),this.state.staticVisibilityCullKernel=this.createComputeKernel({label:"renderer-static-visibility-cull",code:"\nstruct RendererTemporalVisibilityUniforms {\n currentViewProj: mat4x4<f32>,\n previousViewProj: mat4x4<f32>,\n currentCameraPosition: vec4<f32>,\n previousCameraPosition: vec4<f32>,\n viewportAndTime: vec4<f32>,\n};\n\nstruct RendererVisibilityParams {\n drawCount: u32,\n hizMipCount: u32,\n instanceCount: u32,\n flags: u32,\n};\n\nstruct DrawMetadata {\n centerRadius: vec4<f32>,\n args0: vec4<f32>,\n extra: vec4<f32>,\n};\n\nstruct StaticInstanceMetadata {\n centerRadius: vec4<f32>,\n drawAndSourceIndex: vec4<u32>,\n};\n\n@group(0) @binding(0) var<uniform> temporalVisibility: RendererTemporalVisibilityUniforms;\n@group(0) @binding(1) var<uniform> visibilityParams: RendererVisibilityParams;\n@group(0) @binding(2) var hizSampler: sampler;\n@group(0) @binding(3) var hizTexture: texture_2d<f32>;\n@group(0) @binding(4) var<storage, read> instanceMetadata: array<StaticInstanceMetadata>;\n@group(0) @binding(5) var<storage, read> drawMetadata: array<DrawMetadata>;\n@group(0) @binding(6) var<storage, read_write> visibleCounts: array<atomic<u32>>;\n@group(0) @binding(7) var<storage, read_write> visibleInstanceIndices: array<u32>;\n@group(0) @binding(8) var<storage, read_write> visibleInstanceMask: array<atomic<u32>>;\n@group(0) @binding(9) var<storage, read_write> postVisibleCounts: array<atomic<u32>>;\n\nfn spherePlaneRadius(viewProj: mat4x4<f32>, plane: vec4<f32>, radius: f32) -> f32 {\n let worldNormal = vec3(\n dot(viewProj[0], plane),\n dot(viewProj[1], plane),\n dot(viewProj[2], plane),\n );\n return radius * length(worldNormal);\n}\n\nfn projectedSphereRadius(\n viewProj: mat4x4<f32>,\n ndc: vec3<f32>,\n clipW: f32,\n radius: f32,\n) -> vec2<f32> {\n let rowX = vec3(viewProj[0].x, viewProj[1].x, viewProj[2].x);\n let rowY = vec3(viewProj[0].y, viewProj[1].y, viewProj[2].y);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let denominator = max(clipW - radius * length(rowW), 0.0001);\n return radius * vec2(\n length(rowX) + abs(ndc.x) * length(rowW),\n length(rowY) + abs(ndc.y) * length(rowW),\n ) / denominator;\n}\n\nfn nearestSphereDepth(viewProj: mat4x4<f32>, clip: vec4<f32>, radius: f32) -> f32 {\n let rowZ = vec3(viewProj[0].z, viewProj[1].z, viewProj[2].z);\n let rowW = vec3(viewProj[0].w, viewProj[1].w, viewProj[2].w);\n let minClipZ = clip.z - radius * length(rowZ);\n let maxClipW = clip.w + radius * length(rowW);\n return max(0.0, minClipZ / max(maxClipW, 0.0001));\n}\n\nfn isSphereInFrustum(\n viewProj: mat4x4<f32>,\n center: vec3<f32>,\n radius: f32,\n) -> bool {\n let clip = viewProj * vec4(center, 1.0);\n let left = clip.w + clip.x;\n let right = clip.w - clip.x;\n let bottom = clip.w + clip.y;\n let top = clip.w - clip.y;\n let near = clip.z;\n let far = clip.w - clip.z;\n\n return\n left >= -spherePlaneRadius(viewProj, vec4(1.0, 0.0, 0.0, 1.0), radius) &&\n right >= -spherePlaneRadius(viewProj, vec4(-1.0, 0.0, 0.0, 1.0), radius) &&\n bottom >= -spherePlaneRadius(viewProj, vec4(0.0, 1.0, 0.0, 1.0), radius) &&\n top >= -spherePlaneRadius(viewProj, vec4(0.0, -1.0, 0.0, 1.0), radius) &&\n near >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, 1.0, 0.0), radius) &&\n far >= -spherePlaneRadius(viewProj, vec4(0.0, 0.0, -1.0, 1.0), radius);\n}\n\nfn isSphereNearFrustumBoundary(\n viewProj: mat4x4<f32>,\n center: vec3<f32>,\n radius: f32,\n) -> bool {\n let clip = viewProj * vec4(center, 1.0);\n return\n clip.w + clip.x <= spherePlaneRadius(viewProj, vec4(1.0, 0.0, 0.0, 1.0), radius) ||\n clip.w - clip.x <= spherePlaneRadius(viewProj, vec4(-1.0, 0.0, 0.0, 1.0), radius) ||\n clip.w + clip.y <= spherePlaneRadius(viewProj, vec4(0.0, 1.0, 0.0, 1.0), radius) ||\n clip.w - clip.y <= spherePlaneRadius(viewProj, vec4(0.0, -1.0, 0.0, 1.0), radius) ||\n clip.z <= spherePlaneRadius(viewProj, vec4(0.0, 0.0, 1.0, 0.0), radius) ||\n clip.w - clip.z <= spherePlaneRadius(viewProj, vec4(0.0, 0.0, -1.0, 1.0), radius);\n}\n\nfn isSphereVisible(center: vec3<f32>, radius: f32) -> bool {\n let currentViewProj = temporalVisibility.currentViewProj;\n if (!isSphereInFrustum(currentViewProj, center, radius)) {\n return false;\n }\n\n let clip = currentViewProj * vec4(center, 1.0);\n // Near-plane intersections are deliberately kept. A false negative here would\n // incorrectly remove geometry surrounding the camera.\n if (clip.w <= 0.0001) {\n return true;\n }\n\n if ((visibilityParams.flags & 1u) == 0u) {\n return true;\n }\n\n let usesPreviousHiZ = (visibilityParams.flags & 2u) != 0u;\n var hizViewProj = temporalVisibility.currentViewProj;\n var hizCameraPosition = temporalVisibility.currentCameraPosition.xyz;\n if (usesPreviousHiZ) {\n hizViewProj = temporalVisibility.previousViewProj;\n hizCameraPosition = temporalVisibility.previousCameraPosition.xyz;\n }\n\n let hizClip = hizViewProj * vec4(center, 1.0);\n let hizClipWRadius = radius * length(vec3(\n hizViewProj[0].w,\n hizViewProj[1].w,\n hizViewProj[2].w,\n ));\n if (hizClip.w - hizClipWRadius <= 0.0001) {\n return true;\n }\n let hizNdc = hizClip.xyz / hizClip.w;\n let hizProjectedRadius = projectedSphereRadius(\n hizViewProj,\n hizNdc,\n hizClip.w,\n radius,\n );\n let hizClipRadiusX = hizProjectedRadius.x;\n let hizClipRadiusY = hizProjectedRadius.y;\n let hizClipRadiusZ = radius / max(distance(center, hizCameraPosition), 0.001);\n\n // Samples close to the viewport boundary cannot cover the whole projected\n // sphere. This also retains newly revealed regions during camera motion.\n if (\n isSphereNearFrustumBoundary(hizViewProj, center, radius) ||\n hizNdc.x - hizClipRadiusX < -1.0 || hizNdc.x + hizClipRadiusX > 1.0 ||\n hizNdc.y - hizClipRadiusY < -1.0 || hizNdc.y + hizClipRadiusY > 1.0 ||\n hizNdc.z < -hizClipRadiusZ || hizNdc.z > 1.0 + hizClipRadiusZ\n ) {\n return true;\n }\n\n let viewport = temporalVisibility.viewportAndTime.xy;\n let screenDiameter = max(\n max(hizClipRadiusX * viewport.x * 0.5, hizClipRadiusY * viewport.y * 0.5),\n 1.0,\n ) * 2.0;\n let maxMipLevel = max(f32(visibilityParams.hizMipCount) - 1.0, 0.0);\n let mipLevel = clamp(ceil(log2(screenDiameter)), 0.0, maxMipLevel);\n let uvCenter = hizNdc.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);\n let uvRadius = vec2(hizClipRadiusX, hizClipRadiusY) * 0.5;\n let hizDepth = max(\n max(\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2(-uvRadius.x, -uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2( uvRadius.x, -uvRadius.y), mipLevel).r,\n ),\n max(\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2(-uvRadius.x, uvRadius.y), mipLevel).r,\n textureSampleLevel(hizTexture, hizSampler, uvCenter + vec2( uvRadius.x, uvRadius.y), mipLevel).r,\n ),\n );\n let conservativeNearestDepth = nearestSphereDepth(hizViewProj, hizClip, radius);\n return conservativeNearestDepth <= hizDepth + 0.001;\n}\n\n@compute @workgroup_size(64, 1, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3<u32>) {\n let instanceIndex = globalId.x;\n if (instanceIndex >= visibilityParams.instanceCount) {\n return;\n }\n\n let instance = instanceMetadata[instanceIndex];\n if ((visibilityParams.flags & 4u) != 0u && atomicLoad(&visibleInstanceMask[instanceIndex]) != 0u) {\n return;\n }\n let drawIndex = instance.drawAndSourceIndex.x;\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 atomicStore(&visibleInstanceMask[instanceIndex], 1u);\n }\n let firstInstance = u32(round(drawMetadata[drawIndex].args0.z));\n if (isPostpass) {\n let primaryVisibleCount = atomicLoad(&visibleCounts[drawIndex]);\n let postVisibleIndex = atomicAdd(&postVisibleCounts[drawIndex], 1u);\n visibleInstanceIndices[firstInstance + primaryVisibleCount + postVisibleIndex] = instance.drawAndSourceIndex.y;\n } else {\n let visibleIndex = atomicAdd(&visibleCounts[drawIndex], 1u);\n visibleInstanceIndices[firstInstance + visibleIndex] = instance.drawAndSourceIndex.y;\n }\n}\n",bindGroupLayoutEntries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.COMPUTE,sampler:{type:"non-filtering"}},{binding:3,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:5,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:6,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:7,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:8,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:9,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}),this.state.staticVisibilityIndirectBuildKernel=this.createComputeKernel({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"}}]}),this.state.visibilityParamsBuffer=this.state.device.createBuffer({label:"renderer-visibility-params-buffer",size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.createStaticPipelines(),this.setSize(this.canvas.clientWidth||this.canvas.width||1,this.canvas.clientHeight||this.canvas.height||1),this.state.initialized=!0}createComputeKernel(t){if(!this.state.device)throw new Error("WebGpuRenderer.initialize() must complete before creating compute kernels.");return new e(this.state.device,t)}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)}setRenderGraphProfilingEnabled(e){this.renderGraphProfilingEnabled=e}getRenderGraphProfilingEnabled(){return this.renderGraphProfilingEnabled}getTimestampQuerySupported(){return this.timestampQuerySupported}getSampleCount(){return this.sampleCount}setSampleCount(e){const t=ti(e);t!==this.sampleCount&&(this.sampleCount=t,this.destroyMsaaResources(),this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches())}setRenderScale(e){const t=la(e);if(t===this.renderScale)return;this.renderScale=t;const r=this.state.pixelRatio;this.setSize(this.state.presentationWidth/r,this.state.presentationHeight/r,r)}getRenderScale(){return this.renderScale}setProjectionJitter(e,t){if(!Number.isFinite(e)||!Number.isFinite(t))throw new RangeError("Projection jitter must contain finite pixel offsets.");this.projectionJitterPixels.set(e,t)}clearProjectionJitter(){this.projectionJitterPixels.set(0,0)}setMotionVectorProjection(e){this.motionVectorProjection.copy(e),this.motionVectorProjectionPending=!0}invalidateObjectMotion(e){this.objectMotionHistory.delete(e)}getLastFrameProfile(){const e=this.state.latestFrameProfile?.timestampQueryActive&&null===this.state.latestFrameProfile.gpuTimeMs&&this.state.latestCompletedFrameProfile?this.state.latestCompletedFrameProfile:this.state.latestFrameProfile;return e?{...e,cpuPhases:{...e.cpuPhases},passes:e.passes.map(e=>({...e})),visibility:e.visibility?{...e.visibility}:null}:null}resetViewHistory(){this.state.temporalHiZHistoryValid=!1,this.motionVectorHistoryValid=!1,this.motionVectorHistoryGeneration+=1}setHiZOcclusionCullingEnabled(e){this.hiZOcclusionCullingEnabled!==e&&(this.state.temporalHiZHistoryValid=!1),this.hiZOcclusionCullingEnabled=e}getHiZOcclusionCullingEnabled(){return this.hiZOcclusionCullingEnabled}getHiZOcclusionCullingActive(){return this.hiZOcclusionCullingEnabled&&this.indirectFirstInstanceSupported}setMultiDrawIndirectEnabled(e){this.multiDrawIndirectEnabled=e}getMultiDrawIndirectEnabled(){return this.multiDrawIndirectEnabled}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,n="presentation"===t.resolution?this.state.presentationHeight:this.state.height,i=Math.max(1,Math.floor(r*t.scale)),a=Math.max(1,Math.floor(n*t.scale));t.width===i&&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:qr,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:Kr,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:qr,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),this.state.postProcessColorView=this.state.postProcessColorTexture.createView(),this.state.sceneTextureBindGroupLayout&&this.state.linearClampSampler&&this.state.nearestClampSampler&&(this.state.sceneTextureBindGroup=this.state.device.createBindGroup({label:"renderer-scene-texture-bind-group",layout:this.state.sceneTextureBindGroupLayout,entries:[{binding:0,resource:this.state.linearClampSampler},{binding:1,resource:this.state.sceneColorSnapshotView},{binding:2,resource:this.state.nearestClampSampler},{binding:3,resource:this.state.sceneDepthSnapshotView}]})),this.state.hizTexture?.destroy(),this.state.hizMipCount=Math.max(1,Math.floor(Math.log2(Math.max(this.state.width,this.state.height)))+1),this.state.hizTexture=this.state.device.createTexture({label:"renderer-hiz-pyramid",size:{width:this.state.width,height:this.state.height},format:"r32float",mipLevelCount:this.state.hizMipCount,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING}),this.state.hizView=this.state.hizTexture.createView(),this.state.hizMipViews=[],this.state.hizCopyBindGroup=null,this.state.hizReduceBindGroups=[],this.state.visibilityBindGroup=null,this.state.visibilityBindGroupMetadataResource=null;for(let e=0;e<this.state.hizMipCount;e+=1)this.state.hizMipViews.push(this.state.hizTexture.createView({baseMipLevel:e,mipLevelCount:1}));this.hizResourceVersion+=1,this.graphTextureResourceVersion+=1,this.state.temporalHiZHistoryValid=!1,this.motionVectorHistoryValid=!1,this.motionVectorHistoryGeneration+=1;for(const e of this.staticDrawSets)e.visibilityBindGroup=null,e.postVisibilityBindGroup=null,e.visibilityBindGroupHizVersion=0;this.recreateShadowResources()}}setClearColor(e){this.clearColor[0]=e[0],this.clearColor[1]=e[1],this.clearColor[2]=e[2],this.clearColor[3]=e[3]}render(e,t,r=.001*performance.now()){this.renderFrame(e,t,r,!1)}async renderAsync(e,t,r=.001*performance.now()){await this.renderFrame(e,t,r,!0)}compile(e,t){this.prepareSceneForCompilation(e,t,!1)}async compileAsync(e,t){this.state.initialized||await this.initialize(),await this.prepareSceneForCompilation(e,t,!0)}createPMREMGenerator(e=20){if(!this.state.device)throw new Error("WebGpuRenderer.initialize() must complete before creating a PMREM generator.");return new lr({device:this.state.device,getTextureResource:e=>this.getTextureResource(e),registerTextureResource:(e,t)=>this.textureCache.set(e,t)},e)}initTexture(e){this.textureManager.getTextureResource(e)}createStaticDrawSet(e,t={}){return this.staticDrawSetManager.createStaticDrawSet(e,t)}disposeStaticDrawSetResource(e){this.staticDrawSetManager.disposeStaticDrawSetResource(e)}renderFrame(e,t,r,n){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 i=r-this.lastMotionVectorTimeSeconds;Number.isFinite(this.lastMotionVectorTimeSeconds)&&(!Number.isFinite(i)||i<=0||i>.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();const a=performance.now(),s=this.extractScene(e,t);for(const e of s.gpuOpaqueDraws)this.prepareDrawGeometryVertexBuffers(e);for(const e of s.directOpaqueDraws)this.prepareDrawGeometryVertexBuffers(e);for(const e of s.transparentDraws)this.prepareDrawGeometryVertexBuffers(e);this.ensureShadowTextureSizes(s);const o=performance.now()-a,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.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,n,i){if(!t.renderGraphProfilingEnabled||!e.device)return null;const a={frameIndex:e.frameIndex+=1,cpuTimeMs:0,gpuTimeMs:null,drawCallCount:n.drawCallCount,triangleCount:n.triangleCount,cpuPhases:{extractSceneMs:i.extractSceneMs,uploadMs:i.uploadMs,renderGraphMs:0},passes:[],timestampQuerySupported:t.timestampQuerySupported,timestampQueryActive:t.timestampQuerySupported,gpuProfilingReason:null,hiZOcclusionCullingEnabled:t.hiZOcclusionCullingEnabled,hiZOcclusionCullingActive:r,visibility:null};let s=null;const o={begin:(e,r)=>{if(a.passes=e.map(e=>({name:e.name,cpuTimeMs:0,gpuTimeMs:null})),!t.timestampQuerySupported)return a.timestampQueryActive=!1,void(a.gpuProfilingReason="timestamp-query is not supported by this adapter/device");if(0===e.length)return a.timestampQueryActive=!1,void(a.gpuProfilingReason="no render graph passes were recorded");const n=2*e.length,i=Math.max(8,8*n),o=r.device.createQuerySet({label:`renderer-frame-profile-${a.frameIndex}`,type:"timestamp",count:n}),l=r.device.createBuffer({label:`renderer-frame-profile-resolve-${a.frameIndex}`,size:i,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),c=r.device.createBuffer({label:`renderer-frame-profile-read-${a.frameIndex}`,size:i,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});s={profile:a,querySet:o,resolveBuffer:l,readBuffer:c,queryCount:n}},beforePass:(e,t,r)=>{s&&(yn(r.encoder,s.querySet,{endOfPassWriteIndex:2*t})||(a.timestampQueryActive=!1,a.gpuProfilingReason="timestampWrites marker pass is not available on this browser/runtime",s.querySet.destroy(),s.resolveBuffer.destroy(),s.readBuffer.destroy(),s=null))},afterPass:(e,t,r,n)=>{a.passes[t].cpuTimeMs=r,s&&(yn(n.encoder,s.querySet,{beginningOfPassWriteIndex:2*t+1})||(a.timestampQueryActive=!1,a.gpuProfilingReason="timestampWrites marker pass is not available on this browser/runtime",s.querySet.destroy(),s.resolveBuffer.destroy(),s.readBuffer.destroy(),s=null))},end:(t,r,i)=>{if(a.cpuPhases.renderGraphMs=r,a.cpuTimeMs=a.cpuPhases.extractSceneMs+a.cpuPhases.uploadMs+a.cpuPhases.renderGraphMs,a.drawCallCount=n.drawCallCount,a.triangleCount=n.triangleCount,!s){const t=si(a);return e.latestFrameProfile=t,void(e.latestCompletedFrameProfile=t)}i.encoder.resolveQuerySet(s.querySet,0,s.queryCount,s.resolveBuffer,0),i.encoder.copyBufferToBuffer(s.resolveBuffer,0,s.readBuffer,0,8*s.queryCount),e.latestFrameProfile=si(a)}};return{profile:a,observer:o,pendingVisibilityRead:null,get pendingGpuRead(){return s},set pendingGpuRead(e){s=e}}}(this.state,{renderGraphProfilingEnabled:this.renderGraphProfilingEnabled,timestampQuerySupported:this.timestampQuerySupported,hiZOcclusionCullingEnabled:this.hiZOcclusionCullingEnabled},u,l,{extractSceneMs:o,uploadMs:d}),y=()=>{if(!b||!u)return;const e=[];v&&v.count>0&&e.push({buffer:v.indirectBuffer,drawCount:v.count,totalInstances:s.gpuOpaqueDraws.reduce((e,t)=>e+Math.max(0,t.instanceCount),0),kind:"dynamic"});for(const t of this.staticDrawSets)t.publicSet.enabled&&t.lastVisibilityFrameToken===this.staticFrameToken&&e.push({buffer:t.drawMetadataResource.indirectBuffer,drawCount:t.drawMetadataResource.count,totalInstances:t.instanceCount,kind:"static"});!function(e,t,r,n){const i=n.filter(e=>e.drawCount>0);if(0===i.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=i.map(e=>{const t={byteOffset:a,drawCount:e.drawCount,totalInstances:e.totalInstances,kind:e.kind};return a+=5*e.drawCount*Uint32Array.BYTES_PER_ELEMENT,t}),o=t.createBuffer({label:`renderer-visibility-profile-read-${e.profile.frameIndex}`,size:Math.max(4,a),usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});for(let e=0;e<i.length;e+=1){const t=i[e];r.copyBufferToBuffer(t.buffer,0,o,s[e].byteOffset,5*t.drawCount*Uint32Array.BYTES_PER_ELEMENT)}e.pendingVisibilityRead={readBuffer:o,regions:s}}(b,this.state.device,h,e)};if(n)return this.renderGraph.executeAsync(w,b?.observer).then(()=>{y(),this.state.device.queue.submit([h.finish()]),this.commitTemporalHiZHistory(),this.releaseRetiredGeometryResourcesAfterSubmit(),b&&ni(this.state,b)});this.renderGraph.execute(w,b?.observer),y(),this.state.device.queue.submit([h.finish()]),this.commitTemporalHiZHistory(),this.releaseRetiredGeometryResourcesAfterSubmit(),b&&ni(this.state,b)}destroy(){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.state.sceneDepthSnapshotTexture?.destroy(),this.state.postProcessColorTexture?.destroy(),this.state.directionalShadowTexture?.destroy(),this.state.pointShadowTexture?.destroy(),this.state.pointShadowDepthTexture?.destroy(),this.state.spotShadowTexture?.destroy(),this.state.hizTexture?.destroy(),this.state.cameraBuffer?.destroy(),this.state.temporalVisibilityBuffer?.destroy(),this.state.lightBuffer?.destroy(),this.state.shadowCameraBuffer?.destroy();for(const e of this.state.shadowCameraBufferPool)e.destroy();this.state.shadowCameraBufferPool.length=0,this.state.sharedShadowBindGroupByCameraBuffer.clear(),this.state.instanceBuffer?.destroy();for(const e of this.defaultInstanceAttributeBuffers.values())for(const t of e.values())t.destroy();this.defaultInstanceAttributeBuffers.clear(),this.state.visibilityParamsBuffer?.destroy(),this.state.drawMetadataResource?.metadataBuffer.destroy(),this.state.drawMetadataResource?.indirectBuffer.destroy(),this.state.drawMetadataResource?.postIndirectBuffer.destroy(),this.state.initialized=!1,this.state.device?.destroy(),this.state.device=null}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=this.state.device.createPipelineLayout({label:"renderer-depth-prepass-layout",bindGroupLayouts:[this.state.sceneBindGroupLayout]});this.state.depthPrepassPipeline=this.state.device.createRenderPipeline({label:"renderer-depth-prepass-pipeline",layout:e,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"}});const t=this.state.device.createPipelineLayout({label:"renderer-depth-prepass-visible-layout",bindGroupLayouts:[this.state.visibleDepthSceneBindGroupLayout]});this.state.depthPrepassPipelineVisible=this.state.device.createRenderPipeline({label:"renderer-depth-prepass-visible-pipeline",layout:t,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"}});const r=this.state.device.createPipelineLayout({label:"renderer-depth-prepass-direct-layout",bindGroupLayouts:[this.state.directSceneBindGroupLayout]});this.state.depthPrepassPipelineDirect=this.state.device.createRenderPipeline({label:"renderer-depth-prepass-direct-pipeline",layout:r,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"}});const n=this.state.device.createPipelineLayout({label:"renderer-skinned-depth-prepass-layout",bindGroupLayouts:[this.state.sceneBindGroupLayout,this.state.emptyBindGroupLayout,this.state.skinningBindGroupLayout]});this.state.skinnedDepthPrepassPipeline=this.state.device.createRenderPipeline({label:"renderer-skinned-depth-prepass-pipeline",layout:n,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-depth-prepass-module",code:qi}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(en)},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}});const i=this.state.device.createPipelineLayout({label:"renderer-shadow-layout",bindGroupLayouts:[this.state.shadowBindGroupLayout]}),a=this.state.device.createPipelineLayout({label:"renderer-direct-shadow-pipeline-layout",bindGroupLayouts:[this.state.directShadowBindGroupLayout]});this.state.shadowDepthPipeline=this.state.device.createRenderPipeline({label:"renderer-directional-shadow-pipeline",layout:i,vertex:{module:this.state.device.createShaderModule({label:"renderer-directional-shadow-module",code:"\nstruct ShadowCameraUniforms {\n viewProj: mat4x4<f32>,\n lightPositionRange: vec4<f32>,\n};\n\nstruct RendererInstanceData {\n model0: vec4<f32>,\n model1: vec4<f32>,\n model2: vec4<f32>,\n model3: vec4<f32>,\n color: vec4<f32>,\n batching: vec4<f32>,\n previousModel0: vec4<f32>,\n previousModel1: vec4<f32>,\n previousModel2: vec4<f32>,\n previousModel3: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> shadowCamera: ShadowCameraUniforms;\n@group(0) @binding(1) var<storage, read> rendererInstances: array<RendererInstanceData>;\n\nfn rendererInstanceModelMatrix(instanceIndex: u32) -> mat4x4<f32> {\n let instance = rendererInstances[instanceIndex];\n return mat4x4<f32>(instance.model0, instance.model1, instance.model2, instance.model3);\n}\n\n@vertex\nfn vsMain(\n @location(0) position: vec3<f32>,\n @builtin(instance_index) instanceIndex: u32\n) -> @builtin(position) @invariant vec4<f32> {\n let world = rendererInstanceModelMatrix(instanceIndex) * vec4(position, 1.0);\n return shadowCamera.viewProj * world;\n}\n"}),entryPoint:"vsMain",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"front",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}}),this.state.shadowDepthPipelineDirect=this.state.device.createRenderPipeline({label:"renderer-directional-shadow-direct-pipeline",layout:a,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}});const s=this.state.device.createPipelineLayout({label:"renderer-skinned-shadow-layout",bindGroupLayouts:[this.state.shadowBindGroupLayout,this.state.emptyBindGroupLayout,this.state.skinningBindGroupLayout]});this.state.skinnedShadowDepthPipeline=this.state.device.createRenderPipeline({label:"renderer-skinned-directional-shadow-pipeline",layout:s,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-directional-shadow-module",code:Ki}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(en)},primitive:{topology:"triangle-list",cullMode:"front",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}}),this.state.pointShadowPipeline=this.state.device.createRenderPipeline({label:"renderer-point-shadow-pipeline",layout:i,vertex:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-module",code:Wi}),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:Wi}),entryPoint:"fsMain",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}),this.state.pointShadowPipelineDirect=this.state.device.createRenderPipeline({label:"renderer-point-shadow-direct-pipeline",layout:a,vertex:{module:this.state.device.createShaderModule({label:"renderer-point-shadow-direct-module",code:_i}),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:_i}),entryPoint:"fsMain",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}),this.state.skinnedPointShadowPipeline=this.state.device.createRenderPipeline({label:"renderer-skinned-point-shadow-pipeline",layout:s,vertex:{module:this.state.device.createShaderModule({label:"renderer-skinned-point-shadow-module",code:Zi}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(en)},fragment:{module:this.state.device.createShaderModule({label:"renderer-skinned-point-shadow-fragment-module",code:Zi}),entryPoint:"fsMain",targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back",frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}});const o=this.state.device.createPipelineLayout({label:"renderer-present-layout",bindGroupLayouts:[this.state.fullscreenTextureBindGroupLayout]});this.state.presentPipeline=this.state.device.createRenderPipeline({label:"renderer-present-pipeline",layout:o,vertex:{module:this.state.device.createShaderModule({label:"renderer-present-module",code:Yi}),entryPoint:"vsMain"},fragment:{module:this.state.device.createShaderModule({label:"renderer-present-fragment-module",code:Yi}),entryPoint:"fsMain",targets:[{format:this.state.format}]},primitive:{topology:"triangle-list"}});const l=this.state.device.createShaderModule({label:"renderer-scene-color-snapshot-module",code:"\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 // Opaque scene alpha stores the two-bit material flags (0..3). Encode the\n // integer range into normalized alpha so rgba8unorm does not clamp flags\n // 2 and 3 to 1. Late materials decode this channel before testing flags.\n return vec4(clamp(source.rgb, vec3(0.0), vec3(1.0)), clamp(source.a / 3.0, 0.0, 1.0));\n }\n"});this.state.sceneColorSnapshotPipeline=this.state.device.createRenderPipeline({label:"renderer-scene-color-snapshot-pipeline",layout:o,vertex:{module:l,entryPoint:"vsMain"},fragment:{module:l,entryPoint:"fsMain",targets:[{format:Kr}]},primitive:{topology:"triangle-list"}})}recreateShadowResources(){if(this.state.device){this.state.residentSceneBindGroupVersion+=1,this.state.sharedSceneBindGroup=null,this.clearIndirectBundleCache(),this.clearStaticDrawSetBundleCaches(),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}));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}))}}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))),n=Math.max(this.shadowMapSize,...e.lights.spots.map(e=>Math.ceil(e.shadowMapSize)));t===this.state.directionalShadowTextureSize&&r===this.state.pointShadowTextureSize&&n===this.state.spotShadowTextureSize||(this.state.directionalShadowTextureSize=t,this.state.pointShadowTextureSize=r,this.state.spotShadowTextureSize=n,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,n=t.resolution??"render",i=t.format??qr,a="presentation"===n?this.state.presentationWidth:this.state.width,s="presentation"===n?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===i&&c.width===o&&c.height===l&&c.scale===r&&c.resolution===n)return c;c?.texture.destroy();const u=this.state.device.createTexture({label:`renderer-color-target-${e}`,size:{width:o,height:l},format:i,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),d={name:e,format:i,width:o,height:l,scale:r,resolution:n,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),n=this.msaaColorTargetCache.get(e);if(n&&n.format===r&&n.width===t.width&&n.height===t.height&&1===n.scale)return n;n?.texture.destroy();const i=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:i,view:i.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}`,n=this.msaaDepthTargetCache.get(r);if(n&&n.width===e&&n.height===t&&n.sampleCount===this.sampleCount)return n;n?.texture.destroy();const i=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:i,view:i.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,n=t.resolution??"render",i="presentation"===n?this.state.presentationWidth:this.state.width,a="presentation"===n?this.state.presentationHeight:this.state.height,s=Math.max(1,Math.floor(i*r)),o=Math.max(1,Math.floor(a*r)),l=Math.max(1,t.depthOrArrayLayers??1),c=t.format??qr,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===n&&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:n,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 qr;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(),n=[];for(const e in r){const t=r[e].resource;n.includes(t)||n.push(t)}return this.materialGraphTextureReadCache.set(e,{materialVersion:e.version,resources:n}),n}createGraphBuilderContext(e,t,r,n,i,a,s,o,l){let c=!1,u=!1;const d=e=>{const t=new Set;for(let r=0;r<e.length;r+=1){const n=this.getMaterialGraphTextureReads(e[r].material);for(let e=0;e<n.length;e+=1)t.add(n[e])}return Array.from(t)},h={device:this.state.device,encoder:t,camera:s.camera,sceneColorView:this.state.sceneColorView,postProcessColorView:this.state.postProcessColorView,presentationColorView:a,depthView:this.state.mainDepthView,colorFormat:qr,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],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))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}}};return{fogVolumeObjects:s.fogVolumeObjects,extractedLights:s.lights,addDirectionalShadowPass:()=>{e.addPass(new yr("DirectionalShadowPass",()=>{this.executeDirectionalShadowPass(t,n,s,o)},{writes:["directionalShadow"]}))},addPointShadowPass:()=>{s.lights.points.some(e=>e.castShadow)&&e.addPass(new yr("PointShadowPass",()=>{this.executePointShadowPass(t,n,s,o)},{writes:["pointShadow"]}))},addSpotShadowPass:()=>{s.lights.spots.some(e=>e.castShadow)&&e.addPass(new yr("SpotShadowPass",()=>{this.executeSpotShadowPass(t,n,s,o)},{writes:["spotShadow"]}))},addDepthPrepass:()=>{c=!0,this.getHiZOcclusionCullingActive()&&this.hasEnabledStaticDrawSets()&&e.addPass(new yr("TemporalStaticVisibilityPrepass",()=>{this.executeStaticVisibilityPasses(t,"prepass")},{reads:["hiz"],writes:["staticIndirectArgs"]})),e.addPass(new yr("DepthPrepass",()=>{this.executeDepthPrepass(t,r,s,o)},{writes:["mainDepth"]}))},addHiZPasses:()=>{this.getHiZOcclusionCullingActive()&&e.addPass(new yr("HiZPasses",()=>{this.executeHiZPasses(t)},{reads:["mainDepth"],writes:["hiz"]}))},addVisibilityPass:()=>{this.getHiZOcclusionCullingActive()&&(i||this.hasEnabledStaticDrawSets())&&(e.addPass(new yr("VisibilityPass",()=>{i&&this.executeVisibilityPass(t,i),this.executeStaticVisibilityPasses(t,"postpass")},{reads:["hiz"],writes:["indirectArgs","staticIndirectArgs"]})),this.sampleCount>1&&this.hasEnabledStaticDrawSets()&&e.addPass(new yr("TemporalStaticDepthResolvePass",()=>{this.executeStaticTemporalDepthResolvePass(t)},{reads:["staticIndirectArgs"],writes:["mainDepth"]})))},defineColorTarget:(e,t={})=>{this.ensureColorTarget(e,t)},defineTextureTarget:(e,t={})=>{this.ensureTextureTarget(e,t)},addForwardPass:(n="sceneColor")=>{const i=!c,a=[...s.gpuOpaqueDraws,...s.directOpaqueDraws,...s.transparentDraws],h=d(a);if(l?.push({draws:a,colorTargetFormats:[this.getColorTargetFormat(n)],sampleCount:this.sampleCount}),h.includes("mainDepth")){if(!c)throw new Error("Materials that sample mainDepth require a depth prepass.");e.addPass(new yr("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"]})),u=!0}e.addPass(new yr("ForwardPass",()=>{this.executeForwardPass(t,n,this.getColorTargetView(n),r,s,o,i)},{reads:["directionalShadow","pointShadow","spotShadow","mainDepth","indirectArgs",...h.map(e=>"mainDepth"===e?"sceneDepthSnapshot":e)],writes:[n]})),this.getHiZOcclusionCullingActive()&&this.hasEnabledStaticDrawSets()&&e.addPass(new yr("TemporalHiZHistoryPass",()=>{this.executeHiZPasses(t,!0)},{reads:["mainDepth"],writes:["hiz"],dependsOn:["ForwardPass"]}))},addOpaquePass:(n="sceneColor")=>{const i=!c,a=[...s.gpuOpaqueDraws,...s.directOpaqueDraws],h=d(a);if(l?.push({draws:a,colorTargetFormats:[this.getColorTargetFormat(n)],sampleCount:this.sampleCount}),h.includes("mainDepth")){if(!c)throw new Error("Materials that sample mainDepth require a depth prepass.");e.addPass(new yr("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"]})),u=!0}e.addPass(new yr("OpaquePass",()=>{this.executeForwardPass(t,n,this.getColorTargetView(n),r,s,o,i,"opaque")},{reads:["directionalShadow","pointShadow","spotShadow","mainDepth","indirectArgs",...h.map(e=>"mainDepth"===e?"sceneDepthSnapshot":e)],writes:[n]}))},addSceneTextureCopyPass:(r="sceneColor",n)=>{const i=this.staticDrawSets.filter(e=>e.publicSet.enabled&&"late"===e.drawStage).flatMap(e=>e.draws),a=[...s.transparentDraws,...i],o=!0===n?.sceneColor||a.some(e=>e.material.usesSceneColor()),l=!0===n?.sceneDepth||a.some(e=>e.material.usesSceneDepth()),c=d(a).includes("mainDepth");if(!o&&!l&&!c)return;const h=this.getColorTargetDimensions(r);if(h.width!==this.state.width||h.height!==this.state.height||this.getColorTargetFormat(r)!==qr)throw new Error("Scene texture snapshots currently require a full-resolution rgba16float source.");e.addPass(new yr("SceneTextureCopyPass",()=>{if(o){const e=this.getColorTargetView(r);let n=this.state.sceneColorSnapshotBindGroups.get(e);n||(n=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,n));const i=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}}]});i.setPipeline(this.state.sceneColorSnapshotPipeline),i.setBindGroup(0,n),i.draw(3),i.end()}l&&this.executeHiZPasses(t,!1,!0),c&&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:[...o?[r]:[],...l||c?["mainDepth"]:[]],writes:[...o?["sceneColorSnapshot"]:[],...l||c?["sceneDepthSnapshot"]:[]]})),(l||c)&&(u=!0)},addLatePass:(n="sceneColor")=>{const i=this.staticDrawSets.filter(e=>e.publicSet.enabled&&"late"===e.drawStage).flatMap(e=>e.draws);if(0===s.transparentDraws.length&&0===i.length)return;l?.push({draws:s.transparentDraws,colorTargetFormats:[this.getColorTargetFormat(n)],sampleCount:1});const a=[...s.transparentDraws,...i],c=[n,"mainDepth",...d(a)];a.some(e=>e.material.usesSceneColor())&&c.push("sceneColorSnapshot"),a.some(e=>e.material.usesSceneDepth())&&c.push("sceneDepthSnapshot"),e.addPass(new yr("LatePass",()=>{this.executeForwardPass(t,n,this.getColorTargetView(n),r,s,o,!1,"late",!0,1)},{reads:c,writes:[n,"mainDepth"]}))},addHiZHistoryPass:(r="ForwardPass")=>{if(!this.getHiZOcclusionCullingActive()||!this.hasEnabledStaticDrawSets())return;const n="LatePass"===r&&0===s.transparentDraws.length?"OpaquePass":r;e.addPass(new yr("TemporalHiZHistoryPass",()=>{this.executeHiZPasses(t,!0)},{reads:["mainDepth"],writes:["hiz"],dependsOn:[n]}))},addMaterialPass:(n={})=>{const i="string"==typeof n.outputs?[n.outputs]:Array.from(n.outputs??["sceneColor"]),a=n.drawStage??"all",c="opaque"===a?[...s.gpuOpaqueDraws,...s.directOpaqueDraws]:"late"===a?s.transparentDraws:[...s.gpuOpaqueDraws,...s.directOpaqueDraws,...s.transparentDraws],u=n.objectFilter?c.filter(e=>n.objectFilter(e.sourceObject)||!0===e.sourceRanges?.some(e=>n.objectFilter(e.sourceObject))):c,d=e=>"function"==typeof n.overrideMaterial?n.overrideMaterial(e.material,null!==e.skinning):n.overrideMaterial,h=n.overrideMaterial?u.map(e=>({...e,material:d(e)})):u;l?.push({draws:h,colorTargetFormats:i.map(e=>this.getColorTargetFormat(e)),sampleCount:this.sampleCount}),e.addPass(new yr(n.name??"MaterialPass",()=>{this.executeMaterialPass(t,i,r,s,o,n)},{reads:["directionalShadow","pointShadow","spotShadow",...n.loadDepth?["mainDepth"]:[],...n.loadColor?i:[]],writes:this.sampleCount>1?i:[...i,"mainDepth"]}))},addCustomPass:t=>{e.addPass(new yr(t.name,()=>{t.execute(h)},{reads:t.reads,writes:t.writes,dependsOn:t.dependsOn}))},addPresentPass:(r="sceneColor")=>{e.addPass(new yr("PresentPass",()=>{const e=this.getColorTargetView(r);this.executePresentPass(t,e,a)},{reads:[r],writes:["mainColor"]}))}}}transparentDraws=[];opaqueBatches=new Map;acquireDrawCall(){const e=this.drawCallPoolCount;this.drawCallPoolCount+=1;let t=this.drawCallPool[e];return t||(t={geometry:null,geometryKey:{},geometryResource:null,material:null,customDepthMaterial:null,residentInstanceBinding:null,sourceObject:null,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 yt,boundsRadius:0,sortDepth:0,transparentSortGroup:0,transparentSortOrder:0},this.drawCallPool[e]=t),t}acquireOpaqueBatchBuilder(){const e=this.opaqueBatchPoolCount;this.opaqueBatchPoolCount+=1;let t=this.opaqueBatchPool[e];return t||(t={template:null,totalInstanceCount:0,rangePairCount:0,firstInstanceStart:0,firstInstanceCount:0,sourceRanges:[],boundsMin:new yt,boundsMax:new yt},this.opaqueBatchPool[e]=t),t}populateDrawCall(e,t,r,n,i,a,s,o){const l=t.wireframe;l&&this.ensureWireframeIndex(t.geometry,t.geometryResource);const c=t.sourceObject?Boolean(t.sourceObject.receiveShadow):t.receiveShadow;return this.shouldInvalidateDrawMaterialResource(e,t.material,c,t.usesBatching,null)&&(e.materialResource=null),e.geometry=t.geometry,e.geometryKey=l?t.geometryResource.wireframeIndex:t.geometryKey,e.geometryResource=t.geometryResource,e.material=t.material,e.customDepthMaterial=t.customDepthMaterial,e.residentInstanceBinding=t.residentInstanceBinding,e.sourceObject=t.sourceObject,e.usesBatching=t.usesBatching,e.geometryGroup=t.geometryGroup,e.batchKey=t.batchKey,e.batchHash=t.batchHash,e.indexed=l||t.indexed,e.wireframe=l,e.start=l?2*t.start:t.start,e.count=l?2*t.count:t.count,e.transparent=t.transparent,e.renderOrder=t.sourceObject?.renderOrder??t.renderOrder,e.hasRenderCallbacks=this.hasRenderCallbacks(t.sourceObject),e.castShadow=t.sourceObject?Boolean(t.sourceObject.castShadow):t.castShadow,e.receiveShadow=c,e.sortMaterialId=t.sortMaterialId,e.sortGeometryId=t.sortGeometryId,e.sortCustomDepthMaterialId=t.sortCustomDepthMaterialId,e.skinning=null,e.instanceStart=r,e.instanceCount=n,e.boundsCenter.set(i,a,s),e.boundsRadius=o,e.sortDepth=0,e.transparentSortGroup=0,e.transparentSortOrder=0,e.sourceRanges=void 0,e}populateDynamicDrawCall(e,t,r,n,i,a,s,o,l,c,u,d,h,p,f,m,g,v,x,w,b,y,S,C,P,M,B,D,T=null){const I=!0===o?.isBatchedMesh,R=i.wireframe&&"triangle-list"===i.primitiveTopology;return R&&this.ensureWireframeIndex(t,n),this.shouldInvalidateDrawMaterialResource(e,i,x,I,T)&&(e.materialResource=null),e.geometry=t,e.geometryKey=R?n.wireframeIndex:r,e.geometryResource=n,e.material=i,e.customDepthMaterial=a,e.residentInstanceBinding=s,e.sourceObject=o,e.usesBatching=I,e.geometryGroup=l,e.batchKey=c,e.batchHash=u,e.indexed=R||d,e.wireframe=R,e.start=R?2*h:h,e.count=R?2*p:p,e.transparent=f,e.renderOrder=m,e.hasRenderCallbacks=g,e.castShadow=v,e.receiveShadow=x,e.sortMaterialId=w,e.sortGeometryId=b,e.sortCustomDepthMaterialId=y,e.skinning=T,e.instanceStart=S,e.instanceCount=C,e.boundsCenter.set(P,M,B),e.boundsRadius=D,e.sortDepth=0,e.transparentSortGroup=0,e.transparentSortOrder=0,e.sourceRanges=void 0,e}pushOpaqueDrawTemplate(e,t,r,n,i,a,s){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(On(r.template,e)){c=r;break}}else On(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,n=2*c.rangePairCount;e[n]=t,e[n+1]=r}c.rangePairCount+=1;const e=c.boundsMin,o=c.boundsMax,l=n-s,u=i-s,d=a-s,h=n+s,p=i+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(n-s,i-s,a-s),u.boundsMax.set(n+s,i+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;let n=this.toonOutlineMaterialCache.get(e);if(!n){const t=t=>new _t({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?aa:[{name:"position",shaderLocation:0,format:"float32x3"},{name:"normal",shaderLocation:1,format:"float32x3",defaultValue:[0,0,1]}],uniforms:{outlineThickness:r.thickness??.003,outlineColor:(new ct).fromArray(r.color??[0,0,0]),outlineAlpha:r.alpha??e.opacity},side:st,depthTest:!0,depthWrite:!0,transparent:!0});n={regular:t(!1),skinned:t(!0)},this.toonOutlineMaterialCache.set(e,n)}const i=t?n.skinned:n.regular;return i.uniforms.outlineThickness.value=r.thickness??.003,i.uniforms.outlineColor.value.fromArray(r.color??[0,0,0]),i.uniforms.outlineAlpha.value=r.alpha??e.opacity,i}pushToonOutlineDraw(e,t){const r=t?this.getToonOutlineMaterial(t,null!==e.skinning):null;if(!r||e.usesBatching)return;const 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,!0,e.renderOrder,!1,!1,!1,zn(r),e.sortGeometryId,0,e.instanceStart,e.instanceCount,e.boundsCenter.x,e.boundsCenter.y,e.boundsCenter.z,e.boundsRadius,e.skinning);this.transparentDraws.push(n)}updateTransparentDrawSortDepths(e,t,r){for(let n=0;n<e.length;n+=1){const i=e[n];0===i.transparentSortGroup&&(i.sortDepth=(i.boundsCenter.x-t.x)*r.x+(i.boundsCenter.y-t.y)*r.y+(i.boundsCenter.z-t.z)*r.z)}}extractScene(e,t){this.extractionVersion+=1,this.drawCallPoolCount=0,this.opaqueBatchPoolCount=0;this.opaqueBatches.clear();const r=this.transparentDraws;r.length=0;const n=this.residentInstanceUploadsScratch;n.length=0;const i=this.sourceInstanceDataScratch;i.reset();const a=this.gpuOpaqueDrawsScratch;a.length=0;const s=this.directOpaqueDrawsScratch;s.length=0;const o=this.stagedOpaqueDrawsScratch;o.length=0;const l=this.residentOpaqueDrawsScratch;l.length=0;const c=this.opaqueInstanceDataScratch;c.reset();const u=this.finalInstanceDataScratch;u.reset();const d=this.extractedAmbientScratch;d.set(0,0,0,0);let h=null;const p=this.activeDirectionalLightsScratch,f=this.activePointLightsScratch,m=this.activeSpotLightsScratch,g=this.fogVolumeObjectsScratch;p.length=0,f.length=0,m.length=0,g.length=0;const v=this.extractedBoundsMinScratch;v.set(1/0,1/0,1/0);const x=this.extractedBoundsMaxScratch;x.set(-1/0,-1/0,-1/0),function(e,t){const r=e.elements,n=r[0],i=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];qn(t,0,s-n,u-o,f-d,x-m),qn(t,4,s+n,u+o,f+d,x+m),qn(t,8,s+i,u+l,f+h,x+g),qn(t,12,s-i,u-l,f-h,x-g),qn(t,16,s-a,u-c,f-p,x-v),qn(t,20,a,c,p,v)}(Hn(t,this.cameraViewProjScratch),this.cameraFrustumPlanesScratch);const w=this.transparentSortCameraPositionScratch,b=this.transparentSortCameraForwardScratch;t.getWorldPosition(w),t.getWorldDirection(b);const y=this.isSphereVisibleScratch,S=this.updateExtractedBoundsFromMatrixScratch,C=this.objectTraversalStackScratch;C.length=0,C.push(e);for(let e=this.csmCascadeLights.length-1;e>=0;e-=1)C.push(this.csmCascadeLights[e]);for(;C.length>0;){const e=C.pop();if(!e.visible)continue;const r=0!==(e.layers.mask&t.layers.mask);if(!0===e.isFogVolumeObject&&null!=e.volume)g.push(e);else if(e.isAmbientLight){if(r){const t=e;d.x+=t.color.r*t.intensity,d.y+=t.color.g*t.intensity,d.z+=t.color.b*t.intensity,d.w=1}}else if(e.isHemisphereLight){if(r&&null==h){const t=e,r=this.extractedHemisphereScratch;an.setFromMatrixPosition(t.matrixWorld),r.direction.copy(an),r.direction.lengthSq()<=1e-10?r.direction.set(0,1,0):r.direction.normalize(),r.skyColor.set(t.color.r,t.color.g,t.color.b),r.groundColor.set(t.groundColor.r,t.groundColor.g,t.groundColor.b),r.intensity=t.intensity,h=r}}else if(e.isDirectionalLight){if(r&&p.length<4&&!this.hasExtractedDirectionalLight(p,e)){const t=e,r=t.shadow,n=r.camera,i=this.extractedDirectionalLightsScratch[p.length];i.sourceLight=t,t.target.matrixWorldAutoUpdate&&t.target.updateMatrixWorld(!0),an.setFromMatrixPosition(t.matrixWorld),sn.setFromMatrixPosition(t.target.matrixWorld),i.position.copy(an),i.target.copy(sn),i.direction.copy(sn).sub(an).normalize(),i.color.set(t.color.r,t.color.g,t.color.b),i.intensity=t.intensity,i.volumetricIntensity=t.userData?.volumetricIntensity??0,i.castShadow=t.castShadow,i.shadowBias=r.bias,i.shadowNormalBias=r.normalBias,i.shadowRadius=r.radius,i.shadowIntensity=r.intensity,i.shadowMapSize=Math.max(1,r.mapSize.width,r.mapSize.height),i.shadowCameraLeft=n.left,i.shadowCameraRight=n.right,i.shadowCameraTop=n.top,i.shadowCameraBottom=n.bottom,i.shadowCameraNear=n.near,i.shadowCameraFar=n.far,p.push(i)}}else if(e.isPointLight){if(r&&f.length<jr){const t=e,r=t.shadow,n=r.camera;an.setFromMatrixPosition(t.matrixWorld);const i=t.distance>0?t.distance:Math.max(n.far,25);if(!Kn(this.cameraFrustumPlanesScratch,an.x,an.y,an.z,i))continue;const a=this.extractedPointLightsScratch[f.length];a.sourceLight=t,a.position.copy(an),a.color.set(t.color.r,t.color.g,t.color.b),a.intensity=t.intensity,a.volumetricIntensity=t.userData?.volumetricIntensity??0,a.distance=t.distance,a.range=i,a.decay=t.decay,a.castShadow=t.castShadow,a.shadowBias=r.bias,a.shadowNormalBias=r.normalBias,a.shadowRadius=r.radius,a.shadowIntensity=r.intensity,a.shadowMapSize=Math.max(1,r.mapSize.width,r.mapSize.height),a.shadowCameraNear=n.near,a.shadowCameraFar=t.distance>0?t.distance:n.far,f.push(a)}}else if(e.isSpotLight){if(r&&m.length<$r){const t=e,r=t.shadow,n=r.camera,i=this.extractedSpotLightsScratch[m.length];i.sourceLight=t,t.target.matrixWorldAutoUpdate&&t.target.updateMatrixWorld(!0),an.setFromMatrixPosition(t.matrixWorld),sn.setFromMatrixPosition(t.target.matrixWorld);const a=t.distance>0?t.distance:n.far;if(!Kn(this.cameraFrustumPlanesScratch,an.x,an.y,an.z,a))continue;i.position.copy(an),i.direction.copy(sn).sub(an).normalize(),i.color.set(t.color.r,t.color.g,t.color.b),i.intensity=t.intensity,i.volumetricIntensity=t.userData?.volumetricIntensity??0,i.range=a,i.angle=t.angle,i.penumbra=t.penumbra,i.decay=t.decay,i.castShadow=t.castShadow,i.shadowBias=r.bias,i.shadowNormalBias=r.normalBias,i.shadowRadius=r.radius,i.shadowIntensity=r.intensity,i.shadowMapSize=Math.max(1,r.mapSize.width,r.mapSize.height),i.shadowCameraNear=n.near,i.shadowCameraFar=t.distance>0?t.distance:n.far,i.shadowCameraFov=n.fov,m.push(i)}}else r&&e.isBatchedMesh?this.collectBatchedMesh(e,i,S,y,t,w,b):r&&e.isInstancedMesh?this.collectInstancedMesh(e,i,S,y):r&&e.isSkinnedMesh?this.collectSkinnedMesh(e,i,S,y):r&&e.isLine?this.collectLine(e,i,S,y):r&&e.isSprite?this.collectSprite(e,i,S,y):r&&e.isMesh&&this.collectMesh(e,i,S,y);const n=e.children;for(let e=n.length-1;e>=0;e-=1)C.push(n[e])}if(this.csmCascadeLights.length>0){const e=new Map;for(let t=0;t<this.csmCascadeLights.length;t+=1)e.set(this.csmCascadeLights[t],t);p.sort((t,r)=>((null==t.sourceLight?void 0:e.get(t.sourceLight))??4)-((null==r.sourceLight?void 0:e.get(r.sourceLight))??4))}const P=s.length;this.updateTransparentDrawSortDepths(r,w,b),r.sort(Fn),Number.isFinite(v.x)||(v.set(-6,-6,-6),x.set(6,6,6)),o.sort(An);for(let e=0;e<o.length;){const t=o[e],r=c.instanceCount;c.appendRange(i,t.instanceStart,t.instanceCount);let n,l=t.instanceCount,u=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<o.length&&jn(t,o[g]);){const e=o[g];c.appendRange(i,e.instanceStart,e.instanceCount),n??=[{sourceObject:t.sourceObject,instanceStart:r,instanceCount:t.instanceCount}],n.push({sourceObject:e.sourceObject,instanceStart:r+l,instanceCount:e.instanceCount}),l+=e.instanceCount;const a=e.boundsCenter.x-e.boundsRadius,s=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;a<u&&(u=a),s<d&&(d=s),v<h&&(h=v),x>p&&(p=x),w>f&&(f=w),b>m&&(m=b),g+=1}const v=.5*(u+p),x=.5*(d+f),w=.5*(h+m),b=p-v,y=f-x,S=m-w;t.instanceStart=r,t.instanceCount=l,t.sourceRanges=n,t.boundsCenter.set(v,x,w),t.boundsRadius=Math.sqrt(b*b+y*y+S*S),t.indexed&&!t.hasRenderCallbacks?a.push(t):s.push(t),e=g}l.sort(An);for(let e=0;e<l.length;e+=1){const t=l[e];t.indexed&&!t.hasRenderCallbacks?a.push(t):s.push(t)}u.appendBuilder(c);for(let e=0;e<P;e+=1){const t=s[e];if(t.residentInstanceBinding)continue;const r=u.instanceCount;u.appendRange(i,t.instanceStart,t.instanceCount),t.instanceStart=r}a.sort(An),s.sort(An);for(let e=0;e<r.length;e+=1){const t=r[e];if(t.residentInstanceBinding)continue;const n=u.instanceCount;u.appendRange(i,t.instanceStart,t.instanceCount),t.instanceStart=n}f.sort(na),m.sort(na);for(let e=4;e<f.length;e+=1)f[e].castShadow=!1;for(let e=4;e<m.length;e+=1)m[e].castShadow=!1;const M=this.extractedLightsScratch;M.hemisphere=h,M.directional=p[0]??null,M.point=f[0]??null,M.spot=m[0]??null;const B=this.extractedFrameScratch;return B.scene=e,B.camera=t,B.fogVolumeObjects=g,B.transparentDraws=r,B.instanceData=u,B.residentInstanceUploads=n,B}collectLine(e,t,r,n){if(Array.isArray(e.material)||!e.geometry.getAttribute("position"))return;const i=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=`${dn(i)}:${s}`;let c=this.lineProxyCache.get(e);c&&c.signature===l||(c={signature:l,mesh:new mt(i,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,n)}const s=dn(i);let o=this.lineProxyCache.get(e);if(!o||o.signature!==s){const t=i.getAttribute("position"),r=i.index,n=r?.count??t.count,a=Math.max(0,Math.min(n,i.drawRange.start)),l=Number.isFinite(i.drawRange.count)?i.drawRange.count:n-a,c=Math.max(a,Math.min(n,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),n=p(e+1);d.push(t.getX(r),t.getY(r),t.getZ(r)),h.push(t.getX(n),t.getY(n),t.getZ(n))}const f=new lt;f.setIndex([0,2,1,2,3,1,2,4,3,4,5,3,4,6,5,6,7,5]),f.setAttribute("position",new ot(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 ht(new Float32Array(d),3)),f.setAttribute("instanceEnd",new ht(new Float32Array(h),3)),f.instanceCount=d.length/3;const m=Zn(i);f.boundingSphere=new xt(m.center.clone(),m.radius),o={signature:s,mesh:new mt(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,n)}collectSprite(e,t,r,n){let i=this.spriteProxyCache.get(e);if(!i){const t=e.geometry.clone();i={mesh:new mt(t,e.material),centerX:Number.NaN,centerY:Number.NaN},this.spriteProxyCache.set(e,i)}if(i.centerX!==e.center.x||i.centerY!==e.center.y){const t=i.mesh.geometry.getAttribute("position"),r=e.geometry.getAttribute("position");for(let n=0;n<t.count;n+=1)t.setXYZ(n,r.getX(n)+.5-e.center.x,r.getY(n)+.5-e.center.y,r.getZ(n));t.needsUpdate=!0,i.mesh.geometry.computeBoundingSphere(),i.centerX=e.center.x,i.centerY=e.center.y}const a=i.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,n)}hasExtractedDirectionalLight(e,t){for(let r=0;r<e.length;r+=1)if(e[r].sourceLight===t)return!0;return!1}getObjectMotionHistory(e,t){let r=this.objectMotionHistory.get(e);if(!r)return r={matrix:new Float32Array(16),generation:this.motionVectorHistoryGeneration,lastExtractionVersion:-1,valid:!1},r.matrix.set(t),this.objectMotionHistory.set(e,r),r;const n=!0===e.userData.motionBlurTeleported;n&&(e.userData.motionBlurTeleported=!1);const i=(t[12]??0)-r.matrix[12],a=(t[13]??0)-r.matrix[13],s=(t[14]??0)-r.matrix[14],o=Math.max(0,Number(e.userData.motionBlurTeleportDistance??10));return r.valid=this.motionVectorHistoryValid&&r.generation===this.motionVectorHistoryGeneration&&r.lastExtractionVersion===this.extractionVersion-1&&!n&&i*i+a*a+s*s<=o*o,r}commitObjectMotionHistory(e,t){e.matrix.set(t),e.generation=this.motionVectorHistoryGeneration,e.lastExtractionVersion=this.extractionVersion}collectMesh(e,t,r,n){const i=e.geometry;if(void 0===i.attributes.position)return;const a=e.material,s=Array.isArray(a);if(!s&&!1===a.visible||s&&a.every(e=>!1===e.visible))return;const o=this.getGeometryResource(i),l=this.meshExtractionCache.get(e),c=l?.geometryResource===o?l:null,u=c?null:Zn(i),d=c?c.localBoundsCenter:u.center,h=c?c.localBoundsRadius:u.radius,p=e.matrixWorld.elements,f=d.x,m=d.y,g=d.z,v=p[0]*f+p[4]*m+p[8]*g+p[12],x=p[1]*f+p[5]*m+p[9]*g+p[13],w=p[2]*f+p[6]*m+p[10]*g+p[14],b=p[0]*p[0]+p[1]*p[1]+p[2]*p[2],y=p[4]*p[4]+p[5]*p[5]+p[6]*p[6],S=p[8]*p[8]+p[9]*p[9]+p[10]*p[10],C=h*Math.sqrt(Math.max(b,y,S,1e-10));if(!n(v,x,w,C,e.frustumCulled))return;const P=this.resolvedMeshMaterialsScratch;P.length=0;let M=null;if(s)for(let e=0;e<a.length;e+=1)P[e]=this.resolveMaterial(a[e]);else{if(!a.visible)return;M=this.resolveMaterial(a)}const B=ri(e),D=l&&l.customDepthMaterial===B&&l.geometryResource.lastValidatedExtractionVersion===this.extractionVersion&&(!s&&l.material===a&&l.resolvedMaterial===M||s&&null!==l.materials&&null!==l.resolvedMaterials&&gn(l.materials,a)&&wn(l.resolvedMaterials,P))?l:this.getMeshExtractionCacheEntry(e,a,M,P,B,o),T=D.templates.length;if(0===T)return;const I=function(e){const t=e.attributes;let r=!1,n=1/0;for(const e in t){const i=t[e];!0!==i.isInstancedBufferAttribute&&!0!==i.data?.isInstancedInterleavedBuffer||(r=!0,i.count<n&&(n=i.count))}if(!r)return 1;const i=e.instanceCount;return Number.isFinite(i)?Math.max(0,Math.floor(i)):Math.max(0,n)}(i),R=this.getObjectMotionHistory(e,p),V=ea(e),G=ta(e);let z=0;for(let e=0;e<I;e+=1){const r=Rn(t,p,1,1,1,1,void 0,R.matrix,V,G,R.valid?1:0);0===e&&(z=r)}this.commitObjectMotionHistory(R,p),r(p);for(let e=0;e<T;e+=1){const t=D.templates[e],r=this.populateDrawCall(this.acquireDrawCall(),t,z,I,v,x,w,C);t.transparent?this.transparentDraws.push(r):this.pushDraw(r);const n=s?a[t.geometryGroup?.materialIndex??0]:a;this.pushToonOutlineDraw(r,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().");e.matrixWorldAutoUpdate&&e.updateMatrixWorld(),null===t.parent&&t.matrixWorldAutoUpdate&&t.updateMatrixWorld();const n=this.extractScene(e,t);this.ensureShadowTextureSizes(n),this.uploadInstanceData(n.instanceData),this.uploadResidentInstanceData(n.residentInstanceUploads),this.uploadDrawMetadata(this.getHiZOcclusionCullingActive()?n.gpuOpaqueDraws:[]),this.updateCameraUniforms(t,e),this.updateLightUniforms(n);const i=this.compileDrawScratch;i.length=0,i.push(...n.gpuOpaqueDraws,...n.directOpaqueDraws,...n.transparentDraws);for(const e of i)this.prepareDrawGeometryVertexBuffers(e);if(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,n,{drawCallCount:0,triangleCount:0},e);return this.graphBuilder(this.renderGraph,r),Promise.all([...e.map(e=>this.compileDrawMaterialsAsync(e.draws,e.colorTargetFormats,e.sampleCount)),...e.map(e=>this.compileStaticDrawMaterialsAsync(e.colorTargetFormats,e.sampleCount))]).then(async()=>{await(this.state.device?.queue.onSubmittedWorkDone())})}this.compileDrawMaterials(i)}collectInstancedMesh(e,t,r,n){if(void 0===e.geometry?.getAttribute("position"))return;const i=e.material;if(!1===i.visible)return;const a=this.instancedMeshExtractionCache.get(e),s=!0===e.userData.webGpuCacheMaterial&&a?.sourceMaterial===i&&a.sourceMaterialVersion===i.version&&a.material!==this.fallbackMaterial?a.material:this.resolveMaterial(i);if(!s)return;const o=ri(e),l=this.getGeometryResource(e.geometry),c=this.getInstancedMeshExtractionCacheEntry(e,s,o,l),u=e.instanceMatrix.array,d=e.instanceMatrix.version,h=e.instanceColor?.array,p=e.instanceColor?.itemSize??0,f=e.instanceColor?.version??-1,m=c.cacheValid&&c.cachedCount===e.count&&c.cachedInstanceMatrixVersion===d&&c.cachedInstanceColorVersion===f&&Nn(c.cachedMatrixWorld,e.matrixWorld.elements),g=Wn(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 n=e.matrixWorld.elements,i=n[12]??0,a=n[13]??0,s=n[14]??0;c.cachedDrawBoundsCenter.set(i,a,s),c.cachedDrawBoundsRadius=0,c.cachedBoundsMin.set(i,a,s),c.cachedBoundsMax.set(i,a,s),c.cachedInstanceMatrixVersion=d,c.cachedInstanceColorVersion=f,c.cachedCount=e.count,c.cachedDefaultColorData=null,$n(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,n=c.cachedBoundsMax;r.set(1/0,1/0,1/0),n.set(-1/0,-1/0,-1/0);const i=c.localBoundsCenter,a=c.localBoundsRadius,s=e.matrixWorld.elements,o=Wn(s),l=i.x,m=i.y,g=i.z,v=s[0],x=s[4],w=s[8],b=s[12],y=s[1],S=s[5],C=s[9],P=s[13],M=s[2],B=s[6],D=s[10],T=s[14],I=s[3],R=s[7],V=s[11],G=s[15];for(let i=0;i<e.count;i+=1){const e=16*i,s=i*Nr,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,L=u[e+5]??0,A=u[e+6]??0,F=u[e+7]??0,k=u[e+8]??0,E=u[e+9]??0,O=u[e+10]??0,j=u[e+11]??0,$=u[e+12]??0,N=u[e+13]??0,W=u[e+14]??0,_=u[e+15]??0;let H,q,K,Z,Y,X,J,Q,ee,te,re,ne,ie,ae,se,oe;o?(H=c,q=d,K=f,Z=z,Y=U,X=L,J=A,Q=F,ee=k,te=E,re=O,ne=j,ie=$,ae=N,se=W,oe=_):(H=v*c+x*d+w*f+b*z,Y=v*U+x*L+w*A+b*F,ee=v*k+x*E+w*O+b*j,ie=v*$+x*N+w*W+b*_,q=y*c+S*d+C*f+P*z,X=y*U+S*L+C*A+P*F,te=y*k+S*E+C*O+P*j,ae=y*$+S*N+C*W+P*_,K=M*c+B*d+D*f+T*z,J=M*U+B*L+D*A+T*F,re=M*k+B*E+D*O+T*j,se=M*$+B*N+D*W+T*_,Z=I*c+R*d+V*f+G*z,Q=I*U+R*L+V*A+G*F,ne=I*k+R*E+V*O+G*j,oe=I*$+R*N+V*W+G*_),t[s+0]=H,t[s+1]=q,t[s+2]=K,t[s+3]=Z,t[s+4]=Y,t[s+5]=X,t[s+6]=J,t[s+7]=Q,t[s+8]=ee,t[s+9]=te,t[s+10]=re,t[s+11]=ne,t[s+12]=ie,t[s+13]=ae,t[s+14]=se,t[s+15]=oe;const le=i*p;t[s+16]=h?h[le+0]??1:1,t[s+17]=h?h[le+1]??1:1,t[s+18]=h?h[le+2]??1:1,t[s+19]=h&&p>=4?h[le+3]??1:1,t[s+20]=i,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 ce=H*l+Y*m+ee*g+ie,ue=q*l+X*m+te*g+ae,de=K*l+J*m+re*g+se,he=Math.sqrt(H*H+q*q+K*K),pe=Math.sqrt(Y*Y+X*X+J*J),fe=Math.sqrt(ee*ee+te*te+re*re),me=a*Math.max(he,pe,fe,1e-5);Qn(r,n,an.set(ce,ue,de),me)}c.cachedDrawBoundsCenter.copy(r).add(n).multiplyScalar(.5);const z=n.x-c.cachedDrawBoundsCenter.x,U=n.y-c.cachedDrawBoundsCenter.y,L=n.z-c.cachedDrawBoundsCenter.z;c.cachedDrawBoundsRadius=Math.sqrt(z*z+U*U+L*L),c.cachedInstanceMatrixVersion=d,c.cachedInstanceColorVersion=f,c.cachedCount=e.count,c.cachedDefaultColorData=null,$n(e.matrixWorld.elements,c.cachedMatrixWorld),c.residentBufferDirty=!0,c.residentColorBufferDirty=!0,c.cacheValid=!0}}if(!n(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),_n(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,n){if(void 0===e.geometry?.getAttribute("position"))return;const i=e.boundingSphere,a=an;let s=0;if(null!==i){const t=i.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=i.radius*Yn(e.matrixWorld),e.frustumCulled&&!n(a,o,l,s,!0))return}const o=Array.isArray(e.material)?e.material:[e.material],l=ri(e),c=null!==e.geometry.index,u=this.getSkinnedGeometryResource(e);if(this.refreshSkinningPalette(u.skinning.palette),this.refreshSkinningBindMatrices(e,u.skinning),null===i){if(this.updateSkinnedBounds(e,u),a.copy(u.localBoundsCenter).applyMatrix4(e.matrixWorld),s=u.localBoundsRadius*Yn(e.matrixWorld),!n(a.x,a.y,a.z,s,e.frustumCulled))return}else a.copy(i.center).applyMatrix4(e.matrixWorld);this.uploadSkinningResources(u.skinning);const d=this.getObjectMotionHistory(e,e.matrixWorld.elements),h=Vn(t,e.matrixWorld,1,1,1,1,void 0,d.matrix,ea(e),ta(e),d.valid?1:0);if(this.commitObjectMotionHistory(d,e.matrixWorld.elements),r(e.matrixWorld.elements),e.geometry.groups.length>0&&o.length>0){for(const t of e.geometry.groups){const r=o[t.materialIndex??0]??o[0],n=this.resolveSkinnedMaterial(r);if(!n)continue;const i=Un(n,e,c,t.start,Pn(e.geometry,c,t.start,t.count),l),d=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e,u.resource,n,l,null,e,t,i,Ln(zn(n),zn(e),c,t.start,Pn(e.geometry,c,t.start,t.count),l?zn(l):0),c,t.start,Pn(e.geometry,c,t.start,t.count),n.transparent,e.renderOrder,this.hasRenderCallbacks(e),e.castShadow,e.receiveShadow,zn(n),zn(e),l?zn(l):0,h,1,a.x,a.y,a.z,s,u.skinning);this.pushDraw(d),this.pushToonOutlineDraw(d,r)}return}const p=this.resolveSkinnedMaterial(o[0]);if(!p)return;const f=Mn(e.geometry,c),m=Un(p,e,c,f.start,f.count,l),g=this.populateDynamicDrawCall(this.acquireDrawCall(),e.geometry,e,u.resource,p,l,null,e,null,m,Ln(zn(p),zn(e),c,f.start,f.count,l?zn(l):0),c,f.start,f.count,p.transparent,e.renderOrder,this.hasRenderCallbacks(e),e.castShadow,e.receiveShadow,zn(p),zn(e),l?zn(l):0,h,1,a.x,a.y,a.z,s,u.skinning);this.pushDraw(g),this.pushToonOutlineDraw(g,o[0])}collectBatchedMesh(e,t,r,n,i,a,s){if(void 0===e.geometry?.getAttribute("position"))return;const o=this.resolveMaterial(e.material);if(!o)return;const l=ri(e),c=(e.geometry.index,this.getGeometryResource(e.geometry)),u=e,d=u._instanceInfo??u._drawInfo??[],h=d.length,p=u._matricesTexture?.image.data,f=u._colorsTexture?.image.data,m=this.getBatchedMeshExtractionCacheEntry(e,o,l,c,u),g=e.matrixWorld.elements,v=u._matricesTexture?.version??0,x=u._colorsTexture?.version??-1;if(m.cacheValid&&!o.transparent&&m.cachedMatricesVersion===v&&m.cachedColorsVersion===x&&m.cachedInstanceInfoLength===d.length&&m.cachedGeometryCount===(u._geometryCount??0)&&Nn(m.cachedMatrixWorld,g)&&this.batchedGeometryIdsMatchSnapshot(m.geometryIdsSnapshot,d)){let t=!1;for(let r=0;r<m.cachedDraws.length;r+=1){const i=m.cachedDraws[r];n(i.boundsCenter.x,i.boundsCenter.y,i.boundsCenter.z,i.boundsRadius,e.frustumCulled)&&(t=!0,this.pushDraw(this.populateDynamicDrawCall(this.acquireDrawCall(),i.template.geometry,i.template.geometryKey,i.template.geometryResource,i.template.material,i.template.customDepthMaterial,m.residentInstanceBinding,i.template.sourceObject,i.template.geometryGroup,i.template.batchKey,i.template.batchHash,i.template.indexed,i.template.start,i.template.count,i.template.transparent,i.template.sourceObject?.renderOrder??i.template.renderOrder,this.hasRenderCallbacks(i.template.sourceObject),i.template.sourceObject?Boolean(i.template.sourceObject.castShadow):i.template.castShadow,i.template.sourceObject?Boolean(i.template.sourceObject.receiveShadow):i.template.receiveShadow,i.template.sortMaterialId,i.template.sortGeometryId,i.template.sortCustomDepthMaterialId,i.instanceStart,i.instanceCount,i.boundsCenter.x,i.boundsCenter.y,i.boundsCenter.z,i.boundsRadius)))}if(!t)return;return!m.residentBufferDirty&&m.residentInstanceBinding||this.residentInstanceUploadsScratch.push(m),void _n(this.extractedBoundsMinScratch,this.extractedBoundsMaxScratch,m.cachedBoundsMin,m.cachedBoundsMax)}if(o.transparent){const o=[],l=!e.sortObjects||null!==e.customSort;for(let i=0;i<h;i+=1){const c=d[i];if(!c?.active||!c.visible)continue;const u=m.templates[c.geometryIndex];if(!u)continue;p?tn.fromArray(p,16*i):e.getMatrixAt(i,tn),rn.multiplyMatrices(e.matrixWorld,tn);const h=u.localBoundsCenter,g=rn.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(!n(v,x,w,C,e.frustumCulled&&e.perObjectFrustumCulled))continue;const P=f?f[4*i+0]??1:1,M=f?f[4*i+1]??1:1,B=f?f[4*i+2]??1:1,D=f?f[4*i+3]??1:1,T=Vn(t,rn,P,M,B,D,i);r(rn.elements);const I=this.populateDrawCall(this.acquireDrawCall(),u,T,1,v,x,w,C),R=(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:R,index:i,draw:I}):(I.sortDepth=R,this.transparentDraws.push(I))}if(l&&o.length>0){e.sortObjects&&e.customSort?e.customSort.call(e,o,i):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=zn(e);for(let e=0;e<o.length;e+=1){const n=o[e].draw;n.sortDepth=t,n.transparentSortGroup=r,n.transparentSortOrder=e,this.transparentDraws.push(n)}}return}const w=m.activeGroups;for(let e=0;e<w.length;e+=1){const t=w[e];t.activeInFrame=!1,t.activeCount=0}w.length=0;const b=m.cachedBoundsMin,y=m.cachedBoundsMax;b.set(1/0,1/0,1/0),y.set(-1/0,-1/0,-1/0),m.geometryIdsSnapshot.length!==d.length&&(m.geometryIdsSnapshot=new Int32Array(d.length));let S=0;for(let e=0;e<h;e+=1){const t=d[e];if(!t?.active||!t.visible){m.geometryIdsSnapshot[e]=-1;continue}const r=m.groups[t.geometryIndex];r?(m.geometryIdsSnapshot[e]=t.geometryIndex,r.activeInFrame||(r.activeInFrame=!0,r.activeCount=0,r.boundsMin.set(1/0,1/0,1/0),r.boundsMax.set(-1/0,-1/0,-1/0),w.push(r)),r.activeCount+=1,S+=1):m.geometryIdsSnapshot[e]=-1}const C=m.cachedInstanceData.beginWriteInstances(S);let P=0;for(let e=0;e<w.length;e+=1){const t=w[e];t.instanceStart=P,t.writeOffset=P*Nr,P+=t.activeCount}const M=Wn(g),B=g[0],D=g[4],T=g[8],I=g[12],R=g[1],V=g[5],G=g[9],z=g[13],U=g[2],L=g[6],A=g[10],F=g[14],k=g[3],E=g[7],O=g[11],j=g[15];for(let t=0;t<h;t+=1){const r=m.geometryIdsSnapshot[t]??-1;if(r<0)continue;const n=m.groups[r];if(!n)continue;let i,a,s,o,l,c,u,d,h,g,v,x,w,S,P,$,N,W,_,H,q,K,Z,Y,X,J,Q,ee,te,re,ne,ie;if(p){const e=16*t;i=p[e+0]??0,a=p[e+1]??0,s=p[e+2]??0,o=p[e+3]??0,l=p[e+4]??0,c=p[e+5]??0,u=p[e+6]??0,d=p[e+7]??0,h=p[e+8]??0,g=p[e+9]??0,v=p[e+10]??0,x=p[e+11]??0,w=p[e+12]??0,S=p[e+13]??0,P=p[e+14]??0,$=p[e+15]??0}else{e.getMatrixAt(t,tn);const r=tn.elements;i=r[0]??0,a=r[1]??0,s=r[2]??0,o=r[3]??0,l=r[4]??0,c=r[5]??0,u=r[6]??0,d=r[7]??0,h=r[8]??0,g=r[9]??0,v=r[10]??0,x=r[11]??0,w=r[12]??0,S=r[13]??0,P=r[14]??0,$=r[15]??0}M?(N=i,W=a,_=s,H=o,q=l,K=c,Z=u,Y=d,X=h,J=g,Q=v,ee=x,te=w,re=S,ne=P,ie=$):(N=B*i+D*a+T*s+I*o,q=B*l+D*c+T*u+I*d,X=B*h+D*g+T*v+I*x,te=B*w+D*S+T*P+I*$,W=R*i+V*a+G*s+z*o,K=R*l+V*c+G*u+z*d,J=R*h+V*g+G*v+z*x,re=R*w+V*S+G*P+z*$,_=U*i+L*a+A*s+F*o,Z=U*l+L*c+A*u+F*d,Q=U*h+L*g+A*v+F*x,ne=U*w+L*S+A*P+F*$,H=k*i+E*a+O*s+j*o,Y=k*l+E*c+O*u+j*d,ee=k*h+E*g+O*v+j*x,ie=k*w+E*S+O*P+j*$);const ae=f?f[4*t+0]??1:1,se=f?f[4*t+1]??1:1,oe=f?f[4*t+2]??1:1,le=f?f[4*t+3]??1:1,ce=n.writeOffset;C[ce+0]=N,C[ce+1]=W,C[ce+2]=_,C[ce+3]=H,C[ce+4]=q,C[ce+5]=K,C[ce+6]=Z,C[ce+7]=Y,C[ce+8]=X,C[ce+9]=J,C[ce+10]=Q,C[ce+11]=ee,C[ce+12]=te,C[ce+13]=re,C[ce+14]=ne,C[ce+15]=ie,C[ce+16]=ae,C[ce+17]=se,C[ce+18]=oe,C[ce+19]=le,C[ce+20]=t,C[ce+21]=1,C[ce+22]=1,C[ce+23]=0;for(let e=0;e<16;e+=1)C[ce+24+e]=C[ce+e];n.writeOffset+=Nr;const ue=n.template.localBoundsCenter,de=N*ue.x+q*ue.y+X*ue.z+te,he=W*ue.x+K*ue.y+J*ue.z+re,pe=_*ue.x+Z*ue.y+Q*ue.z+ne,fe=Math.sqrt(N*N+W*W+_*_),me=Math.sqrt(q*q+K*K+Z*Z),ge=Math.sqrt(X*X+J*J+Q*Q),ve=n.template.localBoundsRadius*Math.max(fe,me,ge,1e-5),xe=de-ve,we=he-ve,be=pe-ve,ye=de+ve,Se=he+ve,Ce=pe+ve;xe<n.boundsMin.x&&(n.boundsMin.x=xe),we<n.boundsMin.y&&(n.boundsMin.y=we),be<n.boundsMin.z&&(n.boundsMin.z=be),ye>n.boundsMax.x&&(n.boundsMax.x=ye),Se>n.boundsMax.y&&(n.boundsMax.y=Se),Ce>n.boundsMax.z&&(n.boundsMax.z=Ce),xe<b.x&&(b.x=xe),we<b.y&&(b.y=we),be<b.z&&(b.z=be),ye>y.x&&(y.x=ye),Se>y.y&&(y.y=Se),Ce>y.z&&(y.z=Ce)}const $=m.cachedDraws;let N=0;for(let e=0;e<w.length;e+=1){const t=w[e],r=.5*(t.boundsMin.x+t.boundsMax.x),n=.5*(t.boundsMin.y+t.boundsMax.y),i=.5*(t.boundsMin.z+t.boundsMax.z),a=t.boundsMax.x-r,s=t.boundsMax.y-n,o=t.boundsMax.z-i,l=Math.sqrt(a*a+s*s+o*o);let c=$[N];c||(c={template:t.template,instanceStart:0,instanceCount:0,boundsCenter:new yt,boundsRadius:0},$[N]=c),c.template=t.template,c.instanceStart=t.instanceStart,c.instanceCount=t.activeCount,c.boundsCenter.set(r,n,i),c.boundsRadius=l,N+=1}$.length=N,m.cachedMatricesVersion=v,m.cachedColorsVersion=x,m.cachedInstanceInfoLength=d.length,m.cachedGeometryCount=u._geometryCount??0,$n(g,m.cachedMatrixWorld),m.residentBufferDirty=!0,m.cacheValid=!0;let W=!1;for(let t=0;t<$.length;t+=1){const r=$[t];n(r.boundsCenter.x,r.boundsCenter.y,r.boundsCenter.z,r.boundsRadius,e.frustumCulled)&&(W=!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)))}W&&(this.residentInstanceUploadsScratch.push(m),_n(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,_r,0,Nr)}uploadResidentInstanceData(e){if(this.state.device)for(let t=0;t<e.length;t+=1){const r=e[t],n=r.residentInstanceBinding;if(!n)continue;if("instanced-direct"===n.mode){const e=r,t=e.sourceMesh,i=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((!n.buffer||a>r.residentBufferSize)&&(n.buffer?.destroy(),r.residentBufferSize=256*Math.ceil(a/256),n.buffer=this.state.device.createBuffer({label:"renderer-instanced-mesh-matrix-buffer",size:r.residentBufferSize,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),n.sceneBindGroup=null,n.shadowBindGroup=null,n.shadowBindGroups.clear(),n.sceneBindGroupVersion=0,n.shadowBindGroupVersion=0,r.residentBufferDirty=!0),(!n.colorBuffer||o>r.residentColorBufferSize)&&(n.colorBuffer?.destroy(),r.residentColorBufferSize=256*Math.ceil(o/256),n.colorBuffer=this.state.device.createBuffer({label:"renderer-instanced-mesh-color-buffer",size:r.residentColorBufferSize,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),n.sceneBindGroup=null,n.shadowBindGroup=null,n.shadowBindGroups.clear(),n.sceneBindGroupVersion=0,n.shadowBindGroupVersion=0,r.residentColorBufferDirty=!0),r.residentBufferDirty&&n.buffer&&(t.count>0?this.state.device.queue.writeBuffer(n.buffer,0,In(i),0,16*t.count):this.state.device.queue.writeBuffer(n.buffer,0,Hr,0,4),r.residentBufferDirty=!1),r.residentColorBufferDirty&&n.colorBuffer){if(t.instanceColor&&4===t.instanceColor.itemSize&&t.instanceColor.array instanceof Float32Array)this.state.device.queue.writeBuffer(n.colorBuffer,0,In(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 n=4*e;t.instanceColor?(r[n+0]=t.instanceColor.getComponent(e,0),r[n+1]=t.instanceColor.itemSize>1?t.instanceColor.getComponent(e,1):1,r[n+2]=t.instanceColor.itemSize>2?t.instanceColor.getComponent(e,2):1,r[n+3]=t.instanceColor.itemSize>3?t.instanceColor.getComponent(e,3):1):(r[n+0]=1,r[n+1]=1,r[n+2]=1,r[n+3]=1)}this.state.device.queue.writeBuffer(n.colorBuffer,0,In(r),0,r.length)}r.residentColorBufferDirty=!1}continue}const i=Math.max(4,r.cachedInstanceData.byteLength);if((!n.buffer||i>r.residentBufferSize)&&(n.buffer?.destroy(),r.residentBufferSize=256*Math.ceil(i/256),n.buffer=this.state.device.createBuffer({label:"renderer-instanced-mesh-buffer",size:r.residentBufferSize,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),n.sceneBindGroup=null,n.shadowBindGroup=null,n.shadowBindGroups.clear(),n.sceneBindGroupVersion=0,n.shadowBindGroupVersion=0,r.residentBufferDirty=!0),r.residentBufferDirty){if(!n.buffer)continue;r.cachedInstanceData.floatLength>0?this.state.device.queue.writeBuffer(n.buffer,0,r.cachedInstanceData.rawData.buffer,0,r.cachedInstanceData.byteLength):this.state.device.queue.writeBuffer(n.buffer,0,_r,0,Nr),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,e.depthMaterialResources.clear()}}getViewport(e){return e.set(0,0,this.state.width,this.state.height)}getSharedSceneBindGroup(){if(!(this.state.device&&this.state.sceneBindGroupLayout&&this.state.cameraBuffer&&this.state.lightBuffer&&this.state.instanceBuffer&&this.state.shadowComparisonSampler&&this.state.directionalShadowView&&this.state.linearClampSampler&&this.state.pointShadowArrayView&&this.state.spotShadowView))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}]})),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,n){let i=this.dynamicIndirectSubmissionCache.get(e);i||(i=[],this.dynamicIndirectSubmissionCache.set(e,i));const a=void 0!==n;let s=i.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:[]},i.push(s)),s.lastUsedExtractionVersion=this.extractionVersion;const o=s.streams;let l=0,c=null,u=0;for(let i=0;i<e.length;i+=1){const a=e[i],s=n?.[i]??(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=ei(a);if(c&&c.key===h&&c.indirectStartIndex+c.indirectCount===i){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===i;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=i,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:i,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,n){let i=this.indirectStreamKeyCache.get(e);i||(i=new WeakMap,this.indirectStreamKeyCache.set(e,i));let a=i.get(t);a||(a=new WeakMap,i.set(t,a));let s=a.get(r);s||(s=new WeakMap,a.set(r,s));let o=s.get(n);return void 0===o&&(o=this.nextIndirectStreamKey,this.nextIndirectStreamKey+=1,s.set(n,o)),o}getOrCreateStaticIndirectSubmissionStreams(e,t,r=ia){const n=r.join("|"),i=null!==e.visibleIndirectSubmissionStreams&&e.visibleIndirectStreamsSceneBindGroup===t&&e.visibleIndirectStreamsSampleCount===this.sampleCount&&e.visibleIndirectStreamsColorFormatsKey===n;if(i)return e.visibleIndirectSubmissionStreams;let a=!i;for(const t of e.visibleMaterialBindings){const n=this.getMaterialResource(t.material,"packed-visible",t.receiveShadow,r,!1,t.usesBatching),i=t.resource;t.resource=n,i!==n&&(a=!0);for(const r of t.drawIndices)e.visibleDrawMaterialResources[r]!==n&&(a=!0),e.visibleDrawMaterialResources[r]=n}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=n,e.indirectForwardBundleCache.clear()),e.visibleIndirectSubmissionStreams}getOrCreateIndirectForwardBundle(e,t=this.state.drawMetadataResource,r=this.state.indirectForwardBundleCache,n="renderer-indirect-forward-bundle",i=ia,a=!1,s=this.getColorFormatsId(i)){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:`${n}-${o}`,colorFormats:i,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:`${n}-${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 n=t.materialResource.graphTextureBindGroupLayout;if(!n)throw new Error("Graph texture layout is missing.");e.setBindGroup(3,this.createGraphTextureBindGroup(t.material,n));for(let n=0;n<t.indirectCount;n+=1)e.drawIndexedIndirect(r.indirectBuffer,20*(t.indirectStartIndex+n))}setRetainedIndirectBundleState(e,t,r,n){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=n}getIndirectBundleHash(e,t,r){let n=2166136261;return n=En(n,e.key),n=En(n,zn(e.geometryResource.position)),n=En(n,e.geometryResource.index?zn(e.geometryResource.index):0),n=En(n,zn(t.indirectBuffer)),n=En(n,e.indirectStartIndex),n=En(n,e.indirectCount),n=En(n,this.sampleCount),n=En(n,e.material.version),n=En(n,this.graphTextureResourceVersion),n=En(n,r),n>>>0}getColorFormatsId(e){if(e===ia)return 1;const t=this.colorFormatsIdentityCache.get(e);if(void 0!==t)return t;const r=1===e.length?e[0]:e.join("|");let n=this.colorFormatsValueCache.get(r);return void 0===n&&(n=this.nextColorFormatsId,this.nextColorFormatsId+=1,this.colorFormatsValueCache.set(r,n)),this.colorFormatsIdentityCache.set(e,n),n}getDirectForwardBundleKey(e,t,r){let n=2166136261;n=En(n,e.length),n=En(n,this.sampleCount),n=En(n,zn(t));for(let i=0;i<e.length;i+=1){const a=e[i],s=this.getMaterialResourceForDraw(a,r),o=this.resolveSceneBindGroupForDraw(a,t);n=En(n,zn(a.material)),n=En(n,a.receiveShadow?1:0),n=En(n,a.material.version??0),n=En(n,zn(s.pipeline)),n=En(n,zn(s.bindGroup)),n=En(n,zn(o)),n=En(n,zn(a.geometryKey)),n=En(n,zn(a.geometryResource.position)),n=En(n,zn(a.geometryResource.normal)),n=En(n,zn(a.geometryResource.uv)),n=En(n,zn(a.geometryResource.color)),n=En(n,a.geometryResource.index?zn(a.geometryResource.index):0);for(const e of a.geometryResource.extraAttributeBuffers.values())n=En(n,zn(e));n=En(n,a.indexed?1:0),n=En(n,a.start),n=En(n,a.count),n=En(n,a.instanceStart),n=En(n,a.instanceCount);const l=a.material.getTexturesList();n=En(n,l.length);for(let e=0;e<l.length;e+=1){const t=l[e];n=En(n,zn(t)),n=En(n,t.version)}}return`forward-direct:${n}:${e.length}:samples=${this.sampleCount}:formats=${r.join("|")}`}getOrCreateDirectForwardBundle(e,t,r,n=ia){if(!this.state.device||!this.state.format||0===e.length)return null;const i=this.getDirectForwardBundleKey(e,t,n),a=this.state.directForwardBundleCache.get(i);if(a){for(let t=0;t<e.length;t+=1){const n=e[t];n.materialResource&&this.updateMaterialUniformBuffer(n.material,n.materialResource),this.recordDraw(n,r)}return a}const s=this.state.device.createRenderBundleEncoder({label:`renderer-direct-forward-bundle-${i}`,colorFormats:n,depthStencilFormat:"depth32float",sampleCount:this.sampleCount});let o=null,l=null,c=null,u=null;for(let i=0;i<e.length;i+=1){const a=e[i],d=a.geometryResource,h=this.getMaterialResourceForDraw(a,n),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-${i}`});return this.state.directForwardBundleCache.set(i,d),d}getOrCreateStaticMaterialBundle(e,t,r,n){const i=`${zn(t)}:${this.sampleCount}:${n.join("|")}`,a=this.materialPassStaticBundleCache.get(e)?.get(i);if(a)return this.recordStaticDrawStats(e,r),a;const s=this.getOrCreateDirectForwardBundle(e.draws,t,r,n);if(!s)return null;let o=this.materialPassStaticBundleCache.get(e);return o||(o=new Map,this.materialPassStaticBundleCache.set(e,o)),o.set(i,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,n=r.buffer,i=r.colorBuffer??r.buffer;return n&&i?(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:n}},{binding:3,resource:{buffer:i}},{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}]}:{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:n}},{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}]}),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 n=e.residentInstanceBinding,i=n.buffer,a=n.colorBuffer??n.buffer;if(!i||!a)return t;if(n.shadowBindGroupVersion!==this.state.residentShadowBindGroupVersion&&(n.shadowBindGroup=null,n.shadowBindGroups.clear(),n.shadowBindGroupVersion=this.state.residentShadowBindGroupVersion),r===this.state.shadowCameraBuffer&&n.shadowBindGroup)return n.shadowBindGroup;const s=n.shadowBindGroups.get(r);if(s)return s;const o=this.state.device.createBindGroup("instanced-direct"===n.mode?{label:"renderer-resident-direct-shadow-bind-group",layout:this.state.directShadowBindGroupLayout,entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:i}},{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:i}}]});return n.shadowBindGroups.set(r,o),r===this.state.shadowCameraBuffer&&(n.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*Wr;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 n=this.drawMetadataUpload,i=this.indirectDrawUpload;for(let t=0;t<e.length;t+=1){const r=e[t],a=t*Wr;n[a+0]=r.boundsCenter.x,n[a+1]=r.boundsCenter.y,n[a+2]=r.boundsCenter.z,n[a+3]=r.boundsRadius,n[a+4]=r.count,n[a+5]=r.start,n[a+6]=r.instanceStart,n[a+7]=r.instanceCount,n[a+8]=1,n[a+9]=0,n[a+10]=0,n[a+11]=0;const s=5*t;i[s+0]=r.count,i[s+1]=r.instanceCount,i[s+2]=r.start,i[s+3]=0,i[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*Wr*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,n,0,t),this.state.device.queue.writeBuffer(this.state.drawMetadataResource.indirectBuffer,0,i,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+=ei(e)}executeVisibilityPass(e,t){ui.call(this,e,t)}executeStaticVisibilityPasses(e,t){di.call(this,e,t)}getOrCreateStaticVisibilityBindGroup(e,t){return hi.call(this,e,t)}executeDirectionalShadowPass(e,t,r,n){pi.call(this,e,t,r,n)}executePointShadowPass(e,t,r,n){fi.call(this,e,t,r,n)}executeSpotShadowPass(e,t,r,n){mi.call(this,e,t,r,n)}executeDepthPrepass(e,t,r,n){gi.call(this,e,t,r,n)}executeStaticDepthPrepass(e,t,r){vi.call(this,e,t,r)}executeStaticTemporalDepthResolvePass(e){wi.call(this,e)}getOrCreateStaticDepthPrepassBundle(e,t){return yi.call(this,e,t)}executeHiZPasses(e,t=!1,r=!1){Pi.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))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}}]}),e.visibleSceneBindGroupVersion=this.state.residentSceneBindGroupVersion),e.visibleSceneBindGroup}getOrCreateStaticVisibleDepthSceneBindGroup(e){if(!this.state.device||!this.state.visibleDepthSceneBindGroupLayout||!this.state.cameraBuffer)throw new Error("Renderer visible depth scene bind group resources are not initialized.");return e.visibleDepthSceneBindGroup&&e.visibleDepthSceneBindGroupVersion===this.state.residentSceneBindGroupVersion||(e.visibleDepthSceneBindGroup=this.state.device.createBindGroup({label:`${e.label}-static-visible-depth-scene-bind-group`,layout:this.state.visibleDepthSceneBindGroupLayout,entries:[{binding:0,resource:{buffer:this.state.cameraBuffer}},{binding:2,resource:{buffer:e.instanceBuffer}},{binding:3,resource:{buffer:e.instanceVisibilityResource.visibleInstanceIndicesBuffer}}]}),e.visibleDepthSceneBindGroupVersion=this.state.residentSceneBindGroupVersion),e.visibleDepthSceneBindGroup}executeMaterialPass(e,t,r,n,i,a={}){if(!this.state.mainDepthView||0===t.length)return;const s=t.map(e=>this.getColorTargetFormat(e)),o=this.getColorFormatsId(s),l=t.map(e=>this.getColorTargetView(e)),c=this.sampleCount>1,u=c?t.map(e=>this.ensureMsaaColorTarget(e)):[],d=this.getColorTargetDimensions(t[0]),h=c?this.ensureMsaaDepthTarget(d.width,d.height):null,p=e.beginRenderPass({label:"renderer-material-pass",colorAttachments:t.map((e,t)=>({view:u[t]?.view??l[t],resolveTarget:u[t]?l[t]:void 0,clearValue:1===t?{r:.5,g:.5,b:1,a:1}:t>=2?{r:0,g:0,b:0,a:1}:{r:a.clearColor?.[0]??this.clearColor[0],g:a.clearColor?.[1]??this.clearColor[1],b:a.clearColor?.[2]??this.clearColor[2],a:a.clearColor?.[3]??this.clearColor[3]},loadOp:a.loadColor?"load":"clear",storeOp:u[t]?"discard":"store"})),depthStencilAttachment:{view:h?.view??this.state.mainDepthView,depthClearValue:1,depthLoadOp:h?"clear":a.loadDepth?"load":"clear",depthStoreOp:h?"discard":"store"}});let f=null,m=null,g=null,v=null,x=null;const w=e=>{e.sourceObject&&e.hasRenderCallbacks&&e.sourceObject.onBeforeRender(this,n.scene,n.camera,e.geometry,e.material,e.geometryGroup);const t=e.geometryResource;let a=e.material;const o=this.getMaterialResourceForDraw(e,s),l=this.resolveSceneBindGroupForDraw(e,r);if(f!==o.pipeline&&(f=o.pipeline,g=null,x=null,p.setPipeline(f)),g!==e.geometryKey&&(g=e.geometryKey,this.bindGeometryVertexBuffers(p,e.geometry,t,o.vertexAttributes,e.instanceStart,e.instanceCount,e.wireframe)),v!==l&&(v=l,p.setBindGroup(0,l)),m!==a){if(m=a,p.setBindGroup(1,o.bindGroup),!o.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");p.setBindGroup(3,this.createGraphTextureBindGroup(a,o.graphTextureBindGroupLayout))}o.usesSkinning&&e.skinning&&x!==e.skinning.bindGroup&&(x=e.skinning.bindGroup,p.setBindGroup(2,x)),e.indexed&&(e.wireframe?t.wireframeIndex:t.index)?p.drawIndexed(e.count,e.instanceCount,e.start,0,e.instanceStart):p.draw(e.count,e.instanceCount,e.start,e.instanceStart),this.recordDraw(e,i),e.sourceObject&&e.hasRenderCallbacks&&e.sourceObject.onAfterRender(this,n.scene,n.camera,e.geometry,e.material,e.geometryGroup)},b=a.drawStage??"all";if(a.objectFilter||a.overrideMaterial){const e=e=>{if(a.objectFilter){const t=e.sourceRanges?.filter(e=>a.objectFilter(e.sourceObject));if(null!=t&&t.length>0){const r="function"==typeof a.overrideMaterial?a.overrideMaterial(e.material,null!==e.skinning):a.overrideMaterial;for(const n of t)w({...e,sourceObject:n.sourceObject,instanceStart:n.instanceStart,instanceCount:n.instanceCount,material:r??e.material,sourceRanges:void 0});return}if(!a.objectFilter(e.sourceObject))return}const t="function"==typeof a.overrideMaterial?a.overrideMaterial(e.material,null!==e.skinning):a.overrideMaterial;w(t?{...e,material:t}:e)};if("late"!==b){for(const t of this.staticDrawSets)if(t.publicSet.enabled&&"opaque"===t.drawStage)for(const r of t.draws)e(r);for(const t of n.gpuOpaqueDraws)e(t);for(const t of n.directOpaqueDraws)e(t)}if("opaque"!==b)for(const t of n.transparentDraws)e(t);return void p.end()}if("late"!==b){for(const e of this.staticDrawSets){if(!e.publicSet.enabled||0===e.draws.length||"opaque"!==e.drawStage)continue;if(this.getHiZOcclusionCullingActive()&&e.lastVisibilityFrameToken===this.staticFrameToken){const t=this.getOrCreateStaticVisibleSceneBindGroup(e),r=this.getOrCreateStaticIndirectSubmissionStreams(e,t,s);for(const t of r){if(this.getMultiDrawIndirectActive()){if(p.setPipeline(t.materialResource.pipeline),this.bindGeometryVertexBuffers(p,t.geometry,t.geometryResource,t.materialResource.vertexAttributes,0,1,t.material.wireframe),p.setBindGroup(0,t.sceneBindGroup),p.setBindGroup(1,t.materialResource.bindGroup),!t.materialResource.graphTextureBindGroupLayout)throw new Error("Graph texture layout is missing.");p.setBindGroup(3,this.createGraphTextureBindGroup(t.material,t.materialResource.graphTextureBindGroupLayout)),p.multiDrawIndexedIndirect(e.drawMetadataResource.indirectBuffer,5*t.indirectStartIndex*Uint32Array.BYTES_PER_ELEMENT,t.indirectCount)}else this.renderBundleScratch[0]=this.getOrCreateIndirectForwardBundle(t,e.drawMetadataResource,e.indirectForwardBundleCache,`${e.label}-static-indirect-material-bundle`,s,!1,o),p.executeBundles(this.renderBundleScratch);i.drawCallCount+=t.drawCallCount,i.triangleCount+=t.triangleCount}continue}const t=this.getOrCreateStaticMaterialBundle(e,r,i,s);t&&(this.renderBundleScratch[0]=t,p.executeBundles(this.renderBundleScratch))}if(this.getHiZOcclusionCullingActive()&&this.state.drawMetadataResource){const e=this.indirectMaterialResourcesScratch;e.length=n.gpuOpaqueDraws.length;for(let t=0;t<n.gpuOpaqueDraws.length;t+=1)e[t]=this.getMaterialResourceForDraw(n.gpuOpaqueDraws[t],s);const t=this.buildIndirectSubmissionStreams(n.gpuOpaqueDraws,r,void 0,e);for(const e of t){const t=this.getOrCreateIndirectForwardBundle(e,this.state.drawMetadataResource,this.state.indirectForwardBundleCache,"renderer-indirect-material-bundle",s,!0,o);t?(this.renderBundleScratch[0]=t,p.executeBundles(this.renderBundleScratch)):this.submitIndirectStreamDirect(p,e,this.state.drawMetadataResource),i.drawCallCount+=e.drawCallCount,i.triangleCount+=e.triangleCount}}else{const e=kn(n.gpuOpaqueDraws)||n.gpuOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(n.gpuOpaqueDraws,r,i,s);if(e)this.renderBundleScratch[0]=e,p.executeBundles(this.renderBundleScratch);else for(const e of n.gpuOpaqueDraws)w(e)}const e=kn(n.directOpaqueDraws)||n.directOpaqueDraws.some(e=>null!==e.skinning)?null:this.getOrCreateDirectForwardBundle(n.directOpaqueDraws,r,i,s);if(e)this.renderBundleScratch[0]=e,p.executeBundles(this.renderBundleScratch);else for(const e of n.directOpaqueDraws)w(e)}if("opaque"!==b)for(const e of n.transparentDraws)w(e);p.end()}executeForwardPass(e,t,r,n,i,a,s=!1,o="all",l=!1,c=this.sampleCount){Mi.call(this,e,t,r,n,i,a,s,o,l,c)}executeStaticForwardPass(e,t,r,n="all",i=this.sampleCount){Bi.call(this,e,t,r,n,i)}getOrCreateStaticDirectForwardBundle(e,t,r=this.sampleCount){return Di.call(this,e,t,r)}refreshStaticDrawMaterialResources(e){Ii.call(this,e)}syncStaticVisibleMaterialBindingCaches(e){Ti.call(this,e)}recordStaticDrawStats(e,t){Ri.call(this,e,t)}hasEnabledStaticDrawSets(){return Vi.call(this)}executePresentPass(e,t,r){Gi.call(this,e,t,r)}clearDirectionalShadow(e){zi.call(this,e)}clearPointShadow(e){Ui.call(this,e)}clearSpotShadow(e){Li.call(this,e)}drawDepthLike(e,t,r,n){Ai.call(this,e,t,r,n)}getGeometryResource(e){if(!this.state.device)throw new Error("Renderer is not initialized.");const t=this.geometryCache.get(e);if(t&&this.updateDynamicGeometryAttributes(e,t))return t.lastValidatedExtractionVersion=this.extractionVersion,t;if(t&&t.lastValidatedExtractionVersion===this.extractionVersion)return t;if(t&&function(e,t){if(t.indexVersion!==(e.index?.version??0)||t.drawRangeStart!==e.drawRange.start||t.drawRangeCount!==e.drawRange.count)return!1;if(t.groups.length!==e.groups.length)return!1;for(let r=0;r<t.groups.length;r+=1){const n=t.groups[r],i=e.groups[r];if(n.start!==i?.start||n.count!==i?.count||n.materialIndex!==(i?.materialIndex??0))return!1}for(let r=0;r<t.attributes.length;r+=1){const n=t.attributes[r],i=e.getAttribute(n.name);if(i?un(i)!==n.version||i.itemSize!==n.itemSize||i.count!==n.count:0!==n.version||0!==n.itemSize||0!==n.count)return!1}return!0}(e,t))return t.lastValidatedExtractionVersion=this.extractionVersion,t;t&&(this.clearIndirectBundleCache(),this.retireGeometryResource(t));const r=e.getAttribute("position");if(!r)throw new Error("BufferGeometry is missing the required position attribute.");const n=r.count,i=Sn(r,n,3,[0,0,0]),a=Sn(e.getAttribute("normal"),n,3,[0,0,1]),s=Sn(e.getAttribute("uv"),n,2,[0,0]),o=Sn(e.getAttribute("color"),n,4,[1,1,1,1]),l=e.getAttribute("skinIndex"),c=e.getAttribute("skinWeight"),u=l?Cn(l,n,"uint32x4",[]):void 0,d=c?Cn(c,n,"float32x4",[]):void 0;let h=null,p=null;if(e.index){const t=e.index.array,r=t instanceof Uint32Array?t:new Uint16Array(t);p=t instanceof Uint32Array?"uint32":"uint16",h=vn(this.state.device,r,GPUBufferUsage.INDEX,`${e.uuid}-index`)}const f={signature:dn(e),indexVersion:e.index?.version??0,drawRangeStart:e.drawRange.start,drawRangeCount:e.drawRange.count,vertexCount:n,attributes:["position","normal","uv","color",...l?["skinIndex"]:[],...c?["skinWeight"]:[]].map(t=>{const r=e.getAttribute(t);return{name:t,version:un(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,i,a,s,o,u,d,e.index?.array),extraAttributeBuffers:new Map,extraAttributeBufferVersions:new Map,wireframeIndex:null,wireframeIndexFormat:null};return this.geometryCache.set(e,f),f}updateDynamicGeometryAttributes(e,t){if(!this.state.device)return!1;let r=!1;for(const n of t.attributes){const t=e.getAttribute(n.name),i=t?.itemSize??0,a=t?.count??0;if(i!==n.itemSize||a!==n.count)return!1;r||=un(t)!==n.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 n=t.groups[r],i=e.groups[r];if(n.start!==i?.start||n.count!==i?.count||n.materialIndex!==(i?.materialIndex??0))return!1}const n={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),i=un(t);if(i===r.version)continue;const a=n[r.name];if(!t||!a?.buffer)return!1;const s=Number(a.format.at(-1)),o="updateRanges"in t&&t.updateRanges.length>0?t.updateRanges:[{start:0,count:t.count*t.itemSize}];for(const e of o){const r=Math.max(0,Math.floor(e.start/t.itemSize)),n=Math.min(t.count,Math.ceil((e.start+e.count)/t.itemSize));if(n<=r)continue;const i="uint32x4"===a.format?new Uint32Array((n-r)*s):new Float32Array((n-r)*s);for(let e=r;e<n;e++){const n=(e-r)*s,o=[t.getX(e),t.itemSize>1?t.getY(e):void 0,t.itemSize>2?t.getZ(e):void 0,t.itemSize>3?t.getW(e):void 0];for(let e=0;e<s;e++)i[n+e]=o[e]??a.defaults[e]??0}this.state.device.queue.writeBuffer(a.buffer,r*s*4,i)}"clearUpdateRanges"in t&&t.clearUpdateRanges(),r.version=i}return t.signature=dn(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"),n=e.geometry.getAttribute("position");if(!t||!r||!n)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 i=this.getGeometryResource(e.geometry),a=function(e){return[dn(e.geometry),un(e.geometry.getAttribute("skinIndex")),un(e.geometry.getAttribute("skinWeight")),e.skeleton.bones.length].join(";")}(e);let s=this.skinnedGeometryCache.get(e);if(s?.resource===i&&s.skinning.palette.skeleton===e.skeleton&&(s.sourceSignature=a),!s||s.sourceSignature!==a||s.skinning.palette.skeleton!==e.skeleton){s&&s.skinning.bindUniformBuffer.destroy();const o=this.getSkinningPalette(e.skeleton),l=this.state.device.createBuffer({label:`${e.uuid}-skinning-bind-matrices`,size:32*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),c=new Float32Array(32);c.set(e.bindMatrix.elements,0),c.set(e.bindMatrixInverse.elements,16);const u={sourceSignature:a,resource:i,skinning:{bindGroup:this.state.device.createBindGroup({label:`${e.uuid}-skinning-bind-group`,layout:this.state.skinningBindGroupLayout,entries:[{binding:0,resource:{buffer:o.matrixBuffer}},{binding:1,resource:{buffer:l}},{binding:2,resource:{buffer:o.previousMatrixBuffer}}]}),bindUniformBuffer:l,bindMatrices:c,palette:o,bindUniformDirty:!0},boneBounds:this.createSkinningBoneBounds(e,n,t,r),localBoundsMin:new yt,localBoundsMax:new yt,localBoundsCenter:new yt,localBoundsRadius:1};s=u,this.skinnedGeometryCache.set(e,u)}if(!s)throw new Error("Skinned geometry cache entry could not be created.");return s}getSkinningPalette(e){const t=this.skinPaletteCache.get(e);if(t)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;Jn(e);const n=new Float32Array(e.boneMatrices),i={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:n,dirty:!0,lastRefreshExtractionVersion:-1};return this.skinPaletteCache.set(e,i),this.skinPaletteResources.add(i),i}refreshSkinningPalette(e){if(e.lastRefreshExtractionVersion===this.extractionVersion)return;e.lastRefreshExtractionVersion=this.extractionVersion;const{skeleton:t}=e;Jn(t),e.dirty=!0}refreshSkinningBindMatrices(e,t){const r=t.bindMatrices;let n=!1;for(let t=0;t<16;t+=1){const i=e.bindMatrix.elements[t],a=e.bindMatrixInverse.elements[t];r[t]===i&&r[t+16]===a||(n=!0),r[t]=i,r[t+16]=a}t.bindUniformDirty||=n}uploadSkinningResources(e){if(this.state.device){if(e.palette.dirty){const t=e.palette.skeleton.boneMatrices;this.state.device.queue.writeBuffer(e.palette.previousMatrixBuffer,0,e.palette.previousMatrices.buffer,e.palette.previousMatrices.byteOffset,e.palette.previousMatrices.byteLength),this.state.device.queue.writeBuffer(e.palette.matrixBuffer,0,t.buffer,t.byteOffset,16*e.palette.skeleton.bones.length*Float32Array.BYTES_PER_ELEMENT),e.palette.previousMatrices.set(t),e.palette.dirty=!1}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,n){const i=Array.from({length:e.skeleton.bones.length},()=>new yt(1/0,1/0,1/0)),a=Array.from({length:e.skeleton.bones.length},()=>new yt(-1/0,-1/0,-1/0));for(let e=0;e<t.count;e+=1){an.set(t.getX(e),t.getY(e),t.getZ(e));for(let t=0;t<4;t+=1){if(n.getComponent(e,t)<=0)continue;const s=Math.round(r.getComponent(e,t)),o=i[s],l=a[s];o&&l&&(o.min(an),l.max(an))}}return i.map((e,t)=>{if(!Number.isFinite(e.x))return null;const r=a[t],n=e.clone().add(r).multiplyScalar(.5);return{center:n,radius:r.distanceTo(n)}})}updateSkinnedBounds(e,t){const r=t.localBoundsMin,n=t.localBoundsMax,i=Zn(e.geometry);r.set(i.center.x-i.radius,i.center.y-i.radius,i.center.z-i.radius),n.set(i.center.x+i.radius,i.center.y+i.radius,i.center.z+i.radius);for(let i=0;i<t.boneBounds.length;i+=1){const a=t.boneBounds[i];if(!a)continue;const s=Xn(a.center,a.radius,e.bindMatrix,t.skinning.palette.skeleton.boneMatrices,16*i,e.bindMatrixInverse,an);r.min(sn.copy(an).addScalar(-s)),n.max(sn.copy(an).addScalar(s))}t.localBoundsCenter.copy(r).add(n).multiplyScalar(.5),t.localBoundsRadius=n.distanceTo(t.localBoundsCenter)}createGeometryBuffers(e,t,r,n,i,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=vn(this.state.device,t,GPUBufferUsage.INDEX,`${e}-index`)}return{position:vn(this.state.device,t,l|GPUBufferUsage.COPY_DST,`${e}-position`),normal:vn(this.state.device,r,c|GPUBufferUsage.COPY_DST,`${e}-normal`),uv:vn(this.state.device,n,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-uv`),color:vn(this.state.device,i,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-color`),skinIndex:a?vn(this.state.device,a,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e}-skin-index`):null,skinWeight:s?vn(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+=pn(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 n=e.length-r;const i=[],a=new Set;for(const t of["vertex","instance"]){if(0===n)break;const r=e.filter(e=>(e.stepMode??"vertex")===t),s=Math.min(r.length,n+1);if(s<2)continue;const o=r.slice(0,s);i.push(o);for(const e of o)a.add(e);n-=s-1}if(n>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=i.find(e=>e[0]===t);e&&s.push(e)}return this.vertexAttributeGroupCache.set(e,s),s}getGeometryAttributeBufferKey(e){const t=this.vertexAttributeBufferKeyCache.get(e);if(void 0!==t)return t;const r=function(e){const t=e.defaultValue?Array.from(e.defaultValue).join(","):"";return`${e.name}:${e.format}:${e.stepMode??"vertex"}:${t}`}(e);return this.vertexAttributeBufferKeyCache.set(e,r),r}getGeometryAttributeGroupBufferKey(e){const t=this.vertexAttributeGroupBufferKeyCache.get(e);if(void 0!==t)return t;const r=e.map(e=>this.getGeometryAttributeBufferKey(e)).join("|");return this.vertexAttributeGroupBufferKeyCache.set(e,r),r}getMaterialVertexAttributes(e,t){let r=this.materialVertexAttributeCache.get(e);if(r&&r.version===e.version||(r={version:e.version,unskinned:e.vertexAttributes.slice()},this.materialVertexAttributeCache.set(e,r)),!t)return r.unskinned;if(r.skinned)return r.skinned;const n=r.unskinned.slice(),i=[{name:"skinIndex",shaderLocation:4,format:"uint32x4"},{name:"skinWeight",shaderLocation:5,format:"float32x4"}];for(const e of i){const t=n.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=n.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}".`);n.push(e)}return r.skinned=n,r.skinned}getGeometryVertexBuffer(e,t,r,n=0,i=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(n)):0;if(o&&!s)return this.getDefaultInstanceAttributeBuffer(r,l+Math.max(1,i));const c=un(s),u=this.geometryVertexBufferFastCache.get(t),d=u?.get(r),h=d?.get(l);if(h&&h.source===s&&h.version===c&&h.itemSize===(s?.itemSize??0)&&h.count===(s?.count??0))return h.buffer;const p=`${this.getGeometryAttributeBufferKey(r)}${o?`:instance-start=${l}`:""}`,f=s?`${c}:${s.itemSize}:${s.count}`:"default",m=t.extraAttributeBuffers.get(p);if(m&&t.extraAttributeBufferVersions.get(p)===f)return this.cacheGeometryVertexBufferFast(t,r,l,s,c,m),m;if(!s&&!r.defaultValue)throw new Error(`Geometry "${e.uuid}" is missing required vertex attribute "${r.name}".`);const g=Cn(s,o?l+Math.max(1,s?.count??1,i):t.vertexCount,r.format,r.defaultValue??[],o?l:0);if(m&&m.size>=Math.max(4,g.byteLength))return this.state.device.queue.writeBuffer(m,0,g.buffer,g.byteOffset,g.byteLength),t.extraAttributeBufferVersions.set(p,f),this.cacheGeometryVertexBufferFast(t,r,l,s,c,m),m;const v=vn(this.state.device,g,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e.uuid}-${r.name}-${r.format}`);return m&&(this.clearIndirectBundleCache(),this.retiredGeometryBuffers.push(m)),t.extraAttributeBuffers.set(p,v),t.extraAttributeBufferVersions.set(p,f),this.cacheGeometryVertexBufferFast(t,r,l,s,c,v),v}cacheGeometryVertexBufferFast(e,t,r,n,i,a){let s=this.geometryVertexBufferFastCache.get(e);s||(s=new WeakMap,this.geometryVertexBufferFastCache.set(e,s));let o=s.get(t);o||(o=new Map,s.set(t,o));const l=n;o.set(r,{source:n,version:i,itemSize:l?.itemSize??0,count:l?.count??0,buffer:a})}getInterleavedGeometryVertexBuffer(e,t,r,n,i){if(!this.state.device)throw new Error("Renderer is not initialized.");const a=r[0].stepMode??"vertex",s=Math.max(0,Math.trunc(n)),o="instance"===a?s+Math.max(1,i,...r.map(t=>e.getAttribute(t.name)?.count??1)):t.vertexCount,l=`interleaved:${this.getGeometryAttributeGroupBufferKey(r)}:instance-start=${"instance"===a?s:0}`,c=r.map(t=>{const r=e.getAttribute(t.name);return r?`${un(r)}:${r.itemSize}:${r.count}`:"default"}).join("|"),u=t.extraAttributeBuffers.get(l);if(u&&t.extraAttributeBufferVersions.get(l)===c)return u;const d=[];let h=0;for(const e of r)d.push(h),h+=pn(e.format);const p=new Uint8Array(o*h);for(let t=0;t<r.length;t+=1){const n=r[t],i=Cn(e.getAttribute(n.name),o,n.format,n.defaultValue??[],"instance"===a?s:0),l=new Uint8Array(i.buffer,i.byteOffset,i.byteLength),c=pn(n.format);for(let e=0;e<o;e+=1)p.set(l.subarray(e*c,(e+1)*c),e*h+d[t])}if(u&&u.size>=Math.max(4,p.byteLength))return this.state.device.queue.writeBuffer(u,0,p.buffer,p.byteOffset,p.byteLength),t.extraAttributeBufferVersions.set(l,c),u;const f=vn(this.state.device,p,GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST,`${e.uuid}-interleaved-${a}`);return u&&(this.clearIndirectBundleCache(),this.retiredGeometryBuffers.push(u)),t.extraAttributeBuffers.set(l,f),t.extraAttributeBufferVersions.set(l,c),f}ensureWireframeIndex(e,t){if(t.wireframeIndex)return;if(!this.state.device)throw new Error("Renderer is not initialized.");const r=e.index?.array,n=r?.length??t.vertexCount,i=Math.floor(n/3),a=t.vertexCount>65535,s=a?new Uint32Array(6*i):new Uint16Array(6*i);for(let e=0;e<i;e+=1){const t=3*e,n=6*e,i=r?r[t]:t,a=r?r[t+1]:t+1,o=r?r[t+2]:t+2;s[n]=i,s[n+1]=a,s[n+2]=a,s[n+3]=o,s[n+4]=o,s[n+5]=i}t.wireframeIndexFormat=a?"uint32":"uint16",t.wireframeIndex=vn(this.state.device,s,GPUBufferUsage.INDEX,`${e.uuid}-wireframe-index`)}bindGeometryVertexBuffers(e,t,r,n,i=0,a=1,s=!1){let o=this.vertexBufferBindingPlanCache.get(n);o||(o=this.getVertexAttributeGroups(n).map(e=>({group:e,standardAttribute:1===e.length?this.getStandardVertexAttribute(e[0]):null})),this.vertexBufferBindingPlanCache.set(n,o));for(let n=0;n<o.length;n+=1){const{group:s,standardAttribute:l}=o[n],c=l?r[l]:null;e.setVertexBuffer(n,c??(1===s.length?this.getGeometryVertexBuffer(t,r,s[0],i,a):this.getInterleavedGeometryVertexBuffer(t,r,s,i,a)))}s&&r.wireframeIndex&&r.wireframeIndexFormat?e.setIndexBuffer(r.wireframeIndex,r.wireframeIndexFormat):r.index&&r.indexFormat&&e.setIndexBuffer(r.index,r.indexFormat)}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&&!bn(e.defaultValue,da)?"uv"!==e.name||"float32x2"!==e.format||void 0!==e.defaultValue&&!bn(e.defaultValue,ua)?"color"!==e.name||"float32x4"!==e.format||void 0!==e.defaultValue&&!bn(e.defaultValue,ha)?"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){const t=e.customDepthMaterial?[e.material,e.customDepthMaterial]:[e.material];for(const r of t){const t=this.getMaterialVertexAttributes(r,null!==e.skinning);for(const r of this.getVertexAttributeGroups(t))1===r.length?this.getGeometryVertexBuffer(e.geometry,e.geometryResource,r[0],e.instanceStart,e.instanceCount):this.getInterleavedGeometryVertexBuffer(e.geometry,e.geometryResource,r,e.instanceStart,e.instanceCount)}}getDefaultInstanceAttributeBuffer(e,t){if(!this.state.device)throw new Error("Renderer is not initialized.");const r=Math.max(1,t,Math.ceil(this.state.instanceBufferSize/(Float32Array.BYTES_PER_ELEMENT*Nr))),n=2**Math.ceil(Math.log2(r)),i=`${e.format}:${(e.defaultValue??[]).join(",")}`;let a=this.defaultInstanceAttributeBuffers.get(i);a||(a=new Map,this.defaultInstanceAttributeBuffers.set(i,a));const s=a.get(n);if(s)return s;const o=vn(this.state.device,Cn(void 0,n,e.format,e.defaultValue??[]),GPUBufferUsage.VERTEX,`renderer-default-instance-${e.format}`);return a.set(n,o),o}getMeshExtractionCacheEntry(e,t,r,n,i,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===i&&(null!==l&&s.material===l&&s.resolvedMaterial===r||null!==o&&null!==s.materials&&null!==s.resolvedMaterials&&gn(s.materials,o)&&wn(s.resolvedMaterials,n)))return s;const c=null!==e.geometry.index,u=Zn(e.geometry),d=[];if(e.geometry.groups.length>0)for(const t of e.geometry.groups){const s=o?n[t.materialIndex??0]??n[0]:r;if(!s)continue;const l=Pn(e.geometry,c,t.start,t.count),u=Un(s,e.geometry,c,t.start,l,i),h=zn(s),p=zn(e.geometry),f=i?zn(i):0;d.push({geometry:e.geometry,geometryKey:e.geometry,geometryResource:a,material:s,customDepthMaterial:i,residentInstanceBinding:null,sourceObject:e,usesBatching:!1,geometryGroup:t,batchKey:u,batchHash:Ln(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??n?.[0]??null;if(t){const r=Mn(e.geometry,c),n=Un(t,e.geometry,c,r.start,r.count,i),s=zn(t),o=zn(e.geometry),l=i?zn(i):0;d.push({geometry:e.geometry,geometryKey:e.geometry,geometryResource:a,material:t,customDepthMaterial:i,residentInstanceBinding:null,sourceObject:e,usesBatching:!1,geometryGroup:null,batchKey:n,batchHash:Ln(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?n.slice():null,customDepthMaterial:i,indexed:c,templates:d,localBoundsCenter:u.center.clone(),localBoundsRadius:u.radius};return this.meshExtractionCache.set(e,h),h}getInstancedMeshExtractionCacheEntry(e,t,r,n){const i=null!==e.geometry.index,a=Mn(e.geometry,i),s=Zn(e.geometry),o=this.instancedMeshExtractionCache.get(e);if(o&&o.geometryResource===n&&o.material===t&&o.customDepthMaterial===r&&o.indexed===i&&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=zn(t),c=zn(e.geometry),u=r?zn(r):0,d={geometryResource:n,sourceMesh:e,sourceMaterial:e.material,sourceMaterialVersion:e.material.version,material:t,customDepthMaterial:r,indexed:i,drawRangeStart:a.start,drawRangeCount:a.count,batchKey:Un(t,e,i,a.start,a.count,r),batchHash:Ln(l,c,i,a.start,a.count,u),sortMaterialId:l,sortGeometryId:c,sortCustomDepthMaterialId:u,localBoundsCenter:s.center.clone(),localBoundsRadius:s.radius,cachedInstanceData:new Oi(1024),cachedBoundsMin:new yt,cachedBoundsMax:new yt,cachedDrawBoundsCenter:new yt,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,n,i){const a=i._geometryCount??0,s=this.batchedMeshExtractionCache.get(e);if(s&&s.geometryResource===n&&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 i=0;i<a;i+=1){const a=e.getGeometryRangeAt(i);if(!a||a.count<=0)continue;const s=Pn(e.geometry,o,a.start,a.count),u=Un(t,e.geometry,o,a.start,s,r),d=zn(t),h=zn(e.geometry),p=r?zn(r):0,f=e.getBoundingSphereAt(i,nn),m={geometry:e.geometry,geometryKey:e.geometry,geometryResource:n,material:t,customDepthMaterial:r,residentInstanceBinding:null,sourceObject:e,usesBatching:!0,geometryGroup:null,batchKey:u,batchHash:Ln(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:i,localBoundsCenter:f?f.center.clone():new yt,localBoundsRadius:f?.radius??1};l[i]=m,c[i]={template:m,boundsMin:new yt,boundsMax:new yt,activeInFrame:!1,activeCount:0,instanceStart:0,writeOffset:0}}const u={geometryResource:n,material:t,customDepthMaterial:r,indexed:o,templates:l,groups:c,activeGroups:[],cachedInstanceData:new Oi(1024),cachedDraws:[],cachedBoundsMin:new yt,cachedBoundsMax:new yt,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 n=t[r];if((e[r]??-1)!==(n?.active&&n.visible?n.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 n=t.uniformValueHash;if(e.uniformValuesAutoUpdate){if(n=e.getUniformValueHash(),t.uniformValueHash===n)return}else if(t.uniformValuesAutoVersion===e.uniformValuesAutoVersion)return;const i=Ze(e.uniforms,r);!t.uniformBuffer||i.byteLength>t.uniformBuffer.size||(t.uniformValueHash=n,t.uniformValuesAutoVersion=e.uniformValuesAutoVersion,this.state.device.queue.writeBuffer(t.uniformBuffer,0,i))}materialResourceMatches(e,t,r,n=this.sampleCount){if(e.key!==r)return!1;if(e.materialVersion===t.version&&e.textureVersionHash===t.getTextureVersionHash()&&e.rendererSampleCount===n&&e.uniformBufferSize===t.getUniformLayout().byteLength)return!0;const i=wn(e.textures,t.getTexturesList())&&bn(e.textureVersions,t.getTextureVersionsList())&&wn(e.storageBuffers,t.getStorageBufferList())&&e.rendererSampleCount===n&&e.uniformBufferSize===t.getUniformLayout().byteLength;return i&&(e.materialVersion=t.version,e.textureVersionHash=t.getTextureVersionHash()),i}destroyMaterialResource(e){e?.uniformBuffer?.destroy()}createMaterialBindGroupData(e,t,r){if(!this.state.device)throw new Error("Renderer is not initialized.");const n=[],i=[],a=Array.from(e.getTexturesList()),s=Array.from(e.getTextureVersionsList()),o=e.getStorageBufferBindingList();let l=null;if(Object.keys(e.uniforms).length>0){const r=Ze(e.uniforms,e.getUniformLayout());l=this.state.device.createBuffer({label:`${t}-uniforms`,size:r.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.state.device.queue.writeBuffer(l,0,r),n.push({binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}),i.push({binding:0,resource:{buffer:l}})}for(const[e,t]of a.entries()){const a=1+2*e,s=this.getTextureResource(t);n.push({binding:a,visibility:r,sampler:{type:s.samplerBindingType}},{binding:a+1,visibility:r,texture:{sampleType:s.sampleType,viewDimension:s.viewDimension}}),i.push({binding:a,resource:s.sampler},{binding:a+1,resource:s.view})}const c=1+2*a.length,u=Array.from(e.getStorageBufferList());for(const[e,t]of o.entries()){const r=c+e;n.push({binding:r,visibility:xn(t.visibility),buffer:{type:"read-only-storage"}}),i.push({binding:r,resource:{buffer:t.buffer}})}return{bindGroupLayoutEntries:n,bindGroupEntries:i,uniformBuffer:l,textures:a,textureVersions:s,storageBuffers:u}}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 n=r?.get(t);if(n&&n.materialVersion===e.version&&n.resourceVersion===this.graphTextureResourceVersion)return n.bindGroup;const i=[];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:this.state.linearClampSampler,n="mainDepth"===e.resource?this.state.sceneDepthSnapshotView:this.getGraphTextureView(e.resource);i.push({binding:2*t,resource:r},{binding:2*t+1,resource:n})});const a=this.state.device.createBindGroup({label:`${e.uuid}-graph-textures`,layout:t,entries:i});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"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),n=null!==r.skinning,i=this.drawUsesBatching(r),a=`${r.material.uuid}:${e}:receiveShadow=${r.receiveShadow?1:0}:skinning=${n?1:0}:batching=${i?1:0}`;t.has(a)||(r.materialResource=this.getMaterialResource(r.material,e,r.receiveShadow,void 0,n,i),t.add(a))}}async compileDrawMaterialsAsync(e,t=ia,r=this.sampleCount){const n=new Set,i=new Set,a=[];for(const s of e){const e=this.getDrawInstanceAccessMode(s),o=null!==s.skinning,l=this.drawUsesBatching(s),c=`${s.material.uuid}:${e}:receiveShadow=${s.receiveShadow?1:0}:skinning=${o?1:0}:batching=${l?1:0}`;if(n.has(c)||(a.push(this.getMaterialResourceAsync(s.material,e,s.receiveShadow,t,o,l,r).then(e=>(s.materialResource=e,e))),n.add(c)),s.customDepthMaterial){const t=`${s.customDepthMaterial.uuid}:${e}:skinning=${o?1:0}`;i.has(t)||(a.push(this.getDepthPassMaterialResourceAsyncForDraw(s.customDepthMaterial,"directionalShadow",s)),i.add(t))}if(null!==s.material.depthVertexShader||l){const t=null!==s.material.depthVertexShader?["prepass","directionalShadow","pointShadow"]:["prepass","directionalShadow"];for(const r of t){const t=`${s.material.uuid}:${r}:${e}:skinning=${o?1:0}:batching=${l?1:0}`;i.has(t)||(a.push(this.getDepthPassMaterialResourceAsyncForDraw(s.material,r,s)),i.add(t))}}}await Promise.all(a)}async compileStaticDrawMaterialsAsync(e,t=this.sampleCount){const r=[],n=new Set;for(const i of this.staticDrawSets)if(i.publicSet.enabled){r.push(this.compileDrawMaterialsAsync(i.draws,e,t));for(const a of i.visibleMaterialBindings){const i=`${a.material.uuid}:receiveShadow=${a.receiveShadow?1:0}:batching=${a.usesBatching?1:0}`;n.has(i)||(n.add(i),r.push(this.getMaterialResourceAsync(a.material,"packed-visible",a.receiveShadow,e,!1,a.usesBatching,t)))}}await Promise.all(r)}getDepthPassMaterialKey(e,t,r,n,i){if(!this.state.device)throw new Error("Renderer is not initialized.");return`${e.customProgramCacheKey()}:${t}:instance=${r}:skinning=${n?1:0}:batching=${i?1:0}:textures=${e.getTextureLayoutKey(this.state.device)}`}getForwardMaterialKey(e,t,r,n,i,a,s=this.sampleCount){return`${e.customProgramCacheKey()}:instance=${t}:receiveShadow=${r?1:0}:skinning=${i?1:0}:batching=${a?1:0}:textures=${e.getTextureLayoutKey(this.state.device)}:samples=${s}:targets=${n.join("|")}`}getInstanceAccessModeIndex(e){return"packed"===e?0:"packed-visible"===e?1:2}getForwardMaterialFastCacheIndex(e,t,r,n){return this.getInstanceAccessModeIndex(e)|(t?4:0)|(r?8:0)|(n?16:0)}getDepthMaterialFastCacheIndex(e,t,r,n){return("prepass"===e?0:"directionalShadow"===e?1:2)+3*this.getInstanceAccessModeIndex(t)+(r?9:0)+(n?18:0)}fastMaterialResourceMatches(e,t,r=this.sampleCount){return e.materialVersion===t.version&&e.textureVersionHash===t.getTextureVersionHash()&&e.rendererSampleCount===r}setForwardMaterialFastCache(e,t,r){let n=this.forwardMaterialFastCache.get(e);n||(n=[],this.forwardMaterialFastCache.set(e,n)),n[t]=r}getForwardMaterialTargetFastCacheKey(e,t){return 32*this.getColorFormatsId(e)+t}setForwardMaterialTargetFastCache(e,t,r){let n=this.forwardMaterialTargetFastCache.get(e);n||(n=new Map,this.forwardMaterialTargetFastCache.set(e,n)),n.set(t,r)}setForwardMaterialFrameCache(e,t,r){let n=this.forwardMaterialFrameCache.get(e);n||(n=[],this.forwardMaterialFrameCache.set(e,n)),n[t]={extractionVersion:this.extractionVersion,resource:r}}setDepthMaterialFastCache(e,t,r){let n=this.depthMaterialFastCache.get(e);n||(n=[],this.depthMaterialFastCache.set(e,n)),n[t]=r}getDrawInstanceAccessMode(e){return"instanced-direct"===e.residentInstanceBinding?.mode?"instanced-direct":"packed"}drawUsesBatching(e){return e.usesBatching}buildMaterialShaderCode(e,t,r,n,i=!1,a=!1){const s=Mt(`${t}\n${r}`,this.createMaterialPreprocessorDefines(e,n,i,a),{sourceName:n});return n.includes("vertex")?function(e){return e.replace(/@builtin\s*\(\s*position\s*\)(?!\s*@invariant)\s+(?=[A-Za-z_]\w*\s*:)/g,"@builtin(position) @invariant ").replace(/@builtin\s*\(\s*position\s*\)(?!\s*@invariant)\s+(?=vec4(?:\s*<\s*f32\s*>|f)\b)/g,"@builtin(position) @invariant ")}(s):s}createMaterialPreprocessorDefines(e,t,r=!1,n=!1){const i={HIGH_PRECISION:!0,WEBGPU_RENDERER:!0,WGSL_SHADER_MATERIAL:!0,USE_BATCHING:n,USE_COLOR:!0,USE_COLOR_ALPHA:!0,NUM_DIR_LIGHTS:4,NUM_POINT_LIGHTS:jr,NUM_SPOT_LIGHTS:$r,NUM_DIR_LIGHT_SHADOWS:4,NUM_POINT_LIGHT_SHADOWS:jr,NUM_SPOT_LIGHT_SHADOWS:$r,NUM_CLIPPING_PLANES:0,UNION_CLIPPING_PLANES:0,USE_SKINNING:r,RENDERER_MOTION_VECTORS:!t.includes("shared-depth"),...this.createTexturePreprocessorDefines(e)};return e.side===ut?i.DOUBLE_SIDED=!0:e.side===st&&(i.FLIP_SIDED=!0),!t.includes("receiveShadow=1")&&t.includes("receiveShadow=0")||(i.USE_SHADOWMAP=!0,i.SHADOWMAP_TYPE_PCF=!0),{...i,...e.defines,USE_BATCHING:n}}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[n,i]of Object.entries(r))e.textures[n]&&(t[i]=!0);return t}shouldInvalidateDrawMaterialResource(e,t,r,n,i){return!!e.materialResource&&(e.material!==t||e.receiveShadow!==r||e.usesBatching!==n||e.skinning!==i)}cachedDrawMaterialResourceMatches(e,t,r,n=this.sampleCount){const i=this.getDrawInstanceAccessMode(e),a=null!==e.skinning,s=this.drawUsesBatching(e),o=this.getColorFormatsId(r);return t.instanceAccessMode===i&&t.receiveShadow===e.receiveShadow&&t.useBatching===s&&t.usesSkinning===a&&t.rendererSampleCount===n&&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,n)))}getMaterialResourceForDraw(e,t=ia,r=this.sampleCount){const n=e.materialResource;if(n&&this.cachedDrawMaterialResourceMatches(e,n,t,r))return this.drawMaterialResourceFrameValidation.get(n)!==this.extractionVersion&&(this.updateMaterialUniformBuffer(e.material,n),this.drawMaterialResourceFrameValidation.set(n,this.extractionVersion)),n;const i=this.getDrawInstanceAccessMode(e),a=null!==e.skinning,s=this.drawUsesBatching(e),o=this.getMaterialResource(e.material,i,e.receiveShadow,t,a,s,r);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))}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))}}getDepthPassMaterialResourceForDraw(e,t,r){return this.getDepthPassMaterialResource(e,t,this.getDrawInstanceAccessMode(r),null!==r.skinning,this.drawUsesBatching(r))}getDepthPassMaterialResourceAsyncForDraw(e,t,r){return this.getDepthPassMaterialResourceAsync(e,t,this.getDrawInstanceAccessMode(r),null!==r.skinning,this.drawUsesBatching(r))}getOrCreateSharedDepthPipeline(e,t,r,n,i,a,s){if(!(this.state.device&&this.state.shadowBindGroupLayout&&this.state.directShadowBindGroupLayout&&this.state.skinningBindGroupLayout))throw new Error("Renderer is not initialized.");const o=this.sharedDepthPipelineCache.get(e);if(o)return o;const l=this.state.device.createBindGroupLayout({label:`${e}-shared-depth-material-layout`,entries:i}),c="prepass"===r?"instanced-direct"===n?this.state.directSceneBindGroupLayout:this.state.sceneBindGroupLayout:"instanced-direct"===n?this.state.directShadowBindGroupLayout:this.state.shadowBindGroupLayout,u=this.state.device.createPipelineLayout({label:`${e}-shared-depth-pipeline-layout`,bindGroupLayouts:[c,l,...a?[this.state.skinningBindGroupLayout]:[]]}),d=br(t,"prepass"===r?"camera":"shadow",this.state.device,n,a),h=this.buildMaterialShaderCode(t,d,"pointShadow"===r?t.pointShadowVertexShader??t.vertexShader:t.depthVertexShader??t.vertexShader,`${e}-shared-depth-vertex`,a,s),p="pointShadow"===r?t.pointShadowFragmentShader:t.depthFragmentShader,f=p?this.buildMaterialShaderCode(t,d,p,`${e}-shared-depth-fragment`,a,s):null,m={bindGroupLayout:l,pipeline:this.state.device.createRenderPipeline({label:`${e}-shared-depth-pipeline`,layout:u,vertex:{module:this.state.device.createShaderModule({label:`${e}-shared-depth-vertex`,code:h}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,a))},...f?{fragment:{module:this.state.device.createShaderModule({label:`${e}-shared-depth-fragment`,code:f}),entryPoint:"fsMain",targets:"pointShadow"===r?[{format:"rgba16float"}]:[]}}:{},primitive:{topology:sa(t),cullMode:oa(t,r,s),frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",..."directionalShadow"===r?{depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}:{}}})};return this.sharedDepthPipelineCache.set(e,m),m}async getOrCreateSharedDepthPipelineAsync(e,t,r,n,i,a,s){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 o=this.sharedDepthPipelineCache.get(e);if(o)return o;const l=this.sharedDepthPipelinePromiseCache.get(e);if(l)return l;const c=(async()=>{const o=this.state.device.createBindGroupLayout({label:`${e}-shared-depth-material-layout`,entries:i}),l="prepass"===r?"instanced-direct"===n?this.state.directSceneBindGroupLayout:this.state.sceneBindGroupLayout:"instanced-direct"===n?this.state.directShadowBindGroupLayout:this.state.shadowBindGroupLayout,c=this.state.device.createPipelineLayout({label:`${e}-shared-depth-pipeline-layout`,bindGroupLayouts:[l,o,...a?[this.state.skinningBindGroupLayout]:[]]}),u=br(t,"prepass"===r?"camera":"shadow",this.state.device,n,a),d=this.buildMaterialShaderCode(t,u,"pointShadow"===r?t.pointShadowVertexShader??t.vertexShader:t.depthVertexShader??t.vertexShader,`${e}-shared-depth-vertex`,a,s),h="pointShadow"===r?t.pointShadowFragmentShader:t.depthFragmentShader,p=h?this.buildMaterialShaderCode(t,u,h,`${e}-shared-depth-fragment`,a,s):null,f={bindGroupLayout:o,pipeline:await this.state.device.createRenderPipelineAsync({label:`${e}-shared-depth-pipeline`,layout:c,vertex:{module:this.state.device.createShaderModule({label:`${e}-shared-depth-vertex`,code:d}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,a))},...p?{fragment:{module:this.state.device.createShaderModule({label:`${e}-shared-depth-fragment`,code:p}),entryPoint:"fsMain",targets:"pointShadow"===r?[{format:"rgba16float"}]:[]}}:{},primitive:{topology:sa(t),cullMode:oa(t,r,s),frontFace:"ccw"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",..."directionalShadow"===r?{depthBias:1,depthBiasSlopeScale:2,depthBiasClamp:0}:{}}})};return this.sharedDepthPipelineCache.set(e,f),this.sharedDepthPipelinePromiseCache.delete(e),f})();return this.sharedDepthPipelinePromiseCache.set(e,c),c}getOrCreateSharedForwardPipeline(e,t,r,n,i,a,s,o,l=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 c=this.sharedForwardPipelineCache.get(e);if(c)return c;const u=this.state.device.createBindGroupLayout({label:`${e}-shared-forward-material-layout`,entries:n}),d=this.createGraphTextureBindGroupLayout(t),h=this.state.device.createPipelineLayout({label:`${e}-shared-forward-pipeline-layout`,bindGroupLayouts:["instanced-direct"===r?this.state.directSceneBindGroupLayout:"packed-visible"===r?this.state.visibleSceneBindGroupLayout:this.state.sceneBindGroupLayout,u,s?this.state.skinningBindGroupLayout:this.state.emptyBindGroupLayout,d]}),p=xr(t,this.state.device,r,i,s),f=this.buildMaterialShaderCode(t,p,t.vertexShader,`${e}-shared-forward-vertex`,s,o),m=this.buildMaterialShaderCode(t,p,t.fragmentShader,`${e}-shared-forward-fragment`,s,o),g={bindGroupLayout:u,graphTextureBindGroupLayout:d,pipeline:this.state.device.createRenderPipeline({label:`${e}-shared-forward-pipeline`,layout:h,vertex:{module:this.state.device.createShaderModule({label:`${e}-shared-forward-vertex`,code:f}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,s))},fragment:{module:this.state.device.createShaderModule({label:`${e}-shared-forward-fragment`,code:m}),entryPoint:"fsMain",targets:Qi(m,a,Xi(t))},primitive:{topology:sa(t),cullMode:sa(t).startsWith("triangle")&&t.side!==ut?t.side===st?"front":"back":"none",frontFace:"ccw"},multisample:{count:l},depthStencil:{format:"depth32float",depthWriteEnabled:t.depthWrite,depthCompare:t.depthTest?"less-equal":"always"}})};return this.sharedForwardPipelineCache.set(e,g),g}async getOrCreateSharedForwardPipelineAsync(e,t,r,n,i,a,s,o,l=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 c=this.sharedForwardPipelineCache.get(e);if(c)return c;const u=this.sharedForwardPipelinePromiseCache.get(e);if(u)return u;const d=(async()=>{const c=this.state.device.createBindGroupLayout({label:`${e}-shared-forward-material-layout`,entries:n}),u=this.createGraphTextureBindGroupLayout(t),d=this.state.device.createPipelineLayout({label:`${e}-shared-forward-pipeline-layout`,bindGroupLayouts:["instanced-direct"===r?this.state.directSceneBindGroupLayout:"packed-visible"===r?this.state.visibleSceneBindGroupLayout:this.state.sceneBindGroupLayout,c,s?this.state.skinningBindGroupLayout:this.state.emptyBindGroupLayout,u]}),h=xr(t,this.state.device,r,i,s),p=this.buildMaterialShaderCode(t,h,t.vertexShader,`${e}-shared-forward-vertex`,s,o),f=this.buildMaterialShaderCode(t,h,t.fragmentShader,`${e}-shared-forward-fragment`,s,o),m={bindGroupLayout:c,graphTextureBindGroupLayout:u,pipeline:await this.state.device.createRenderPipelineAsync({label:`${e}-shared-forward-pipeline`,layout:d,vertex:{module:this.state.device.createShaderModule({label:`${e}-shared-forward-vertex`,code:p}),entryPoint:"vsMain",buffers:this.createVertexBufferLayouts(this.getMaterialVertexAttributes(t,s))},fragment:{module:this.state.device.createShaderModule({label:`${e}-shared-forward-fragment`,code:f}),entryPoint:"fsMain",targets:Qi(f,a,Xi(t))},primitive:{topology:sa(t),cullMode:sa(t).startsWith("triangle")&&t.side!==ut?t.side===st?"front":"back":"none",frontFace:"ccw"},multisample:{count:l},depthStencil:{format:"depth32float",depthWriteEnabled:t.depthWrite,depthCompare:t.depthTest?"less-equal":"always"}})};return this.sharedForwardPipelineCache.set(e,m),this.sharedForwardPipelinePromiseCache.delete(e),m})();return this.sharedForwardPipelinePromiseCache.set(e,d),d}getDepthPassMaterialResource(e,t,r,n,i){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 a=this.getDepthMaterialFastCacheIndex(t,r,n,i),s=this.depthMaterialFrameCache.get(e)?.[a];if(s?.extractionVersion===this.extractionVersion)return s.resource;const o=this.depthMaterialFastCache.get(e)?.[a];if(o&&this.fastMaterialResourceMatches(o,e))return this.updateMaterialUniformBuffer(e,o),this.setDepthMaterialFrameCache(e,a,o),o;const l="prepass"===t?this.depthPrepassMaterialCache:n?this.skinnedDirectionalShadowMaterialCache:"instanced-direct"===r?this.directionalShadowMaterialCacheDirect:this.directionalShadowMaterialCache,c=this.getDepthPassMaterialKey(e,t,r,n,i),u=l.get(e),d=u?.get(c);if(d&&this.materialResourceMatches(d,e,c))return this.setDepthMaterialFastCache(e,a,d),this.updateMaterialUniformBuffer(e,d),this.setDepthMaterialFrameCache(e,a,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=this.getOrCreateSharedDepthPipeline(c,e,t,r,h,n,i),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:i,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,n),usesSkinning:n};let y=l.get(e);return y||(y=new Map,l.set(e,y)),y.set(c,b),this.setDepthMaterialFastCache(e,a,b),this.setDepthMaterialFrameCache(e,a,b),b}setDepthMaterialFrameCache(e,t,r){let n=this.depthMaterialFrameCache.get(e);n||(n=[],this.depthMaterialFrameCache.set(e,n)),n[t]={extractionVersion:this.extractionVersion,resource:r}}async getDepthPassMaterialResourceAsync(e,t,r,n,i){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 a=this.getDepthMaterialFastCacheIndex(t,r,n,i),s=this.depthMaterialFastCache.get(e)?.[a];if(s&&this.fastMaterialResourceMatches(s,e))return this.updateMaterialUniformBuffer(e,s),s;const o="prepass"===t?this.depthPrepassMaterialCache:n?this.skinnedDirectionalShadowMaterialCache:"instanced-direct"===r?this.directionalShadowMaterialCacheDirect:this.directionalShadowMaterialCache,l=this.getDepthPassMaterialKey(e,t,r,n,i),c=o.get(e),u=c?.get(l);if(u&&this.materialResourceMatches(u,e,l))return this.setDepthMaterialFastCache(e,a,u),this.updateMaterialUniformBuffer(e,u),u;this.destroyMaterialResource(u),c&&c.delete(l);const{bindGroupLayoutEntries:d,bindGroupEntries:h,uniformBuffer:p,textures:f,textureVersions:m,storageBuffers:g}=this.createMaterialBindGroupData(e,`${e.uuid}-${t}-${r}-material`,GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT),v=await this.getOrCreateSharedDepthPipelineAsync(l,e,t,r,d,n,i),x=this.state.device.createBindGroup({label:`${e.uuid}-${t}-${r}-material-bind-group`,layout:v.bindGroupLayout,entries:h}),w={key:l,materialVersion:e.version,textureVersionHash:e.getTextureVersionHash(),rendererSampleCount:this.sampleCount,instanceAccessMode:r,receiveShadow:!0,useBatching:i,colorTargetFormatsId:0,pipeline:v.pipeline,graphTextureBindGroupLayout:v.graphTextureBindGroupLayout,bindGroup:x,uniformBuffer:p,uniformBufferSize:p?.size??0,uniformValueHash:e.uniformValuesAutoUpdate?e.getUniformValueHash():0,uniformValuesAutoVersion:e.uniformValuesAutoVersion,textures:f,textureVersions:m,storageBuffers:g,vertexAttributes:this.getMaterialVertexAttributes(e,n),usesSkinning:n};let b=o.get(e);return b||(b=new Map,o.set(e,b)),b.set(l,w),this.setDepthMaterialFastCache(e,a,w),w}getMaterialResource(e,t,r=!0,n,i=!1,a=!1,s=this.sampleCount){if(!(this.state.device&&this.state.format&&this.state.sceneBindGroupLayout&&this.state.visibleSceneBindGroupLayout&&this.state.directSceneBindGroupLayout))throw new Error("Renderer is not initialized.");const o=i?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,l=n??ia,c=void 0===n||1===n.length&&n[0]===qr,u=this.getForwardMaterialFastCacheIndex(t,r,i,a),d=c?null:this.getForwardMaterialTargetFastCacheKey(l,u);if(c){const t=this.forwardMaterialFrameCache.get(e)?.[u];if(t?.extractionVersion===this.extractionVersion&&t.resource.rendererSampleCount===s)return t.resource;const r=this.forwardMaterialFastCache.get(e)?.[u];if(r&&this.fastMaterialResourceMatches(r,e,s))return this.updateMaterialUniformBuffer(e,r),this.setForwardMaterialFrameCache(e,u,r),r}else{const t=this.forwardMaterialTargetFastCache.get(e)?.get(d);if(t&&this.fastMaterialResourceMatches(t,e,s))return this.updateMaterialUniformBuffer(e,t),t}const h=this.getForwardMaterialKey(e,t,r,l,i,a,s),p=o.get(e),f=p?.get(h);if(f&&this.materialResourceMatches(f,e,h,s))return c?(this.setForwardMaterialFastCache(e,u,f),this.setForwardMaterialFrameCache(e,u,f)):this.setForwardMaterialTargetFastCache(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=this.getOrCreateSharedForwardPipeline(h,e,t,m,r,l,i,a,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,colorTargetFormatsId:this.getColorFormatsId(l),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,i),usesSkinning:i};let P=o.get(e);return P||(P=new Map,o.set(e,P)),P.set(h,C),c?(this.setForwardMaterialFastCache(e,u,C),this.setForwardMaterialFrameCache(e,u,C)):this.setForwardMaterialTargetFastCache(e,d,C),C}async getMaterialResourceAsync(e,t,r=!0,n,i=!1,a=!1,s=this.sampleCount){if(!(this.state.device&&this.state.format&&this.state.sceneBindGroupLayout&&this.state.visibleSceneBindGroupLayout&&this.state.directSceneBindGroupLayout))throw new Error("Renderer is not initialized.");const o=i?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,l=n??ia,c=void 0===n||1===n.length&&n[0]===qr,u=this.getForwardMaterialFastCacheIndex(t,r,i,a);if(c){const t=this.forwardMaterialFrameCache.get(e)?.[u];if(t?.extractionVersion===this.extractionVersion&&t.resource.rendererSampleCount===s)return t.resource;const r=this.forwardMaterialFastCache.get(e)?.[u];if(r&&this.fastMaterialResourceMatches(r,e,s))return this.updateMaterialUniformBuffer(e,r),this.setForwardMaterialFrameCache(e,u,r),r}const d=this.getForwardMaterialKey(e,t,r,l,i,a,s),h=o.get(e),p=h?.get(d);if(p&&this.materialResourceMatches(p,e,d,s))return c&&(this.setForwardMaterialFastCache(e,u,p),this.setForwardMaterialFrameCache(e,u,p)),this.updateMaterialUniformBuffer(e,p),p;this.destroyMaterialResource(p),h&&h.delete(d);const{bindGroupLayoutEntries:f,bindGroupEntries:m,uniformBuffer:g,textures:v,textureVersions:x,storageBuffers:w}=this.createMaterialBindGroupData(e,`${e.uuid}-${t}-material`,GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT),b=await this.getOrCreateSharedForwardPipelineAsync(d,e,t,f,r,l,i,a,s),y=this.state.device.createBindGroup({label:`${e.uuid}-${t}-material-bind-group`,layout:b.bindGroupLayout,entries:m}),S={key:d,materialVersion:e.version,textureVersionHash:e.getTextureVersionHash(),rendererSampleCount:s,instanceAccessMode:t,receiveShadow:r,useBatching:a,colorTargetFormatsId:this.getColorFormatsId(l),pipeline:b.pipeline,graphTextureBindGroupLayout:b.graphTextureBindGroupLayout,bindGroup:y,uniformBuffer:g,uniformBufferSize:g?.size??0,uniformValueHash:e.uniformValuesAutoUpdate?e.getUniformValueHash():0,uniformValuesAutoVersion:e.uniformValuesAutoVersion,textures:v,textureVersions:x,storageBuffers:w,vertexAttributes:this.getMaterialVertexAttributes(e,i),usesSkinning:i};let C=o.get(e);return C||(C=new Map,o.set(e,C)),C.set(d,S),c&&(this.setForwardMaterialFastCache(e,u,S),this.setForwardMaterialFrameCache(e,u,S)),S}updateCameraUniforms(e,t){if(!this.state.device||!this.state.cameraBuffer)return;const r=this.cameraProjectionScratch.copy(e.projectionMatrix);r.elements[8]-=2*this.projectionJitterPixels.x/this.state.width,r.elements[9]-=2*this.projectionJitterPixels.y/this.state.height;const n=this.cameraViewProjScratch.copy(Zr).multiply(r).multiply(e.matrixWorldInverse);e.getWorldPosition(an);const i=this.cameraUniformScratch;i.set(n.elements,0),i[16]=an.x,i[17]=an.y,i[18]=an.z,i[19]=1,i[20]=this.state.width,i[21]=this.state.height,i[22]=this.state.pixelRatio,i[23]=this.state.frameTimeSeconds,i.set(e.matrixWorldInverse.elements,24),i.set(rn.multiplyMatrices(Zr,r).elements,40),i[56]=e.near,i[57]=e.far,i[58]=1/Math.max(e.far-e.near,1e-4),i[59]=0;const a=t.fog;null!=a?(i[60]=a.color.r,i[61]=a.color.g,i[62]=a.color.b,i[63]=1,"density"in a?(i[64]=0,i[65]=0,i[66]=a.density,i[67]=1):(i[64]=a.near,i[65]=a.far,i[66]=0,i[67]=0)):(i.fill(0,60,68),i[67]=-1);const s=this.motionVectorProjectionPending?this.motionVectorProjection:e.projectionMatrix,o=this.motionVectorCurrentViewProj.copy(Zr).multiply(s).multiply(e.matrixWorldInverse);i.set(o.elements,68),i.set((this.motionVectorHistoryValid?this.motionVectorPreviousViewProj:o).elements,84),i[100]=this.motionVectorHistoryValid?1:0,i[101]=this.state.width,i[102]=this.state.height,i[103]=0,this.motionVectorProjectionPending=!1,this.state.device.queue.writeBuffer(this.state.cameraBuffer,0,i,0,104)}updateTemporalVisibilityUniforms(e){if(!this.state.device||!this.state.temporalVisibilityBuffer)return;const t=Hn(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 n=this.state.temporalHiZHistoryValid?this.temporalVisibilityPreviousCameraPosition:this.temporalVisibilityCurrentCameraPosition;r[36]=n.x,r[37]=n.y,r[38]=n.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;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],n=3976+4*e;t[n+0]=r.x,t[n+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 n=e.lights.directionals[r],i=this.directionalShadowCameras[r];i.left=n.shadowCameraLeft,i.right=n.shadowCameraRight,i.top=n.shadowCameraTop,i.bottom=n.shadowCameraBottom,i.near=n.shadowCameraNear,i.far=n.shadowCameraFar,i.position.copy(n.position),i.lookAt(n.target),i.updateMatrixWorld(!0),i.updateProjectionMatrix();const a=8+4*r;t[a+0]=n.direction.x,t[a+1]=n.direction.y,t[a+2]=n.direction.z,t[a+3]=1;const s=24+4*r;t[s+0]=n.color.x,t[s+1]=n.color.y,t[s+2]=n.color.z,t[s+3]=n.intensity;const o=40+4*r;t[o+0]=n.shadowBias,t[o+1]=n.castShadow?1:0,t[o+2]=this.state.directionalShadowTextureSize,t[o+3]=n.shadowNormalBias;const l=56+4*r;t[l+0]=n.shadowRadius,t[l+1]=n.shadowIntensity,t.set(Hn(i,this.shadowViewProjScratch).elements,72+16*r)}for(let r=0;r<e.lights.points.length;r+=1){const n=e.lights.points[r],i=136+4*r;t[i+0]=n.position.x,t[i+1]=n.position.y,t[i+2]=n.position.z,t[i+3]=n.range;const a=392+4*r;t[a+0]=n.color.x,t[a+1]=n.color.y,t[a+2]=n.color.z,t[a+3]=n.intensity;const s=648+4*r;t[s+0]=n.distance,t[s+1]=n.decay;const o=904+4*r;t[o+0]=n.shadowBias,t[o+1]=n.castShadow?1:0,t[o+2]=this.state.pointShadowTextureSize,t[o+3]=n.shadowNormalBias;const l=1160+4*r;t[l+0]=n.shadowRadius,t[l+1]=n.shadowIntensity,t[l+2]=n.shadowCameraNear,t[l+3]=n.shadowCameraFar}for(let r=0;r<e.lights.spots.length;r+=1){const n=e.lights.spots[r],i=1416+4*r;t[i+0]=n.position.x,t[i+1]=n.position.y,t[i+2]=n.position.z,t[i+3]=n.range;const a=1672+4*r;t[a+0]=n.direction.x,t[a+1]=n.direction.y,t[a+2]=n.direction.z,t[a+3]=Math.cos(n.angle);const s=1928+4*r;t[s+0]=n.color.x,t[s+1]=n.color.y,t[s+2]=n.color.z,t[s+3]=n.intensity;const o=2184+4*r;t[o+0]=n.shadowBias,t[o+1]=n.castShadow?1:0,t[o+2]=this.state.spotShadowTextureSize,t[o+3]=n.shadowNormalBias;const l=2440+4*r;t[l+0]=n.shadowRadius,t[l+1]=n.shadowIntensity;const c=2696+4*r;if(t[c+0]=n.range,t[c+1]=Math.cos(n.angle*(1-n.penumbra)),t[c+2]=n.decay,n.castShadow){const e=this.spotShadowCameras[r];e.near=n.shadowCameraNear,e.far=n.shadowCameraFar,e.fov=n.shadowCameraFov,e.aspect=1,e.position.copy(n.position),sn.copy(n.position).add(n.direction),e.lookAt(sn),e.updateMatrixWorld(!0),e.updateProjectionMatrix(),t.set(Hn(e,this.shadowViewProjScratch).elements,2952+16*r)}}this.state.device.queue.writeBuffer(this.state.lightBuffer,0,t,0,Jr)}writeShadowCameraBuffer(e,t,r,n,i,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]=n,o[19]=i,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 ua=[0,0],da=[0,0,1],ha=[1,1,1,1];import{DataTexture as pa,Matrix4 as fa,RepeatWrapping as ma}from"three";var ga={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}}},va=class{options;noiseTexture=function(){const e=new Array(25).fill(0);let t=Math.floor(2.5),r=4;for(let n=1;n<=25;){-1===t&&5===r?(t=0,r=3):(5===r&&(r=0),t<0&&(t=4));const i=5*t+r;0===e[i]?(e[i]=n++,t-=1,r+=1):(t+=1,r-=2)}const n=new Uint8Array(100);for(let t=0;t<e.length;t+=1){const r=2*Math.PI*e[t]/e.length;n[4*t]=Math.round(255*(.5*Math.cos(r)+.5)),n[4*t+1]=Math.round(255*(.5*Math.sin(r)+.5)),n[4*t+2]=127,n[4*t+3]=255}const i=new pa(n,5,5);return i.wrapS=ma,i.wrapT=ma,i.needsUpdate=!0,i}();gtaoPasses=new Map;temporalPasses=new Map;denoisePasses=new Map;compositePasses=new Map;writeIndex=0;frameIndex=0;historyValid=!1;constructor(e={}){this.options=Pa(e)}get enabled(){return this.options.enabled}get temporalEnabled(){return!1!==this.options.temporal}setOptions(e){Object.assign(this.options,Pa({...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(ga[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}),n=`${t.depth}:${t.normal}:${r}`;let i=this.gtaoPasses.get(n);i||(i=new xa(t.depth,t.normal,r,this.noiseTexture,this.options),this.gtaoPasses.set(n,i));const a=!1!==this.options.temporal&&null!=t.velocity;i.frameIndex=a?this.frameIndex:0,e.addFullscreenPass(i);let s=r;if(a&&!1!==this.options.temporal&&null!=t.velocity){const n=e.createColorTarget(`${this.options.targetPrefix}TemporalA`,{format:"r16float",scale:this.options.resolutionScale}),i=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?i:n,c=0===this.writeIndex?n:i,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 wa(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 ba(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,n={}){const i=n.output??e.createColorTarget(`${this.options.targetPrefix}Composite`,{format:"rgba16float"}),a=Math.max(0,n.intensity??.6),s=Math.max(1e-4,n.power??1),o=`${t}:${r}:${i}:${a}:${s}`;let l=this.compositePasses.get(o);return l||(l=new ya(t,r,i,a,s),this.compositePasses.set(o,l)),e.addFullscreenPass(l),i}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}},xa=class{constructor(e,t,r,n,i){this.options=i,this.inputs={sceneDepth:e,sceneNormal:t},this.outputs=r,this.textures={gtaoNoise:n},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`}(i)}options;name="GTAOPass";sampler="nearest";uniformBufferSize=224;inputs;outputs;textures;fragmentShader;uniforms=new Float32Array(this.uniformBufferSize/4);webGpuProjection=new fa;webGpuProjectionInverse=new fa;frameIndex=0;updateUniforms=e=>(this.webGpuProjection.copy(Sa).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)},wa=class{constructor(e,t,r,n,i,a,s,o,l){this.options=o,this.state=l,this.inputs={currentAo:e,sceneDepth:t,velocity:r,historyAo:n,historyDepth:i},this.outputs=[a,s]}options;state;name="GTAOTemporalPass";sampler="linear";uniformBufferSize=80;inputs;outputs;fragmentShader=Ca;uniforms=new Float32Array(this.uniformBufferSize/4);inverseProjection=new fa;updateUniforms=e=>(this.inverseProjection.copy(Sa).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)},ba=class{constructor(e,t,r,n,i,a){this.options=a,this.inputs={aoInput:e,sceneDepth:t,sceneNormal:r},this.outputs=n,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`}(i,a.samples)}options;name="GTAODenoisePass";sampler="nearest";uniformBufferSize=144;inputs;outputs;fragmentShader;uniforms=new Float32Array(this.uniformBufferSize/4);webGpuProjectionInverse=new fa;updateUniforms=e=>(this.webGpuProjectionInverse.copy(Sa).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)},ya=class{name="GTAOCompositePass";sampler="nearest";uniformBufferSize=16;inputs;outputs;uniforms;constructor(e,t,r,n,i){this.inputs={sceneColor:e,ambientOcclusion:t},this.outputs=r,this.uniforms=new Float32Array([n,i,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"},Sa=(new fa).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);var Ca="\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 Pa(e){return{enabled:e.enabled??!0,radius:Math.max(.001,e.radius??.25),resolutionScale:Ba(e.resolutionScale??1,.25,1),thickness:Math.max(.001,e.thickness??1),distanceExponent:Math.max(.01,e.distanceExponent??1),distanceFalloff:Ba(e.distanceFalloff??1,0,1),directions:Da(e.directions??3,1,8),steps:Da(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:Ma(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:Ba(e.temporal?.historyWeight??.9,0,.98),depthRejection:Ba(e.temporal?.depthRejection??.08,.001,1),neighborhoodClamp:e.temporal?.neighborhoodClamp??!0}}}function Ma(e){return e<=4?4:e<=8?8:e<=12?12:16}function Ba(e,t,r){return Math.min(r,Math.max(t,e))}function Da(e,t,r){return Math.floor(Ba(e,t,r))}import{Matrix4 as Ta}from"three";var Ia=class{options;passes=new Map;constructor(e={}){var t,r,n;this.options={resolutionScale:Ua(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:Ua(e.maxRoughness??.8,.01,1),steps:(t=e.steps??2048,r=8,n=2048,Math.round(Ua(t,r,n))),pixelStride:Ua(e.pixelStride??1,1,4),normalSpace:e.normalSpace??"world",blur:e.blur??!0,blurRadius:Ua(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}),n=`trace:${t.sceneColor}:${t.depth}:${t.normalRoughness}:${r}`;let i=this.passes.get(n);i||(i=new Ra(t,r,this.options),this.passes.set(n,i)),e.addFullscreenPass(i);let a=r;if(this.options.blur)for(let r=0;r<2;r++){const n=e.createColorTarget(`${this.options.targetPrefix}Blur${r}`,{format:"rgba16float",scale:this.options.resolutionScale}),i=`blur:${a}:${t.depth}:${t.normalRoughness}:${n}:${r}:${this.options.blurRadius}`;let s=this.passes.get(i);s||(s=new Va(a,t.depth,t.normalRoughness,n,r,this.options.blurRadius),this.passes.set(i,s)),e.addFullscreenPass(s),a=n}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 Ga(t.sceneColor,a,s,this.options.intensity),this.passes.set(o,l)),e.addFullscreenPass(l),s}},Ra=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 Ta;inverseProjection=new Ta;updateUniforms=e=>(this.projection.copy(za).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)},Va=class{name;sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms;constructor(e,t,r,n,i,a){this.name=0===i?"SSRBlurHorizontalPass":"SSRBlurVerticalPass",this.inputs={reflection:e,sceneDepth:t,normalRoughness:r},this.outputs=n,this.uniforms=new Float32Array([0===i?1:0,1===i?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}"},Ga=class{name="SSRCompositePass";sampler="linear";uniformBufferSize=16;inputs;outputs;uniforms;constructor(e,t,r,n){this.inputs={sceneColor:e,reflection:t},this.outputs=r,this.uniforms=new Float32Array([n,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 za=(new Ta).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);function Ua(e,t,r){return Math.min(r,Math.max(t,e))}import{Matrix4 as La,Vector2 as Aa}from"three";var Fa=(new La).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),ka=class{renderScale;sampleCount;minCurrentWeight;motionWeightScale;depthThreshold;relativeDepthThreshold;targetPrefix;writeIndex=0;historyValid=!1;frameIndex=0;renderWidth=1;renderHeight=1;outputWidth=1;outputHeight=1;jitter=new Aa;unjitteredProjection=new La;previousJitterUv=new Aa;currentJitterUv=new Aa;previousViewProjection=new La;resolvePasses=new Map;constructor(e={}){this.renderScale=ja(e.renderScale??1,.25,1),this.sampleCount=Math.max(1,Math.floor(e.sampleCount??32)),this.minCurrentWeight=ja(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(Oa(this.frameIndex%this.sampleCount+1,2)-.5,Oa(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,n){const i=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:i,c=0===this.writeIndex?i:a,u=0===this.writeIndex?o:s,d=0===this.writeIndex?s:o,h=`${t}:${r}:${n??"camera"}:${l}:${u}:${c}:${d}`;let p=this.resolvePasses.get(h);return p||(p=new Ea(t,r,n,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=ja(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)),n=Math.max(1,Math.floor(t));r===this.outputWidth&&n===this.outputHeight||(this.outputWidth=r,this.outputHeight=n,this.renderWidth=Math.max(1,Math.floor(r*this.renderScale)),this.renderHeight=Math.max(1,Math.floor(n*this.renderScale)),this.reset())}updateResolveUniforms(e,t,r,n){t.copy(Fa).multiply(n.camera.projectionMatrix).multiply(n.camera.matrixWorldInverse),r.copy(t).invert(),e.set(r.elements,0),e.set((this.historyValid?this.previousViewProjection:t).elements,16),e.set([n.presentationWidth,n.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}},Ea=class{constructor(e,t,r,n,i,a,s,o){var l;this.state=o,this.inputs=null==r?{currentColor:e,currentDepth:t,historyColor:n,historyDepth:i}:{currentColor:e,currentDepth:t,historyColor:n,historyDepth:i,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 La;currentViewProjectionInverse=new La;updateUniforms=e=>(this.state.updateResolveUniforms(this.uniforms,this.currentViewProjection,this.currentViewProjectionInverse,e),this.uniforms)};function Oa(e,t){let r=1,n=0;for(;e>0;)r/=t,n+=r*(e%t),e=Math.floor(e/t);return n}function ja(e,t,r){return Math.min(r,Math.max(t,e))}var $a=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=Wa(e.subpixelBlending??.75,0,1),this.targetPrefix=e.targetPrefix??"fxaa"}addPass(e,t,r={}){const n=r.output??e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float",resolution:"presentation"}),i=`${t}:${n}`;let a=this.passes.get(i);return a||(a=new Na(t,n,this),this.passes.set(i,a)),e.addFullscreenPass(a),n}},Na=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),Wa(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 Wa(e,t,r){return Math.min(r,Math.max(t,e))}import{ClampToEdgeWrapping as _a,DataTexture as Ha,LinearFilter as qa,NoColorSpace as Ka,RGFormat as Za,UnsignedByteType as Ya}from"three";var Xa={low:{searchSteps:4,diagonalSteps:0},medium:{searchSteps:8,diagonalSteps:0},high:{searchSteps:16,diagonalSteps:8},ultra:{searchSteps:32,diagonalSteps:16}},Ja=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=us(e.cornerRounding??.25,0,1),this.sharpness=us(e.sharpness??0,0,1),this.quality=Xa[e.quality??"high"],this.targetPrefix=e.targetPrefix??"smaa",this.areaTexture=function(){const e=new Ha(function(){if(rs)return rs;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 n=0;n<16;n+=1){const[i,a]=t[n];for(let t=0;t<16;t+=1)for(let r=0;r<16;r+=1){ns(e,16*i+r,16*a+t,is(n,r*r,t*t))}const[s,o]=r[n];for(let t=0;t<20;t+=1)for(let r=0;r<20;r+=1){ns(e,80+20*s+r,20*o+t,os(n,r,t))}}return rs=e,e}(),160,80,Za,Ya);return e.name="SMAA-Area-Lookup",e.colorSpace=Ka,e.minFilter=qa,e.magFilter=qa,e.wrapS=_a,e.wrapT=_a,e.generateMipmaps=!1,e.needsUpdate=!0,e}()}addPass(e,t,r={}){const n=e.createColorTarget(`${this.targetPrefix}Edges`,{format:"rg8unorm",resolution:"render"}),i=e.createColorTarget(`${this.targetPrefix}Weights`,{format:"rgba8unorm",resolution:"render"}),a=r.output??e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float",resolution:"render"}),s=`${t}:${n}`;let o=this.edgePasses.get(s);o||(o=new Qa(t,n,this),this.edgePasses.set(s,o));const l=`${n}:${i}`;let c=this.weightPasses.get(l);c||(c=new es(n,i,this.areaTexture,this),this.weightPasses.set(l,c));const u=`${t}:${i}:${a}`;let d=this.blendPasses.get(u);return d||(d=new ts(t,i,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}},Qa=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"},es=class{constructor(e,t,r,n){this.state=n,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,us(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"},ts=class{constructor(e,t,r,n){this.state=n,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([us(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 rs=null;function ns(e,t,r,n){const i=2*(160*r+t);e[i]=Math.floor(255*us(n[0],0,1)),e[i+1]=Math.floor(255*us(n[1],0,1))}function is(e,t,r){const n=t+r+1,i=.5,a=-.5,s=()=>as([0,a],[n/2,0],t),o=()=>as([n/2,0],[n,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 ss(n,s(),o());case 4:return t<=r?as([0,i],[n/2,0],t):[0,0];case 6:case 14:case 7:return as([0,i],[n,a],t);case 8:return t>=r?as([n/2,0],[n,i],t):[0,0];case 9:case 11:case 13:return as([0,a],[n,i],t);case 12:return ss(n,as([0,i],[n/2,0],t),as([n/2,0],[n,i],t))}}function as(e,t,r){const n=t[0]-e[0],i=t[1]-e[1];if(Math.abs(n)<1e-6)return[0,0];const a=r,s=r+1,o=e[1]+i*(a-e[0])/n,l=e[1]+i*(s-e[0])/n;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]*n/i+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 ss(e,t,r){const n=e=>[.5*Math.sqrt(2*e[0]),.5*Math.sqrt(2*e[1])],i=us(e/32,0,1),a=n(t),s=n(r);return[cs(a[0],t[0],i)+cs(s[0],r[0],i),cs(a[1],t[1],i)+cs(s[1],r[1],i)]}function os(e,t,r){const n=t+r+1,[i,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 n=30;let i=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<n;e+=1)for(let t=0;t<n;t+=1){const s=t/(n-1),o=e/(n-1);u(1+r+s,r+o)&&(i+=1),u(1+r+s,1+r+o)&&(a+=1)}const d=n*n;return[1-i/d,a/d]}(i>0?[e[0],e[1]]:e,a>0?[r[0],r[1]]:r,t),o=(e,t)=>s([1,e],[1+n,t+n]);switch(e){case 0:return ls(o(1,1),o(0,0));case 1:return ls(s([1,0],[n,n]),o(0,0));case 2:return ls(s([0,0],[1+n,n]),o(0,0));case 3:return o(0,0);case 4:return ls(s([1,1],[n,n]),s([1,1],[1+n,n]));case 5:return ls(s([1,1],[n,n]),o(0,0));case 6:return s([1,1],[1+n,n]);case 7:return ls(s([1,1],[1+n,n]),o(0,0));case 8:return ls(s([0,0],[1+n,1+n]),s([1,0],[1+n,1+n]));case 9:return s([1,0],[1+n,1+n]);case 10:return ls(s([0,0],[1+n,1+n]),o(0,0));case 11:return ls(s([1,0],[1+n,1+n]),o(0,0));case 12:return s([1,1],[1+n,1+n]);case 13:return ls(s([1,1],[1+n,1+n]),s([1,0],[1+n,1+n]));case 14:return ls(s([1,1],[1+n,1+n]),s([1,1],[1+n,n]));case 15:return ls(s([1,1],[1+n,1+n]),o(0,0));default:return[0,0]}}function ls(e,t){return[.5*(e[0]+t[0]),.5*(e[1]+t[1])]}function cs(e,t,r){return e+(t-e)*r}function us(e,t,r){return Math.min(r,Math.max(t,e))}var ds=class{strength;threshold;knee;radius;levels;targetPrefix;passes=new Map;constructor(e={}){var t,r,n;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=ms(e.radius??.2,0,1),this.levels=(t=e.levels??5,r=1,n=5,Math.floor(ms(t,r,n))),this.targetPrefix=e.targetPrefix??"bloom"}addPass(e,t,r={}){const n=[];let i=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=i,l=`h:${t}:${o}:${a}`;let c=this.passes.get(l);c||(c=0===t?new hs(o,a,this):new ps(`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 ps(`BloomVertical${t}`,a,s,!1,t),this.passes.set(u,d)),e.addFullscreenPass(d),n.push(s),i=s}const a=r.output??e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"}),s=Object.fromEntries(n.map((e,t)=>[`blur${t}`,e])),o=`composite:${t}:${n.join(":")}:${a}`;let l=this.passes.get(o);return l||(l=new fs(t,s,a,this,this.levels),this.passes.set(o,l)),e.addFullscreenPass(l),a}},hs=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}"},ps=class{constructor(e,t,r,n,i){this.name=e,this.inputs={source:t},this.outputs=r;const a=n?"vec2<f32>(texel.x, 0.0)":"vec2<f32>(0.0, texel.y)",s=(1+.35*i).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},fs=class{constructor(e,t,r,n,i){this.state=n,this.inputs={source:e,...t},this.outputs=r;const a=[1,.8,.6,.4,.2],s=Array.from({length:i},(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,ms(this.state.radius,0,1),0,0]),this.uniforms);fragmentShader};function ms(e,t,r){return Math.min(r,Math.max(t,e))}var gs=[1,1,1],vs=[0,0,0],xs=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"}),n=`${t}:${r}`;let i=this.passes.get(n);return i||(i=new ws(t,r,this.options),this.passes.set(n,i)),e.addFullscreenPass(i),r}},ws=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,gs),t(e?.contrast,gs),t(e?.gamma,gs),t(e?.gain,gs),t(e?.offset,vs)};return t(this.state.whiteBalance,gs),t(this.state.tint,gs),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 bs}from"three";var ys=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 n=e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"}),i=`${t}:${r}:${n}`;let a=this.passes.get(i);return a||(a=new Ss(t,r,n,this.options),this.passes.set(i,a)),e.addFullscreenPass(a),n}},Ss=class{constructor(e,t,r,n){this.state=n,this.inputs={source:e,sceneDepth:t},this.outputs=r}state;name="DepthOfField";sampler="linear";uniformBufferSize=80;inputs;outputs;uniforms=new Float32Array(20);inverseProjection=new bs;updateUniforms=e=>(this.inverseProjection.copy(Cs).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); }"},Cs=(new bs).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1);import{Matrix4 as Ps,Vector2 as Ms,Vector3 as Bs}from"three";var Ds=(new Ps).set(1,0,0,0,0,1,0,0,0,0,.5,.5,0,0,0,1),Ts=(e=>(e[e.Disabled=0]="Disabled",e[e.CameraOnly=1]="CameraOnly",e[e.ObjectAndCamera=2]="ObjectAndCamera",e[e.ForceObjectBlur=3]="ForceObjectBlur",e))(Ts||{}),Is={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}},Rs=class{options;targetPrefix;currentViewProjection=new Ps;currentInverseViewProjection=new Ps;currentInverseProjection=new Ps;previousViewProjection=new Ps;pendingViewProjection=new Ps;previousProjection=new Ps;previousCameraWorld=new Ps;previousCameraPosition=new Bs;currentCameraPosition=new Bs;currentJitterUv=new Ms;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:Gs(e.sampleCount??8),shutterScale:zs(e.shutterScale??.75,0,4),maxBlurPixels:zs(e.maxBlurPixels??18,0,128),cameraBlurScale:zs(e.cameraBlurScale??.1,0,4),objectBlurScale:zs(e.objectBlurScale??1,0,8),depthRejectionStrength:zs(e.depthRejectionStrength??24,0,200),velocityThresholdPixels:zs(e.velocityThresholdPixels??.6,0,16),dilation:e.dilation??!0,debugVelocity:e.debugVelocity??!1,targetFrameRate:zs(e.targetFrameRate??60,15,240),maxFrameTime:zs(e.maxFrameTime??.1,1/240,1),cameraCutDistance:zs(e.cameraCutDistance??8,0,1e3),cameraCutRotationThreshold:zs(e.cameraCutRotationThreshold??.75,0,2),projectionCutThreshold:zs(e.projectionCutThreshold??.25,0,4)},this.targetPrefix=e.targetPrefix??"motionBlur"}applyPreset(e){Object.assign(this.options,Is[e]),this.options.sampleCount=Gs(this.options.sampleCount)}prepareCamera(e,t,r,n){t===this.width&&r===this.height||(this.width=Math.max(1,t),this.height=Math.max(1,r),this.reset());const i=n-this.previousTimeSeconds;Number.isFinite(i)&&i>0&&(this.frameDuration=Math.min(i,this.options.maxFrameTime),i>this.options.maxFrameTime&&this.reset()),this.previousTimeSeconds=n,this.timeSeconds=n,this.pruneOverrides(),e.getWorldPosition(this.currentCameraPosition),this.historyValid&&(this.currentCameraPosition.distanceTo(this.previousCameraPosition)>this.options.cameraCutDistance||function(e,t){let r=0;const n=[0,1,2,4,5,6,8,9,10];for(const i of n)r=Math.max(r,Math.abs(e.elements[i]-t.elements[i]));return r}(e.matrixWorld,this.previousCameraWorld)>this.options.cameraCutRotationThreshold||function(e,t){let r=0;for(let n=0;n<16;n+=1)r=Math.max(r,Math.abs(e.elements[n]-t.elements[n]));return r}(e.projectionMatrix,this.previousProjection)>this.options.projectionCutThreshold)&&this.reset(),this.pendingViewProjection.copy(Ds).multiply(e.projectionMatrix).multiply(e.matrixWorldInverse),this.currentViewProjection.copy(this.pendingViewProjection),this.currentInverseViewProjection.copy(this.currentViewProjection).invert(),this.currentInverseProjection.copy(Ds).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,n=e.mainDepth){const i=this.getResolvedSettings();if(!i.enabled||0===i.sampleCount)return t;const a=e.createColorTarget(`${this.targetPrefix}Color`,{format:"rgba16float"}),s=Gs(i.sampleCount),o=`${t}:${r}:${n}:${a}:${s}`;let l=this.passes.get(o);return l||(l=new Vs(t,r,n,a,s,this),this.passes.set(o,l)),l.settings=i,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,Gs(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}},Vs=class{constructor(e,t,r,n,i,a){this.state=a,this.name=`MotionBlurResolve${i}`,this.inputs={source:e,velocity:t,depth:r},this.outputs=n,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`}(i)}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 Gs(e){return e<=0?0:e<=4?4:e<=8?8:e<=12?12:16}function zs(e,t,r){return Math.min(r,Math.max(t,e))}var Us=class{enabled;visibleEdgeColor;edgeStrength;edgeThickness;edgeSoftness;selectedObjects=new Set;selectedInstances=[];targetPrefix;maskMaterial;skinnedMaskMaterial;instanceMaskMaterials=new Map;passes=new Map;constructor(e={}){this.enabled=e.enabled??!0,this.visibleEdgeColor=[...e.visibleEdgeColor??[1,1,1]],this.edgeStrength=Math.max(0,e.edgeStrength??5),this.edgeThickness=Math.max(0,e.edgeThickness??.6),this.edgeSoftness=Math.max(0,e.edgeSoftness??.6),this.targetPrefix=e.targetPrefix??"outline",this.maskMaterial=Ls(!1),this.skinnedMaskMaterial=Ls(!0)}setSelectedObjects(e){this.selectedObjects.clear();for(const t of e)this.selectedObjects.add(t)}setSelectedInstances(e){this.selectedInstances.length=0;for(const t of e)Number.isInteger(t.instanceIndex)&&t.instanceIndex>=0&&this.selectedInstances.push(t)}addPass(e,t){if(!this.enabled||0===this.selectedObjects.size&&0===this.selectedInstances.length)return t;const r=e.createColorTarget(`${this.targetPrefix}Mask`,{format:"rgba8unorm"}),n=this.selectedObjects;e.addMaterialPass({name:"OutlineMask",outputs:r,clearColor:[0,0,0,0],loadDepth:!0,objectFilter:e=>null!==e&&function(e,t){for(let r=e;null!==r;r=r.parent)if(t.has(r))return!0;return!1}(e,n),overrideMaterial:(e,t)=>t?this.skinnedMaskMaterial:this.maskMaterial});for(let t=0;t<this.selectedInstances.length;t+=1){const n=this.selectedInstances[t];let i=this.instanceMaskMaterials.get(n.instanceIndex);i||(i=[Ls(!1,n.instanceIndex),Ls(!0,n.instanceIndex)],this.instanceMaskMaterials.set(n.instanceIndex,i)),e.addMaterialPass({name:`OutlineInstanceMask${t}-${n.instanceIndex}`,outputs:r,loadColor:!0,loadDepth:!0,objectFilter:e=>e===n.object,overrideMaterial:(e,t)=>t?i[1]:i[0]})}const i=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}:${i}`,()=>new As(r,i,this)),this.addCachedPass(e,`blur-h:${i}:${a}`,()=>new Fs("OutlineBlurHorizontal",i,a,!0,this)),this.addCachedPass(e,`blur-v:${a}:${s}`,()=>new Fs("OutlineBlurVertical",a,s,!1,this)),this.addCachedPass(e,`composite:${t}:${s}:${o}`,()=>new ks(t,s,o,this)),o}addCachedPass(e,t,r){let n=this.passes.get(t);n||(n=r(),this.passes.set(t,n)),e.addFullscreenPass(n)}dispose(){this.maskMaterial.dispose(),this.skinnedMaskMaterial.dispose();for(const e of this.instanceMaskMaterials.values())e[0].dispose(),e[1].dispose();this.instanceMaskMaterials.clear(),this.passes.clear()}};function Ls(e,t=-1){return new _t({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 As=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}"},Fs=class{constructor(e,t,r,n,i){this.name=e,this.horizontal=n,this.state=i,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}"},ks=class{constructor(e,t,r,n){this.state=n,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 Es,BackSide as Os,Bone as js,BatchedMesh as $s,BoxGeometry as Ns,BufferAttribute as Ws,BufferGeometry as _s,CanvasTexture as Hs,Color as qs,CompressedArrayTexture as Ks,CompressedArrayTexture as Zs,CompressedCubeTexture as Ys,CompressedTexture as Xs,CubeTexture as Js,Data3DTexture as Qs,DataArrayTexture as eo,DataTexture as to,DepthTexture as ro,DirectionalLight as no,DoubleSide as io,FrontSide as ao,Group as so,HemisphereLight as oo,InstancedMesh as lo,MathUtils as co,Matrix4 as uo,Mesh as ho,Object3D as po,OrthographicCamera as fo,PerspectiveCamera as mo,PlaneGeometry as go,PointLight as vo,RepeatWrapping as xo,Scene as wo,Skeleton as bo,SkinnedMesh as yo,SphereGeometry as So,SpotLight as Co,Texture as Po,Vector2 as Mo,Vector3 as Bo,Vector4 as Do}from"three";export{Es as AmbientLight,Os as BackSide,$s as BatchedMesh,ds as BloomEffect,js as Bone,Ns as BoxGeometry,Ws as BufferAttribute,_s as BufferGeometry,Hs as CanvasTexture,qs as Color,xs as ColorGradingEffect,Ks as CompressedArrayTexture,Ys as CompressedCubeTexture,Xs as CompressedTexture,Zs as CompressedTextureArray,e as ComputeKernel,Js as CubeTexture,Wt as DEFAULT_WGSL_VERTEX_ATTRIBUTES,Qs as Data3DTexture,eo as DataArrayTexture,to as DataTexture,ys as DepthOfFieldEffect,ro as DepthTexture,no as DirectionalLight,io as DoubleSide,$a as FXAAEffect,it as FrameGraphBuilder,ao as FrontSide,va as GTAOEffect,ga as GTAO_PRESETS,so as Group,oo as HemisphereLight,lo as InstancedMesh,Is as MOTION_BLUR_PRESETS,co as MathUtils,uo as Matrix4,ho as Mesh,Rs as MotionBlurEffect,Ts as MotionBlurMode,po as Object3D,fo as OrthographicCamera,Us as OutlineEffect,mo as PerspectiveCamera,go as PlaneGeometry,vo as PointLight,Jt as RenderGraph,xo as RepeatWrapping,Ja as SMAAEffect,Ia as SSREffect,wo as Scene,bo as Skeleton,yo as SkinnedMesh,So as SphereGeometry,Co as SpotLight,ka as TemporalAAEffect,Po as Texture,M as VOLUMETRIC_FOG_MATERIAL_WGSL,u as VOLUMETRIC_FOG_PRESETS,Mo as Vector2,Bo as Vector3,Do as Vector4,x as VolumetricFogEffect,c as VolumetricFogVolumeObject,_t as WGSLShaderMaterial,lr as WebGpuPMREMGenerator,ca as WebGpuRenderer,wr as buildParticleLightingShaderHeader,B as configureVolumetricFogMaterial};
|