@hology/core 0.0.266 → 0.0.267

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.
@@ -1,4 +1,4 @@
1
- import*as e from"three";import{calculateGpuSpriteOptionalStateLayout as t,GPU_SPRITE_BASE_COMMAND_BYTES as s,GPU_SPRITE_EMITTER_BYTES as i,GPU_SPRITE_TRANSFORM_COMMAND_BYTES as r,GpuSpriteRuntime as n}from"./gpu-sprite-runtime.js";import{GpuSpriteTemplateCache as a,instantiateGpuSpriteTemplate as l}from"./gpu-sprite-template.js";import{GpuVfxScheduler as o}from"./gpu-vfx-scheduler.js";export class GpuSpriteWorldRuntime{constructor(t,s,i){this.pools=i,this.activeByHandleSlot=[],this.activePages=new Set,this.positionScratch=new e.Vector3,this.activePagesDirty=!1,this.runtime=t,this.scheduler=s,this.templateCount=i.length;for(let e=0;e<t.emitters.length;e++)t.setEmitterActive(e,!1);t.setActivePages([])}static async create(h){if(0===h.templates.length)return null;const c=h.templateCache??new a,m=await Promise.all(h.templates.map(e=>null!=e.preparedTemplate?Promise.resolve({template:e.preparedTemplate,compatibility:e.preparedTemplate.compatibility,reasons:e.preparedTemplate.reasons}):c.resolve(e.asset,{assets:h.assets,renderClassCache:h.renderClassCache,resolveCustomMaterial:h.resolveCustomMaterial,revision:e.revision})));if(m.some(e=>null==e.template))return null;const u=m.map(e=>e.template),p=Math.max(1,Math.floor(h.particlePageSize??256)),d=[],f=new Map,g=[],S=[];let I=0;for(let t=0;t<u.length;t++){const s=u[t],i=h.templates[t],r=Math.max(1,Math.floor(i.maximumInstances)),n=s.renderClasses.map(e=>{let t=f.get(e);return null==t&&(t=d.length,f.set(e,t),d.push(e)),t}),a=g.length,o=new e.Vector3,c=l(s,new Array(r).fill(o));for(const e of c)e.renderClass=n[e.renderClass??0]??0,null!=e.parentEmitter&&(e.parentEmitter+=a),g.push(e);S.push({template:s,baseEmitterIndex:a,maximumInstances:r,freeSlots:Array.from({length:r},(e,t)=>r-t-1),emitterCapacities:s.emitters.map(e=>e.capacity),emitterIndexScratch:new Array(s.emitters.length).fill(0),emitterPositionOffsets:s.emitters.map(e=>e.position.clone()),maximumParticleLife:s.emitters.reduce((e,t)=>Math.max(e,t.life),0)}),I+=Math.ceil(s.particleCapacity/p)*p*r}const y=g.reduce((e,t)=>e+t.capacity,0),v=d.some(e=>null!=e.meshVertices),x=d.some(e=>!0===e.localSpace&&null==e.trail),E=g.some(e=>!0===e.localSpace&&null!=d[e.renderClass??0]?.trail),P=g.length*(E?r:s),C=v||g.some(e=>1!==e.meshScaleStart.x||1!==e.meshScaleStart.y||1!==e.meshScaleStart.z||1!==e.meshScaleEnd.x||1!==e.meshScaleEnd.y||1!==e.meshScaleEnd.z),T=g.reduce((e,t)=>{const s=d[t.renderClass??0]?.trail;return e+(null==s?0:t.capacity*(s.historyLength+1))},0),b=t({capacity:I,particleTransforms:C,vortex:g.some(e=>e.hasVortex),disperse:g.some(e=>e.hasDisperse),collisionEvents:g.some(e=>2===e.childSpawnEvent),trailHistoryEntries:T,meshSamplerEntries:g.reduce((e,t)=>{const s=t.meshSampler;return e+(null==s?0:4*s.vertexCount+2*s.triangleCount+4*s.boneCount)},0)});if(16*I*4+4*y+4*I+4*I*4+g.length*i+Math.max(s,P)+160+16*d.length*2+d.reduce((e,t)=>e+(t.meshVertices?.byteLength??0),0)+b.bytes+(v||x?16*g.length*4:0)>(h.maximumStorageBytes??Number.POSITIVE_INFINITY))return null;if(null!=h.device){const e=h.device.limits.maxStorageBufferBindingSize;if([16*I*4,4*g.reduce((e,t)=>e+t.capacity,0),4*I,4*I*4,g.length*i,Math.max(s,P),...v||x?[16*g.length*4]:[],...b.bytes>0?[b.bytes]:[]].some(t=>t>e))return null;if(7+(b.bytes>0?1:0)>h.device.limits.maxStorageBuffersPerShaderStage)return null}const B=new n(g,d,void 0,{pageSize:p,capacity:I,aliveCountReadback:h.aliveCountReadback});return new GpuSpriteWorldRuntime(B,new o({pageSize:p,maximumParticles:I}),S)}spawn(e,t){const s=this.pools[e],i=s?.freeSlots.pop();if(null==s||null==i)return null;const r=this.scheduler.createInstance({particleCapacity:s.template.particleCapacity,duration:s.template.duration});if(null==r)return s.freeSlots.push(i),null;const n=this.scheduler.arena.get(r).pages,a={handle:r,templateIndex:e,pages:n,logicalSlot:i,stoppingDeadline:Number.POSITIVE_INFINITY};this.activeByHandleSlot[r.slot]=a;for(const e of n)this.activePages.add(e);this.activePagesDirty=!0;const l=s.template.emitters.length;for(let e=0;e<l;e++){const r=s.baseEmitterIndex+i*l+e;s.emitterIndexScratch[e]=r;const n=this.runtime.emitters[r];this.positionScratch.copy(s.emitterPositionOffsets[e]),!0!==n.localSpace&&null==n.parentEmitter&&this.positionScratch.add(t),this.runtime.queueEmitterState(r,this.positionScratch,!0,!0)}return this.runtime.mapParticlePages(n,s.emitterIndexScratch,s.emitterCapacities),this.scheduler.play(r),a}destroy(e){const t=this.activeByHandleSlot[e.handle.slot];if(null==t||t.handle.generation!==e.handle.generation)return!1;const s=this.pools[t.templateIndex],i=s.template.emitters.length;for(let e=0;e<i;e++){const r=s.baseEmitterIndex+t.logicalSlot*i+e;this.runtime.queueEmitterState(r,this.runtime.emitters[r].position,!1)}for(const e of t.pages)this.activePages.delete(e);return this.activePagesDirty=!0,s.freeSlots.push(t.logicalSlot),this.activeByHandleSlot[e.handle.slot]=null,this.scheduler.destroyInstance(e.handle)}setPosition(e,t){const s=this.resolve(e);if(null==s)return!1;const i=this.pools[s.templateIndex];for(let e=0;e<i.template.emitters.length;e++){const r=this.emitterIndex(s,i,e);!0!==this.runtime.emitters[r].localSpace&&null==this.runtime.emitters[r].parentEmitter&&(this.positionScratch.copy(t).add(i.emitterPositionOffsets[e]),this.runtime.queueEmitterState(r,this.positionScratch,!0))}return!0}setTransform(e,t){const s=this.resolve(e);if(null==s)return!1;const i=this.pools[s.templateIndex];for(let e=0;e<i.template.emitters.length;e++){const r=this.emitterIndex(s,i,e),n=this.runtime.emitters[r];this.runtime.setEmitterTransform(r,t),!0!==n.localSpace&&null==n.parentEmitter&&(this.positionScratch.copy(i.emitterPositionOffsets[e]).applyMatrix4(t),this.runtime.queueEmitterState(r,this.positionScratch,!0))}return!0}pause(e){const t=this.resolve(e);return!(null==t||!this.scheduler.pause(t.handle))&&(this.forEachEmitter(t,e=>this.runtime.queueEmitterPaused(e,!0)),!0)}play(e){const t=this.resolve(e);return!(null==t||!this.scheduler.play(t.handle))&&(this.forEachEmitter(t,e=>this.runtime.queueEmitterPaused(e,!1)),!0)}restart(e){const t=this.resolve(e);return!(null==t||!this.scheduler.restart(t.handle))&&(t.stoppingDeadline=Number.POSITIVE_INFINITY,this.forEachEmitter(t,e=>{this.runtime.queueEmitterState(e,this.runtime.emitters[e].position,!0,!0)}),!0)}stop(e,t){const s=this.resolve(e),i=null==s?null:this.scheduler.getInstance(s.handle);if(null==s||null==i||!this.scheduler.stop(s.handle))return!1;const r=this.pools[s.templateIndex];return s.stoppingDeadline=i.elapsedTime+(null==t?r.maximumParticleLife:Math.max(0,t)),this.forEachEmitter(s,e=>this.runtime.queueEmitterStop(e,t)),!0}setTimescale(e,t){const s=this.resolve(e);return!(null==s||!this.scheduler.setTimescale(s.handle,t))&&(this.forEachEmitter(s,e=>this.runtime.queueEmitterTimescale(e,t)),!0)}setInput(e,t,s){const i=this.resolve(e);if(null==i)return!1;const r=this.pools[i.templateIndex];let n=!1;for(const e of r.template.inputBindings)e.inputId===t&&(n=this.runtime.setEmitterBoundValue(this.emitterIndex(i,r,e.emitterIndex),e,s)||n);return n&&this.scheduler.setDuration(i.handle,this.calculateInstanceDuration(i,r)),n}has(e){return null!=this.resolve(e)}update(e){this.scheduler.update(e),this.runtime.update(e);for(const e of this.activeByHandleSlot){if(null==e)continue;const t=this.scheduler.getInstance(e.handle);if(null==t)continue;const s=this.pools[e.templateIndex];(!1===t.playing&&t.elapsedTime>=s.template.duration||t.stopping&&t.elapsedTime>=e.stoppingDeadline)&&this.destroy(e)}this.flushActivePages()}flushActivePages(){this.activePagesDirty&&(this.runtime.setActivePages(this.activePages),this.activePagesDirty=!1)}dispose(){this.runtime.dispose();for(const e of this.activeByHandleSlot)null!=e&&this.scheduler.destroyInstance(e.handle);this.activeByHandleSlot.length=0}resolve(e){const t=this.activeByHandleSlot[e.handle.slot];return null!=t&&t.handle.generation===e.handle.generation&&null!=this.scheduler.getInstance(t.handle)?t:null}emitterIndex(e,t,s){return t.baseEmitterIndex+e.logicalSlot*t.template.emitters.length+s}forEachEmitter(e,t){const s=this.pools[e.templateIndex];for(let i=0;i<s.template.emitters.length;i++)t(this.emitterIndex(e,s,i))}calculateInstanceDuration(e,t){let s=0;for(let i=0;i<t.template.emitters.length;i++){const r=this.runtime.emitters[this.emitterIndex(e,t,i)],n="continuous"===r.rate.type?r.rate.duration<0?Number.POSITIVE_INFINITY:r.rate.delay+r.rate.duration+r.life:r.rate.delay+r.life;s=Math.max(s,n)}return s}}/*
1
+ import*as e from"three";import{calculateGpuSpriteOptionalStateLayout as t,GPU_SPRITE_BASE_COMMAND_BYTES as s,GPU_SPRITE_EMITTER_BYTES as i,GPU_SPRITE_TRANSFORM_COMMAND_BYTES as r,GpuSpriteRuntime as a}from"./gpu-sprite-runtime.js";import{GpuSpriteTemplateCache as n,instantiateGpuSpriteTemplate as l}from"./gpu-sprite-template.js";import{GpuVfxScheduler as o}from"./gpu-vfx-scheduler.js";export class GpuSpriteWorldRuntime{constructor(t,s,i){this.pools=i,this.activeByHandleSlot=[],this.activePages=new Set,this.positionScratch=new e.Vector3,this.activePagesDirty=!1,this.runtime=t,this.scheduler=s,this.templateCount=i.length;for(let e=0;e<t.emitters.length;e++)t.setEmitterActive(e,!1);t.setActivePages([])}static async create(c){if(0===c.templates.length)return null;const m=c.templateCache??new n,h=await Promise.all(c.templates.map(e=>null!=e.preparedTemplate?Promise.resolve({template:e.preparedTemplate,compatibility:e.preparedTemplate.compatibility,reasons:e.preparedTemplate.reasons}):m.resolve(e.asset,{assets:c.assets,renderClassCache:c.renderClassCache,resolveCustomMaterial:c.resolveCustomMaterial,revision:e.revision})));if(h.some(e=>null==e.template))return null;const u=h.map(e=>e.template),p=Math.max(1,Math.floor(c.particlePageSize??256)),d=[],f=new Map,g=[],S=[];let I=0;for(let t=0;t<u.length;t++){const s=u[t],i=c.templates[t],r=Math.max(1,Math.floor(i.maximumInstances)),a=s.renderClasses.map(e=>{let t=f.get(e);return null==t&&(t=d.length,f.set(e,t),d.push(e)),t}),n=g.length,o=new e.Vector3,m=l(s,new Array(r).fill(o));for(const e of m)e.renderClass=a[e.renderClass??0]??0,null!=e.parentEmitter&&(e.parentEmitter+=n),g.push(e);S.push({template:s,baseEmitterIndex:n,maximumInstances:r,freeSlots:Array.from({length:r},(e,t)=>r-t-1),emitterCapacities:s.emitters.map(e=>e.capacity),emitterIndexScratch:new Array(s.emitters.length).fill(0),emitterPositionOffsets:s.emitters.map(e=>e.position.clone()),maximumParticleLife:s.emitters.reduce((e,t)=>Math.max(e,t.life),0)}),I+=Math.ceil(s.particleCapacity/p)*p*r}const v=g.reduce((e,t)=>e+t.capacity,0),y=d.some(e=>null!=e.meshVertices),x=d.some(e=>!0===e.localSpace&&null==e.trail),E=g.some(e=>!0===e.localSpace&&null!=d[e.renderClass??0]?.trail),P=g.length*(E?r:s),C=y||g.some(e=>1!==e.meshScaleStart.x||1!==e.meshScaleStart.y||1!==e.meshScaleStart.z||1!==e.meshScaleEnd.x||1!==e.meshScaleEnd.y||1!==e.meshScaleEnd.z),T=g.reduce((e,t)=>{const s=d[t.renderClass??0]?.trail;return e+(null==s?0:t.capacity*(s.historyLength+1))},0),b=t({capacity:I,particleTransforms:C,vortex:g.some(e=>e.hasVortex),disperse:g.some(e=>e.hasDisperse),collisionEvents:g.some(e=>2===e.childSpawnEvent),trailHistoryEntries:T,meshSamplerEntries:g.reduce((e,t)=>{const s=t.meshSampler;return e+(null==s?0:4*s.vertexCount+2*s.triangleCount+4*s.boneCount)},0)});if(16*I*4+4*v+4*I+4*I*4+g.length*i+Math.max(s,P)+160+16*d.length*2+d.reduce((e,t)=>e+(t.meshVertices?.byteLength??0),0)+b.bytes+(y||x?16*g.length*4:0)>(c.maximumStorageBytes??Number.POSITIVE_INFINITY))return null;if(null!=c.device){const e=c.device.limits.maxStorageBufferBindingSize;if([16*I*4,4*g.reduce((e,t)=>e+t.capacity,0),4*I,4*I*4,g.length*i,Math.max(s,P),...y||x?[16*g.length*4]:[],...b.bytes>0?[b.bytes]:[]].some(t=>t>e))return null;if(7+(b.bytes>0?1:0)>c.device.limits.maxStorageBuffersPerShaderStage)return null}const w=new a(g,d,void 0,{pageSize:p,capacity:I,aliveCountReadback:c.aliveCountReadback});if(w.setPipelineDiagnosticAssets(d.map(e=>u.flatMap((t,s)=>{const i=t.renderClasses.indexOf(e);return i<0?[]:[{assetId:c.templates[s].asset.id,name:c.templates[s].asset.name,revision:c.templates[s].revision,outputIndex:i}]}))),null!=c.device){const{SCENE_COLOR_FORMAT:e}=await import("@hology/webgpu-renderer");await Promise.all([w.prepareComputePipelines(c.device),w.prepareRenderPipelines(c.device,e)])}return new GpuSpriteWorldRuntime(w,new o({pageSize:p,maximumParticles:I}),S)}spawn(e,t){const s=this.pools[e],i=s?.freeSlots.pop();if(null==s||null==i)return null;const r=this.scheduler.createInstance({particleCapacity:s.template.particleCapacity,duration:s.template.duration});if(null==r)return s.freeSlots.push(i),null;const a=this.scheduler.arena.get(r).pages,n={handle:r,templateIndex:e,pages:a,logicalSlot:i,stoppingDeadline:Number.POSITIVE_INFINITY};this.activeByHandleSlot[r.slot]=n;for(const e of a)this.activePages.add(e);this.activePagesDirty=!0;const l=s.template.emitters.length;for(let e=0;e<l;e++){const r=s.baseEmitterIndex+i*l+e;s.emitterIndexScratch[e]=r;const a=this.runtime.emitters[r];this.positionScratch.copy(s.emitterPositionOffsets[e]),!0!==a.localSpace&&null==a.parentEmitter&&this.positionScratch.add(t),this.runtime.queueEmitterState(r,this.positionScratch,!0,!0)}return this.runtime.mapParticlePages(a,s.emitterIndexScratch,s.emitterCapacities),this.scheduler.play(r),n}destroy(e){const t=this.activeByHandleSlot[e.handle.slot];if(null==t||t.handle.generation!==e.handle.generation)return!1;const s=this.pools[t.templateIndex],i=s.template.emitters.length;for(let e=0;e<i;e++){const r=s.baseEmitterIndex+t.logicalSlot*i+e;this.runtime.queueEmitterState(r,this.runtime.emitters[r].position,!1)}for(const e of t.pages)this.activePages.delete(e);return this.activePagesDirty=!0,s.freeSlots.push(t.logicalSlot),this.activeByHandleSlot[e.handle.slot]=null,this.scheduler.destroyInstance(e.handle)}setPosition(e,t){const s=this.resolve(e);if(null==s)return!1;const i=this.pools[s.templateIndex];for(let e=0;e<i.template.emitters.length;e++){const r=this.emitterIndex(s,i,e);!0!==this.runtime.emitters[r].localSpace&&null==this.runtime.emitters[r].parentEmitter&&(this.positionScratch.copy(t).add(i.emitterPositionOffsets[e]),this.runtime.queueEmitterState(r,this.positionScratch,!0))}return!0}setTransform(e,t){const s=this.resolve(e);if(null==s)return!1;const i=this.pools[s.templateIndex];for(let e=0;e<i.template.emitters.length;e++){const r=this.emitterIndex(s,i,e),a=this.runtime.emitters[r];this.runtime.setEmitterTransform(r,t),!0!==a.localSpace&&null==a.parentEmitter&&(this.positionScratch.copy(i.emitterPositionOffsets[e]).applyMatrix4(t),this.runtime.queueEmitterState(r,this.positionScratch,!0))}return!0}pause(e){const t=this.resolve(e);return!(null==t||!this.scheduler.pause(t.handle))&&(this.forEachEmitter(t,e=>this.runtime.queueEmitterPaused(e,!0)),!0)}play(e){const t=this.resolve(e);return!(null==t||!this.scheduler.play(t.handle))&&(this.forEachEmitter(t,e=>this.runtime.queueEmitterPaused(e,!1)),!0)}restart(e){const t=this.resolve(e);return!(null==t||!this.scheduler.restart(t.handle))&&(t.stoppingDeadline=Number.POSITIVE_INFINITY,this.forEachEmitter(t,e=>{this.runtime.queueEmitterState(e,this.runtime.emitters[e].position,!0,!0)}),!0)}stop(e,t){const s=this.resolve(e),i=null==s?null:this.scheduler.getInstance(s.handle);if(null==s||null==i||!this.scheduler.stop(s.handle))return!1;const r=this.pools[s.templateIndex];return s.stoppingDeadline=i.elapsedTime+(null==t?r.maximumParticleLife:Math.max(0,t)),this.forEachEmitter(s,e=>this.runtime.queueEmitterStop(e,t)),!0}setTimescale(e,t){const s=this.resolve(e);return!(null==s||!this.scheduler.setTimescale(s.handle,t))&&(this.forEachEmitter(s,e=>this.runtime.queueEmitterTimescale(e,t)),!0)}setInput(e,t,s){const i=this.resolve(e);if(null==i)return!1;const r=this.pools[i.templateIndex];let a=!1;for(const e of r.template.inputBindings)e.inputId===t&&(a=this.runtime.setEmitterBoundValue(this.emitterIndex(i,r,e.emitterIndex),e,s)||a);return a&&this.scheduler.setDuration(i.handle,this.calculateInstanceDuration(i,r)),a}has(e){return null!=this.resolve(e)}update(e){this.scheduler.update(e),this.runtime.update(e);for(const e of this.activeByHandleSlot){if(null==e)continue;const t=this.scheduler.getInstance(e.handle);if(null==t)continue;const s=this.pools[e.templateIndex];(!1===t.playing&&t.elapsedTime>=s.template.duration||t.stopping&&t.elapsedTime>=e.stoppingDeadline)&&this.destroy(e)}this.flushActivePages()}flushActivePages(){this.activePagesDirty&&(this.runtime.setActivePages(this.activePages),this.activePagesDirty=!1)}dispose(){this.runtime.dispose();for(const e of this.activeByHandleSlot)null!=e&&this.scheduler.destroyInstance(e.handle);this.activeByHandleSlot.length=0}resolve(e){const t=this.activeByHandleSlot[e.handle.slot];return null!=t&&t.handle.generation===e.handle.generation&&null!=this.scheduler.getInstance(t.handle)?t:null}emitterIndex(e,t,s){return t.baseEmitterIndex+e.logicalSlot*t.template.emitters.length+s}forEachEmitter(e,t){const s=this.pools[e.templateIndex];for(let i=0;i<s.template.emitters.length;i++)t(this.emitterIndex(e,s,i))}calculateInstanceDuration(e,t){let s=0;for(let i=0;i<t.template.emitters.length;i++){const r=this.runtime.emitters[this.emitterIndex(e,t,i)],a="continuous"===r.rate.type?r.rate.duration<0?Number.POSITIVE_INFINITY:r.rate.delay+r.rate.duration+r.life:r.rate.delay+r.life;s=Math.max(s,a)}return s}}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import e from"typedi";import{BehaviorSubject as t,Subject as i}from"rxjs";import{loadScene as n}from"../scene/bootstrap.js";import{ActorFactory as s}from"./actors/factory.js";import{SceneMaterializer as r}from"../scene/materializer.js";import{SceneDataService as o}from"../scene/scene-data-service.js";import{World as a}from"./services/world.js";import{ViewController as c}from"./services/render.js";import{RenderingView as l,GraphicsRuntime as p}from"../rendering.js";import{PhysicsSystem as h}from"./services/physics/physics-system.js";import{MeshComponent as d}from"./actors/builtin/components/mesh-component.js";import{builtInComponents as m}from"./actors/builtin/components/index.js";import{InputService as u}from"./input/index.js";import{RuntimeAssetsService as g}from"../scene/runtime-asset-service.js";import{AssetResourceLoader as w}from"../scene/asset-resource-loader.js";import{AssetLoader as f}from"./services/asset-loader.js";import{RuntimeBundledBackendService as y}from"../scene/runtime-bundled-backend-service.js";import{AssetsProvider as S}from"../scene/assets-provider.js";import{ShaderProvider as v}from"./services/shader-provider.js";import{PointerEvents as b}from"./services/pointer-events.js";import{GpuVfxWorldService as I}from"../effects/vfx/gpu-vfx-world-service.js";import{NetMode as j}from"./net/net-session.js";import{GameStateContext as A}from"./game-state-context.js";import{PlayerSessions as V}from"./player-sessions.js";import{polyfillClient as P}from"./polyfill.js";import{withInjectionContext as C}from"./inject.js";import{RenderingHost as R}from"./rendering-host.js";import{SceneTransitionService as z}from"./services/scene-transition.js";import{SceneRef as H}from"../scene/scene-ref.js";import{ActorPersistence as N}from"./services/actor-persistence.js";let x=0;export function initiateApplication(t,i){const n="function"==typeof t?t:void 0,s=i??t;var r;P(),"element"in s&&null!=s.element&&(r=s.element,Object.assign(r.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden"}));const o=s.renderingHost??(null!=s.renderingView?new R(s.renderingView,!1,("renderingViewFactory"in s?s.renderingViewFactory:void 0)??(()=>new l(s.renderingView.container,s.renderingView.options))):function(e,t,i){const n=new p,s=()=>function(e,t,i,n){return new l(e,{graphicsRuntime:n,backend:t?.backend??"webgpu",enableXR:!0===i?.enabled,maxPixelRatio:t?.maxPixelRatio,resolutionScale:t?.resolutionScale,dynamicResolution:t?.dynamicResolution,upscaling:t?.upscaling,webgpuPostProcessing:t?.webgpuPostProcessing,webgpuDirectionalShadows:t?.webgpuDirectionalShadows,webgpuVfx:t?.webgpuVfx??"auto",msaa:t?.msaa,fpsCap:t?.fpsCap,depthPrepass:{enabled:!0===t?.depthPrepass?.enabled},bloom:{enabled:!1!==t?.bloom?.enabled},reflection:{enabled:!1!==t?.reflection?.enabled},occlusionCulling:{enabled:!1!==t?.occlusionCulling?.enabled},shadows:{enabled:t?.shadows?.enabled??!0,autoUpdate:t?.shadows?.autoUpdate??!0,cascadeUpdateIntervals:[22,40,60,120]}})}(e,t,i,n);return new R(s(),!0,s)}(s.element,s.rendering,s.xr)),a=e.of("hology-application-"+ ++x),c=new HologyApplicationRuntime(s,a,o,n??s.defaultGameClass);return c.startInitialization(),c}export function initiateGame(e,t){const{sceneName:i,detailTier:n,multi:s,localPlayer:r,persistence:o,...a}=t,c=initiateApplication(e,a),l=c.ready.then(()=>c.loadGame({sceneName:i,detailTier:n,multi:s,localPlayer:r,persistence:o}));return new HologyRuntime(c,l)}export class GameInstance{onPreload(){}onStart(){}onUnload(){return this.onShutdown()}onShutdown(){}}export class HologyApplicationRuntime{constructor(e,n,s,r){this.config=e,this.applicationContainer=n,this.renderingHost=s,this.defaultGameClass=r,this.stateSubject=new t({type:"initializing"}),this.state=this.stateSubject.asObservable(),this.shutdownSubject=new i,this.shutdownStarted=this.shutdownSubject.asObservable(),this.transitionTail=Promise.resolve(),this.initializationPromise=Promise.resolve(),this.transitionIntent=0,this.shutdownFlag=!1,this.ready=new Promise((e,t)=>{this.resolveReady=e,this.rejectReady=t})}get renderingView(){return this.renderingHost.activeView}get currentState(){return this.stateSubject.value}startInitialization(){this.initializationPromise=this.initialize()}async initialize(){try{if(this.registerApplicationServices(),await this.renderingHost.applicationView.compileAsync(),this.shutdownFlag)return void this.rejectReady(k());const e=this.getApplicationService(u);this.renderingHost.start(t=>e.update(t),t=>e.sampleGamepadButtons(t)),this.setState({type:"menu"}),this.resolveReady()}catch(e){this.setState({type:"error",operation:"initialize",error:e}),this.rejectReady(e)}}loadGame(e,t){const i="function"==typeof e?e:this.defaultGameClass,n=t??e;if(null==i)return Promise.reject(new Error("loadGame() requires a game class because no default was configured"));const s=++this.transitionIntent;return this.enqueue(async()=>(await this.ready,this.assertRunning(),this.checkIntent(s),null!=this.session&&await this.disposeSession(this.session,!0),this.checkIntent(s),this.performLoad(i,n,s)))}unloadGame(){const e=++this.transitionIntent;return this.enqueue(async()=>{if(await this.ready,!this.shutdownFlag&&e===this.transitionIntent){try{null!=this.session&&await this.disposeSession(this.session,!0)}catch(t){throw this.shutdownFlag||e!==this.transitionIntent||this.setState({type:"error",operation:"unload",error:t}),t}this.shutdownFlag||e!==this.transitionIntent||this.setState({type:"menu"})}})}transitionScene(e){const t="string"==typeof e?{scene:new H(e,e)}:e instanceof H?{scene:e}:e,i=this.transitionIntent;return this.enqueue(async()=>{await this.ready,this.assertRunning(),this.checkIntent(i);const e=this.session;if(null==e)throw new Error("transitionScene() requires an active game session");try{return await this.performSceneTransition(e,t,i),e}catch(e){throw G(e)||this.shutdownFlag||i!==this.transitionIntent||this.setState({type:"error",operation:"load",error:e}),e}})}async shutdown(){this.shutdownFlag||(this.shutdownFlag=!0,++this.transitionIntent,this.shutdownSubject.next(),this.shutdownSubject.complete(),await this.initializationPromise.catch(()=>{}),await this.transitionTail.catch(()=>{}),null!=this.session&&await this.disposeSession(this.session,!1),this.getApplicationService(u).stop(),this.getOptionalApplicationService(b)?.stop(),this.getApplicationService(w).disposeAll(),this.getApplicationService(g).dispose(),this.getApplicationService(c).dispose(!1),this.renderingHost.shutdown(),e.reset(this.applicationContainer.id),this.setState({type:"stopped"}),this.stateSubject.complete())}getWorld(){return this.session?.world}getGameInstance(){return this.session?.gameInstance}getApplicationService(e){return this.applicationContainer.get(e)}getSessionService(e){return this.session?.container.get(e)}getService(e){return null!=this.session?this.session.container.get(e):this.applicationContainer.get(e)}registerRenderStage(e){return this.renderingHost.registerStage(e)}registerApplicationServices(){const e=new c(this.renderingView);this.applicationContainer.set(l,this.renderingHost.applicationView),this.applicationContainer.set(c,e);const t=new y(this.config.runtimeDataUrl),i=new g(t),n=new w;n.setDataDir(this.config.dataDir),n.setDirectFileLoading(!0===this.config.directAssetFileLoading),"webgpu"===this.renderingHost.applicationView.requestedBackend?n.initKtx2ForWebGpu():n.initKtx2(this.renderingHost.applicationView.renderer);const s=Object.entries(this.config.shaders).map(([e,t])=>({name:e,type:t}));this.applicationContainer.set(y,t),this.applicationContainer.set(S,i),this.applicationContainer.set(g,i),this.applicationContainer.set(w,n),this.applicationContainer.set(f,new f(n,i,s)),this.applicationContainer.set(v,new v(s));const r=C(this.applicationContainer,e=>e.get(u));this.applicationContainer.set(u,r)}async performLoad(t,i,s){if(null!=i.persistence&&null!=i.multi?.session&&i.multi.session.mode!==j.none)throw new Error("Actor persistence currently supports single-player sessions only");const o=this.createSession(i);this.session=o;try{this.loading(i.sceneName,"physics",.08),await Promise.all([o.physics.start(),o.renderingView.initializeBackend()]),this.checkIntent(s),this.loading(i.sceneName,"runtime-data",.2),await this.getApplicationService(y).preloadData(),this.checkIntent(s),this.loading(i.sceneName,"scene",.42);const a=await n(o.renderingView,i.sceneName,this.config.dataDir,this.config.shaders,this.config.actors,o.components,o.actorFactory,this.getApplicationService(y),this.getApplicationService(g),this.getApplicationService(w),{detailTier:i.detailTier,nodeMode:i.multi?.session.mode??j.none,persistence:o.world.persistence});if(o.materializer.dispose(),o.materializer=a.materializer,o.sceneRoots=a.sceneRoots,o.container.set(r,a.materializer),o.world.materializer=a.materializer,o.world.scene=a.scene,o.physics.scene=a.scene,this.checkIntent(s),null!=i.multi?.session){const{NetService:e}=await import("./net/service/net-service.js"),t=C(o.container,t=>t.get(e));t.session=i.multi.session,t.start(),o.stopPlayers=()=>t.stop()}if(e.import([d]),await this.restoreSceneActors(o,a.materializer,a.actors,s),o.physics.addFromScene(a.scene),await o.world.startSceneEventGraphs(a.materializer),this.checkIntent(s),o.gameInstance=C(o.container,e=>(e.set({id:t,type:t}),e.get(t))),this.loading(i.sceneName,"game-preload",.58),o.gameInstance instanceof GameInstance&&await o.gameInstance.onPreload(),this.checkIntent(s),this.loading(i.sceneName,"shaders",.7),await o.renderingView.compileAsync(),this.checkIntent(s),this.loading(i.sceneName,"textures",.82),await o.renderingView.initTexturesAsync(),this.checkIntent(s),"webgpu"===o.renderingView.activeBackend){this.loading(i.sceneName,"vfx-warmup",.94);const e=o.container.get(I).beginPipelineWarmup();try{const e=performance.now();console.info("[Hology GPU VFX warmup] Rendering loading frame",i.sceneName),o.renderingView.render(0),console.info("[Hology GPU VFX warmup] Render returned; waiting for GPU queue",{sceneName:i.sceneName,renderMs:performance.now()-e}),await(o.renderingView.webGpuDevice?.queue.onSubmittedWorkDone()),console.info("[Hology GPU VFX warmup] GPU queue completed",{sceneName:i.sceneName,totalMs:performance.now()-e})}finally{e()}}return this.checkIntent(s),o.gameInstance instanceof GameInstance&&await o.gameInstance.onStart(),this.checkIntent(s),o.viewController.paused=!1,this.renderingHost.activate(o.renderingView),this.setState({type:"playing",sceneName:i.sceneName}),o}catch(e){throw await this.disposeSession(o,!1),G(e)||this.shutdownFlag||s!==this.transitionIntent||this.setState({type:"error",operation:"load",error:e}),e}}createSession(t){const i=e.of("hology-session-"+ ++x);this.copyApplicationServices(i);const n=this.renderingHost.createView(),p=new c(n);p.paused=!0,i.set(l,n),i.set(c,p);const d={...m,...this.config.components??{}},u=new N;null!=t.persistence&&u.configure(t.persistence),i.set(N,u);const f=new s(i,{inEditor:!1});f.classes=this.config.actors,i.set(s,f);const y=new r(n.scene,new o,this.getApplicationService(g),this.getApplicationService(w),n,Object.entries(this.config.shaders).map(([e,t])=>({name:e,type:t})),Object.entries(this.config.actors).map(([e,t])=>({name:e,type:t})),f,Object.entries(d).map(([e,t])=>({name:e,type:t})));y.inEditor=!1,y.netMode=t.multi?.session.mode??j.none,i.set(r,y);const S=C(i,e=>e.get(a));u.enabled&&(S.persistence=u),S.scene=n.scene,i.set(a,S);const v=C(i,e=>e.get(h));i.set(h,v);const b=new z;b.bind(async e=>{await this.transitionScene(e)}),i.set(z,b);const I=C(i,e=>e.get(V));i.set(V,I);const P=C(i,e=>e.get(A));return i.set(A,P),null==t.multi?.session&&I.startStandalone(t.localPlayer??{id:"local-player",displayName:"Player"}),{sceneName:t.sceneName,detailTier:t.detailTier,container:i,renderingView:n,viewController:p,actorFactory:f,materializer:y,world:S,physics:v,components:d,sceneTransition:b,sceneRoots:[],netMode:t.multi?.session.mode??j.none,stopPlayers:null==t.multi?.session?()=>{I.stop(),P.stop()}:void 0}}async performSceneTransition(e,t,i){if(e.netMode!==j.none)throw new Error("In-session scene transitions are not yet supported for network sessions");const s=t.scene.id.trim();if(0===s.length)throw new Error("A destination scene id is required");const o=e.sceneName,a=e.viewController.paused;e.viewController.paused=!0,this.renderingHost.activate(this.renderingHost.applicationView),e.world.persistence?.captureAll(),this.setState({type:"unloading",sceneName:o}),e.world.stopSceneEventGraphs();const c=e.world.removeSceneLifetimeActors(e.sceneRoots);for(const t of e.sceneRoots)e.physics.removeRemoved(t),t.removeFromParent();e.sceneRoots=[],e.materializer.dispose(c),this.checkIntent(i),this.loading(s,"scene",.42);const l=await n(e.renderingView,s,this.config.dataDir,this.config.shaders,this.config.actors,e.components,e.actorFactory,this.getApplicationService(y),this.getApplicationService(g),this.getApplicationService(w),{detailTier:e.detailTier,nodeMode:e.netMode,persistence:e.world.persistence});this.checkIntent(i),e.materializer=l.materializer,e.sceneRoots=l.sceneRoots,e.sceneName=s,e.container.set(r,l.materializer),e.world.materializer=l.materializer,await this.restoreSceneActors(e,l.materializer,l.actors,i),e.physics.addFromScene(l.scene),await e.world.startSceneEventGraphs(l.materializer),await(t.afterLoad?.(e.world)),this.checkIntent(i),this.loading(s,"shaders",.7),await e.renderingView.compileAsync(),this.checkIntent(i),this.loading(s,"textures",.82),await e.renderingView.initTexturesAsync(),this.checkIntent(i),e.sceneTransition.publish({previousSceneName:o,sceneName:s}),e.viewController.paused=a,this.renderingHost.activate(e.renderingView),this.setState({type:"playing",sceneName:s})}async restoreSceneActors(e,t,i,n){if(null==e.world.persistence){for(const t of i)e.world.addActor(t);return}const s=i.filter(t=>!e.world.actors.includes(t));for(const t of s)e.world.addActor(t,void 0,void 0,void 0,!0);const r=t.registerPersistentActors();await e.world.persistence.restore(r,()=>this.checkIntent(n)),this.checkIntent(n);for(const t of s)e.world.beginActorPlay(t)}copyApplicationServices(e){const t=[u,S,g,y,w,f,v];for(const i of t)e.set(i,this.applicationContainer.get(i))}async disposeSession(t,i){if(t.disposed)return;let n;t.disposed=!0,i&&this.setState({type:"unloading",sceneName:t.sceneName});try{t.viewController.paused=!0,t.world.persistence?.captureAll(),t.stopPlayers?.(),t.sceneTransition.dispose(),t.world.stopSceneEventGraphs(),t.gameInstance instanceof GameInstance&&await t.gameInstance.onUnload()}catch(e){n=e}finally{for(const e of[...t.world.actors])t.world.removeActor(e);t.physics.stop(),t.materializer.dispose(),this.renderingHost.activeView===t.renderingView&&this.renderingHost.activate(this.renderingHost.applicationView),t.viewController.dispose(!1),this.renderingHost.releaseView(t.renderingView),e.reset(t.container.id),this.session===t&&(this.session=void 0)}if(null!=n)throw n}enqueue(e){const t=this.transitionTail.then(e,e);return this.transitionTail=t.catch(()=>{}),t}checkIntent(e){if(this.assertRunning(),e!==this.transitionIntent)throw k()}assertRunning(){if(this.shutdownFlag)throw new Error("Hology application has been shut down")}loading(e,t,i){this.setState({type:"loading",sceneName:e,stage:t,progress:i})}setState(e){const t=this.renderingHost.applicationView;"loading"===e.type?t.stopAnimationLoop():"menu"!==e.type&&("error"!==e.type||"initialize"===e.operation)||this.renderingHost.activeView!==t||t.running||this.renderingHost.activate(t),this.stateSubject.next(e)}getOptionalApplicationService(e){return this.applicationContainer.has(e)?this.applicationContainer.get(e):void 0}}export class HologyRuntime{constructor(e,t){this.application=e,this.ready=t.then(()=>!0),this.shutdownStarted=e.shutdownStarted}get status(){return"playing"===this.application.currentState.type?5:"stopped"===this.application.currentState.type||"error"===this.application.currentState.type?10:0}get gameInstance(){return this.application.getGameInstance()}get isShutdown(){return"stopped"===this.application.currentState.type}getWorld(){return this.application.getWorld()}getService(e){return this.application.getService(e)}shutdown(){return this.application.shutdown()}}function k(){return new DOMException("Superseded by a newer game transition","AbortError")}function G(e){return e instanceof DOMException&&"AbortError"===e.name}/*
1
+ import{setWebGpuPipelineLoading as e}from"../rendering/webgpu-runtime-bridge.js";import t from"typedi";import{BehaviorSubject as i,Subject as n}from"rxjs";import{loadScene as s}from"../scene/bootstrap.js";import{ActorFactory as r}from"./actors/factory.js";import{SceneMaterializer as o}from"../scene/materializer.js";import{SceneDataService as a}from"../scene/scene-data-service.js";import{World as c}from"./services/world.js";import{ViewController as l}from"./services/render.js";import{RenderingView as p,GraphicsRuntime as h}from"../rendering.js";import{PhysicsSystem as d}from"./services/physics/physics-system.js";import{MeshComponent as m}from"./actors/builtin/components/mesh-component.js";import{builtInComponents as u}from"./actors/builtin/components/index.js";import{InputService as g}from"./input/index.js";import{RuntimeAssetsService as w}from"../scene/runtime-asset-service.js";import{AssetResourceLoader as f}from"../scene/asset-resource-loader.js";import{AssetLoader as y}from"./services/asset-loader.js";import{RuntimeBundledBackendService as v}from"../scene/runtime-bundled-backend-service.js";import{AssetsProvider as S}from"../scene/assets-provider.js";import{ShaderProvider as b}from"./services/shader-provider.js";import{PointerEvents as j}from"./services/pointer-events.js";import{GpuVfxWorldService as I}from"../effects/vfx/gpu-vfx-world-service.js";import{NetMode as A}from"./net/net-session.js";import{GameStateContext as V}from"./game-state-context.js";import{PlayerSessions as P}from"./player-sessions.js";import{polyfillClient as N}from"./polyfill.js";import{withInjectionContext as C}from"./inject.js";import{RenderingHost as R}from"./rendering-host.js";import{SceneTransitionService as z}from"./services/scene-transition.js";import{SceneRef as G}from"../scene/scene-ref.js";import{ActorPersistence as H}from"./services/actor-persistence.js";let x=0;export function initiateApplication(e,i){const n="function"==typeof e?e:void 0,s=i??e;var r;N(),"element"in s&&null!=s.element&&(r=s.element,Object.assign(r.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden"}));const o=s.renderingHost??(null!=s.renderingView?new R(s.renderingView,!1,("renderingViewFactory"in s?s.renderingViewFactory:void 0)??(()=>new p(s.renderingView.container,s.renderingView.options))):function(e,t,i){const n=new h,s=()=>function(e,t,i,n){return new p(e,{graphicsRuntime:n,backend:t?.backend??"webgpu",enableXR:!0===i?.enabled,maxPixelRatio:t?.maxPixelRatio,resolutionScale:t?.resolutionScale,dynamicResolution:t?.dynamicResolution,upscaling:t?.upscaling,webgpuPostProcessing:t?.webgpuPostProcessing,webgpuDirectionalShadows:t?.webgpuDirectionalShadows,webgpuVfx:t?.webgpuVfx??"auto",msaa:t?.msaa,fpsCap:t?.fpsCap,depthPrepass:{enabled:!0===t?.depthPrepass?.enabled},bloom:{enabled:!1!==t?.bloom?.enabled},reflection:{enabled:!1!==t?.reflection?.enabled},occlusionCulling:{enabled:!1!==t?.occlusionCulling?.enabled},shadows:{enabled:t?.shadows?.enabled??!0,autoUpdate:t?.shadows?.autoUpdate??!0,cascadeUpdateIntervals:[22,40,60,120]}})}(e,t,i,n);return new R(s(),!0,s)}(s.element,s.rendering,s.xr)),a=t.of("hology-application-"+ ++x),c=new HologyApplicationRuntime(s,a,o,n??s.defaultGameClass);return c.startInitialization(),c}export function initiateGame(e,t){const{sceneName:i,detailTier:n,multi:s,localPlayer:r,persistence:o,...a}=t,c=initiateApplication(e,a),l=c.ready.then(()=>c.loadGame({sceneName:i,detailTier:n,multi:s,localPlayer:r,persistence:o}));return new HologyRuntime(c,l)}export class GameInstance{onPreload(){}onStart(){}onUnload(){return this.onShutdown()}onShutdown(){}}export class HologyApplicationRuntime{constructor(e,t,s,r){this.config=e,this.applicationContainer=t,this.renderingHost=s,this.defaultGameClass=r,this.stateSubject=new i({type:"initializing"}),this.state=this.stateSubject.asObservable(),this.shutdownSubject=new n,this.shutdownStarted=this.shutdownSubject.asObservable(),this.transitionTail=Promise.resolve(),this.initializationPromise=Promise.resolve(),this.transitionIntent=0,this.shutdownFlag=!1,this.ready=new Promise((e,t)=>{this.resolveReady=e,this.rejectReady=t})}get renderingView(){return this.renderingHost.activeView}get currentState(){return this.stateSubject.value}startInitialization(){this.initializationPromise=this.initialize()}async initialize(){try{if(this.registerApplicationServices(),await this.renderingHost.applicationView.compileAsync(),this.shutdownFlag)return void this.rejectReady(k());const e=this.getApplicationService(g);this.renderingHost.start(t=>e.update(t),t=>e.sampleGamepadButtons(t)),this.setState({type:"menu"}),this.resolveReady()}catch(e){this.setState({type:"error",operation:"initialize",error:e}),this.rejectReady(e)}}loadGame(e,t){const i="function"==typeof e?e:this.defaultGameClass,n=t??e;if(null==i)return Promise.reject(new Error("loadGame() requires a game class because no default was configured"));const s=++this.transitionIntent;return this.enqueue(async()=>(await this.ready,this.assertRunning(),this.checkIntent(s),null!=this.session&&await this.disposeSession(this.session,!0),this.checkIntent(s),this.performLoad(i,n,s)))}unloadGame(){const e=++this.transitionIntent;return this.enqueue(async()=>{if(await this.ready,!this.shutdownFlag&&e===this.transitionIntent){try{null!=this.session&&await this.disposeSession(this.session,!0)}catch(t){throw this.shutdownFlag||e!==this.transitionIntent||this.setState({type:"error",operation:"unload",error:t}),t}this.shutdownFlag||e!==this.transitionIntent||this.setState({type:"menu"})}})}transitionScene(e){const t="string"==typeof e?{scene:new G(e,e)}:e instanceof G?{scene:e}:e,i=this.transitionIntent;return this.enqueue(async()=>{await this.ready,this.assertRunning(),this.checkIntent(i);const e=this.session;if(null==e)throw new Error("transitionScene() requires an active game session");try{return await this.performSceneTransition(e,t,i),e}catch(e){throw F(e)||this.shutdownFlag||i!==this.transitionIntent||this.setState({type:"error",operation:"load",error:e}),e}})}async shutdown(){this.shutdownFlag||(this.shutdownFlag=!0,++this.transitionIntent,this.shutdownSubject.next(),this.shutdownSubject.complete(),await this.initializationPromise.catch(()=>{}),await this.transitionTail.catch(()=>{}),null!=this.session&&await this.disposeSession(this.session,!1),this.getApplicationService(g).stop(),this.getOptionalApplicationService(j)?.stop(),this.getApplicationService(f).disposeAll(),this.getApplicationService(w).dispose(),this.getApplicationService(l).dispose(!1),this.renderingHost.shutdown(),t.reset(this.applicationContainer.id),this.setState({type:"stopped"}),this.stateSubject.complete())}getWorld(){return this.session?.world}getGameInstance(){return this.session?.gameInstance}getApplicationService(e){return this.applicationContainer.get(e)}getSessionService(e){return this.session?.container.get(e)}getService(e){return null!=this.session?this.session.container.get(e):this.applicationContainer.get(e)}registerRenderStage(e){return this.renderingHost.registerStage(e)}registerApplicationServices(){const e=new l(this.renderingView);this.applicationContainer.set(p,this.renderingHost.applicationView),this.applicationContainer.set(l,e);const t=new v(this.config.runtimeDataUrl),i=new w(t),n=new f;n.setDataDir(this.config.dataDir),n.setDirectFileLoading(!0===this.config.directAssetFileLoading),"webgpu"===this.renderingHost.applicationView.requestedBackend?n.initKtx2ForWebGpu():n.initKtx2(this.renderingHost.applicationView.renderer);const s=Object.entries(this.config.shaders).map(([e,t])=>({name:e,type:t}));this.applicationContainer.set(v,t),this.applicationContainer.set(S,i),this.applicationContainer.set(w,i),this.applicationContainer.set(f,n),this.applicationContainer.set(y,new y(n,i,s)),this.applicationContainer.set(b,new b(s));const r=C(this.applicationContainer,e=>e.get(g));this.applicationContainer.set(g,r)}async performLoad(i,n,r){if(null!=n.persistence&&null!=n.multi?.session&&n.multi.session.mode!==A.none)throw new Error("Actor persistence currently supports single-player sessions only");const a=this.createSession(n);this.session=a;try{this.loading(n.sceneName,"physics",.08),await Promise.all([a.physics.start(),a.renderingView.initializeBackend()]),await e(a.renderingView.webGpuDevice,!0,"loading: "+n.sceneName),this.checkIntent(r),this.loading(n.sceneName,"runtime-data",.2),await this.getApplicationService(v).preloadData(),this.checkIntent(r),this.loading(n.sceneName,"scene",.42);const c=await s(a.renderingView,n.sceneName,this.config.dataDir,this.config.shaders,this.config.actors,a.components,a.actorFactory,this.getApplicationService(v),this.getApplicationService(w),this.getApplicationService(f),{detailTier:n.detailTier,nodeMode:n.multi?.session.mode??A.none,persistence:a.world.persistence});if(a.materializer.dispose(),a.materializer=c.materializer,a.sceneRoots=c.sceneRoots,a.container.set(o,c.materializer),a.world.materializer=c.materializer,a.world.scene=c.scene,a.physics.scene=c.scene,this.checkIntent(r),null!=n.multi?.session){const{NetService:e}=await import("./net/service/net-service.js"),t=C(a.container,t=>t.get(e));t.session=n.multi.session,t.start(),a.stopPlayers=()=>t.stop()}if(t.import([m]),await this.restoreSceneActors(a,c.materializer,c.actors,r),a.physics.addFromScene(c.scene),await a.world.startSceneEventGraphs(c.materializer),this.checkIntent(r),a.gameInstance=C(a.container,e=>(e.set({id:i,type:i}),e.get(i))),this.loading(n.sceneName,"game-preload",.58),a.gameInstance instanceof GameInstance&&await a.gameInstance.onPreload(),this.checkIntent(r),this.loading(n.sceneName,"shaders",.7),await a.renderingView.compileAsync(),this.checkIntent(r),this.loading(n.sceneName,"textures",.82),await a.renderingView.initTexturesAsync(),this.checkIntent(r),"webgpu"===a.renderingView.activeBackend){this.loading(n.sceneName,"vfx-warmup",.94);const e=C(a.container,e=>e.get(I).beginPipelineWarmup());try{const e=performance.now();console.info("[Hology GPU VFX warmup] Rendering loading frame",n.sceneName),a.renderingView.render(0),console.info("[Hology GPU VFX warmup] Render returned; waiting for GPU queue",{sceneName:n.sceneName,renderMs:performance.now()-e}),await(a.renderingView.webGpuDevice?.queue.onSubmittedWorkDone()),console.info("[Hology GPU VFX warmup] GPU queue completed",{sceneName:n.sceneName,totalMs:performance.now()-e})}finally{e()}}return this.checkIntent(r),await e(a.renderingView.webGpuDevice,!1,"playing: "+n.sceneName),a.gameInstance instanceof GameInstance&&await a.gameInstance.onStart(),this.checkIntent(r),a.viewController.paused=!1,this.renderingHost.activate(a.renderingView),this.setState({type:"playing",sceneName:n.sceneName}),a}catch(e){throw await this.disposeSession(a,!1),F(e)||this.shutdownFlag||r!==this.transitionIntent||this.setState({type:"error",operation:"load",error:e}),e}}createSession(e){const i=t.of("hology-session-"+ ++x);this.copyApplicationServices(i);const n=this.renderingHost.createView(),s=new l(n);s.paused=!0,i.set(p,n),i.set(l,s);const h={...u,...this.config.components??{}},m=new H;null!=e.persistence&&m.configure(e.persistence),i.set(H,m);const g=new r(i,{inEditor:!1});g.classes=this.config.actors,i.set(r,g);const y=new o(n.scene,new a,this.getApplicationService(w),this.getApplicationService(f),n,Object.entries(this.config.shaders).map(([e,t])=>({name:e,type:t})),Object.entries(this.config.actors).map(([e,t])=>({name:e,type:t})),g,Object.entries(h).map(([e,t])=>({name:e,type:t})));y.inEditor=!1,y.netMode=e.multi?.session.mode??A.none,i.set(o,y);const v=C(i,e=>e.get(c));m.enabled&&(v.persistence=m),v.scene=n.scene,i.set(c,v);const S=C(i,e=>e.get(d));i.set(d,S);const b=new z;b.bind(async e=>{await this.transitionScene(e)}),i.set(z,b);const j=C(i,e=>e.get(P));i.set(P,j);const I=C(i,e=>e.get(V));return i.set(V,I),null==e.multi?.session&&j.startStandalone(e.localPlayer??{id:"local-player",displayName:"Player"}),{sceneName:e.sceneName,detailTier:e.detailTier,container:i,renderingView:n,viewController:s,actorFactory:g,materializer:y,world:v,physics:S,components:h,sceneTransition:b,sceneRoots:[],netMode:e.multi?.session.mode??A.none,stopPlayers:null==e.multi?.session?()=>{j.stop(),I.stop()}:void 0}}async performSceneTransition(t,i,n){if(t.netMode!==A.none)throw new Error("In-session scene transitions are not yet supported for network sessions");const r=i.scene.id.trim();if(0===r.length)throw new Error("A destination scene id is required");await e(t.renderingView.webGpuDevice,!0,"transition: "+r);const a=t.sceneName,c=t.viewController.paused;t.viewController.paused=!0,this.renderingHost.activate(this.renderingHost.applicationView),t.world.persistence?.captureAll(),this.setState({type:"unloading",sceneName:a}),t.world.stopSceneEventGraphs();const l=t.world.removeSceneLifetimeActors(t.sceneRoots);for(const e of t.sceneRoots)t.physics.removeRemoved(e),e.removeFromParent();t.sceneRoots=[],t.materializer.dispose(l),this.checkIntent(n),this.loading(r,"scene",.42);const p=await s(t.renderingView,r,this.config.dataDir,this.config.shaders,this.config.actors,t.components,t.actorFactory,this.getApplicationService(v),this.getApplicationService(w),this.getApplicationService(f),{detailTier:t.detailTier,nodeMode:t.netMode,persistence:t.world.persistence});this.checkIntent(n),t.materializer=p.materializer,t.sceneRoots=p.sceneRoots,t.sceneName=r,t.container.set(o,p.materializer),t.world.materializer=p.materializer,await this.restoreSceneActors(t,p.materializer,p.actors,n),t.physics.addFromScene(p.scene),await t.world.startSceneEventGraphs(p.materializer),await(i.afterLoad?.(t.world)),this.checkIntent(n),this.loading(r,"shaders",.7),await t.renderingView.compileAsync(),this.checkIntent(n),this.loading(r,"textures",.82),await t.renderingView.initTexturesAsync(),this.checkIntent(n),await e(t.renderingView.webGpuDevice,!1,"playing: "+r),t.sceneTransition.publish({previousSceneName:a,sceneName:r}),t.viewController.paused=c,this.renderingHost.activate(t.renderingView),this.setState({type:"playing",sceneName:r})}async restoreSceneActors(e,t,i,n){if(null==e.world.persistence){for(const t of i)e.world.addActor(t);return}const s=i.filter(t=>!e.world.actors.includes(t));for(const t of s)e.world.addActor(t,void 0,void 0,void 0,!0);const r=t.registerPersistentActors();await e.world.persistence.restore(r,()=>this.checkIntent(n)),this.checkIntent(n);for(const t of s)e.world.beginActorPlay(t)}copyApplicationServices(e){const t=[g,S,w,v,f,y,b];for(const i of t)e.set(i,this.applicationContainer.get(i))}async disposeSession(e,i){if(e.disposed)return;let n;e.disposed=!0,i&&this.setState({type:"unloading",sceneName:e.sceneName});try{e.viewController.paused=!0,e.world.persistence?.captureAll(),e.stopPlayers?.(),e.sceneTransition.dispose(),e.world.stopSceneEventGraphs(),e.gameInstance instanceof GameInstance&&await e.gameInstance.onUnload()}catch(e){n=e}finally{for(const t of[...e.world.actors])e.world.removeActor(t);e.physics.stop(),e.materializer.dispose(),this.renderingHost.activeView===e.renderingView&&this.renderingHost.activate(this.renderingHost.applicationView),e.viewController.dispose(!1),this.renderingHost.releaseView(e.renderingView),t.reset(e.container.id),this.session===e&&(this.session=void 0)}if(null!=n)throw n}enqueue(e){const t=this.transitionTail.then(e,e);return this.transitionTail=t.catch(()=>{}),t}checkIntent(e){if(this.assertRunning(),e!==this.transitionIntent)throw k()}assertRunning(){if(this.shutdownFlag)throw new Error("Hology application has been shut down")}loading(e,t,i){this.setState({type:"loading",sceneName:e,stage:t,progress:i})}setState(e){const t=this.renderingHost.applicationView;"loading"===e.type?t.stopAnimationLoop():"menu"!==e.type&&("error"!==e.type||"initialize"===e.operation)||this.renderingHost.activeView!==t||t.running||this.renderingHost.activate(t),this.stateSubject.next(e)}getOptionalApplicationService(e){return this.applicationContainer.has(e)?this.applicationContainer.get(e):void 0}}export class HologyRuntime{constructor(e,t){this.application=e,this.ready=t.then(()=>!0),this.shutdownStarted=e.shutdownStarted}get status(){return"playing"===this.application.currentState.type?5:"stopped"===this.application.currentState.type||"error"===this.application.currentState.type?10:0}get gameInstance(){return this.application.getGameInstance()}get isShutdown(){return"stopped"===this.application.currentState.type}getWorld(){return this.application.getWorld()}getService(e){return this.application.getService(e)}shutdown(){return this.application.shutdown()}}function k(){return new DOMException("Superseded by a newer game transition","AbortError")}function F(e){return e instanceof DOMException&&"AbortError"===e.name}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import*as e from"three";import{compileNodeWebGpuFullscreen as t,compileNodeShaderMaterialForWebGpu as a,NodeShaderMaterial as n,webGpuRendererBindings as i,webGpuTiledRendererBindings as s,textureSampler2d as o,float as r,length as l,max as u,rgba as p,isWgslCompiler as m,isWgslFragmentCompiler as c,sqrt as f,normalize as d,transformed as h,uniformFloat as M,uniforms as v,vec4 as y,Vec3Node as g,toonMaterial as V}from"three-shader-graph";import{StandardShader as w}from"../shader/builtin/standard-shader.js";import{LambertShader as S}from"../shader/builtin/lambert-shader.js";import{ToonShader as x}from"../shader/builtin/toon-shader.js";import{UnlitShader as I}from"../shader/builtin/unlit-shader.js";import{SpriteShader as T}from"../shader/sprite-shader.js";import{elapsedTimeUniformName as E}from"../shader-nodes/time.js";import{depthUniformName as b,farUniformName as U,nearUniformName as A,resolutionUniformName as C,sceneNormalUniformName as W}from"../shader-nodes/depth.js";import{sceneMapUniformName as N}from"../shader-nodes/scene-sample.js";const k={...i,uniformExpressions:{...i.uniformExpressions,ambientLightColor:{type:"vec3",expression:"rendererAmbientLight()"},[E]:{type:"float",expression:"rendererElapsedTime()"},[A]:{type:"float",expression:"rendererCameraNear()"},[U]:{type:"float",expression:"rendererCameraFar()"},[C]:{type:"vec2",expression:"rendererViewportSize()"}},sceneTextures:{[N]:{semantic:"sceneColor",sampleType:"float"},[b]:{semantic:"sceneDepth",sampleType:"depth"}},attributes:{material:{shaderLocation:6,format:"float32x4",defaultValue:[0,0,0,0]},material2:{shaderLocation:7,format:"float32x4",defaultValue:[0,0,0,0]},hole:{shaderLocation:8,format:"float32",defaultValue:[0]},offset:{shaderLocation:9,format:"float32x3",stepMode:"instance",defaultValue:[0,0,0]},velocity:{shaderLocation:10,format:"float32x4",stepMode:"instance",defaultValue:[0,0,0,0]},size:{shaderLocation:11,format:"float32x3",stepMode:"instance",defaultValue:[0,0,0]},rotation:{shaderLocation:12,format:"float32",stepMode:"instance",defaultValue:[0]},particleData:{shaderLocation:13,format:"float32x3",stepMode:"instance",defaultValue:[1,1,0]},particleColor:{shaderLocation:14,format:"float32x4",stepMode:"instance",defaultValue:[1,1,1,1]}}};class L extends g{constructor(e){super(),this.fallback=e}compile(e){if(!m(e))return{out:e.get(this.fallback)};if(c(e))throw new Error("OutlineLocalPositionNode can only be used in the vertex stage");const t=`outline_local_position_${e.variable()}`;return{chunk:`\n#ifdef USE_SKINNING\n let ${t} = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight).xyz;\n#else\n let ${t} = input.position;\n#endif`,out:t}}}class R extends g{constructor(e){super(),this.fallback=e}compile(e){if(!m(e))return{out:e.get(this.fallback)};if(c(e))throw new Error("OutlineLocalNormalNode can only be used in the vertex stage");const t=`outline_local_normal_${e.variable()}`;return{chunk:`\n#ifdef USE_SKINNING\n let ${t} = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n#else\n let ${t} = input.normal;\n#endif`,out:t}}}export function setMaterialUniformValuesAutoUpdate(e,t){e.uniformValuesAutoUpdate=t}export function markMaterialUniformValuesNeedUpdate(e){const t=e;"uniformValuesNeedsUpdate"in t?t.uniformValuesNeedsUpdate=!0:t.uniformValuesAutoVersion=(t.uniformValuesAutoVersion??0)+1}function D(e){return!1!==e.uniformValuesAutoUpdate}function F(e){return e.uniformValuesAutoVersion??0}export function withThreeDefaultVertexAttributeValues(e){return e.map(e=>"uv1"===e.name&&null==e.defaultValue?{...e,defaultValue:[0,0]}:e)}const O=new WeakMap,j=new WeakMap;export function createNodeMaterialSignature(e){const t=j.get(e);if(null!=t)return t;const a=JSON.stringify({version:e.version,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader,alphaTest:e.alphaTest,alphaToCoverage:e.alphaToCoverage,blending:e.blending,colorWrite:e.colorWrite,depthFunc:e.depthFunc,depthTest:e.depthTest,depthWrite:e.depthWrite,polygonOffset:e.polygonOffset,polygonOffsetFactor:e.polygonOffsetFactor,polygonOffsetUnits:e.polygonOffsetUnits,premultipliedAlpha:e.premultipliedAlpha,side:e.side,stencilWrite:e.stencilWrite,transparent:e.transparent,wireframe:e.wireframe});return j.set(e,a),a}export class NodeMaterialWebGpuResolver{constructor(e,t,a){this.webGpu=e,this.mrtResolver=t,this.environmentTextureResolver=a,this.cache=new WeakMap,this.failedSignatures=new WeakMap,this.mappedMaterialsCache=new WeakMap,this.mappedMaterialsSignatures=new WeakMap,this.observedNodeMaterials=new Map,this.outlineMaterials=new WeakMap,this.outlineUniformVersions=new WeakMap,this.worldEnvironmentMaterials=new WeakSet,this.worldEnvironment=null,this.worldEnvironmentTexture=null,this.worldEnvironmentIntensity=0,this.worldEnvironmentRevision=0,this.cacheValues=new Set}setWorldEnvironment(e){const t=e?.texture??null,a=e?.intensity??0;if(this.worldEnvironmentTexture!==t||this.worldEnvironmentIntensity!==a){if(this.worldEnvironmentTexture!==t)this.worldEnvironmentRevision++;else if(null!=e)for(const e of this.cacheValues)e.inheritsWorldEnvironment&&null!=e.material.uniforms.envMapIntensity&&(e.material.uniforms.envMapIntensity.value=a,e.material.uniformValuesNeedsUpdate=!0);this.worldEnvironment=e,this.worldEnvironmentTexture=t,this.worldEnvironmentIntensity=a}}resolve(e,t=void 0){let i,o=!1;if(e instanceof n)i=e,this.observeNodeMaterial(i);else{const t=this.getOrCreateMappedNodeMaterial(e);if(null==t)return;i=t,o=!0}if("outline"===t){if(null==i.outputAlbedo)return;o&&G(e,i),i.userData.outlineParameters=e.userData?.outlineParameters,i=this.getOrCreateOutlineMaterial(i),o=!1}i.visible=e.visible,o&&(i.userData.receiveDecals=e.userData.receiveDecals);const r=t??"default",l=this.cache.get(i),u=l?.get(r);if(o&&null!=u&&u.sourceVersion===e.version&&u.worldEnvironmentRevision===this.worldEnvironmentRevision){const t=D(e),a=F(e);return u.material.uniformValuesAutoUpdate=t,this.syncInheritedWorldEnvironmentSource(i,u),t||u.sourceUniformValuesAutoVersion!==a?(G(e,i),u.compiled.syncLiveUniforms(u.material.uniforms),$(i,u.material.uniforms),z(i,u.material),u.sourceUniformValuesAutoVersion=a,t||(u.material.uniformValuesNeedsUpdate=!0),u.material):u.material}if(!o&&null!=u&&u.sourceVersion===e.version&&u.worldEnvironmentRevision===this.worldEnvironmentRevision&&B(i,u.compiled))return this.syncInheritedWorldEnvironmentSource(i,u),P(i,u),u.material;o&&G(e,i);const p=this.prepareWorldEnvironment(i),m=this.getNodeMaterialSignature(i,p);if(u?.signature===m&&B(i,u.compiled))return o?(u.material.uniformValuesAutoUpdate=D(e),u.compiled.syncLiveUniforms(u.material.uniforms),$(i,u.material.uniforms),z(i,u.material),u.sourceUniformValuesAutoVersion=F(e),u.material.uniformValuesAutoUpdate||(u.material.uniformValuesNeedsUpdate=!0)):P(i,u,!0),u.sourceVersion=e.version,u.worldEnvironmentRevision=this.worldEnvironmentRevision,u.material;try{const n=this.mrtResolver?.(i,t),c=a(i,"opaque"===t?{...k,arrays:s.arrays}:k,n),f=new this.webGpu.WGSLShaderMaterial({vertexShader:c.vertexShader,fragmentShader:c.fragmentShader,depthVertexShader:c.depthVertexShader,depthFragmentShader:c.depthFragmentShader,pointShadowVertexShader:c.pointShadowVertexShader,pointShadowFragmentShader:c.pointShadowFragmentShader,uniforms:c.uniforms,textures:c.textures,sceneTextures:c.sceneTextures,graphTextures:c.graphTextures,vertexAttributes:withThreeDefaultVertexAttributeValues(c.vertexAttributes),uniformValuesAutoUpdate:o?D(e):i.uniformValuesAutoUpdate,transparent:c.renderState?.transparent,alphaTest:c.renderState?.alphaTest,depthTest:c.renderState?.depthTest,depthWrite:c.renderState?.depthWrite,side:c.renderState?.side,wireframe:i.wireframe});f.name=e.name||i.name||e.uuid,f.uniformValuesAutoUpdate=o?D(e):i.uniformValuesAutoUpdate,function(e,t){if(null==e)return;Object.assign(t,e)}(c.renderState,f),null!=u&&(u.material.dispose(),this.cacheValues.delete(u));const d={signature:m,compiled:c,material:f,inheritsWorldEnvironment:p,sourceVersion:e.version,sourceUniformValuesAutoVersion:o?F(e):i.uniformValuesAutoVersion,worldEnvironmentRevision:this.worldEnvironmentRevision},h=l??new Map;return h.set(r,d),this.cache.set(i,h),this.cacheValues.add(d),$(i,f.uniforms),z(i,f),f}catch(e){let t=this.failedSignatures.get(i);if(null==t&&(t=new Map,this.failedSignatures.set(i,t)),t.get(r)!==m){t.set(r,m);const a=e instanceof Error?e.message:String(e),n=i.name||i.uuid;console.warn(`[Hology WebGPU experiment] Falling back for NodeShaderMaterial "${n}": ${a}`,{material:i,error:e})}return}}getOrCreateOutlineMaterial(t){let a=this.outlineMaterials.get(t);if(null==a){const i=t.nodeMaterialDefinition,s=t.outputAlbedo;if(null==s)throw new Error("Cannot derive an outline material without an albedo output");const o=M("outlineThickness",.003),m=M("outlineDarkening",.65),c=M("outlineAlpha",1),g=new L(h.position.xyz),w=new R(h.normal),S=i.transform?.multiplyVec(y(g,1))??y(g,1),x=v.modelViewMatrix.multiplyVec(S),I=d(v.normalMatrix.multiplyVec(w)),T=f(u(l(x.xyz),r(1e-4))).multiply(.5),E=x.xyz.add(I.multiplyScalar(o.multiply(T))),b=v.projectionMatrix.multiplyVec(x),U=v.projectionMatrix.multiplyVec(y(E,1)),A=(i.position??b).add(U.subtract(b)),C=p(V({color:s.rgb.multiplyScalar(r(1).subtract(m))}),t.outputOpacity.multiply(c));a=new n({color:C,position:A,opacity:t.outputOpacity,discard:i.discard,alphaTest:t.alphaTest,transparent:!0,fog:!1,outputEncoding:i.outputEncoding,uniforms:i.uniforms,uniformNodes:i.uniformNodes}),a.side=e.BackSide,a.depthTest=!0,a.depthWrite=!0,this.outlineMaterials.set(t,a),this.outlineUniformVersions.delete(t)}const i=t.userData?.outlineParameters,s=i?.thickness??.003,o=e.MathUtils.clamp(i?.darkening??.65,0,1),m=e.MathUtils.clamp(i?.alpha??t.opacity,0,1),c=a.uniforms.outlineThickness.value!==s||a.uniforms.outlineDarkening.value!==o||a.uniforms.outlineAlpha.value!==m;a.uniforms.outlineThickness.value=s,a.uniforms.outlineDarkening.value=o,a.uniforms.outlineAlpha.value=m,a.userData.outlineSource=t,a.uniformValuesAutoUpdate=t.uniformValuesAutoUpdate;let g=this.outlineUniformVersions.get(t);const w=t.uniformValuesAutoUpdate||null==g||g.version!==t.uniformValuesAutoVersion||g.uniforms!==t.uniforms;if(w){for(const e in t.uniforms)null!=a.uniforms[e]&&(a.uniforms[e].value=t.uniforms[e].value);g?(g.version=t.uniformValuesAutoVersion,g.uniforms=t.uniforms):(g={version:t.uniformValuesAutoVersion,uniforms:t.uniforms},this.outlineUniformVersions.set(t,g))}return t.uniformValuesAutoUpdate||!c&&!w||(a.uniformValuesNeedsUpdate=!0),a}compileFullscreen(e){const a=t({color:e.outputColor,wgslBindings:{...k,uniformExpressions:{},graphTextures:{...k.graphTextures,[W]:{resource:"hologyNormalRoughness",dimension:"2d",sampleType:"float",sampler:"filtering"}}}}),n=a.syncLiveUniforms;return{...a,syncLiveUniforms(t){n(t),$(e,t)}}}getOrCreateMappedNodeMaterial(t){const a=function(t){const a=[t.vertexColors,t.transparent,t.alphaTest,t.side,t.depthTest,t.depthWrite,t.wireframe??!1];t instanceof e.MeshStandardMaterial||t instanceof e.MeshPhysicalMaterial?a.push(t.map?t.map.uuid:null,t.normalMap?t.normalMap.uuid:null,t.roughnessMap?t.roughnessMap.uuid:null,t.metalnessMap?t.metalnessMap.uuid:null,t.aoMap?t.aoMap.uuid:null,t.emissiveMap?t.emissiveMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.envMap?t.envMap.uuid:null):t instanceof e.MeshLambertMaterial?a.push(t.map?t.map.uuid:null,t.normalMap?t.normalMap.uuid:null,t.aoMap?t.aoMap.uuid:null,t.emissiveMap?t.emissiveMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.envMap?t.envMap.uuid:null):t instanceof e.MeshToonMaterial?a.push(t.map?t.map.uuid:null,t.normalMap?t.normalMap.uuid:null,t.aoMap?t.aoMap.uuid:null,t.emissiveMap?t.emissiveMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.gradientMap?t.gradientMap.uuid:null):t instanceof e.MeshBasicMaterial?a.push(t.map?t.map.uuid:null,t.aoMap?t.aoMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.envMap?t.envMap.uuid:null):t instanceof e.MeshPhongMaterial?a.push(t.map?t.map.uuid:null,t.normalMap?t.normalMap.uuid:null,t.aoMap?t.aoMap.uuid:null,t.emissiveMap?t.emissiveMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.envMap?t.envMap.uuid:null):t instanceof e.SpriteMaterial&&a.push(t.map?t.map.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.sizeAttenuation);return a.join(",")}(t),n=this.mappedMaterialsCache.get(t),i=this.mappedMaterialsSignatures.get(t);if(null!=n&&i===a)return n;if(null!=n){n.dispose();const e=this.cache.get(n);if(null!=e){for(const t of e.values())t.material.dispose(),this.cacheValues.delete(t);this.cache.delete(n)}}const s=function(t){if(t instanceof e.SpriteMaterial){const e=new T;e.color=t.color,e.opacity=t.opacity,e.rotation=t.rotation,e.screenSpaceSize=t.sizeAttenuation?0:1,e.alphaTest=t.alphaTest,t.map&&(e.map=t.map),t.alphaMap&&(e.alphaMap=t.alphaMap);const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a}if(t instanceof e.MeshStandardMaterial||t instanceof e.MeshPhysicalMaterial){const e=new w;e.color=t.color,e.opacity=t.opacity,e.roughness=t.roughness,e.metalness=t.metalness,e.vertexColor=t.vertexColors,t.map&&(e.map=o(t.map)),t.normalMap&&(e.normalMap=o(t.normalMap),e.normalScale=t.normalScale),t.roughnessMap&&(e.roughnessMap=o(t.roughnessMap)),t.metalnessMap&&(e.metalnessMap=o(t.metalnessMap)),t.aoMap&&(e.aoMap=o(t.aoMap),e.aoMapIntensity=t.aoMapIntensity),t.emissiveMap&&(e.emissiveMap=o(t.emissiveMap)),t.lightMap&&(e.lightMap=o(t.lightMap),e.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(e.alphaMap=o(t.alphaMap)),e.emissive=t.emissive,e.emissiveIntensity=t.emissiveIntensity,e.envMap=t.envMap,e.envMapIntensity=t.envMapIntensity,e.alphaTest=t.alphaTest;const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a.wireframe=t.wireframe,a}if(t instanceof e.MeshLambertMaterial){const e=new S;e.color=t.color,e.opacity=t.opacity,e.vertexColor=t.vertexColors,t.map&&(e.map=o(t.map)),t.normalMap&&(e.normalMap=o(t.normalMap),e.normalScale=t.normalScale),t.aoMap&&(e.aoMap=o(t.aoMap),e.aoMapIntensity=t.aoMapIntensity),t.emissiveMap&&(e.emissiveMap=o(t.emissiveMap)),t.lightMap&&(e.lightMap=o(t.lightMap),e.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(e.alphaMap=o(t.alphaMap)),e.emissive=t.emissive,e.emissiveIntensity=t.emissiveIntensity,e.envMap=t.envMap,e.alphaTest=t.alphaTest;const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a.wireframe=t.wireframe,a}if(t instanceof e.MeshToonMaterial){const e=new x;e.color=t.color,e.opacity=t.opacity,e.vertexColor=t.vertexColors,t.map&&(e.map=o(t.map)),t.normalMap&&(e.normalMap=o(t.normalMap),e.normalScale=t.normalScale),t.aoMap&&(e.aoMap=o(t.aoMap),e.aoMapIntensity=t.aoMapIntensity),t.emissiveMap&&(e.emissiveMap=o(t.emissiveMap)),t.lightMap&&(e.lightMap=o(t.lightMap),e.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(e.alphaMap=o(t.alphaMap)),e.emissive=t.emissive,e.emissiveIntensity=t.emissiveIntensity,e.alphaTest=t.alphaTest;const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a.wireframe=t.wireframe,a}if(t instanceof e.MeshBasicMaterial||t instanceof e.LineBasicMaterial){const a=new I;a.color=t.color,a.opacity=t.opacity,a.vertexColor=t.vertexColors,t instanceof e.MeshBasicMaterial&&(t.map&&(a.map=o(t.map)),t.aoMap&&(a.aoMap=o(t.aoMap),a.aoMapIntensity=t.aoMapIntensity),t.lightMap&&(a.lightMap=o(t.lightMap),a.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(a.alphaMap=o(t.alphaMap)),a.envMap=t.envMap),a.alphaTest=t.alphaTest;const n=a.build();return n.transparent=t.transparent,n.side=t.side,n.depthTest=t.depthTest,n.depthWrite=t.depthWrite,n.wireframe=t instanceof e.MeshBasicMaterial&&t.wireframe,n}if(t instanceof e.MeshPhongMaterial){const e=new w;e.color=t.color,e.opacity=t.opacity,e.roughness=Math.max(0,1-t.shininess/100),e.metalness=0,e.vertexColor=t.vertexColors,t.map&&(e.map=o(t.map)),t.normalMap&&(e.normalMap=o(t.normalMap),e.normalScale=t.normalScale),t.aoMap&&(e.aoMap=o(t.aoMap),e.aoMapIntensity=t.aoMapIntensity),t.emissiveMap&&(e.emissiveMap=o(t.emissiveMap)),t.lightMap&&(e.lightMap=o(t.lightMap),e.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(e.alphaMap=o(t.alphaMap)),e.emissive=t.emissive,e.emissiveIntensity=t.emissiveIntensity,e.envMap=t.envMap,e.alphaTest=t.alphaTest;const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a.wireframe=t.wireframe,a}return null}(t);return null==s?null:(s.wireframe=t.wireframe??!1,this.mappedMaterialsCache.set(t,s),this.mappedMaterialsSignatures.set(t,a),t.addEventListener("dispose",()=>{const e=this.mappedMaterialsCache.get(t);if(null!=e){e.dispose(),this.mappedMaterialsCache.delete(t),this.mappedMaterialsSignatures.delete(t);const a=this.cache.get(e);if(null!=a){for(const e of a.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}}}),s)}canResolve(e){return null!=this.resolve(e)}dispose(){for(const[e,t]of this.observedNodeMaterials)e.removeEventListener("dispose",t);this.observedNodeMaterials.clear();for(const e of this.cacheValues)e.material.dispose();this.cacheValues.clear()}syncInheritedWorldEnvironmentSource(e,t){t.inheritsWorldEnvironment&&null!=this.worldEnvironment&&(e.uniforms.envMap.value=this.worldEnvironment.texture,e.uniforms.envMapIntensity.value=this.worldEnvironment.intensity)}getNodeMaterialSignature(e,t){const a=`${createNodeMaterialSignature(e)}|receiveDecals:${!1!==e.userData.receiveDecals}`;return t?`${a}|worldEnvironment:${this.worldEnvironmentRevision}`:a}prepareWorldEnvironment(t){var a,n,i,s,o,r;if(null!=t.envMap){const s=this.environmentTextureResolver?.(t.envMap)??t.envMap;return(a=t.uniforms).envMap??(a.envMap={value:s}),t.uniforms.envMap.value=s,(n=t.uniforms).envMapIntensity??(n.envMapIntensity={value:1}),(i=t.uniforms).envMapRotation??(i.envMapRotation={value:new e.Matrix3}),this.worldEnvironmentMaterials.delete(t),!1}return null==this.worldEnvironment?(this.worldEnvironmentMaterials.has(t)&&(delete t.uniforms.envMap,delete t.uniforms.envMapIntensity,delete t.uniforms.envMapRotation,this.worldEnvironmentMaterials.delete(t)),!1):((s=t.uniforms).envMap??(s.envMap={value:this.worldEnvironment.texture}),t.uniforms.envMap.value=this.worldEnvironment.texture,(o=t.uniforms).envMapIntensity??(o.envMapIntensity={value:this.worldEnvironment.intensity}),t.uniforms.envMapIntensity.value=this.worldEnvironment.intensity,(r=t.uniforms).envMapRotation??(r.envMapRotation={value:new e.Matrix3}),this.worldEnvironmentMaterials.add(t),!0)}observeNodeMaterial(e){if(this.observedNodeMaterials.has(e))return;const t=()=>{e.removeEventListener("dispose",t),this.observedNodeMaterials.delete(e);const a=this.cache.get(e);if(null!=a){for(const e of a.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}const n=this.outlineMaterials.get(e);if(null!=n){const t=this.cache.get(n);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(n)}this.failedSignatures.delete(n),j.delete(n),n.dispose(),this.outlineMaterials.delete(e),this.outlineUniformVersions.delete(e)}this.failedSignatures.delete(e),j.delete(e)};this.observedNodeMaterials.set(e,t),e.addEventListener("dispose",t)}}function P(e,t,a=!1){const n=t.material;n.uniformValuesAutoUpdate=e.uniformValuesAutoUpdate,(a||e.uniformValuesAutoUpdate||t.sourceUniformValuesAutoVersion!==e.uniformValuesAutoVersion)&&(t.compiled.syncLiveUniforms(n.uniforms),$(e,n.uniforms),z(e,n),t.sourceUniformValuesAutoVersion=e.uniformValuesAutoVersion,n.uniformValuesAutoUpdate||(n.uniformValuesNeedsUpdate=!0))}function $(e,t){let a=O.get(t);if(null==a){a=[];for(const e in t){const n=t[e],i=n.value,s=!0===i?.isVector2?2:!0===i?.isVector3?3:!0===i?.isVector4?4:!0===i?.isColor?5:0;a.push({name:e,target:n,copyKind:s})}O.set(t,a)}const n=e.uniforms;for(let e=0;e<a.length;e++){const t=a[e],i=n[t.name];if(null==i)continue;const s=i.value,o=t.target.value;if(s!==o){if(0!==t.copyKind){const e=s,a=o;if((2===t.copyKind?!0===e?.isVector2:3===t.copyKind?!0===e?.isVector3:4===t.copyKind?!0===e?.isVector4:!0===e?.isColor)&&"function"==typeof a?.copy){a.copy(s);continue}}t.target.value=s}}}function z(t,a){const n=t.uniforms.envMapIntensity,i=a.uniforms.envMapIntensity;null!=n&&null!=i&&(i.value=n.value);const s=t.uniforms.envMapRotation?.value,o=a.uniforms.envMapRotation?.value;s instanceof e.Matrix3&&o instanceof e.Matrix3&&o.copy(s)}function B(e,t){for(const a in t.textures){const n=t.textures[a],i=e.uniforms[a]?.value;if(_(i)&&i!==n)return!1}return!0}function _(e){return!0===e?.isTexture}function G(t,a){if(t instanceof e.SpriteMaterial){const n=a;a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),n.rotation=t.rotation,n.screenSpaceSize=t.sizeAttenuation?0:1}else t instanceof e.MeshStandardMaterial||t instanceof e.MeshPhysicalMaterial?(a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),a.uniforms.roughness&&(a.uniforms.roughness.value=t.roughness),a.uniforms.metalness&&(a.uniforms.metalness.value=t.metalness),a.uniforms.emissive&&(a.uniforms.emissive.value instanceof e.Vector3?a.uniforms.emissive.value.setFromColor(t.emissive):a.uniforms.emissive.value instanceof e.Color&&a.uniforms.emissive.value.copy(t.emissive)),a.uniforms.emissiveIntensity&&(a.uniforms.emissiveIntensity.value=t.emissiveIntensity),a.uniforms.normalScale&&t.normalScale&&(a.uniforms.normalScale.value=t.normalScale.x),a.uniforms.aoMapIntensity&&(a.uniforms.aoMapIntensity.value=t.aoMapIntensity),a.uniforms.lightMapIntensity&&(a.uniforms.lightMapIntensity.value=t.lightMapIntensity),a.uniforms.envMapIntensity&&(a.uniforms.envMapIntensity.value=t.envMapIntensity)):t instanceof e.MeshLambertMaterial||t instanceof e.MeshToonMaterial?(a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),a.uniforms.emissive&&(a.uniforms.emissive.value instanceof e.Vector3?a.uniforms.emissive.value.setFromColor(t.emissive):a.uniforms.emissive.value instanceof e.Color&&a.uniforms.emissive.value.copy(t.emissive)),a.uniforms.emissiveIntensity&&(a.uniforms.emissiveIntensity.value=t.emissiveIntensity),a.uniforms.normalScale&&t.normalScale&&(a.uniforms.normalScale.value=t.normalScale.x),a.uniforms.aoMapIntensity&&(a.uniforms.aoMapIntensity.value=t.aoMapIntensity),a.uniforms.lightMapIntensity&&(a.uniforms.lightMapIntensity.value=t.lightMapIntensity)):t instanceof e.MeshBasicMaterial||t instanceof e.LineBasicMaterial?(a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),t instanceof e.MeshBasicMaterial&&(a.uniforms.aoMapIntensity&&(a.uniforms.aoMapIntensity.value=t.aoMapIntensity),a.uniforms.lightMapIntensity&&(a.uniforms.lightMapIntensity.value=t.lightMapIntensity))):t instanceof e.MeshPhongMaterial&&(a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),a.uniforms.roughness&&(a.uniforms.roughness.value=Math.max(0,1-t.shininess/100)),a.uniforms.emissive&&(a.uniforms.emissive.value instanceof e.Vector3?a.uniforms.emissive.value.setFromColor(t.emissive):a.uniforms.emissive.value instanceof e.Color&&a.uniforms.emissive.value.copy(t.emissive)),a.uniforms.emissiveIntensity&&(a.uniforms.emissiveIntensity.value=t.emissiveIntensity),a.uniforms.normalScale&&t.normalScale&&(a.uniforms.normalScale.value=t.normalScale.x),a.uniforms.aoMapIntensity&&(a.uniforms.aoMapIntensity.value=t.aoMapIntensity),a.uniforms.lightMapIntensity&&(a.uniforms.lightMapIntensity.value=t.lightMapIntensity))}/*
1
+ import*as e from"three";import{compileNodeWebGpuFullscreen as t,compileNodeShaderMaterialForWebGpu as a,NodeShaderMaterial as i,webGpuRendererBindings as n,webGpuTiledRendererBindings as s,textureSampler2d as o,float as r,length as l,max as u,rgba as p,isWgslCompiler as m,isWgslFragmentCompiler as c,sqrt as f,normalize as d,transformed as h,uniformFloat as M,uniforms as v,vec4 as y,Vec3Node as g,toonMaterial as V}from"three-shader-graph";import{StandardShader as w}from"../shader/builtin/standard-shader.js";import{LambertShader as I}from"../shader/builtin/lambert-shader.js";import{ToonShader as S}from"../shader/builtin/toon-shader.js";import{UnlitShader as x}from"../shader/builtin/unlit-shader.js";import{SpriteShader as T}from"../shader/sprite-shader.js";import{elapsedTimeUniformName as E}from"../shader-nodes/time.js";import{depthUniformName as b,farUniformName as U,nearUniformName as A,resolutionUniformName as C,sceneNormalUniformName as W}from"../shader-nodes/depth.js";import{sceneMapUniformName as N}from"../shader-nodes/scene-sample.js";const k={...n,uniformExpressions:{...n.uniformExpressions,ambientLightColor:{type:"vec3",expression:"rendererAmbientLight()"},[E]:{type:"float",expression:"rendererElapsedTime()"},[A]:{type:"float",expression:"rendererCameraNear()"},[U]:{type:"float",expression:"rendererCameraFar()"},[C]:{type:"vec2",expression:"rendererViewportSize()"}},sceneTextures:{[N]:{semantic:"sceneColor",sampleType:"float"},[b]:{semantic:"sceneDepth",sampleType:"depth"}},attributes:{material:{shaderLocation:6,format:"float32x4",defaultValue:[0,0,0,0]},material2:{shaderLocation:7,format:"float32x4",defaultValue:[0,0,0,0]},hole:{shaderLocation:8,format:"float32",defaultValue:[0]},offset:{shaderLocation:9,format:"float32x3",stepMode:"instance",defaultValue:[0,0,0]},velocity:{shaderLocation:10,format:"float32x4",stepMode:"instance",defaultValue:[0,0,0,0]},size:{shaderLocation:11,format:"float32x3",stepMode:"instance",defaultValue:[0,0,0]},rotation:{shaderLocation:12,format:"float32",stepMode:"instance",defaultValue:[0]},particleData:{shaderLocation:13,format:"float32x3",stepMode:"instance",defaultValue:[1,1,0]},particleColor:{shaderLocation:14,format:"float32x4",stepMode:"instance",defaultValue:[1,1,1,1]}}};class L extends g{constructor(e){super(),this.fallback=e}compile(e){if(!m(e))return{out:e.get(this.fallback)};if(c(e))throw new Error("OutlineLocalPositionNode can only be used in the vertex stage");const t=`outline_local_position_${e.variable()}`;return{chunk:`\n#ifdef USE_SKINNING\n let ${t} = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight).xyz;\n#else\n let ${t} = input.position;\n#endif`,out:t}}}class R extends g{constructor(e){super(),this.fallback=e}compile(e){if(!m(e))return{out:e.get(this.fallback)};if(c(e))throw new Error("OutlineLocalNormalNode can only be used in the vertex stage");const t=`outline_local_normal_${e.variable()}`;return{chunk:`\n#ifdef USE_SKINNING\n let ${t} = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n#else\n let ${t} = input.normal;\n#endif`,out:t}}}export function setMaterialUniformValuesAutoUpdate(e,t){e.uniformValuesAutoUpdate=t}export function markMaterialUniformValuesNeedUpdate(e){const t=e;"uniformValuesNeedsUpdate"in t?t.uniformValuesNeedsUpdate=!0:t.uniformValuesAutoVersion=(t.uniformValuesAutoVersion??0)+1}function D(e){return!1!==e.uniformValuesAutoUpdate}function F(e){return e.uniformValuesAutoVersion??0}export function withThreeDefaultVertexAttributeValues(e){return e.map(e=>"uv1"===e.name&&null==e.defaultValue?{...e,defaultValue:[0,0]}:e)}const O=new WeakMap,j=new WeakMap;export function createNodeMaterialSignature(e){const t=j.get(e);if(null!=t)return t;const a=JSON.stringify({version:e.version,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader,alphaTest:e.alphaTest,alphaToCoverage:e.alphaToCoverage,blending:e.blending,colorWrite:e.colorWrite,depthFunc:e.depthFunc,depthTest:e.depthTest,depthWrite:e.depthWrite,polygonOffset:e.polygonOffset,polygonOffsetFactor:e.polygonOffsetFactor,polygonOffsetUnits:e.polygonOffsetUnits,premultipliedAlpha:e.premultipliedAlpha,side:e.side,stencilWrite:e.stencilWrite,transparent:e.transparent,wireframe:e.wireframe});return j.set(e,a),a}export class NodeMaterialWebGpuResolver{constructor(e,t,a){this.webGpu=e,this.mrtResolver=t,this.environmentTextureResolver=a,this.cache=new WeakMap,this.failedSignatures=new WeakMap,this.mappedMaterialsCache=new WeakMap,this.mappedMaterialsSignatures=new WeakMap,this.observedNodeMaterials=new Map,this.outlineMaterials=new WeakMap,this.outlineUniformVersions=new WeakMap,this.worldEnvironmentMaterials=new WeakSet,this.worldEnvironment=null,this.worldEnvironmentTexture=null,this.worldEnvironmentIntensity=0,this.worldEnvironmentRevision=0,this.cacheValues=new Set}setWorldEnvironment(e){const t=e?.texture??null,a=e?.intensity??0;if(this.worldEnvironmentTexture!==t||this.worldEnvironmentIntensity!==a){if(this.worldEnvironmentTexture!==t)this.worldEnvironmentRevision++;else if(null!=e)for(const e of this.cacheValues)e.inheritsWorldEnvironment&&null!=e.material.uniforms.envMapIntensity&&(e.material.uniforms.envMapIntensity.value=a,e.material.uniformValuesNeedsUpdate=!0);this.worldEnvironment=e,this.worldEnvironmentTexture=t,this.worldEnvironmentIntensity=a}}resolve(e,t=void 0){let n,o=!1;if(e instanceof i)n=e,this.observeNodeMaterial(n);else{const t=this.getOrCreateMappedNodeMaterial(e);if(null==t)return;n=t,o=!0}if("outline"===t){if(null==n.outputAlbedo)return;o&&G(e,n),n.userData.outlineParameters=e.userData?.outlineParameters,n=this.getOrCreateOutlineMaterial(n),o=!1}n.visible=e.visible,o&&(n.userData.receiveDecals=e.userData.receiveDecals);const r=t??"default",l=this.cache.get(n),u=l?.get(r);if(o&&null!=u&&u.sourceVersion===e.version&&u.worldEnvironmentRevision===this.worldEnvironmentRevision){const t=D(e),a=F(e);return u.material.uniformValuesAutoUpdate=t,this.syncInheritedWorldEnvironmentSource(n,u),t||u.sourceUniformValuesAutoVersion!==a?(G(e,n),u.compiled.syncLiveUniforms(u.material.uniforms),$(n,u.material.uniforms),z(n,u.material),u.sourceUniformValuesAutoVersion=a,t||(u.material.uniformValuesNeedsUpdate=!0),u.material):u.material}if(!o&&null!=u&&u.sourceVersion===e.version&&u.worldEnvironmentRevision===this.worldEnvironmentRevision&&B(n,u.compiled))return this.syncInheritedWorldEnvironmentSource(n,u),P(n,u),u.material;o&&G(e,n);const p=this.prepareWorldEnvironment(n),m=this.getNodeMaterialSignature(n,p);if(u?.signature===m&&B(n,u.compiled))return o?(u.material.uniformValuesAutoUpdate=D(e),u.compiled.syncLiveUniforms(u.material.uniforms),$(n,u.material.uniforms),z(n,u.material),u.sourceUniformValuesAutoVersion=F(e),u.material.uniformValuesAutoUpdate||(u.material.uniformValuesNeedsUpdate=!0)):P(n,u,!0),u.sourceVersion=e.version,u.worldEnvironmentRevision=this.worldEnvironmentRevision,u.material;try{const i=this.mrtResolver?.(n,t),c=a(n,"opaque"===t?{...k,arrays:s.arrays}:k,i),f=new this.webGpu.WGSLShaderMaterial({vertexShader:c.vertexShader,fragmentShader:c.fragmentShader,depthVertexShader:c.depthVertexShader,depthFragmentShader:c.depthFragmentShader,pointShadowVertexShader:c.pointShadowVertexShader,pointShadowFragmentShader:c.pointShadowFragmentShader,uniforms:c.uniforms,textures:c.textures,sceneTextures:c.sceneTextures,graphTextures:c.graphTextures,vertexAttributes:withThreeDefaultVertexAttributeValues(c.vertexAttributes),uniformValuesAutoUpdate:o?D(e):n.uniformValuesAutoUpdate,transparent:c.renderState?.transparent,alphaTest:c.renderState?.alphaTest,depthTest:c.renderState?.depthTest,depthWrite:c.renderState?.depthWrite,side:c.renderState?.side,wireframe:n.wireframe});f.name=e.name||n.name||e.uuid,f.userData.pipelineOrigin={assetId:e.userData.assetId??n.userData.assetId,assetName:e.userData.assetName??n.userData.assetName,sourceUuid:e.uuid,sourceName:e.name,sourceType:e.type,sourceVersion:e.version},f.uniformValuesAutoUpdate=o?D(e):n.uniformValuesAutoUpdate,function(e,t){if(null==e)return;Object.assign(t,e)}(c.renderState,f),null!=u&&(u.material.dispose(),this.cacheValues.delete(u));const d={signature:m,compiled:c,material:f,inheritsWorldEnvironment:p,sourceVersion:e.version,sourceUniformValuesAutoVersion:o?F(e):n.uniformValuesAutoVersion,worldEnvironmentRevision:this.worldEnvironmentRevision},h=l??new Map;return h.set(r,d),this.cache.set(n,h),this.cacheValues.add(d),$(n,f.uniforms),z(n,f),f}catch(e){let t=this.failedSignatures.get(n);if(null==t&&(t=new Map,this.failedSignatures.set(n,t)),t.get(r)!==m){t.set(r,m);const a=e instanceof Error?e.message:String(e),i=n.name||n.uuid;console.warn(`[Hology WebGPU experiment] Falling back for NodeShaderMaterial "${i}": ${a}`,{material:n,error:e})}return}}getOrCreateOutlineMaterial(t){let a=this.outlineMaterials.get(t);if(null==a){const n=t.nodeMaterialDefinition,s=t.outputAlbedo;if(null==s)throw new Error("Cannot derive an outline material without an albedo output");const o=M("outlineThickness",.003),m=M("outlineDarkening",.65),c=M("outlineAlpha",1),g=new L(h.position.xyz),w=new R(h.normal),I=n.transform?.multiplyVec(y(g,1))??y(g,1),S=v.modelViewMatrix.multiplyVec(I),x=d(v.normalMatrix.multiplyVec(w)),T=f(u(l(S.xyz),r(1e-4))).multiply(.5),E=S.xyz.add(x.multiplyScalar(o.multiply(T))),b=v.projectionMatrix.multiplyVec(S),U=v.projectionMatrix.multiplyVec(y(E,1)),A=(n.position??b).add(U.subtract(b)),C=p(V({color:s.rgb.multiplyScalar(r(1).subtract(m))}),t.outputOpacity.multiply(c));a=new i({color:C,position:A,opacity:t.outputOpacity,discard:n.discard,alphaTest:t.alphaTest,transparent:!0,fog:!1,outputEncoding:n.outputEncoding,uniforms:n.uniforms,uniformNodes:n.uniformNodes}),a.side=e.BackSide,a.depthTest=!0,a.depthWrite=!0,this.outlineMaterials.set(t,a),this.outlineUniformVersions.delete(t)}const n=t.userData?.outlineParameters,s=n?.thickness??.003,o=e.MathUtils.clamp(n?.darkening??.65,0,1),m=e.MathUtils.clamp(n?.alpha??t.opacity,0,1),c=a.uniforms.outlineThickness.value!==s||a.uniforms.outlineDarkening.value!==o||a.uniforms.outlineAlpha.value!==m;a.uniforms.outlineThickness.value=s,a.uniforms.outlineDarkening.value=o,a.uniforms.outlineAlpha.value=m,a.userData.outlineSource=t,a.uniformValuesAutoUpdate=t.uniformValuesAutoUpdate;let g=this.outlineUniformVersions.get(t);const w=t.uniformValuesAutoUpdate||null==g||g.version!==t.uniformValuesAutoVersion||g.uniforms!==t.uniforms;if(w){for(const e in t.uniforms)null!=a.uniforms[e]&&(a.uniforms[e].value=t.uniforms[e].value);g?(g.version=t.uniformValuesAutoVersion,g.uniforms=t.uniforms):(g={version:t.uniformValuesAutoVersion,uniforms:t.uniforms},this.outlineUniformVersions.set(t,g))}return t.uniformValuesAutoUpdate||!c&&!w||(a.uniformValuesNeedsUpdate=!0),a}compileFullscreen(e){const a=t({color:e.outputColor,wgslBindings:{...k,uniformExpressions:{},graphTextures:{...k.graphTextures,[W]:{resource:"hologyNormalRoughness",dimension:"2d",sampleType:"float",sampler:"filtering"}}}}),i=a.syncLiveUniforms;return{...a,syncLiveUniforms(t){i(t),$(e,t)}}}getOrCreateMappedNodeMaterial(t){const a=function(t){const a=[t.vertexColors,t.transparent,t.alphaTest,t.side,t.depthTest,t.depthWrite,t.wireframe??!1];t instanceof e.MeshStandardMaterial||t instanceof e.MeshPhysicalMaterial?a.push(t.map?t.map.uuid:null,t.normalMap?t.normalMap.uuid:null,t.roughnessMap?t.roughnessMap.uuid:null,t.metalnessMap?t.metalnessMap.uuid:null,t.aoMap?t.aoMap.uuid:null,t.emissiveMap?t.emissiveMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.envMap?t.envMap.uuid:null):t instanceof e.MeshLambertMaterial?a.push(t.map?t.map.uuid:null,t.normalMap?t.normalMap.uuid:null,t.aoMap?t.aoMap.uuid:null,t.emissiveMap?t.emissiveMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.envMap?t.envMap.uuid:null):t instanceof e.MeshToonMaterial?a.push(t.map?t.map.uuid:null,t.normalMap?t.normalMap.uuid:null,t.aoMap?t.aoMap.uuid:null,t.emissiveMap?t.emissiveMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.gradientMap?t.gradientMap.uuid:null):t instanceof e.MeshBasicMaterial?a.push(t.map?t.map.uuid:null,t.aoMap?t.aoMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.envMap?t.envMap.uuid:null):t instanceof e.MeshPhongMaterial?a.push(t.map?t.map.uuid:null,t.normalMap?t.normalMap.uuid:null,t.aoMap?t.aoMap.uuid:null,t.emissiveMap?t.emissiveMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.envMap?t.envMap.uuid:null):t instanceof e.SpriteMaterial&&a.push(t.map?t.map.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.sizeAttenuation);return a.join(",")}(t),i=this.mappedMaterialsCache.get(t),n=this.mappedMaterialsSignatures.get(t);if(null!=i&&n===a)return i;if(null!=i){i.dispose();const e=this.cache.get(i);if(null!=e){for(const t of e.values())t.material.dispose(),this.cacheValues.delete(t);this.cache.delete(i)}}const s=function(t){if(t instanceof e.SpriteMaterial){const e=new T;e.color=t.color,e.opacity=t.opacity,e.rotation=t.rotation,e.screenSpaceSize=t.sizeAttenuation?0:1,e.alphaTest=t.alphaTest,t.map&&(e.map=t.map),t.alphaMap&&(e.alphaMap=t.alphaMap);const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a}if(t instanceof e.MeshStandardMaterial||t instanceof e.MeshPhysicalMaterial){const e=new w;e.color=t.color,e.opacity=t.opacity,e.roughness=t.roughness,e.metalness=t.metalness,e.vertexColor=t.vertexColors,t.map&&(e.map=o(t.map)),t.normalMap&&(e.normalMap=o(t.normalMap),e.normalScale=t.normalScale),t.roughnessMap&&(e.roughnessMap=o(t.roughnessMap)),t.metalnessMap&&(e.metalnessMap=o(t.metalnessMap)),t.aoMap&&(e.aoMap=o(t.aoMap),e.aoMapIntensity=t.aoMapIntensity),t.emissiveMap&&(e.emissiveMap=o(t.emissiveMap)),t.lightMap&&(e.lightMap=o(t.lightMap),e.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(e.alphaMap=o(t.alphaMap)),e.emissive=t.emissive,e.emissiveIntensity=t.emissiveIntensity,e.envMap=t.envMap,e.envMapIntensity=t.envMapIntensity,e.alphaTest=t.alphaTest;const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a.wireframe=t.wireframe,a}if(t instanceof e.MeshLambertMaterial){const e=new I;e.color=t.color,e.opacity=t.opacity,e.vertexColor=t.vertexColors,t.map&&(e.map=o(t.map)),t.normalMap&&(e.normalMap=o(t.normalMap),e.normalScale=t.normalScale),t.aoMap&&(e.aoMap=o(t.aoMap),e.aoMapIntensity=t.aoMapIntensity),t.emissiveMap&&(e.emissiveMap=o(t.emissiveMap)),t.lightMap&&(e.lightMap=o(t.lightMap),e.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(e.alphaMap=o(t.alphaMap)),e.emissive=t.emissive,e.emissiveIntensity=t.emissiveIntensity,e.envMap=t.envMap,e.alphaTest=t.alphaTest;const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a.wireframe=t.wireframe,a}if(t instanceof e.MeshToonMaterial){const e=new S;e.color=t.color,e.opacity=t.opacity,e.vertexColor=t.vertexColors,t.map&&(e.map=o(t.map)),t.normalMap&&(e.normalMap=o(t.normalMap),e.normalScale=t.normalScale),t.aoMap&&(e.aoMap=o(t.aoMap),e.aoMapIntensity=t.aoMapIntensity),t.emissiveMap&&(e.emissiveMap=o(t.emissiveMap)),t.lightMap&&(e.lightMap=o(t.lightMap),e.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(e.alphaMap=o(t.alphaMap)),e.emissive=t.emissive,e.emissiveIntensity=t.emissiveIntensity,e.alphaTest=t.alphaTest;const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a.wireframe=t.wireframe,a}if(t instanceof e.MeshBasicMaterial||t instanceof e.LineBasicMaterial){const a=new x;a.color=t.color,a.opacity=t.opacity,a.vertexColor=t.vertexColors,t instanceof e.MeshBasicMaterial&&(t.map&&(a.map=o(t.map)),t.aoMap&&(a.aoMap=o(t.aoMap),a.aoMapIntensity=t.aoMapIntensity),t.lightMap&&(a.lightMap=o(t.lightMap),a.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(a.alphaMap=o(t.alphaMap)),a.envMap=t.envMap),a.alphaTest=t.alphaTest;const i=a.build();return i.transparent=t.transparent,i.side=t.side,i.depthTest=t.depthTest,i.depthWrite=t.depthWrite,i.wireframe=t instanceof e.MeshBasicMaterial&&t.wireframe,i}if(t instanceof e.MeshPhongMaterial){const e=new w;e.color=t.color,e.opacity=t.opacity,e.roughness=Math.max(0,1-t.shininess/100),e.metalness=0,e.vertexColor=t.vertexColors,t.map&&(e.map=o(t.map)),t.normalMap&&(e.normalMap=o(t.normalMap),e.normalScale=t.normalScale),t.aoMap&&(e.aoMap=o(t.aoMap),e.aoMapIntensity=t.aoMapIntensity),t.emissiveMap&&(e.emissiveMap=o(t.emissiveMap)),t.lightMap&&(e.lightMap=o(t.lightMap),e.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(e.alphaMap=o(t.alphaMap)),e.emissive=t.emissive,e.emissiveIntensity=t.emissiveIntensity,e.envMap=t.envMap,e.alphaTest=t.alphaTest;const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a.wireframe=t.wireframe,a}return null}(t);return null==s?null:(s.wireframe=t.wireframe??!1,this.mappedMaterialsCache.set(t,s),this.mappedMaterialsSignatures.set(t,a),t.addEventListener("dispose",()=>{const e=this.mappedMaterialsCache.get(t);if(null!=e){e.dispose(),this.mappedMaterialsCache.delete(t),this.mappedMaterialsSignatures.delete(t);const a=this.cache.get(e);if(null!=a){for(const e of a.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}}}),s)}canResolve(e){return null!=this.resolve(e)}dispose(){for(const[e,t]of this.observedNodeMaterials)e.removeEventListener("dispose",t);this.observedNodeMaterials.clear();for(const e of this.cacheValues)e.material.dispose();this.cacheValues.clear()}syncInheritedWorldEnvironmentSource(e,t){t.inheritsWorldEnvironment&&null!=this.worldEnvironment&&(e.uniforms.envMap.value=this.worldEnvironment.texture,e.uniforms.envMapIntensity.value=this.worldEnvironment.intensity)}getNodeMaterialSignature(e,t){const a=`${createNodeMaterialSignature(e)}|receiveDecals:${!1!==e.userData.receiveDecals}`;return t?`${a}|worldEnvironment:${this.worldEnvironmentRevision}`:a}prepareWorldEnvironment(t){var a,i,n,s,o,r;if(null!=t.envMap){const s=this.environmentTextureResolver?.(t.envMap)??t.envMap;return(a=t.uniforms).envMap??(a.envMap={value:s}),t.uniforms.envMap.value=s,(i=t.uniforms).envMapIntensity??(i.envMapIntensity={value:1}),(n=t.uniforms).envMapRotation??(n.envMapRotation={value:new e.Matrix3}),this.worldEnvironmentMaterials.delete(t),!1}return null==this.worldEnvironment?(this.worldEnvironmentMaterials.has(t)&&(delete t.uniforms.envMap,delete t.uniforms.envMapIntensity,delete t.uniforms.envMapRotation,this.worldEnvironmentMaterials.delete(t)),!1):((s=t.uniforms).envMap??(s.envMap={value:this.worldEnvironment.texture}),t.uniforms.envMap.value=this.worldEnvironment.texture,(o=t.uniforms).envMapIntensity??(o.envMapIntensity={value:this.worldEnvironment.intensity}),t.uniforms.envMapIntensity.value=this.worldEnvironment.intensity,(r=t.uniforms).envMapRotation??(r.envMapRotation={value:new e.Matrix3}),this.worldEnvironmentMaterials.add(t),!0)}observeNodeMaterial(e){if(this.observedNodeMaterials.has(e))return;const t=()=>{e.removeEventListener("dispose",t),this.observedNodeMaterials.delete(e);const a=this.cache.get(e);if(null!=a){for(const e of a.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}const i=this.outlineMaterials.get(e);if(null!=i){const t=this.cache.get(i);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(i)}this.failedSignatures.delete(i),j.delete(i),i.dispose(),this.outlineMaterials.delete(e),this.outlineUniformVersions.delete(e)}this.failedSignatures.delete(e),j.delete(e)};this.observedNodeMaterials.set(e,t),e.addEventListener("dispose",t)}}function P(e,t,a=!1){const i=t.material;i.uniformValuesAutoUpdate=e.uniformValuesAutoUpdate,(a||e.uniformValuesAutoUpdate||t.sourceUniformValuesAutoVersion!==e.uniformValuesAutoVersion)&&(t.compiled.syncLiveUniforms(i.uniforms),$(e,i.uniforms),z(e,i),t.sourceUniformValuesAutoVersion=e.uniformValuesAutoVersion,i.uniformValuesAutoUpdate||(i.uniformValuesNeedsUpdate=!0))}function $(e,t){let a=O.get(t);if(null==a){a=[];for(const e in t){const i=t[e],n=i.value,s=!0===n?.isVector2?2:!0===n?.isVector3?3:!0===n?.isVector4?4:!0===n?.isColor?5:0;a.push({name:e,target:i,copyKind:s})}O.set(t,a)}const i=e.uniforms;for(let e=0;e<a.length;e++){const t=a[e],n=i[t.name];if(null==n)continue;const s=n.value,o=t.target.value;if(s!==o){if(0!==t.copyKind){const e=s,a=o;if((2===t.copyKind?!0===e?.isVector2:3===t.copyKind?!0===e?.isVector3:4===t.copyKind?!0===e?.isVector4:!0===e?.isColor)&&"function"==typeof a?.copy){a.copy(s);continue}}t.target.value=s}}}function z(t,a){const i=t.uniforms.envMapIntensity,n=a.uniforms.envMapIntensity;null!=i&&null!=n&&(n.value=i.value);const s=t.uniforms.envMapRotation?.value,o=a.uniforms.envMapRotation?.value;s instanceof e.Matrix3&&o instanceof e.Matrix3&&o.copy(s)}function B(e,t){for(const a in t.textures){const i=t.textures[a],n=e.uniforms[a]?.value;if(_(n)&&n!==i)return!1}return!0}function _(e){return!0===e?.isTexture}function G(t,a){if(t instanceof e.SpriteMaterial){const i=a;a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),i.rotation=t.rotation,i.screenSpaceSize=t.sizeAttenuation?0:1}else t instanceof e.MeshStandardMaterial||t instanceof e.MeshPhysicalMaterial?(a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),a.uniforms.roughness&&(a.uniforms.roughness.value=t.roughness),a.uniforms.metalness&&(a.uniforms.metalness.value=t.metalness),a.uniforms.emissive&&(a.uniforms.emissive.value instanceof e.Vector3?a.uniforms.emissive.value.setFromColor(t.emissive):a.uniforms.emissive.value instanceof e.Color&&a.uniforms.emissive.value.copy(t.emissive)),a.uniforms.emissiveIntensity&&(a.uniforms.emissiveIntensity.value=t.emissiveIntensity),a.uniforms.normalScale&&t.normalScale&&(a.uniforms.normalScale.value=t.normalScale.x),a.uniforms.aoMapIntensity&&(a.uniforms.aoMapIntensity.value=t.aoMapIntensity),a.uniforms.lightMapIntensity&&(a.uniforms.lightMapIntensity.value=t.lightMapIntensity),a.uniforms.envMapIntensity&&(a.uniforms.envMapIntensity.value=t.envMapIntensity)):t instanceof e.MeshLambertMaterial||t instanceof e.MeshToonMaterial?(a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),a.uniforms.emissive&&(a.uniforms.emissive.value instanceof e.Vector3?a.uniforms.emissive.value.setFromColor(t.emissive):a.uniforms.emissive.value instanceof e.Color&&a.uniforms.emissive.value.copy(t.emissive)),a.uniforms.emissiveIntensity&&(a.uniforms.emissiveIntensity.value=t.emissiveIntensity),a.uniforms.normalScale&&t.normalScale&&(a.uniforms.normalScale.value=t.normalScale.x),a.uniforms.aoMapIntensity&&(a.uniforms.aoMapIntensity.value=t.aoMapIntensity),a.uniforms.lightMapIntensity&&(a.uniforms.lightMapIntensity.value=t.lightMapIntensity)):t instanceof e.MeshBasicMaterial||t instanceof e.LineBasicMaterial?(a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),t instanceof e.MeshBasicMaterial&&(a.uniforms.aoMapIntensity&&(a.uniforms.aoMapIntensity.value=t.aoMapIntensity),a.uniforms.lightMapIntensity&&(a.uniforms.lightMapIntensity.value=t.lightMapIntensity))):t instanceof e.MeshPhongMaterial&&(a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),a.uniforms.roughness&&(a.uniforms.roughness.value=Math.max(0,1-t.shininess/100)),a.uniforms.emissive&&(a.uniforms.emissive.value instanceof e.Vector3?a.uniforms.emissive.value.setFromColor(t.emissive):a.uniforms.emissive.value instanceof e.Color&&a.uniforms.emissive.value.copy(t.emissive)),a.uniforms.emissiveIntensity&&(a.uniforms.emissiveIntensity.value=t.emissiveIntensity),a.uniforms.normalScale&&t.normalScale&&(a.uniforms.normalScale.value=t.normalScale.x),a.uniforms.aoMapIntensity&&(a.uniforms.aoMapIntensity.value=t.aoMapIntensity),a.uniforms.lightMapIntensity&&(a.uniforms.lightMapIntensity.value=t.lightMapIntensity))}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import*as e from"three";import{NodeMaterialWebGpuResolver as t}from"./node-material-webgpu-resolver.js";import{configureWebGpuRuntimeBindings as i}from"./webgpu-runtime-bridge.js";import{float as n,varyingTransformed as r,vec4 as o}from"three-shader-graph";import{NodeShaderMaterial as s}from"../shader-nodes/index.js";import{sceneMapUniformName as a}from"../shader-nodes/scene-sample.js";import{depthUniformName as l}from"../shader-nodes/depth.js";import{MATERIAL_FLAG_ALPHA_TEST as d,MATERIAL_FLAG_RECEIVE_DECALS as c}from"../shader-nodes/material-flags.js";import{createMotionVectorOutput as h}from"./motion-vector-node.js";export class ExperimentalWebGpuBackend{constructor(e,t,i,n,r,o,s,a,l,d,c,h,u,p,m,g,f,v,S,b,P,x){this.renderer=e,this.fallbackMaterial=t,this.nodeMaterialResolver=i,this.gBufferFallbackSource=n,this.bloom=r,this.fxaa=o,this.smaa=s,this.gtao=a,this.ssr=l,this.taa=d,this.motionBlur=c,this.volumetricFog=h,this.colorGrading=u,this.depthOfField=p,this.outline=m,this.postProcessEffects=g,this.renderGraphExtensions=f,this.presentationExtensions=v,this.antiAliasingState=S,this.directionalShadowState=b,this.nativeDlss=P,this.kind="webgpu",this.renderScale=1,this.pmremGenerator=null,this.pmremResults=new WeakMap,this.ownedPmremResults=new Set,this.warnedUnsupportedPostProcessStages=new Set,this.secondaryMotionPrepared=!1,this.canvas=x}static async probeAvailability(){if("undefined"==typeof navigator||!("gpu"in navigator))return{available:!1,reason:"The runtime does not expose navigator.gpu."};try{const e=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});return null==e?{available:!1,reason:"No WebGPU adapter is available."}:{available:!0,adapter:e}}catch(e){return{available:!1,reason:`Requesting a WebGPU adapter failed: ${e instanceof Error?e.message:String(e)}`}}}static async create(m={},g){const f=await import("@hology/webgpu-renderer");i({createComputeKernel:(e,t)=>new f.ComputeKernel(e,t),buildParticleLightingShaderHeader:f.buildParticleLightingShaderHeader});const v=document.createElement("canvas");v.dataset.hologyRenderer="webgpu-experimental";const S=new f.WGSLShaderMaterial({vertexShader:u,fragmentShader:p}),b=!1!==m.nativeUpscaling&&"dlss"===m.nativeUpscaling?.method,P=b?(await import("./native-dlss-upscaler.js")).createNativeDlssUpscaler(m.nativeUpscaling?.mode??"quality"):null,x=null!=P;S.side=f.DoubleSide;const w=f,y=null!=m.motionBlur&&!1!==m.motionBlur,M=!1!==m.gtao&&(null==m.gtao||!1!==m.gtao.temporal),E=!1!==m.volumetricFog&&(null==m.volumetricFog||!1!==m.volumetricFog.temporal),F=x?"off":b?"taa":null!=(D=m).antiAliasing?D.antiAliasing:null!=D.taa&&!1!==D.taa?"taa":null!=D.smaa&&!1!==D.smaa?"smaa":null!=D.fxaa&&!1!==D.fxaa?"fxaa":!1===D.taa?"off":"taa";var D;const L=null!=m.antiAliasing,C=y||M||E||(L||"taa"===F)||x;let O=null;const G=new t(w,(e,t)=>"opaque"===t?[e.outputColor.xyz.rgba(n(e.alphaTest>0?d:0).add(!1===e.userData.receiveDecals?0:c)),o((e.outputNormal??r.normal).multiplyScalar(.5).addScalar(.5),e.outputRoughness??n(1)),...C?[h(e)]:[]]:void 0,e=>O?.getEnvironmentTexture(e)??e),R=new e.MeshStandardMaterial({color:8688803,roughness:1});if(null==G.resolve(R,"opaque"))throw S.dispose(),R.dispose(),new Error("Failed to compile the WebGPU G-buffer fallback material.");const T=!1===m.gtao?null:new f.GTAOEffect({normalSpace:"view",...f.GTAO_PRESETS.high,...m.gtao??{}}),A=!1===m.ssr||null==m.ssr?null:new f.SSREffect({normalSpace:"view",resolutionScale:.5,...m.ssr??{}}),B=!1===m.bloom?null:new f.BloomEffect({threshold:1,strength:.9,radius:.2,...m.bloom??{}}),W=L||!1!==m.fxaa&&"fxaa"===F?new f.FXAAEffect(!1===m.fxaa?{}:m.fxaa):null,V=L||!1!==m.smaa&&"smaa"===F?new f.SMAAEffect(!1===m.smaa?{}:m.smaa):null,k=x||L||!1!==m.taa&&"taa"===F?new f.TemporalAAEffect({renderScale:1,...!1===m.taa?{}:m.taa}):null,U={mode:F},j=!1===m.motionBlur||null==m.motionBlur?null:new f.MotionBlurEffect(m.motionBlur),I=m.volumetricFog||void 0,N=!1===m.volumetricFog?null:new f.VolumetricFogEffect(void 0,{...f.VOLUMETRIC_FOG_PRESETS.high,maxDistance:64,spatialJitter:!0,scatteringIntensity:Math.PI,...I,temporal:!1!==I?.temporal&&{...f.VOLUMETRIC_FOG_PRESETS.high.temporal,...I?.temporal},blur:!1!==I?.blur&&{...!1===f.VOLUMETRIC_FOG_PRESETS.high.blur?{}:f.VOLUMETRIC_FOG_PRESETS.high.blur,depthAwareUpsample:!0,...I?.blur}}),H=!1===m.colorGrading?null:new f.ColorGradingEffect({enabled:!1,...m.colorGrading??{}}),$=!1===m.depthOfField?null:new f.DepthOfFieldEffect({enabled:!1,...m.depthOfField??{}}),_=!1===m.outline?null:new f.OutlineEffect({enabled:!1,...m.outline??{}}),q=[],z=new WeakMap,J=new Set,K=[],Z=[],Q=(e,t,i)=>{let n=i;const r=q.filter(e=>e.enabled&&e.stage===t).sort((e,t)=>e.priority-t.priority||e.id-t.id);for(const t of r){if(!(t.material instanceof s)){const e=`${t.id}:material`;J.has(e)||(J.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: only NodeShaderMaterial effects are supported.`));continue}try{let i=z.get(t.material);null!=i&&i.version===t.material.version||(i={version:t.material.version,shader:G.compileFullscreen(t.material)},z.set(t.material,i));const r=e.createColorTarget(`hologyCustomPostProcess${t.id}`);e.addNodeFullscreenPass({name:`HologyCustomPostProcess${t.id}`,shader:i.shader,inputOverrides:{[a]:n},outputs:r}),n=r}catch(e){const i=`${t.id}:compile:${t.material.version}`;J.has(i)||(J.add(i),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: ${e instanceof Error?e.message:String(e)}`,e))}}return n},X={enabled:!0},Y=new f.WebGpuRenderer({canvas:v,fallbackMaterial:S,materialResolver:(e,t)=>G.resolve(e,t),invokeObjectRenderCallbacks:!1,hiZOcclusionCulling:!0,renderGraphProfiling:!1,sampleCount:1,multiDrawIndirect:!1,nativePostSubmit:P?.postSubmit,presentationOverlay:e=>{for(const t of Z)t(e)}});Y.setRenderScale("taa"===F?k?.renderScale??1:1),Y.setRenderGraphBuilder((e,t)=>{const i=new f.FrameGraphBuilder(t),n=i.createColorTarget("hologyNormalRoughness",{format:"rgba8unorm"}),r=C?i.createColorTarget("hologyMotionVectors",{format:"rgba16float"}):null;for(const e of K)"beforeScene"===e.stage&&e(i,i.sceneColor);X.enabled&&i.addDirectionalShadowPass(),i.addPointShadowPass(),i.addSpotShadowPass(),i.addDepthPrepass(),i.addHiZPasses(),i.addVisibilityPass(),i.addMaterialPass({name:"OpaqueGBufferPass",outputs:null==r?[i.sceneColor,n]:[i.sceneColor,n,r],drawStage:"opaque",loadDepth:!0}),i.addHiZHistoryPass("OpaqueGBufferPass");let o=i.sceneColor;if(T?.enabled){const e=T.addPasses(i,{depth:i.mainDepth,normal:n,velocity:r??void 0});o=T.addCompositePass(i,o,e)}null!=A&&(o=A.addPasses(i,{sceneColor:o,depth:i.mainDepth,normalRoughness:n}));const s=new Set(K.flatMap(e=>e.getSceneTextureReads?.()??[]));i.addSceneTextureCopyPass(o,{sceneColor:s.has("sceneColorSnapshot"),sceneDepth:s.has("sceneDepthSnapshot")||q.some(e=>e.enabled&&null!=e.material.uniforms[l])}),o=Q(i,"beforeFog",o),i.addLatePass(o);for(const e of K)null!=e.stage&&"afterScene"!==e.stage||e(i,o);null!=N&&(o=N.addPasses(i,{sceneColor:o,depth:i.mainDepth,velocity:r??void 0,volumeObjects:t.fogVolumeObjects,lights:t.extractedLights})),null!=j&&null!=r&&(o=j.addPass(i,o,r,i.mainDepth)),null!=B&&(o=B.addPass(i,o)),o=Q(i,"beforeOutline",o),null!=_&&(o=_.addPass(i,o)),o=Q(i,"beforeDepthOfField",o),null!=$&&(o=$.addPass(i,o,i.mainDepth)),o=Q(i,"beforeColorAdjustment",o),null!=H&&(o=H.addPass(i,o)),o=Q(i,"beforeAntiAliasing",o);let a="taa"===U.mode&&null!=k?k.addPass(i,o,i.mainDepth,r??void 0):o;"smaa"===U.mode&&null!=V?a=V.addPass(i,a):"fxaa"===U.mode&&null!=W&&(a=W.addPass(i,a)),a=Q(i,"beforeOutput",a);for(const e of K)"beforePresent"===e.stage&&e(i,a);!0===P?.enabled&&null!=r?P.addInputPass(i,a,r):i.present(a)});try{return await Y.initialize(g),O=new ExperimentalWebGpuBackend(Y,S,G,R,B,W,V,T,A,k,j,N,H,$,_,q,K,Z,U,X,P,v),O}catch(e){throw Y.destroy(),S.dispose(),G.dispose(),R.dispose(),T?.dispose(),V?.dispose(),j?.dispose(),N?.dispose(),_?.dispose(),e}}static supportsCamera(t){return t instanceof e.PerspectiveCamera||t instanceof e.OrthographicCamera}setSize(e,t,i,n=1){const r=this.canvas.width,o=this.canvas.height;let s=Math.min(1,Math.max(.25,n));if(!0===this.nativeDlss?.enabled){const n=Math.max(1,Math.floor(e*i)),r=Math.max(1,Math.floor(t*i));s=this.nativeDlss.getRenderScale(n,r)}const a=s!==this.renderScale;this.renderScale=s,this.renderer.setRenderScale(s),this.taa?.setRenderScale(s),this.renderer.setSize(e,t,i),(a||this.canvas.width!==r||this.canvas.height!==o)&&this.resetViewHistory()}initTexture(e){this.renderer.initTexture(e)}setPostProcessEffects(e){this.postProcessEffects.splice(0,this.postProcessEffects.length,...e);for(const t of e){if("beforeLut"!==t.stage)continue;const e=`${t.id}:${t.stage}`;this.warnedUnsupportedPostProcessStages.has(e)||(this.warnedUnsupportedPostProcessStages.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: stage "${t.stage}" has no native WebGPU anchor.`))}}getDevice(){return this.renderer.getDevice()}setRenderGraphExtensions(e){this.renderGraphExtensions.length=0;for(const t of e)this.renderGraphExtensions.push(t)}setPresentationExtensions(e){this.presentationExtensions.length=0;for(const t of e)this.presentationExtensions.push(t)}setEnableOutlines(e){null!=this.outline&&(this.outline.enabled=e)}setTiledLightingEnabled(e){this.renderer.setTiledLightingEnabled(e)}setDynamicBatchingEnabled(e){this.renderer.setDynamicBatchingEnabled(e)}setSelectedObjects(e){this.outline?.setSelectedObjects(e)}setSelectedObjectInstances(e){this.outline?.setSelectedInstances(e)}setCascadedShadowRanges(e,t=[]){this.renderer.setCascadedShadowRanges(e,t),this.volumetricFog?.setCascadedDirectionalLights(t)}setDirectionalShadowOptions(e,t){this.directionalShadowState.enabled=e,this.renderer.setDirectionalShadowsEnabled(e),this.renderer.setDirectionalShadowMapSize(t)}setWorldEnvironment(e){if(null==e)return void this.nodeMaterialResolver.setWorldEnvironment(null);const t=this.getEnvironmentTexture(e.source);this.nodeMaterialResolver.setWorldEnvironment({texture:t,intensity:e.intensity})}getEnvironmentTexture(t){if(t.mapping===e.CubeUVReflectionMapping)return t;let i=this.pmremResults.get(t);return null==i&&(this.pmremGenerator??(this.pmremGenerator=this.renderer.createPMREMGenerator()),i=this.pmremGenerator.fromEquirectangular(t),this.pmremResults.set(t,i),this.ownedPmremResults.add(i)),i.texture}resetViewHistory(){this.renderer.resetViewHistory(),this.taa?.reset(),this.motionBlur?.reset(),this.gtao?.reset(),this.volumetricFog?.reset(),this.nativeDlss?.reset()}async compile(e,t){if(!this.secondaryMotionPrepared){let t=!1;e.traverse(e=>{const i=e.userData.secondaryMotion?.regions;Array.isArray(i)&&i.some(e=>e.enabled)&&(t=!0)});const i=this.renderer.getDevice();if(t&&i){const{prepareSecondaryMotionRuntime:e}=await import("../secondary-motion/runtime.js");e(i),this.secondaryMotionPrepared=!0}}await this.renderer.compileAsync(e,t)}createStaticDrawSet(e,t,i=!1,n="skip"){this.renderer.setHiZOcclusionCullingEnabled(!0);const r=this.renderer.createStaticDrawSet(e,{label:t,onUnsupported:n,allowUnsortedLateDraws:i});return 0===r.drawCount?(r.dispose(),null):r}render(e,t,i){const n="taa"===this.antiAliasingState.mode?this.taa:null;this.volumetricFog?.setScene(e),this.renderer.setMotionVectorProjection(t.projectionMatrix),this.motionBlur?.prepareCamera(t,this.canvas.width,this.canvas.height,i),this.motionBlur?.requiresRendererHistoryReset()&&(this.renderer.resetViewHistory(),this.gtao?.reset(),this.volumetricFog?.reset()),n?.prepareCamera(t,this.canvas.width,this.canvas.height),this.nativeDlss?.prepareFrame(t);const r=!0===this.nativeDlss?.enabled?this.nativeDlss.jitter:null;this.motionBlur?.setJitterUv(n?.currentJitterUv.x??(null==r?0:r.x/Math.max(1,this.canvas.width*this.renderScale)),n?.currentJitterUv.y??(null==r?0:-r.y/Math.max(1,this.canvas.height*this.renderScale))),null!=r&&this.renderer.setProjectionJitter(r.x,r.y);let o=!1;try{this.renderer.render(e,t,i),o=!0}finally{null!=r&&this.renderer.clearProjectionJitter(),n?.finishCamera(t),o&&this.motionBlur?.commitCamera(),o&&this.nativeDlss?.finishFrame(t)}}setMotionBlurOptions(e){null!=this.motionBlur&&Object.assign(this.motionBlur.options,e)}setGTAOOptions(e){this.gtao?.setOptions(e)}setAntiAliasingMode(e){e!==this.antiAliasingState.mode&&("taa"===e&&null==this.taa||"smaa"===e&&null==this.smaa||"fxaa"===e&&null==this.fxaa?console.warn(`[Hology WebGPU experiment] Anti-aliasing mode "${e}" was not initialized. Set webgpuPostProcessing.antiAliasing in the initial rendering configuration to enable runtime switching.`):(this.antiAliasingState.mode=e,this.resetTemporalHistory()))}setGTAOQuality(e){this.gtao?.applyPreset(e)}setVolumetricFogOptions(e){this.volumetricFog?.setOptions(e)}setVolumetricFogQuality(e){this.volumetricFog?.applyPreset(e)}pushMotionBlurOverride(e){return this.motionBlur?.pushOverride(e)??null}invalidateObjectMotion(e){this.renderer.invalidateObjectMotion(e)}getLastFrameProfile(){return this.renderer.getLastFrameProfile()}setPostProcessState(e){null!=this.colorGrading&&(Object.assign(this.colorGrading.options,e??{enabled:!1}),this.colorGrading.options.enabled=!0===e?.enabled),null!=this.depthOfField&&(this.depthOfField.options.enabled=null!=e?.depthFocus||null!=e?.depthAperture||null!=e?.depthMaxBlur,this.depthOfField.options.focus=e?.depthFocus,this.depthOfField.options.aperture=e?.depthAperture,this.depthOfField.options.maxBlur=e?.depthMaxBlur)}setProfilingEnabled(e){this.renderer.setRenderGraphProfilingEnabled(e)}resetTemporalHistory(){this.taa?.reset(),this.motionBlur?.reset(),this.gtao?.reset(),this.volumetricFog?.reset(),this.renderer.resetViewHistory(),this.nativeDlss?.reset()}inspect(e,t){return inspectWebGpuScene(e,t,this.nodeMaterialResolver)}destroy(){this.nativeDlss?.dispose(),this.nodeMaterialResolver.dispose(),this.gBufferFallbackSource.dispose(),this.gtao?.dispose(),this.smaa?.dispose(),this.motionBlur?.dispose(),this.volumetricFog?.dispose();for(const e of this.ownedPmremResults)e.dispose();this.ownedPmremResults.clear(),this.renderer.destroy(),this.fallbackMaterial.dispose()}}export function inspectWebGpuScene(e,t,i){const n={meshes:0,skinnedMeshes:0,instancedMeshes:0,batchedMeshes:0,sprites:0,points:0,lines:0,missingPositionGeometry:0,transparentMaterials:0,shaderMaterialsReplaced:0,materialsReplaced:0,unsupportedCamera:ExperimentalWebGpuBackend.supportsCamera(t)?0:1};return e.traverse(e=>{if(e.isSprite)return void n.sprites++;if(e.isPoints)return void n.points++;if(e.isLine)return void n.lines++;if(!e.isMesh)return;const t=e;t.isBatchedMesh?n.batchedMeshes++:t.isInstancedMesh?n.instancedMeshes++:t.isSkinnedMesh?n.skinnedMeshes++:n.meshes++,null==t.geometry?.getAttribute("position")&&n.missingPositionGeometry++;const r=Array.isArray(t.material)?t.material:[t.material];for(const e of r){if(null==e)continue;e.transparent&&n.transparentMaterials++;const t=!0===e.isWGSLShaderMaterial||!0===e.isLineMaterial,r=!t&&!0===i?.canResolve(e);t||r||(n.materialsReplaced++,e.isShaderMaterial&&n.shaderMaterialsReplaced++)}}),n}export function formatWebGpuSceneCapabilitySummary(e){return`[Hology WebGPU experiment] ${JSON.stringify(e)}`}const u="\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#ifdef USE_SKINNING\n @location(4) skinIndex: vec4<u32>,\n @location(5) skinWeight: vec4<f32>,\n#endif\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) color: vec4<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n#ifdef USE_SKINNING\n let localPosition = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight);\n let localNormal = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n#else\n let localPosition = input.position;\n let localNormal = input.normal;\n#endif\n let world = rendererWorldPosition(localPosition, input.instanceIndex);\n output.position = rendererClipPosition(localPosition, input.instanceIndex);\n output.worldPosition = world.xyz;\n output.worldNormal = rendererWorldNormal(localNormal, input.instanceIndex);\n output.color = input.color * rendererObjectColor(input.instanceIndex);\n return output;\n}\n",p="\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) color: vec4<f32>,\n};\n\nfn distanceAttenuation(distanceToLight: f32, cutoffDistance: f32, decayExponent: f32) -> f32 {\n var distanceFalloff = 1.0 / max(pow(distanceToLight, decayExponent), 0.01);\n if (cutoffDistance > 0.0) {\n let ratio = distanceToLight / cutoffDistance;\n let cutoff = clamp(1.0 - ratio * ratio * ratio * ratio, 0.0, 1.0);\n distanceFalloff *= cutoff * cutoff;\n }\n return distanceFalloff;\n}\n\n@fragment\nfn fsMain(input: VertexOutput) -> @location(0) vec4<f32> {\n let normal = normalize(input.worldNormal);\n let normalTint = normal * 0.5 + vec3<f32>(0.5);\n let base = mix(vec3<f32>(0.52, 0.58, 0.64), normalTint, 0.22) * input.color.rgb;\n var lighting = rendererIndirectDiffuse(normal) + vec3<f32>(0.08);\n var directionalLighting = vec3<f32>(0.0);\n let directionalCount = rendererDirectionalLightCount();\n\n for (var index: u32 = 0u; index < directionalCount; index = index + 1u) {\n let lightDirection = rendererDirectionalLightDirectionForLight(index);\n let shadow = rendererSampleDirectionalShadowForLightWithNormal(index, input.worldPosition, normal);\n directionalLighting += rendererDirectionalLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * shadow;\n }\n if (directionalCount > 0u) {\n lighting += directionalLighting / f32(directionalCount);\n }\n\n for (var index: u32 = 0u; index < rendererPointLightCount(); index = index + 1u) {\n let lightVector = rendererPointLightPositionForLight(index) - input.worldPosition;\n let distanceToLight = length(lightVector);\n let lightDirection = normalize(lightVector);\n let shadow = rendererSamplePointShadowForLightWithNormal(index, input.worldPosition, normal);\n lighting += rendererPointLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * distanceAttenuation(distanceToLight, rendererPointLightRangeForLight(index), rendererPointLightDecayForLight(index)) * shadow;\n }\n\n for (var index: u32 = 0u; index < rendererSpotLightCount(); index = index + 1u) {\n let lightVector = rendererSpotLightPositionForLight(index) - input.worldPosition;\n let distanceToLight = length(lightVector);\n let lightDirection = normalize(lightVector);\n let angleCos = dot(-lightDirection, rendererSpotLightDirectionForLight(index));\n let cone = smoothstep(rendererSpotLightConeCosForLight(index), rendererSpotLightPenumbraCosForLight(index), angleCos);\n let shadow = rendererSampleSpotShadowForLightWithNormal(index, input.worldPosition, normal);\n lighting += rendererSpotLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * cone * distanceAttenuation(distanceToLight, rendererSpotLightRangeForLight(index), rendererSpotLightDecayForLight(index)) * shadow;\n }\n\n return vec4<f32>(base * max(lighting, vec3<f32>(0.08)), input.color.a);\n}\n";/*
1
+ import*as e from"three";import{NodeMaterialWebGpuResolver as t}from"./node-material-webgpu-resolver.js";import{configureWebGpuRuntimeBindings as i}from"./webgpu-runtime-bridge.js";import{float as n,varyingTransformed as r,vec4 as a}from"three-shader-graph";import{NodeShaderMaterial as o}from"../shader-nodes/index.js";import{sceneMapUniformName as s}from"../shader-nodes/scene-sample.js";import{depthUniformName as l}from"../shader-nodes/depth.js";import{MATERIAL_FLAG_ALPHA_TEST as d,MATERIAL_FLAG_RECEIVE_DECALS as c}from"../shader-nodes/material-flags.js";import{createMotionVectorOutput as h}from"./motion-vector-node.js";export class ExperimentalWebGpuBackend{constructor(e,t,i,n,r,a,o,s,l,d,c,h,u,p,m,g,f,v,S,b,P,x){this.renderer=e,this.fallbackMaterial=t,this.nodeMaterialResolver=i,this.gBufferFallbackSource=n,this.bloom=r,this.fxaa=a,this.smaa=o,this.gtao=s,this.ssr=l,this.taa=d,this.motionBlur=c,this.volumetricFog=h,this.colorGrading=u,this.depthOfField=p,this.outline=m,this.postProcessEffects=g,this.renderGraphExtensions=f,this.presentationExtensions=v,this.antiAliasingState=S,this.directionalShadowState=b,this.nativeDlss=P,this.kind="webgpu",this.renderScale=1,this.pmremGenerator=null,this.pmremResults=new WeakMap,this.ownedPmremResults=new Set,this.warnedUnsupportedPostProcessStages=new Set,this.secondaryMotionPrepared=!1,this.canvas=x}static async probeAvailability(){if("undefined"==typeof navigator||!("gpu"in navigator))return{available:!1,reason:"The runtime does not expose navigator.gpu."};try{const e=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});return null==e?{available:!1,reason:"No WebGPU adapter is available."}:{available:!0,adapter:e}}catch(e){return{available:!1,reason:`Requesting a WebGPU adapter failed: ${e instanceof Error?e.message:String(e)}`}}}static async create(m={},g){const f=await import("@hology/webgpu-renderer");i({registerPipelineDiagnosticOrigin:f.registerPipelineDiagnosticOrigin,createComputeKernel:(e,t)=>new f.ComputeKernel(e,t),buildParticleLightingShaderHeader:f.buildParticleLightingShaderHeader});const v=document.createElement("canvas");v.dataset.hologyRenderer="webgpu-experimental";const S=new f.WGSLShaderMaterial({vertexShader:u,fragmentShader:p}),b=!1!==m.nativeUpscaling&&"dlss"===m.nativeUpscaling?.method,P=b?(await import("./native-dlss-upscaler.js")).createNativeDlssUpscaler(m.nativeUpscaling?.mode??"quality"):null,x=null!=P;S.side=f.DoubleSide;const w=f,y=null!=m.motionBlur&&!1!==m.motionBlur,M=!1!==m.gtao&&(null==m.gtao||!1!==m.gtao.temporal),D=!1!==m.volumetricFog&&(null==m.volumetricFog||!1!==m.volumetricFog.temporal),E=x?"off":b?"taa":null!=(F=m).antiAliasing?F.antiAliasing:null!=F.taa&&!1!==F.taa?"taa":null!=F.smaa&&!1!==F.smaa?"smaa":null!=F.fxaa&&!1!==F.fxaa?"fxaa":!1===F.taa?"off":"taa";var F;const O=null!=m.antiAliasing,L=y||M||D||(O||"taa"===E)||x;let C=null;const G=new t(w,(e,t)=>"opaque"===t?[e.outputColor.xyz.rgba(n(e.alphaTest>0?d:0).add(!1===e.userData.receiveDecals?0:c)),a((e.outputNormal??r.normal).multiplyScalar(.5).addScalar(.5),e.outputRoughness??n(1)),...L?[h(e)]:[]]:void 0,e=>C?.getEnvironmentTexture(e)??e),R=new e.MeshStandardMaterial({color:8688803,roughness:1});if(null==G.resolve(R,"opaque"))throw S.dispose(),R.dispose(),new Error("Failed to compile the WebGPU G-buffer fallback material.");const T=!1===m.gtao?null:new f.GTAOEffect({normalSpace:"view",...f.GTAO_PRESETS.high,...m.gtao??{}}),A=!1===m.ssr||null==m.ssr?null:new f.SSREffect({normalSpace:"view",resolutionScale:.5,...m.ssr??{}}),B=!1===m.bloom?null:new f.BloomEffect({threshold:1,strength:.9,radius:.2,...m.bloom??{}}),W=O||!1!==m.fxaa&&"fxaa"===E?new f.FXAAEffect(!1===m.fxaa?{}:m.fxaa):null,k=O||!1!==m.smaa&&"smaa"===E?new f.SMAAEffect(!1===m.smaa?{}:m.smaa):null,V=x||O||!1!==m.taa&&"taa"===E?new f.TemporalAAEffect({renderScale:1,...!1===m.taa?{}:m.taa}):null,I={mode:E},U=!1===m.motionBlur||null==m.motionBlur?null:new f.MotionBlurEffect(m.motionBlur),N=m.volumetricFog||void 0,j=!1===m.volumetricFog?null:new f.VolumetricFogEffect(void 0,{...f.VOLUMETRIC_FOG_PRESETS.high,maxDistance:64,spatialJitter:!0,scatteringIntensity:Math.PI,...N,temporal:!1!==N?.temporal&&{...f.VOLUMETRIC_FOG_PRESETS.high.temporal,...N?.temporal},blur:!1!==N?.blur&&{...!1===f.VOLUMETRIC_FOG_PRESETS.high.blur?{}:f.VOLUMETRIC_FOG_PRESETS.high.blur,depthAwareUpsample:!0,...N?.blur}}),H=!1===m.colorGrading?null:new f.ColorGradingEffect({enabled:!1,...m.colorGrading??{}}),$=!1===m.depthOfField?null:new f.DepthOfFieldEffect({enabled:!1,...m.depthOfField??{}}),_=!1===m.outline?null:new f.OutlineEffect({enabled:!1,...m.outline??{}}),q=[],z=new WeakMap,J=new Set,K=[],Z=[],Q=(e,t,i)=>{let n=i;const r=q.filter(e=>e.enabled&&e.stage===t).sort((e,t)=>e.priority-t.priority||e.id-t.id);for(const t of r){if(!(t.material instanceof o)){const e=`${t.id}:material`;J.has(e)||(J.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: only NodeShaderMaterial effects are supported.`));continue}try{let i=z.get(t.material);null!=i&&i.version===t.material.version||(i={version:t.material.version,shader:G.compileFullscreen(t.material),diagnosticOrigin:{key:"post-process:"+String(t.material.userData.assetId??(t.material.name||t.material.uuid)),material:{name:t.material.name,uuid:t.material.uuid,version:t.material.version,assetId:t.material.userData.assetId,assetName:t.material.userData.assetName}}},z.set(t.material,i));const r=e.createColorTarget(`hologyCustomPostProcess${t.id}`);e.addNodeFullscreenPass({name:`HologyCustomPostProcess${t.id}`,diagnosticOrigin:i.diagnosticOrigin,shader:i.shader,inputOverrides:{[s]:n},outputs:r}),n=r}catch(e){const i=`${t.id}:compile:${t.material.version}`;J.has(i)||(J.add(i),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: ${e instanceof Error?e.message:String(e)}`,e))}}return n},X={enabled:!0},Y=new f.WebGpuRenderer({canvas:v,fallbackMaterial:S,materialResolver:(e,t)=>G.resolve(e,t),invokeObjectRenderCallbacks:!1,hiZOcclusionCulling:!0,renderGraphProfiling:!1,sampleCount:1,multiDrawIndirect:!1,nativePostSubmit:P?.postSubmit,presentationOverlay:e=>{for(const t of Z)t(e)}});Y.setRenderScale("taa"===E?V?.renderScale??1:1),Y.setRenderGraphBuilder((e,t)=>{const i=new f.FrameGraphBuilder(t),n=i.createColorTarget("hologyNormalRoughness",{format:"rgba8unorm"}),r=L?i.createColorTarget("hologyMotionVectors",{format:"rgba16float"}):null;for(const e of K)"beforeScene"===e.stage&&e(i,i.sceneColor);X.enabled&&i.addDirectionalShadowPass(),i.addPointShadowPass(),i.addSpotShadowPass(),i.addDepthPrepass(),i.addHiZPasses(),i.addVisibilityPass(),i.addMaterialPass({name:"OpaqueGBufferPass",outputs:null==r?[i.sceneColor,n]:[i.sceneColor,n,r],drawStage:"opaque",loadDepth:!0}),i.addHiZHistoryPass("OpaqueGBufferPass");let a=i.sceneColor;if(T?.enabled){const e=T.addPasses(i,{depth:i.mainDepth,normal:n,velocity:r??void 0});a=T.addCompositePass(i,a,e)}null!=A&&(a=A.addPasses(i,{sceneColor:a,depth:i.mainDepth,normalRoughness:n}));const o=new Set(K.flatMap(e=>e.getSceneTextureReads?.()??[]));i.addSceneTextureCopyPass(a,{sceneColor:o.has("sceneColorSnapshot"),sceneDepth:o.has("sceneDepthSnapshot")||q.some(e=>e.enabled&&null!=e.material.uniforms[l])}),a=Q(i,"beforeFog",a),i.addLatePass(a);for(const e of K)null!=e.stage&&"afterScene"!==e.stage||e(i,a);null!=j&&(a=j.addPasses(i,{sceneColor:a,depth:i.mainDepth,velocity:r??void 0,volumeObjects:t.fogVolumeObjects,lights:t.extractedLights})),null!=U&&null!=r&&(a=U.addPass(i,a,r,i.mainDepth)),null!=B&&(a=B.addPass(i,a)),a=Q(i,"beforeOutline",a),null!=_&&(a=_.addPass(i,a)),a=Q(i,"beforeDepthOfField",a),null!=$&&(a=$.addPass(i,a,i.mainDepth)),a=Q(i,"beforeColorAdjustment",a),null!=H&&(a=H.addPass(i,a)),a=Q(i,"beforeAntiAliasing",a);let s="taa"===I.mode&&null!=V?V.addPass(i,a,i.mainDepth,r??void 0):a;"smaa"===I.mode&&null!=k?s=k.addPass(i,s):"fxaa"===I.mode&&null!=W&&(s=W.addPass(i,s)),s=Q(i,"beforeOutput",s);for(const e of K)"beforePresent"===e.stage&&e(i,s);!0===P?.enabled&&null!=r?P.addInputPass(i,s,r):i.present(s)});try{return await Y.initialize(g),C=new ExperimentalWebGpuBackend(Y,S,G,R,B,W,k,T,A,V,U,j,H,$,_,q,K,Z,I,X,P,v),C}catch(e){throw Y.destroy(),S.dispose(),G.dispose(),R.dispose(),T?.dispose(),k?.dispose(),U?.dispose(),j?.dispose(),_?.dispose(),e}}static supportsCamera(t){return t instanceof e.PerspectiveCamera||t instanceof e.OrthographicCamera}setSize(e,t,i,n=1){const r=this.canvas.width,a=this.canvas.height;let o=Math.min(1,Math.max(.25,n));if(!0===this.nativeDlss?.enabled){const n=Math.max(1,Math.floor(e*i)),r=Math.max(1,Math.floor(t*i));o=this.nativeDlss.getRenderScale(n,r)}const s=o!==this.renderScale;this.renderScale=o,this.renderer.setRenderScale(o),this.taa?.setRenderScale(o),this.renderer.setSize(e,t,i),(s||this.canvas.width!==r||this.canvas.height!==a)&&this.resetViewHistory()}initTexture(e){this.renderer.initTexture(e)}setPostProcessEffects(e){this.postProcessEffects.splice(0,this.postProcessEffects.length,...e);for(const t of e){if("beforeLut"!==t.stage)continue;const e=`${t.id}:${t.stage}`;this.warnedUnsupportedPostProcessStages.has(e)||(this.warnedUnsupportedPostProcessStages.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: stage "${t.stage}" has no native WebGPU anchor.`))}}getDevice(){return this.renderer.getDevice()}setRenderGraphExtensions(e){this.renderGraphExtensions.length=0;for(const t of e)this.renderGraphExtensions.push(t)}setPresentationExtensions(e){this.presentationExtensions.length=0;for(const t of e)this.presentationExtensions.push(t)}setEnableOutlines(e){null!=this.outline&&(this.outline.enabled=e)}setTiledLightingEnabled(e){this.renderer.setTiledLightingEnabled(e)}setDynamicBatchingEnabled(e){this.renderer.setDynamicBatchingEnabled(e)}setSelectedObjects(e){this.outline?.setSelectedObjects(e)}setSelectedObjectInstances(e){this.outline?.setSelectedInstances(e)}setCascadedShadowRanges(e,t=[]){this.renderer.setCascadedShadowRanges(e,t),this.volumetricFog?.setCascadedDirectionalLights(t)}setDirectionalShadowOptions(e,t){this.directionalShadowState.enabled=e,this.renderer.setDirectionalShadowsEnabled(e),this.renderer.setDirectionalShadowMapSize(t)}setWorldEnvironment(e){if(null==e)return void this.nodeMaterialResolver.setWorldEnvironment(null);const t=this.getEnvironmentTexture(e.source);this.nodeMaterialResolver.setWorldEnvironment({texture:t,intensity:e.intensity})}getEnvironmentTexture(t){if(t.mapping===e.CubeUVReflectionMapping)return t;let i=this.pmremResults.get(t);return null==i&&(this.pmremGenerator??(this.pmremGenerator=this.renderer.createPMREMGenerator()),i=this.pmremGenerator.fromEquirectangular(t),this.pmremResults.set(t,i),this.ownedPmremResults.add(i)),i.texture}resetViewHistory(){this.renderer.resetViewHistory(),this.taa?.reset(),this.motionBlur?.reset(),this.gtao?.reset(),this.volumetricFog?.reset(),this.nativeDlss?.reset()}async compile(e,t){if(!this.secondaryMotionPrepared){let t=!1;e.traverse(e=>{const i=e.userData.secondaryMotion?.regions;Array.isArray(i)&&i.some(e=>e.enabled)&&(t=!0)});const i=this.renderer.getDevice();if(t&&i){const{prepareSecondaryMotionRuntime:e}=await import("../secondary-motion/runtime.js");e(i),this.secondaryMotionPrepared=!0}}await this.renderer.compileAsync(e,t)}createStaticDrawSet(e,t,i=!1,n="skip"){this.renderer.setHiZOcclusionCullingEnabled(!0);const r=this.renderer.createStaticDrawSet(e,{label:t,onUnsupported:n,allowUnsortedLateDraws:i});return 0===r.drawCount?(r.dispose(),null):r}render(e,t,i){const n="taa"===this.antiAliasingState.mode?this.taa:null;this.volumetricFog?.setScene(e),this.renderer.setMotionVectorProjection(t.projectionMatrix),this.motionBlur?.prepareCamera(t,this.canvas.width,this.canvas.height,i),this.motionBlur?.requiresRendererHistoryReset()&&(this.renderer.resetViewHistory(),this.gtao?.reset(),this.volumetricFog?.reset()),n?.prepareCamera(t,this.canvas.width,this.canvas.height),this.nativeDlss?.prepareFrame(t);const r=!0===this.nativeDlss?.enabled?this.nativeDlss.jitter:null;this.motionBlur?.setJitterUv(n?.currentJitterUv.x??(null==r?0:r.x/Math.max(1,this.canvas.width*this.renderScale)),n?.currentJitterUv.y??(null==r?0:-r.y/Math.max(1,this.canvas.height*this.renderScale))),null!=r&&this.renderer.setProjectionJitter(r.x,r.y);let a=!1;try{this.renderer.render(e,t,i),a=!0}finally{null!=r&&this.renderer.clearProjectionJitter(),n?.finishCamera(t),a&&this.motionBlur?.commitCamera(),a&&this.nativeDlss?.finishFrame(t)}}setMotionBlurOptions(e){null!=this.motionBlur&&Object.assign(this.motionBlur.options,e)}setGTAOOptions(e){this.gtao?.setOptions(e)}setAntiAliasingMode(e){e!==this.antiAliasingState.mode&&("taa"===e&&null==this.taa||"smaa"===e&&null==this.smaa||"fxaa"===e&&null==this.fxaa?console.warn(`[Hology WebGPU experiment] Anti-aliasing mode "${e}" was not initialized. Set webgpuPostProcessing.antiAliasing in the initial rendering configuration to enable runtime switching.`):(this.antiAliasingState.mode=e,this.resetTemporalHistory()))}setGTAOQuality(e){this.gtao?.applyPreset(e)}setVolumetricFogOptions(e){this.volumetricFog?.setOptions(e)}setVolumetricFogQuality(e){this.volumetricFog?.applyPreset(e)}pushMotionBlurOverride(e){return this.motionBlur?.pushOverride(e)??null}invalidateObjectMotion(e){this.renderer.invalidateObjectMotion(e)}getLastFrameProfile(){return this.renderer.getLastFrameProfile()}setPostProcessState(e){null!=this.colorGrading&&(Object.assign(this.colorGrading.options,e??{enabled:!1}),this.colorGrading.options.enabled=!0===e?.enabled),null!=this.depthOfField&&(this.depthOfField.options.enabled=null!=e?.depthFocus||null!=e?.depthAperture||null!=e?.depthMaxBlur,this.depthOfField.options.focus=e?.depthFocus,this.depthOfField.options.aperture=e?.depthAperture,this.depthOfField.options.maxBlur=e?.depthMaxBlur)}setProfilingEnabled(e){this.renderer.setRenderGraphProfilingEnabled(e)}resetTemporalHistory(){this.taa?.reset(),this.motionBlur?.reset(),this.gtao?.reset(),this.volumetricFog?.reset(),this.renderer.resetViewHistory(),this.nativeDlss?.reset()}inspect(e,t){return inspectWebGpuScene(e,t,this.nodeMaterialResolver)}destroy(){this.nativeDlss?.dispose(),this.nodeMaterialResolver.dispose(),this.gBufferFallbackSource.dispose(),this.gtao?.dispose(),this.smaa?.dispose(),this.motionBlur?.dispose(),this.volumetricFog?.dispose();for(const e of this.ownedPmremResults)e.dispose();this.ownedPmremResults.clear(),this.renderer.destroy(),this.fallbackMaterial.dispose()}}export function inspectWebGpuScene(e,t,i){const n={meshes:0,skinnedMeshes:0,instancedMeshes:0,batchedMeshes:0,sprites:0,points:0,lines:0,missingPositionGeometry:0,transparentMaterials:0,shaderMaterialsReplaced:0,materialsReplaced:0,unsupportedCamera:ExperimentalWebGpuBackend.supportsCamera(t)?0:1};return e.traverse(e=>{if(e.isSprite)return void n.sprites++;if(e.isPoints)return void n.points++;if(e.isLine)return void n.lines++;if(!e.isMesh)return;const t=e;t.isBatchedMesh?n.batchedMeshes++:t.isInstancedMesh?n.instancedMeshes++:t.isSkinnedMesh?n.skinnedMeshes++:n.meshes++,null==t.geometry?.getAttribute("position")&&n.missingPositionGeometry++;const r=Array.isArray(t.material)?t.material:[t.material];for(const e of r){if(null==e)continue;e.transparent&&n.transparentMaterials++;const t=!0===e.isWGSLShaderMaterial||!0===e.isLineMaterial,r=!t&&!0===i?.canResolve(e);t||r||(n.materialsReplaced++,e.isShaderMaterial&&n.shaderMaterialsReplaced++)}}),n}export function formatWebGpuSceneCapabilitySummary(e){return`[Hology WebGPU experiment] ${JSON.stringify(e)}`}const u="\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#ifdef USE_SKINNING\n @location(4) skinIndex: vec4<u32>,\n @location(5) skinWeight: vec4<f32>,\n#endif\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) color: vec4<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n#ifdef USE_SKINNING\n let localPosition = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight);\n let localNormal = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n#else\n let localPosition = input.position;\n let localNormal = input.normal;\n#endif\n let world = rendererWorldPosition(localPosition, input.instanceIndex);\n output.position = rendererClipPosition(localPosition, input.instanceIndex);\n output.worldPosition = world.xyz;\n output.worldNormal = rendererWorldNormal(localNormal, input.instanceIndex);\n output.color = input.color * rendererObjectColor(input.instanceIndex);\n return output;\n}\n",p="\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) color: vec4<f32>,\n};\n\nfn distanceAttenuation(distanceToLight: f32, cutoffDistance: f32, decayExponent: f32) -> f32 {\n var distanceFalloff = 1.0 / max(pow(distanceToLight, decayExponent), 0.01);\n if (cutoffDistance > 0.0) {\n let ratio = distanceToLight / cutoffDistance;\n let cutoff = clamp(1.0 - ratio * ratio * ratio * ratio, 0.0, 1.0);\n distanceFalloff *= cutoff * cutoff;\n }\n return distanceFalloff;\n}\n\n@fragment\nfn fsMain(input: VertexOutput) -> @location(0) vec4<f32> {\n let normal = normalize(input.worldNormal);\n let normalTint = normal * 0.5 + vec3<f32>(0.5);\n let base = mix(vec3<f32>(0.52, 0.58, 0.64), normalTint, 0.22) * input.color.rgb;\n var lighting = rendererIndirectDiffuse(normal) + vec3<f32>(0.08);\n var directionalLighting = vec3<f32>(0.0);\n let directionalCount = rendererDirectionalLightCount();\n\n for (var index: u32 = 0u; index < directionalCount; index = index + 1u) {\n let lightDirection = rendererDirectionalLightDirectionForLight(index);\n let shadow = rendererSampleDirectionalShadowForLightWithNormal(index, input.worldPosition, normal);\n directionalLighting += rendererDirectionalLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * shadow;\n }\n if (directionalCount > 0u) {\n lighting += directionalLighting / f32(directionalCount);\n }\n\n for (var index: u32 = 0u; index < rendererPointLightCount(); index = index + 1u) {\n let lightVector = rendererPointLightPositionForLight(index) - input.worldPosition;\n let distanceToLight = length(lightVector);\n let lightDirection = normalize(lightVector);\n let shadow = rendererSamplePointShadowForLightWithNormal(index, input.worldPosition, normal);\n lighting += rendererPointLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * distanceAttenuation(distanceToLight, rendererPointLightRangeForLight(index), rendererPointLightDecayForLight(index)) * shadow;\n }\n\n for (var index: u32 = 0u; index < rendererSpotLightCount(); index = index + 1u) {\n let lightVector = rendererSpotLightPositionForLight(index) - input.worldPosition;\n let distanceToLight = length(lightVector);\n let lightDirection = normalize(lightVector);\n let angleCos = dot(-lightDirection, rendererSpotLightDirectionForLight(index));\n let cone = smoothstep(rendererSpotLightConeCosForLight(index), rendererSpotLightPenumbraCosForLight(index), angleCos);\n let shadow = rendererSampleSpotShadowForLightWithNormal(index, input.worldPosition, normal);\n lighting += rendererSpotLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * cone * distanceAttenuation(distanceToLight, rendererSpotLightRangeForLight(index), rendererSpotLightDecayForLight(index)) * shadow;\n }\n\n return vec4<f32>(base * max(lighting, vec3<f32>(0.08)), input.color.a);\n}\n";/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -10,6 +10,7 @@ export interface WebGpuComputeKernel {
10
10
  createBindGroup(device: GPUDevice, entries: GPUBindGroupEntry[], label?: string): GPUBindGroup;
11
11
  }
12
12
  interface WebGpuRuntimeBindings {
13
+ registerPipelineDiagnosticOrigin?: (device: GPUDevice, label: string, origin: import('@hology/webgpu-renderer').PipelineDiagnosticOrigin) => void;
13
14
  createComputeKernel(device: GPUDevice, descriptor: WebGpuComputeKernelDescriptor): WebGpuComputeKernel;
14
15
  buildParticleLightingShaderHeader(receiveShadow?: boolean, modelMatrixBody?: string): string;
15
16
  }
@@ -18,5 +19,7 @@ export declare function configureWebGpuRuntimeBindings(value: WebGpuRuntimeBindi
18
19
  export declare function ensureWebGpuRuntimeBindings(): Promise<void>;
19
20
  export declare function createWebGpuComputeKernel(device: GPUDevice, descriptor: WebGpuComputeKernelDescriptor): WebGpuComputeKernel;
20
21
  export declare function buildWebGpuParticleLightingShaderHeader(receiveShadow?: boolean, modelMatrixBody?: string): string;
22
+ export declare function registerWebGpuPipelineOrigin(device: GPUDevice, label: string, origin: import('@hology/webgpu-renderer').PipelineDiagnosticOrigin): void;
23
+ export declare function setWebGpuPipelineLoading(device: GPUDevice | null | undefined, loading: boolean, phase: string): Promise<void>;
21
24
  export {};
22
25
  //# sourceMappingURL=webgpu-runtime-bridge.d.ts.map
@@ -1,4 +1,4 @@
1
- let e=null,n=null;export function configureWebGpuRuntimeBindings(n){e=n}export async function ensureWebGpuRuntimeBindings(){null==e&&(n??(n=import("@hology/webgpu-renderer").then(e=>{configureWebGpuRuntimeBindings({createComputeKernel:(n,i)=>new e.ComputeKernel(n,i),buildParticleLightingShaderHeader:e.buildParticleLightingShaderHeader})}).catch(e=>{throw n=null,e})),await n)}export function createWebGpuComputeKernel(n,i){if(null==e)throw new Error("WebGPU runtime bindings are unavailable. Initialize the WebGPU rendering backend first.");return e.createComputeKernel(n,i)}export function buildWebGpuParticleLightingShaderHeader(n=!0,i){if(null==e)throw new Error("WebGPU runtime bindings are unavailable. Initialize the WebGPU rendering backend first.");return e.buildParticleLightingShaderHeader(n,i)}/*
1
+ let e=null,i=null;export function configureWebGpuRuntimeBindings(i){e=i}export async function ensureWebGpuRuntimeBindings(){null==e&&(i??(i=import("@hology/webgpu-renderer").then(e=>{configureWebGpuRuntimeBindings({registerPipelineDiagnosticOrigin:e.registerPipelineDiagnosticOrigin,createComputeKernel:(i,n)=>new e.ComputeKernel(i,n),buildParticleLightingShaderHeader:e.buildParticleLightingShaderHeader})}).catch(e=>{throw i=null,e})),await i)}export function createWebGpuComputeKernel(i,n){if(null==e)throw new Error("WebGPU runtime bindings are unavailable. Initialize the WebGPU rendering backend first.");return e.createComputeKernel(i,n)}export function buildWebGpuParticleLightingShaderHeader(i=!0,n){if(null==e)throw new Error("WebGPU runtime bindings are unavailable. Initialize the WebGPU rendering backend first.");return e.buildParticleLightingShaderHeader(i,n)}export function registerWebGpuPipelineOrigin(i,n,r){e?.registerPipelineDiagnosticOrigin?.(i,n,r)}export async function setWebGpuPipelineLoading(e,i,n){if(null==e)return;const{setPipelineDiagnosticLoading:r}=await import("@hology/webgpu-renderer");r(e,i,n)}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */