@hology/core 0.0.229 → 0.0.231

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{CustomRenderer as e,MeshRenderer as t,PUID as r}from"@hology/nebula";import*as a from"three";import{InstancedBufferAttribute as i,Object3D as o}from"three";import{NodeShaderMaterial as n}from"three-shader-graph";import{StretchedSprite as s}from"./stretched-sprite.js";import{Trail as l}from"./trail-renderer.js";import{SpriteNodeShaderMaterial as c}from"../../shader/sprite-shader";import{particleEnergyUniformName as d}from"../../shader-nodes/particle";import{AssetMeshInstance as m}from"../../scene/asset-resource-loader.js";var u;!function(e){e[e.mesh=0]="mesh",e[e.instanced=1]="instanced",e[e.sprite=2]="sprite",e[e.stretchedBillboard=3]="stretchedBillboard",e[e.trail=4]="trail"}(u||(u={}));export class MultiRenderer extends e{constructor(e,t,r,a){super(),this.worldContainer=e,this.localContainer=t,this.three=r,this.view=a,this.localRenderers=[],this.worldRenderers=[]}onSystemUpdate(){for(const e of this.worldRenderers)e?.onSystemUpdate();for(const e of this.localRenderers)e?.onSystemUpdate()}onParticleCreated(e){e.target=null,this.getRenderer(e)?.onParticleCreated(e)}onParticleUpdate(e){this.getRenderer(e)?.onParticleUpdate(e)}onParticleDead(e){this.getRenderer(e)?.onParticleDead(e),e._renderer=null}getRenderer(e){if(e._renderer)return e._renderer;const t=(null!=e?.parent?e?.parent._space:null)??"world",r="world"===t?this.worldContainer:this.localContainer,i="world"===t?this.worldRenderers:this.localRenderers;return"trail"===e.body.type?(null==i[u.trail]&&(i[u.trail]=new TrailRenderer(r,this.three)),e._renderer=i[u.trail]):e.body instanceof s?(null==i[u.stretchedBillboard]&&(i[u.stretchedBillboard]=new StretchedSpriteInstancedRenderer(r,this.three,this.view)),e._renderer=i[u.stretchedBillboard]):e.body instanceof a.Sprite||e.body instanceof a.Mesh&&"sprite"===e.body.name?(null==i[u.sprite]&&(i[u.sprite]=new CombinedRenderer(r,this.three)),e._renderer=i[u.sprite]):e.body instanceof a.Mesh&&0==e.body.children.length&&e.body.material instanceof n?(null==i[u.instanced]&&(i[u.instanced]=new InstancedRenderer(r,this.three,this.view)),e._renderer=i[u.instanced]):e.body instanceof a.Object3D?(null==i[u.mesh]&&(i[u.mesh]=new CombinedRenderer(r,this.three)),e._renderer=i[u.mesh]):void 0}dispose(){this.localRenderers.forEach(e=>{e instanceof InstancedRenderer&&e.dispose()}),this.worldRenderers.forEach(e=>{e instanceof InstancedRenderer&&e.dispose()})}}export class TrailRenderer extends t{constructor(){super(...arguments),this.trails=[]}dispose(){}onSystemUpdate(){for(const e of this.trails)e.update()}onParticleCreated(e){const t=e.body,r=new l(this.container,!1),i=new o;this.container.add(i),i.updateMatrixWorld(),i.updateWorldMatrix(!0,!0);const n=t.material?.clone()??l.createBaseMaterial(t.texture,t.scrollSpeed,t.opacityChannel,t.billboard??!1);n.uniforms.taper&&(n.uniforms.taper.value=t.taper??!1);const s=new a.Color(t.color??0).multiplyScalar(t.intensity??1),c=new a.Color(t.colorEnd??0).multiplyScalar(t.intensityEnd??t.intensity??1);n.uniforms.headColor&&n.uniforms.tailColor&&(n.uniforms.headColor.value=new a.Vector4(s.r,s.g,s.b,t.opacityStart??1),n.uniforms.tailColor.value=new a.Vector4(c.r,c.g,c.b,t.opacityEnd??1)),n.uniforms.color&&null==n.uniforms.headColor&&(n.uniforms.color.value=s),n.uniforms.opacity&&null==n.uniforms.headColor&&(n.uniforms.opacity.value=t.opacityStart??1),t.bloom&&(n.userData.hasBloom=!0),r.initialize(n,Math.round(t.length??10),!1,t.width,null,i,t.billboard??!1),null!=t.renderOrder&&null!=r.mesh&&(r.mesh.renderOrder=t.renderOrder);const d=e.rotation;i.rotation.set(d.x,d.y,d.z);e.scale;r.activate(),this.trails.push(r),e.target=i}onParticleUpdate(e){const t=e.target;t.position.copy(e.position);const r=e.body;let a=U;e.old&&e.old.position?a.set(e.position.x-e.old.position.x,e.position.y-e.old.position.y,e.position.z-e.old.position.z):a.copy(e.velocity),a.lengthSq()>1e-8?a.normalize():a.copy(w);const i=C;i.setFromUnitVectors(a,w),t.rotation.set(0,0,0),t.rotation.set(e.rotation.x,e.rotation.y,e.rotation.z),t.applyQuaternion(i);const o=this.trails.findIndex(e=>e.targetObject.id===t.id);if(-1!=o){const t=this.trails[o];if(e.useAlpha){if(t.material.uniforms.headColor&&t.material.uniforms.tailColor){t.material.uniforms.headColor.value.setW((r.opacityStart??1)*e.alpha);t.material.uniforms.tailColor.value.setW((r.opacityEnd??1)*e.alpha)}null!=t.material.uniforms.opacity&&(t.material.uniforms.opacity.value=e.alpha)}e.useColor&&null!=t.material.uniforms.color&&t.material.uniforms.color.value.copy(e.color),null!=t.material.uniforms[d]&&(t.material.uniforms[d].value=e.energy)}}onParticleDead(e){const t=e.target,r=this.trails.findIndex(e=>e.targetObject.id===t.id);if(-1!=r){const e=this.trails[r];e.removeFromParent(),e.mesh.removeFromParent(),e.targetObject.removeFromParent(),t.removeFromParent(),this.trails.splice(r,1)}}}export class CombinedRenderer extends t{dispose(){}scale(e){const t=e.transform.initialScale;e.target instanceof a.Sprite?null!=t?e.target.scale.set(t.x*e.scale*e.radius,t.y*e.scale*e.radius,1):e.target.scale.set(e.scale*e.radius,e.scale*e.radius,1):null!=t?e.target.scale.set(t.x*e.scale,t.y*e.scale,t.z*e.scale):super.scale(e)}rotate(e){e.target.material.rotation=e.rotation.z}onParticleCreated(e){e.target||(e.target=this._targetPool.get(e.body),(e.useAlpha||e.useColor)&&(e.target instanceof a.Mesh||e.target instanceof a.Sprite&&e.target.material instanceof a.Material)&&(e.target.material.__puid=r.id(e.body.material),e.target.material=this._materialPool.get(e.target.material))),e.target&&e.target instanceof o&&(e.target.position.set(e.position.x,e.position.y,e.position.z),this.container.add(e.target))}onParticleUpdate(e){const{target:t,useAlpha:r,useColor:i,rotation:n}=e;if(t){if(t.position.copy(e.position),this.isThreeSprite(e)||(t instanceof a.Mesh&&t.material instanceof c?e.target.material.rotation=e.rotation.z:t.rotation.set(n.x,n.y,n.z)),this.scale(e),e.transform&&e.transform.orientAlongVelocity&&t instanceof o){const r=h.set(e.velocity.x,e.velocity.y,e.velocity.z).normalize(),a=t.getWorldDirection(p);a.applyAxisAngle(g,Math.PI/-2),f.setFromUnitVectors(a,r),t.quaternion.copy(f)}(r||i)&&this.applyUniforms(t,e)}}applyUniforms(e,t){e instanceof m&&e.traverse(r=>r!==e&&this.applyUniforms(r,t)),e instanceof a.Mesh&&(t.useAlpha&&(e.material instanceof c&&null!=e.material.uniforms.opacity&&(e.material.uniforms.opacity.value=t.alpha),e.material instanceof a.ShaderMaterial&&null!=e.material.uniforms.opacity?e.material.uniforms.opacity.value=t.alpha:e.material.opacity=t.alpha,e.material.transparent=!0),t.useColor&&(null!=e.material.color?e.material.color.copy(t.color):e.material instanceof a.ShaderMaterial&&null!=e.material.uniforms.color&&(e.material.uniforms.color.value=t.color)))}onParticleDead(e){e.target&&(e.target.material&&(e.useAlpha||e.useColor)&&this._materialPool.expire(e.target.material),this._targetPool.expire(e.target),this.container.remove(e.target),e.target=null)}}export class StretchedSpriteInstancedRenderer extends t{constructor(e,t,r){super(e,t),this.view=r,this.meshes=[]}dispose(){this.meshes.forEach(e=>e.mesh.geometry.dispose())}onSystemUpdate(){for(const e of this.meshes){const t=e.mesh.geometry.getAttribute("offset"),r=e.mesh.geometry.getAttribute("size"),i=e.mesh.geometry.getAttribute("velocity"),o=e.mesh.geometry.getAttribute("rotation"),n=e.mesh.geometry.getAttribute("particleColor");let s=0;for(const l of e.particles){if(null==l||l.dead)continue;if(l.useColor||l.color instanceof a.Color){const e=P.copy(l.color).getRGB(v);n.setXYZW(s,e.r,e.g,e.b,1),n.needsUpdate=!0}l.useAlpha&&(n.setW(s,l.alpha),n.needsUpdate=!0),"number"==typeof l.rotation?o.setX(s,l.rotation):o.setX(s,l.rotation.x);const e=l.position;if(t.setXYZ(s,e.x,e.y,e.z),"number"!=typeof l.scale)throw new Error("Particle scale is not a number");r.setXYZ(s,l.scale,l.scale,l.scale);let c=l.body.scaleFactor;0===c&&(c=.001);const d=1,m=l.velocity;i.setXYZW(s,m.x*c,m.y*c,m.z*c,d),s++}s>0&&(t.clearUpdateRanges(),t.addUpdateRange(0,3*s),t.needsUpdate=!0,r.clearUpdateRanges(),r.addUpdateRange(0,3*s),r.needsUpdate=!0,n.clearUpdateRanges(),n.addUpdateRange(0,4*s),n.needsUpdate=!0,i.clearUpdateRanges(),i.addUpdateRange(0,4*s),i.needsUpdate=!0,o.clearUpdateRanges(),o.addUpdateRange(0,s),o.needsUpdate=!0)}}calcMaxCount(e){if(null==e)return 1;const t=e.parent.rate,r=t.timePan.a;if(!Number.isFinite(r)||r<=0)return t.numPan.b*this.calcMaxCount(e.parent.parentParticle);return Math.min(t.numPan.b*Math.ceil(e.life/Math.min(Math.max(t.timePan.a,.01),1)),1e5)*this.calcMaxCount(e.parent.parentParticle)}onParticleCreated(e){if(e.body instanceof s&&null==e.target){const t=e.body;let r=this.meshes.find(e=>e.mesh.material.uuid===t.material.uuid);if(null==r){const o=this.calcMaxCount(e),n=new a.InstancedBufferGeometry;n.setIndex(t.geometry.getIndex()),n.setAttribute("position",t.geometry.getAttribute("position")),t.geometry.hasAttribute("normal")&&n.setAttribute("normal",t.geometry.getAttribute("normal")),n.setAttribute("uv",t.geometry.getAttribute("uv"));const s=new i(new Float32Array(3*o),3);s.setUsage(a.DynamicDrawUsage),n.setAttribute("offset",s);const l=new i(new Float32Array(4*o),4);if(l.setUsage(a.DynamicDrawUsage),n.setAttribute("particleColor",l),t.material instanceof c){const e=new a.Color(t.material.color);for(let t=0;t<l.count;t++)l.setXYZW(t,e.r,e.g,e.b,1)}const d=new i(new Float32Array(3*o),3);d.setUsage(a.DynamicDrawUsage),n.setAttribute("size",d);const m=new i(new Float32Array(4*o),4);m.setUsage(a.DynamicDrawUsage),n.setAttribute("velocity",m);const u=new i(new Float32Array(4*o),1);u.setUsage(a.DynamicDrawUsage),n.setAttribute("rotation",u),r={mesh:new a.Mesh(n,t.material),indices:new Float32Array(o),particles:[]},r.mesh.renderOrder=t.renderOrder,this.meshes.push(r),this.container.add(r.mesh)}let o=r.indices.findIndex(e=>0===e);o<0&&(o=function(e){let t=e[0],r=0;for(let a=1;a<e.length;a++)e[a]<t&&(t=e[a],r=a);return r}(r.indices)),r.indices[o]=performance.now(),e.target=o,r.particles[o]=e}}onParticleUpdate(e){}onParticleDead(e){const t=e.body;let r=this.meshes.find(e=>e.mesh.material.uuid===t.material.uuid);if(r){const t=r.mesh.geometry.getAttribute("size");t.setXYZ(e.target,0,0,0),t.needsUpdate=!0,r.particles[e.target]=null,r.indices[e.target]=0}e.target=null}}const h=new a.Vector3,p=new a.Vector3,f=new a.Quaternion,g=new a.Vector3(1,0,0);export class InstancedRenderer extends t{constructor(e,t,r){super(e,t),this.view=r,this.meshes=[]}dispose(){this.meshes.forEach(e=>e.mesh.dispose())}onSystemUpdate(){for(const e of this.meshes);}calcMaxCount(e){if(null==e)return 1;const t=e.parent.rate,r=t.timePan.a;if(!Number.isFinite(r)||r<=0)return t.numPan.b*this.calcMaxCount(e.parent.parentParticle);return Math.min(t.numPan.b*Math.ceil(e.life/Math.min(Math.max(t.timePan.a,.01),1)),1e5)*this.calcMaxCount(e.parent.parentParticle)}onParticleCreated(e){if(e.body instanceof a.Sprite)return;const t=e.body;let r=this.meshes.find(e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid);if(null==r){const i=this.calcMaxCount(e);r={mesh:new a.InstancedMesh(t.geometry,t.material,i),indices:new Array(i).fill(null),particles:[]},r.mesh.renderOrder=t.renderOrder,r.mesh.userData.webGpuCacheMaterial=!0;const o=new Float32Array(4*i);o.fill(1),r.mesh.instanceColor=new a.InstancedBufferAttribute(o,4),r.mesh.setColorAt(0,P.setScalar(1)),r.mesh.instanceColor.needsUpdate=!0,r.mesh.material.defines.USE_INSTANCING="",r.mesh.material.needsUpdate=!0;const n=new Float32Array(3*i);x.makeScale(0,0,0);for(let e=0;e<i;e++)n[3*e+0]=1,n[3*e+1]=1,n[3*e+2]=1,r.mesh.instanceMatrix.array.set(x.elements,16*e);r.mesh.instanceMatrix.needsUpdate=!0,r.mesh.geometry.setAttribute("particleData",new a.InstancedBufferAttribute(n,3)),this.meshes.push(r),this.container.add(r.mesh)}let i=r.indices.findIndex(e=>null==e);if(i<0&&(i=r.indices.indexOf(Math.min(...r.indices))),r.indices[i]=performance.now(),e.target=i,r.particles[i]=e,"number"==typeof e.target){e.transform.initialScale;const t=e.body;let r=this.meshes.find(e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid);b(e,r.mesh),e.useAlpha&&(r.mesh.material.transparent||(r.mesh.material.transparent=!0,r.mesh.material.needsUpdate=!0))}}onParticleUpdate(e){const{target:t,useAlpha:r,useColor:a,rotation:i}=e;if(null==t)return;const o=e.body,n=this.meshes.find(e=>e.mesh.geometry.uuid===o.geometry.uuid&&e.mesh.material.uuid===o.material.uuid);if(null==n)return;if(n.mesh.frustumCulled=!1,b(e,n.mesh),a){P.copy(e.color);const t=n.mesh.instanceColor.array,r=e.target*n.mesh.instanceColor.itemSize;t[r+0]=P.r,t[r+1]=P.g,t[r+2]=P.b,n.mesh.instanceColor.itemSize>=4&&(t[r+3]=1),n.mesh.instanceColor.needsUpdate=!0}const s=n.mesh.geometry.getAttribute("particleData");r&&s.setX(e.target,e.alpha),s.setY(e.target,e.energy),s.needsUpdate=!0}onParticleDead(e){if(null!=e.target){const t=e.body,r=this.meshes.find(e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid);if(null==r)return;r.indices[e.target]=null,e.scale=0,b(e,r.mesh),r.mesh.instanceMatrix.needsUpdate=!0,e.target=null}}}const y=new o;function b(e,t){if(U.set(e.position.x,e.position.y,e.position.z),e.transform&&e.transform.orientAlongVelocity){const r=h.set(e.position.x-e.old.position.x,e.position.y-e.old.position.y,e.position.z-e.old.position.z).normalize();t.getMatrixAt(e.target,y.matrix);const a=y.getWorldDirection(A);a.applyAxisAngle(g,Math.PI/-2),C.setFromUnitVectors(a,r)}else M.set(e.rotation.x,e.rotation.y,e.rotation.z),C.setFromEuler(M);const r=e.transform.initialScale;null!=r?A.set(r.x*e.scale,r.y*e.scale,r.z*e.scale):A.set(e.scale,e.scale,e.scale),x.compose(U,C,A),t.instanceMatrix.array.set(x.elements,16*e.target),t.instanceMatrix.needsUpdate=!0}const w=new a.Vector3(0,0,-1),x=new a.Matrix4,C=new a.Quaternion,U=new a.Vector3,A=new a.Vector3,M=new a.Euler,P=new a.Color(0),v={r:0,g:0,b:0};function R(e,t){const r=e.mesh,i=r.count,o=[],n=r.geometry.getAttribute("particleData"),s=new a.Vector3;for(let l=0;l<i;l++){const i=new a.Matrix4,c=new a.Color;r.getMatrixAt(l,i),r.getColorAt(l,c);const d=n.getX(l);s.setFromMatrixPosition(i);const m=s.distanceTo(t.position);o.push({index:l,distance:m,matrix:i,particle:e.particles[l],color:c,pdx:d})}o.sort((e,t)=>t.distance-e.distance);for(let e=0;e<i;e++){const t=o[e].matrix;null==o[e].particle&&t.makeScale(0,0,0),r.setMatrixAt(e,t),r.setColorAt(e,o[e].color),n.setX(e,o[e].pdx)}r.instanceMatrix.needsUpdate=!0}export{R as sortInstancedMeshByDistance};/*
1
+ import{CustomRenderer as e,MeshRenderer as t,PUID as r}from"@hology/nebula";import*as a from"three";import{InstancedBufferAttribute as o,Object3D as n}from"three";import{NodeShaderMaterial as i}from"three-shader-graph";import{StretchedSprite as s}from"./stretched-sprite.js";import{Trail as l}from"./trail-renderer.js";import{SpriteNodeShaderMaterial as c}from"../../shader/sprite-shader";import{particleEnergyUniformName as d}from"../../shader-nodes/particle";import{AssetMeshInstance as m}from"../../scene/asset-resource-loader.js";import{markMaterialUniformValuesNeedUpdate as u}from"../../rendering/node-material-webgpu-resolver.js";var h;!function(e){e[e.mesh=0]="mesh",e[e.instanced=1]="instanced",e[e.sprite=2]="sprite",e[e.stretchedBillboard=3]="stretchedBillboard",e[e.trail=4]="trail"}(h||(h={}));export class MultiRenderer extends e{constructor(e,t,r,a){super(),this.worldContainer=e,this.localContainer=t,this.three=r,this.view=a,this.localRenderers=[],this.worldRenderers=[]}onSystemUpdate(){for(const e of this.worldRenderers)e?.onSystemUpdate();for(const e of this.localRenderers)e?.onSystemUpdate()}onParticleCreated(e){e.target=null,this.getRenderer(e)?.onParticleCreated(e)}onParticleUpdate(e){this.getRenderer(e)?.onParticleUpdate(e)}onParticleDead(e){this.getRenderer(e)?.onParticleDead(e),e._renderer=null}getRenderer(e){if(e._renderer)return e._renderer;const t=(null!=e?.parent?e?.parent._space:null)??"world",r="world"===t?this.worldContainer:this.localContainer,o="world"===t?this.worldRenderers:this.localRenderers;return"trail"===e.body.type?(null==o[h.trail]&&(o[h.trail]=new TrailRenderer(r,this.three)),e._renderer=o[h.trail]):e.body instanceof s?(null==o[h.stretchedBillboard]&&(o[h.stretchedBillboard]=new StretchedSpriteInstancedRenderer(r,this.three,this.view)),e._renderer=o[h.stretchedBillboard]):e.body instanceof a.Sprite?(null==o[h.sprite]&&(o[h.sprite]=new CombinedRenderer(r,this.three)),e._renderer=o[h.sprite]):e.body instanceof a.Mesh&&0==e.body.children.length&&e.body.material instanceof i?(null==o[h.instanced]&&(o[h.instanced]=new InstancedRenderer(r,this.three,this.view)),e._renderer=o[h.instanced]):e.body instanceof a.Object3D?(null==o[h.mesh]&&(o[h.mesh]=new CombinedRenderer(r,this.three)),e._renderer=o[h.mesh]):void 0}dispose(){this.localRenderers.forEach(e=>{e instanceof InstancedRenderer&&e.dispose()}),this.worldRenderers.forEach(e=>{e instanceof InstancedRenderer&&e.dispose()})}}export class TrailRenderer extends t{constructor(){super(...arguments),this.trails=[]}dispose(){}onSystemUpdate(){for(const e of this.trails)e.update()}onParticleCreated(e){const t=e.body,r=new l(this.container,!1),o=new n;this.container.add(o),o.updateMatrixWorld(),o.updateWorldMatrix(!0,!0);const i=t.material?.clone()??l.createBaseMaterial(t.texture,t.scrollSpeed,t.opacityChannel,t.billboard??!1);i.uniforms.taper&&(i.uniforms.taper.value=t.taper??!1);const s=new a.Color(t.color??0).multiplyScalar(t.intensity??1),c=new a.Color(t.colorEnd??0).multiplyScalar(t.intensityEnd??t.intensity??1);i.uniforms.headColor&&i.uniforms.tailColor&&(i.uniforms.headColor.value=new a.Vector4(s.r,s.g,s.b,t.opacityStart??1),i.uniforms.tailColor.value=new a.Vector4(c.r,c.g,c.b,t.opacityEnd??1)),i.uniforms.color&&null==i.uniforms.headColor&&(i.uniforms.color.value=s),i.uniforms.opacity&&null==i.uniforms.headColor&&(i.uniforms.opacity.value=t.opacityStart??1),t.bloom&&(i.userData.hasBloom=!0),r.initialize(i,Math.round(t.length??10),!1,t.width,null,o,t.billboard??!1),null!=t.renderOrder&&null!=r.mesh&&(r.mesh.renderOrder=t.renderOrder);const d=e.rotation;o.rotation.set(d.x,d.y,d.z);e.scale;r.activate(),this.trails.push(r),e.target=o}onParticleUpdate(e){const t=e.target;t.position.copy(e.position);const r=e.body;let a=v;e.old&&e.old.position?a.set(e.position.x-e.old.position.x,e.position.y-e.old.position.y,e.position.z-e.old.position.z):a.copy(e.velocity),a.lengthSq()>1e-8?a.normalize():a.copy(U);const o=P;o.setFromUnitVectors(a,U),t.rotation.set(0,0,0),t.rotation.set(e.rotation.x,e.rotation.y,e.rotation.z),t.applyQuaternion(o);const n=this.trails.findIndex(e=>e.targetObject.id===t.id);if(-1!=n){const t=this.trails[n];if(e.useAlpha){if(t.material.uniforms.headColor&&t.material.uniforms.tailColor){t.material.uniforms.headColor.value.setW((r.opacityStart??1)*e.alpha);t.material.uniforms.tailColor.value.setW((r.opacityEnd??1)*e.alpha)}null!=t.material.uniforms.opacity&&(t.material.uniforms.opacity.value=e.alpha)}e.useColor&&null!=t.material.uniforms.color&&t.material.uniforms.color.value.copy(e.color),null!=t.material.uniforms[d]&&(t.material.uniforms[d].value=e.energy),u(t.material)}}onParticleDead(e){const t=e.target,r=this.trails.findIndex(e=>e.targetObject.id===t.id);if(-1!=r){const e=this.trails[r];e.removeFromParent(),e.mesh.removeFromParent(),e.targetObject.removeFromParent(),t.removeFromParent(),this.trails.splice(r,1)}}}export class CombinedRenderer extends t{dispose(){}scale(e){const t=e.transform.initialScale;e.target instanceof a.Sprite?null!=t?e.target.scale.set(t.x*e.scale*e.radius,t.y*e.scale*e.radius,1):e.target.scale.set(e.scale*e.radius,e.scale*e.radius,1):null!=t?e.target.scale.set(t.x*e.scale,t.y*e.scale,t.z*e.scale):super.scale(e)}rotate(e){e.target.material.rotation=e.rotation.z}onParticleCreated(e){e.target||(e.target=this._targetPool.get(e.body),(e.useAlpha||e.useColor)&&(e.target instanceof a.Mesh||e.target instanceof a.Sprite&&e.target.material instanceof a.Material)&&(e.target.material.__puid=r.id(e.body.material),e.target.material=this._materialPool.get(e.target.material))),e.target&&e.target instanceof n&&(e.target.position.set(e.position.x,e.position.y,e.position.z),this.container.add(e.target))}onParticleUpdate(e){const{target:t,useAlpha:r,useColor:o,rotation:i}=e;if(t){if(t.position.copy(e.position),this.isThreeSprite(e)||(t instanceof a.Mesh&&t.material instanceof c?e.target.material.rotation=e.rotation.z:t.rotation.set(i.x,i.y,i.z)),this.scale(e),e.transform&&e.transform.orientAlongVelocity&&t instanceof n){const r=p.set(e.velocity.x,e.velocity.y,e.velocity.z).normalize(),a=t.getWorldDirection(f);a.applyAxisAngle(y,Math.PI/-2),g.setFromUnitVectors(a,r),t.quaternion.copy(g)}(r||o)&&this.applyUniforms(t,e)}}applyUniforms(e,t){if(e instanceof m&&e.traverse(r=>r!==e&&this.applyUniforms(r,t)),e instanceof a.Mesh){let r=!1;t.useAlpha&&(e.material instanceof c&&null!=e.material.uniforms.opacity&&(e.material.uniforms.opacity.value=t.alpha,r=!0),e.material instanceof a.ShaderMaterial&&null!=e.material.uniforms.opacity?(e.material.uniforms.opacity.value=t.alpha,r=!0):(e.material.opacity=t.alpha,r=!0),e.material.transparent=!0),t.useColor&&(null!=e.material.color?(e.material.color.copy(t.color),r=!0):e.material instanceof a.ShaderMaterial&&null!=e.material.uniforms.color&&(e.material.uniforms.color.value=t.color,r=!0)),r&&u(e.material)}}onParticleDead(e){e.target&&(e.target.material&&(e.useAlpha||e.useColor)&&this._materialPool.expire(e.target.material),this._targetPool.expire(e.target),this.container.remove(e.target),e.target=null)}}export class StretchedSpriteInstancedRenderer extends t{constructor(e,t,r){super(e,t),this.view=r,this.meshes=[]}dispose(){this.meshes.forEach(e=>e.mesh.geometry.dispose())}onSystemUpdate(){for(const e of this.meshes){const t=e.mesh.geometry.getAttribute("offset"),r=e.mesh.geometry.getAttribute("size"),o=e.mesh.geometry.getAttribute("velocity"),n=e.mesh.geometry.getAttribute("rotation"),i=e.mesh.geometry.getAttribute("particleColor");let s=0;for(const l of e.particles){if(null==l||l.dead)continue;if(l.useColor||l.color instanceof a.Color){const e=S.copy(l.color).getRGB(z);i.setXYZW(s,e.r,e.g,e.b,1),i.needsUpdate=!0}l.useAlpha&&(i.setW(s,l.alpha),i.needsUpdate=!0),"number"==typeof l.rotation?n.setX(s,l.rotation):n.setX(s,l.rotation.x);const e=l.position;if(t.setXYZ(s,e.x,e.y,e.z),"number"!=typeof l.scale)throw new Error("Particle scale is not a number");r.setXYZ(s,l.scale,l.scale,l.scale);let c=l.body.scaleFactor;0===c&&(c=.001);const d=1,m=l.velocity;o.setXYZW(s,m.x*c,m.y*c,m.z*c,d),s++}s>0&&(t.clearUpdateRanges(),t.addUpdateRange(0,3*s),t.needsUpdate=!0,r.clearUpdateRanges(),r.addUpdateRange(0,3*s),r.needsUpdate=!0,i.clearUpdateRanges(),i.addUpdateRange(0,4*s),i.needsUpdate=!0,o.clearUpdateRanges(),o.addUpdateRange(0,4*s),o.needsUpdate=!0,n.clearUpdateRanges(),n.addUpdateRange(0,s),n.needsUpdate=!0)}}calcMaxCount(e){if(null==e)return 1;const t=e.parent.rate,r=t.timePan.a;if(!Number.isFinite(r)||r<=0)return t.numPan.b*this.calcMaxCount(e.parent.parentParticle);return Math.min(t.numPan.b*Math.ceil(e.life/Math.min(Math.max(t.timePan.a,.01),1)),1e5)*this.calcMaxCount(e.parent.parentParticle)}onParticleCreated(e){if(e.body instanceof s&&null==e.target){const t=e.body;let r=this.meshes.find(e=>e.mesh.material.uuid===t.material.uuid);if(null==r){const n=this.calcMaxCount(e),i=new a.InstancedBufferGeometry;i.setIndex(t.geometry.getIndex()),i.setAttribute("position",t.geometry.getAttribute("position")),t.geometry.hasAttribute("normal")&&i.setAttribute("normal",t.geometry.getAttribute("normal")),i.setAttribute("uv",t.geometry.getAttribute("uv"));const s=new o(new Float32Array(3*n),3);s.setUsage(a.DynamicDrawUsage),i.setAttribute("offset",s);const l=new o(new Float32Array(4*n),4);if(l.setUsage(a.DynamicDrawUsage),i.setAttribute("particleColor",l),t.material instanceof c){const e=new a.Color(t.material.color);for(let t=0;t<l.count;t++)l.setXYZW(t,e.r,e.g,e.b,1)}const d=new o(new Float32Array(3*n),3);d.setUsage(a.DynamicDrawUsage),i.setAttribute("size",d);const m=new o(new Float32Array(4*n),4);m.setUsage(a.DynamicDrawUsage),i.setAttribute("velocity",m);const u=new o(new Float32Array(4*n),1);u.setUsage(a.DynamicDrawUsage),i.setAttribute("rotation",u),r={mesh:new a.Mesh(i,t.material),indices:new Float32Array(n),particles:[]},r.mesh.renderOrder=t.renderOrder,this.meshes.push(r),this.container.add(r.mesh)}let n=r.indices.findIndex(e=>0===e);n<0&&(n=function(e){let t=e[0],r=0;for(let a=1;a<e.length;a++)e[a]<t&&(t=e[a],r=a);return r}(r.indices)),r.indices[n]=performance.now(),e.target=n,r.particles[n]=e}}onParticleUpdate(e){}onParticleDead(e){const t=e.body;let r=this.meshes.find(e=>e.mesh.material.uuid===t.material.uuid);if(r){const t=r.mesh.geometry.getAttribute("size");t.setXYZ(e.target,0,0,0),t.needsUpdate=!0,r.particles[e.target]=null,r.indices[e.target]=0}e.target=null}}const p=new a.Vector3,f=new a.Vector3,g=new a.Quaternion,y=new a.Vector3(1,0,0),b=1e5;function w(e){return Number.isFinite(e)?Math.min(Math.max(Math.ceil(e),1),b):b}export class InstancedRenderer extends t{constructor(e,t,r){super(e,t),this.view=r,this.meshes=[]}dispose(){this.meshes.forEach(e=>e.mesh.dispose())}onSystemUpdate(){for(const e of this.meshes)e.mesh.material.transparent&&e.mesh.material.blending===a.NormalBlending&&F(e,this.view.getCamera())}calcMaxCount(e){if(null==e)return 1;const t=e.parent.rate,r=t.timePan.a,a=t.numPan.b,o=e.parent.parentParticle;if(!Number.isFinite(r)||r<=0)return w(a*this.calcMaxCount(o));return w(a*Math.ceil(e.life/Math.min(Math.max(r,.01),1))*this.calcMaxCount(o))}onParticleCreated(e){if(e.body instanceof a.Sprite)return;const t=e.body;let r=this.meshes.find(e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid);if(null==r){const o=this.calcMaxCount(e);r={mesh:new a.InstancedMesh(t.geometry,t.material,o),indices:new Array(o).fill(null),particles:[],sortOrder:new Array(o),sortDistances:new Float32Array(o),sortedMatrices:new Float32Array(16*o),sortedColors:new Float32Array(4*o),sortedParticleData:new Float32Array(3*o),sortedRotations:new Float32Array(o),sortedParticles:new Array(o),sortedIndices:new Array(o)},r.mesh.renderOrder=t.renderOrder,r.mesh.userData.webGpuCacheMaterial=!0;const n=new Float32Array(4*o);n.fill(1),r.mesh.instanceColor=new a.InstancedBufferAttribute(n,4),r.mesh.setColorAt(0,S.setScalar(1)),r.mesh.instanceColor.needsUpdate=!0,r.mesh.material.defines.USE_INSTANCING="",r.mesh.material.needsUpdate=!0;const i=new Float32Array(3*o);M.makeScale(0,0,0);for(let e=0;e<o;e++)i[3*e+0]=1,i[3*e+1]=1,i[3*e+2]=1,r.mesh.instanceMatrix.array.set(M.elements,16*e);r.mesh.instanceMatrix.needsUpdate=!0,r.mesh.geometry.setAttribute("particleData",new a.InstancedBufferAttribute(i,3));const s=new a.InstancedBufferAttribute(new Float32Array(o),1);s.setUsage(a.DynamicDrawUsage),r.mesh.geometry.setAttribute("rotation",s),this.meshes.push(r),this.container.add(r.mesh)}let o=r.indices.findIndex(e=>null==e);if(o<0&&(o=r.indices.indexOf(Math.min(...r.indices))),o<0||o>=r.mesh.instanceMatrix.count)return void(e.target=null);const n=r.particles[o];if(null!=n&&n!==e&&(n.target=null),r.indices[o]=performance.now(),e.target=o,r.particles[o]=e,r.mesh.count<=o&&(r.mesh.count=o+1),"number"==typeof e.target){e.transform.initialScale;const t=e.body;let r=this.meshes.find(e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid);C(e,r.mesh),e.useAlpha&&(r.mesh.material.transparent||(r.mesh.material.transparent=!0,r.mesh.material.needsUpdate=!0))}}onParticleUpdate(e){const{target:t,useAlpha:r,useColor:a,rotation:o}=e;if(null==t)return;const n=e.body,i=this.meshes.find(e=>e.mesh.geometry.uuid===n.geometry.uuid&&e.mesh.material.uuid===n.material.uuid);if(null==i)return;if(!A(i,e))return void(e.target=null);if(i.mesh.frustumCulled=!1,C(e,i.mesh),a){S.copy(e.color);const t=i.mesh.instanceColor.array,r=e.target*i.mesh.instanceColor.itemSize;t[r+0]=S.r,t[r+1]=S.g,t[r+2]=S.b,i.mesh.instanceColor.itemSize>=4&&(t[r+3]=1),i.mesh.instanceColor.needsUpdate=!0}const s=i.mesh.geometry.getAttribute("particleData");r&&s.setX(e.target,e.alpha),s.setY(e.target,e.energy),s.needsUpdate=!0;const l=i.mesh.geometry.getAttribute("rotation");l.setX(e.target,o.z),l.needsUpdate=!0}onParticleDead(e){if(null!=e.target){const t=e.body,r=this.meshes.find(e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid);if(null==r)return;if(!A(r,e))return void(e.target=null);r.indices[e.target]=null,r.particles[e.target]=null,e.scale=0,C(e,r.mesh),r.mesh.instanceMatrix.needsUpdate=!0,e.target=null}}}const x=new n;function A(e,t){const r=t.target;return"number"==typeof r&&Number.isInteger(r)&&r>=0&&r<e.mesh.instanceMatrix.count&&e.particles[r]===t}function C(e,t){if(!Number.isInteger(e.target)||e.target<0||e.target>=t.instanceMatrix.count)return;if(v.set(e.position.x,e.position.y,e.position.z),e.transform&&e.transform.orientAlongVelocity){const r=p.set(e.position.x-e.old.position.x,e.position.y-e.old.position.y,e.position.z-e.old.position.z).normalize();t.getMatrixAt(e.target,x.matrix);const a=x.getWorldDirection(R);a.applyAxisAngle(y,Math.PI/-2),P.setFromUnitVectors(a,r)}else D.set(e.rotation.x,e.rotation.y,e.rotation.z),P.setFromEuler(D);const r=e.transform.initialScale;null!=r?R.set(r.x*e.scale,r.y*e.scale,r.z*e.scale):R.set(e.scale,e.scale,e.scale),M.compose(v,P,R),t.instanceMatrix.array.set(M.elements,16*e.target),t.instanceMatrix.needsUpdate=!0}const U=new a.Vector3(0,0,-1),M=new a.Matrix4,P=new a.Quaternion,v=new a.Vector3,R=new a.Vector3,D=new a.Euler,S=new a.Color(0),z={r:0,g:0,b:0};function F(e,t){const r=e.mesh,a=r.instanceMatrix.array,o=r.instanceColor.array,n=r.geometry.getAttribute("particleData"),i=n.array,s=r.geometry.getAttribute("rotation"),l=s.array,c=r.worldToLocal(t.getWorldPosition(I));let d=0;for(let t=0;t<e.particles.length;t++){if(null==e.particles[t])continue;const r=16*t,o=a[r+12]-c.x,n=a[r+13]-c.y,i=a[r+14]-c.z;e.sortDistances[t]=o*o+n*n+i*i,e.sortOrder[d++]=t}e.sortOrder.length=d,e.sortOrder.sort((t,r)=>e.sortDistances[r]-e.sortDistances[t]);for(let t=0;t<d;t++){const r=e.sortOrder[t];for(let o=0;o<16;o++)e.sortedMatrices[16*t+o]=a[16*r+o];for(let a=0;a<4;a++)e.sortedColors[4*t+a]=o[4*r+a];for(let a=0;a<3;a++)e.sortedParticleData[3*t+a]=i[3*r+a];e.sortedRotations[t]=l[r],e.sortedParticles[t]=e.particles[r],e.sortedIndices[t]=e.indices[r]}for(let t=0;t<d;t++){const r=e.sortedParticles[t];e.particles[t]=r,e.indices[t]=e.sortedIndices[t],l[t]=e.sortedRotations[t],r.target=t}for(let t=d;t<e.indices.length;t++)e.particles[t]=null,e.indices[t]=null;for(let t=0;t<16*d;t++)a[t]=e.sortedMatrices[t];for(let t=0;t<4*d;t++)o[t]=e.sortedColors[t];for(let t=0;t<3*d;t++)i[t]=e.sortedParticleData[t];r.count=d,r.instanceMatrix.needsUpdate=!0,r.instanceColor.needsUpdate=!0,n.needsUpdate=!0,s.needsUpdate=!0}export{F as sortInstancedMeshByDistance};const I=new a.Vector3;/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,6 +1,11 @@
1
1
  import { Constructable } from 'typedi';
2
2
  import { BaseActor } from './actor.js';
3
3
  export { getComponentClassById, getComponentClassId, getRegisteredComponentClasses, } from './type-registry.js';
4
+ export type ActorComponentParams<T extends ActorComponent> = {
5
+ [K in Exclude<keyof T, keyof ActorComponent> as T[K] extends (...args: any[]) => any ? never : K]: T[K];
6
+ };
7
+ type ActorComponentParamKey<T extends ActorComponent> = Extract<keyof ActorComponentParams<T>, string>;
8
+ export type ActorComponentParamSet<T extends ActorComponent> = Set<ActorComponentParamKey<T>>;
4
9
  export declare abstract class ActorComponent<ActorType extends BaseActor = BaseActor> {
5
10
  actor: ActorType;
6
11
  constructor();
@@ -12,7 +17,7 @@ export declare abstract class ActorComponent<ActorType extends BaseActor = BaseA
12
17
  * actor. Return true only when every supplied change was applied. Returning
13
18
  * false means unsupported and must leave the component unchanged.
14
19
  */
15
- applySceneParameters(parameters: Record<string, unknown>, changedParameters: ReadonlySet<string>): boolean | Promise<boolean>;
20
+ applySceneParameters(parameters: ActorComponentParams<ActorComponent>, changedParameters: ActorComponentParamSet<ActorComponent>): boolean | Promise<boolean>;
16
21
  /**
17
22
  * Code that has to run before every rendered frame. This will run after the
18
23
  * actor's onInit method has run.
@@ -5,7 +5,7 @@ export * from './inject.js';
5
5
  export { Service, Inject } from 'typedi';
6
6
  export { ActorFactory } from './actors/factory.js';
7
7
  export { Actor, BaseActor, getActorClassById, getActorClassId, getRegisteredActorClasses } from './actors/actor.js';
8
- export { Component, ActorComponent, type ComponentOptions, attach, Attach, getComponentClassById, getComponentClassId, getRegisteredComponentClasses } from './actors/component.js';
8
+ export { Component, ActorComponent, type ComponentOptions, attach, Attach, getComponentClassById, getComponentClassId, getRegisteredComponentClasses, ActorComponentParams, ActorComponentParamSet } from './actors/component.js';
9
9
  export * from './services/world.js';
10
10
  export * from './services/game-time-scheduler.js';
11
11
  export * from './services/camera-shake.js';
@@ -8,6 +8,9 @@ type ResolvedWebGpuMaterial = THREE.Material & {
8
8
  readonly pointShadowVertexShader: string | null;
9
9
  readonly pointShadowFragmentShader: string | null;
10
10
  readonly vertexAttributes: readonly WebGpuMaterialVertexAttribute[];
11
+ uniformValuesAutoUpdate: boolean;
12
+ readonly uniformValuesAutoVersion: number;
13
+ uniformValuesNeedsUpdate: boolean;
11
14
  uniforms: Record<string, {
12
15
  value: WebGpuMaterialUniformValue;
13
16
  }>;
@@ -25,6 +28,7 @@ export interface NodeMaterialWebGpuModule {
25
28
  sceneTextures?: Record<string, 'sceneColor' | 'sceneDepth'>;
26
29
  graphTextures?: Record<string, WgslGraphTextureBinding>;
27
30
  vertexAttributes?: readonly WebGpuMaterialVertexAttribute[];
31
+ uniformValuesAutoUpdate?: boolean;
28
32
  transparent?: boolean;
29
33
  alphaTest?: number;
30
34
  depthTest?: boolean;
@@ -33,6 +37,8 @@ export interface NodeMaterialWebGpuModule {
33
37
  wireframe?: boolean;
34
38
  }) => ResolvedWebGpuMaterial;
35
39
  }
40
+ export declare function setMaterialUniformValuesAutoUpdate(material: THREE.Material, enabled: boolean): void;
41
+ export declare function markMaterialUniformValuesNeedUpdate(material: THREE.Material): void;
36
42
  export declare function withThreeDefaultVertexAttributeValues(attributes: readonly WebGpuMaterialVertexAttribute[]): readonly WebGpuMaterialVertexAttribute[];
37
43
  export interface ResolvedWorldEnvironment {
38
44
  readonly texture: THREE.Texture;
@@ -1,4 +1,4 @@
1
- import*as e from"three";import{compileNodeWebGpuFullscreen as a,compileNodeShaderMaterialForWebGpu as t,NodeShaderMaterial as n,webGpuRendererBindings as i,textureSampler2d as s}from"three-shader-graph";import{StandardShader as o}from"../shader/builtin/standard-shader.js";import{LambertShader as r}from"../shader/builtin/lambert-shader.js";import{ToonShader as l}from"../shader/builtin/toon-shader.js";import{UnlitShader as p}from"../shader/builtin/unlit-shader.js";import{SpriteShader as u}from"../shader/sprite-shader.js";import{elapsedTimeUniformName as m}from"../shader-nodes/time.js";import{depthUniformName as h,farUniformName as c,nearUniformName as d,resolutionUniformName as M,sceneNormalUniformName as f}from"../shader-nodes/depth.js";import{sceneMapUniformName as v}from"../shader-nodes/scene-sample.js";const y={...i,uniformExpressions:{...i.uniformExpressions,[m]:{type:"float",expression:"rendererElapsedTime()"},[d]:{type:"float",expression:"rendererCameraNear()"},[c]:{type:"float",expression:"rendererCameraFar()"},[M]:{type:"vec2",expression:"rendererCamera.viewportAndTime.xy"}},sceneTextures:{[v]:{semantic:"sceneColor",sampleType:"float"},[h]:{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]}}};export function withThreeDefaultVertexAttributeValues(e){return e.map(e=>"uv1"===e.name&&null==e.defaultValue?{...e,defaultValue:[0,0]}:e)}const g=new WeakMap,w=new WeakMap;export function createNodeMaterialSignature(e){const a=w.get(e);if(null!=a)return a;const t=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 w.set(e,t),t}export class NodeMaterialWebGpuResolver{constructor(e,a){this.webGpu=e,this.mrtResolver=a,this.cache=new WeakMap,this.failedSignatures=new WeakMap,this.mappedMaterialsCache=new WeakMap,this.mappedMaterialsSignatures=new WeakMap,this.observedNodeMaterials=new Map,this.worldEnvironmentMaterials=new WeakSet,this.worldEnvironment=null,this.worldEnvironmentTexture=null,this.worldEnvironmentIntensity=0,this.worldEnvironmentRevision=0,this.cacheValues=new Set}setWorldEnvironment(e){const a=e?.texture??null,t=e?.intensity??0;if(this.worldEnvironmentTexture!==a||this.worldEnvironmentIntensity!==t){if(this.worldEnvironmentTexture!==a)this.worldEnvironmentRevision++;else if(null!=e)for(const e of this.cacheValues)e.inheritsWorldEnvironment&&null!=e.material.uniforms.envMapIntensity&&(e.material.uniforms.envMapIntensity.value=t);this.worldEnvironment=e,this.worldEnvironmentTexture=a,this.worldEnvironmentIntensity=t}}resolve(a,i=void 0){let s,o=!1;if(a instanceof n)s=a,this.observeNodeMaterial(s);else{const t=this.getOrCreateMappedNodeMaterial(a);if(null==t)return;!function(a,t){if(a instanceof e.SpriteMaterial){const n=t;t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),n.rotation=a.rotation,n.screenSpaceSize=a.sizeAttenuation?0:1}else a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.roughness&&(t.uniforms.roughness.value=a.roughness),t.uniforms.metalness&&(t.uniforms.metalness.value=a.metalness),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity),t.uniforms.envMapIntensity&&(t.uniforms.envMapIntensity.value=a.envMapIntensity)):a instanceof e.MeshLambertMaterial||a instanceof e.MeshToonMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity)):a instanceof e.MeshBasicMaterial||a instanceof e.LineBasicMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),a instanceof e.MeshBasicMaterial&&(t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity))):a instanceof e.MeshPhongMaterial&&(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.roughness&&(t.uniforms.roughness.value=Math.max(0,1-a.shininess/100)),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity))}(a,t),s=t,o=!0}s.visible=a.visible;const r=i??"default",l=this.cache.get(s),p=l?.get(r);if(o&&null!=p&&p.sourceVersion===a.version&&p.worldEnvironmentRevision===this.worldEnvironmentRevision)return this.syncInheritedWorldEnvironmentSource(s,p),p.compiled.syncLiveUniforms(p.material.uniforms),I(s,p.material.uniforms),S(s,p.material),p.material;if(!o&&null!=p&&p.sourceVersion===a.version&&p.worldEnvironmentRevision===this.worldEnvironmentRevision&&x(s,p.compiled))return this.syncInheritedWorldEnvironmentSource(s,p),p.compiled.syncLiveUniforms(p.material.uniforms),I(s,p.material.uniforms),S(s,p.material),p.material;const u=this.prepareWorldEnvironment(s),m=this.getNodeMaterialSignature(s,u);if(p?.signature===m&&x(s,p.compiled))return p.compiled.syncLiveUniforms(p.material.uniforms),I(s,p.material.uniforms),S(s,p.material),p.sourceVersion=a.version,p.worldEnvironmentRevision=this.worldEnvironmentRevision,p.material;try{const e=this.mrtResolver?.(s,i),n=t(s,y,e),o=new this.webGpu.WGSLShaderMaterial({vertexShader:n.vertexShader,fragmentShader:n.fragmentShader,depthVertexShader:n.depthVertexShader,depthFragmentShader:n.depthFragmentShader,pointShadowVertexShader:n.pointShadowVertexShader,pointShadowFragmentShader:n.pointShadowFragmentShader,uniforms:n.uniforms,textures:n.textures,sceneTextures:n.sceneTextures,graphTextures:n.graphTextures,vertexAttributes:withThreeDefaultVertexAttributeValues(n.vertexAttributes),transparent:n.renderState?.transparent,alphaTest:n.renderState?.alphaTest,depthTest:n.renderState?.depthTest,depthWrite:n.renderState?.depthWrite,side:n.renderState?.side,wireframe:s.wireframe});!function(e,a){if(null==e)return;Object.assign(a,e)}(n.renderState,o),null!=p&&(p.material.dispose(),this.cacheValues.delete(p));const h={signature:m,compiled:n,material:o,inheritsWorldEnvironment:u,sourceVersion:a.version,worldEnvironmentRevision:this.worldEnvironmentRevision},c=l??new Map;return c.set(r,h),this.cache.set(s,c),this.cacheValues.add(h),I(s,o.uniforms),S(s,o),o}catch(e){let a=this.failedSignatures.get(s);if(null==a&&(a=new Map,this.failedSignatures.set(s,a)),a.get(r)!==m){a.set(r,m);const t=e instanceof Error?e.message:String(e),n=s.name||s.uuid;console.warn(`[Hology WebGPU experiment] Falling back for NodeShaderMaterial "${n}": ${t}`,{material:s,error:e})}return}}compileFullscreen(e){const t=a({color:e.outputColor,wgslBindings:{...y,uniformExpressions:{},graphTextures:{...y.graphTextures,[f]:{resource:"hologyNormalRoughness",dimension:"2d",sampleType:"float",sampler:"filtering"}}}}),n=t.syncLiveUniforms;return{...t,syncLiveUniforms(a){n(a),I(e,a)}}}getOrCreateMappedNodeMaterial(a){const t=function(a){const t=[a.vertexColors,a.transparent,a.alphaTest,a.side,a.depthTest,a.depthWrite,a.wireframe??!1];a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.roughnessMap?a.roughnessMap.uuid:null,a.metalnessMap?a.metalnessMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshLambertMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshToonMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.gradientMap?a.gradientMap.uuid:null):a instanceof e.MeshBasicMaterial?t.push(a.map?a.map.uuid:null,a.aoMap?a.aoMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshPhongMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.SpriteMaterial&&t.push(a.map?a.map.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.sizeAttenuation);return t.join(",")}(a),n=this.mappedMaterialsCache.get(a),i=this.mappedMaterialsSignatures.get(a);if(null!=n&&i===t)return n;if(null!=n){n.dispose();const e=this.cache.get(n);if(null!=e){for(const a of e.values())a.material.dispose(),this.cacheValues.delete(a);this.cache.delete(n)}}const m=function(a){if(a instanceof e.SpriteMaterial){const e=new u;e.color=a.color,e.opacity=a.opacity,e.rotation=a.rotation,e.screenSpaceSize=a.sizeAttenuation?0:1,e.alphaTest=a.alphaTest,a.map&&(e.map=a.map),a.alphaMap&&(e.alphaMap=a.alphaMap);const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t}if(a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial){const e=new o;e.color=a.color,e.opacity=a.opacity,e.roughness=a.roughness,e.metalness=a.metalness,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.roughnessMap&&(e.roughnessMap=s(a.roughnessMap)),a.metalnessMap&&(e.metalnessMap=s(a.metalnessMap)),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.envMapIntensity=a.envMapIntensity,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshLambertMaterial){const e=new r;e.color=a.color,e.opacity=a.opacity,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshToonMaterial){const e=new l;e.color=a.color,e.opacity=a.opacity,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshBasicMaterial||a instanceof e.LineBasicMaterial){const t=new p;t.color=a.color,t.opacity=a.opacity,t.vertexColor=a.vertexColors,a instanceof e.MeshBasicMaterial&&(a.map&&(t.map=s(a.map)),a.aoMap&&(t.aoMap=s(a.aoMap),t.aoMapIntensity=a.aoMapIntensity),a.lightMap&&(t.lightMap=s(a.lightMap),t.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(t.alphaMap=s(a.alphaMap)),t.envMap=a.envMap),t.alphaTest=a.alphaTest;const n=t.build();return n.transparent=a.transparent,n.side=a.side,n.depthTest=a.depthTest,n.depthWrite=a.depthWrite,n.wireframe=a instanceof e.MeshBasicMaterial&&a.wireframe,n}if(a instanceof e.MeshPhongMaterial){const e=new o;e.color=a.color,e.opacity=a.opacity,e.roughness=Math.max(0,1-a.shininess/100),e.metalness=0,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}return null}(a);return null==m?null:(m.wireframe=a.wireframe??!1,this.mappedMaterialsCache.set(a,m),this.mappedMaterialsSignatures.set(a,t),a.addEventListener("dispose",()=>{const e=this.mappedMaterialsCache.get(a);if(null!=e){e.dispose(),this.mappedMaterialsCache.delete(a),this.mappedMaterialsSignatures.delete(a);const t=this.cache.get(e);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}}}),m)}canResolve(e){return null!=this.resolve(e)}dispose(){for(const[e,a]of this.observedNodeMaterials)e.removeEventListener("dispose",a);this.observedNodeMaterials.clear();for(const e of this.cacheValues)e.material.dispose();this.cacheValues.clear()}syncInheritedWorldEnvironmentSource(e,a){a.inheritsWorldEnvironment&&null!=this.worldEnvironment&&(e.uniforms.envMap.value=this.worldEnvironment.texture,e.uniforms.envMapIntensity.value=this.worldEnvironment.intensity)}getNodeMaterialSignature(e,a){const t=createNodeMaterialSignature(e);return a?`${t}|worldEnvironment:${this.worldEnvironmentRevision}`:t}prepareWorldEnvironment(a){var t,n,i;return null!=a.envMap?(this.worldEnvironmentMaterials.has(a)&&(a.uniforms.envMap={value:a.envMap},a.uniforms.envMapIntensity={value:1},a.uniforms.envMapRotation={value:new e.Matrix3},this.worldEnvironmentMaterials.delete(a)),!1):null==this.worldEnvironment?(this.worldEnvironmentMaterials.has(a)&&(delete a.uniforms.envMap,delete a.uniforms.envMapIntensity,delete a.uniforms.envMapRotation,this.worldEnvironmentMaterials.delete(a)),!1):((t=a.uniforms).envMap??(t.envMap={value:this.worldEnvironment.texture}),a.uniforms.envMap.value=this.worldEnvironment.texture,(n=a.uniforms).envMapIntensity??(n.envMapIntensity={value:this.worldEnvironment.intensity}),a.uniforms.envMapIntensity.value=this.worldEnvironment.intensity,(i=a.uniforms).envMapRotation??(i.envMapRotation={value:new e.Matrix3}),this.worldEnvironmentMaterials.add(a),!0)}observeNodeMaterial(e){if(this.observedNodeMaterials.has(e))return;const a=()=>{e.removeEventListener("dispose",a),this.observedNodeMaterials.delete(e);const t=this.cache.get(e);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}this.failedSignatures.delete(e),w.delete(e)};this.observedNodeMaterials.set(e,a),e.addEventListener("dispose",a)}}function I(e,a){let t=g.get(a);if(null==t){t=[];for(const e in a){const n=a[e],i=n.value,s=!0===i?.isVector2?2:!0===i?.isVector3?3:!0===i?.isVector4?4:!0===i?.isColor?5:0;t.push({name:e,target:n,copyKind:s})}g.set(a,t)}const n=e.uniforms;for(let e=0;e<t.length;e++){const a=t[e],i=n[a.name];if(null==i)continue;const s=i.value,o=a.target.value;if(s!==o){if(0!==a.copyKind){const e=s,t=o;if((2===a.copyKind?!0===e?.isVector2:3===a.copyKind?!0===e?.isVector3:4===a.copyKind?!0===e?.isVector4:!0===e?.isColor)&&"function"==typeof t?.copy){t.copy(s);continue}}a.target.value=s}}}function S(a,t){const n=a.uniforms.envMapIntensity,i=t.uniforms.envMapIntensity;null!=n&&null!=i&&(i.value=n.value);const s=a.uniforms.envMapRotation?.value,o=t.uniforms.envMapRotation?.value;s instanceof e.Matrix3&&o instanceof e.Matrix3&&o.copy(s)}function x(e,a){for(const t in a.textures){const n=a.textures[t],i=e.uniforms[t]?.value;if(T(i)&&i!==n)return!1}return!0}function T(e){return!0===e?.isTexture}/*
1
+ import*as e from"three";import{compileNodeWebGpuFullscreen as a,compileNodeShaderMaterialForWebGpu as t,NodeShaderMaterial as n,webGpuRendererBindings as i,textureSampler2d as s}from"three-shader-graph";import{StandardShader as o}from"../shader/builtin/standard-shader.js";import{LambertShader as r}from"../shader/builtin/lambert-shader.js";import{ToonShader as l}from"../shader/builtin/toon-shader.js";import{UnlitShader as u}from"../shader/builtin/unlit-shader.js";import{SpriteShader as p}from"../shader/sprite-shader.js";import{elapsedTimeUniformName as m}from"../shader-nodes/time.js";import{depthUniformName as c,farUniformName as h,nearUniformName as d,resolutionUniformName as f,sceneNormalUniformName as M}from"../shader-nodes/depth.js";import{sceneMapUniformName as v}from"../shader-nodes/scene-sample.js";const y={...i,uniformExpressions:{...i.uniformExpressions,[m]:{type:"float",expression:"rendererElapsedTime()"},[d]:{type:"float",expression:"rendererCameraNear()"},[h]:{type:"float",expression:"rendererCameraFar()"},[f]:{type:"vec2",expression:"rendererCamera.viewportAndTime.xy"}},sceneTextures:{[v]:{semantic:"sceneColor",sampleType:"float"},[c]:{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]}}};export function setMaterialUniformValuesAutoUpdate(e,a){e.uniformValuesAutoUpdate=a}export function markMaterialUniformValuesNeedUpdate(e){const a=e;"uniformValuesNeedsUpdate"in a?a.uniformValuesNeedsUpdate=!0:a.uniformValuesAutoVersion=(a.uniformValuesAutoVersion??0)+1}function g(e){return!1!==e.uniformValuesAutoUpdate}function V(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 w=new WeakMap,I=new WeakMap;export function createNodeMaterialSignature(e){const a=I.get(e);if(null!=a)return a;const t=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 I.set(e,t),t}export class NodeMaterialWebGpuResolver{constructor(e,a){this.webGpu=e,this.mrtResolver=a,this.cache=new WeakMap,this.failedSignatures=new WeakMap,this.mappedMaterialsCache=new WeakMap,this.mappedMaterialsSignatures=new WeakMap,this.observedNodeMaterials=new Map,this.worldEnvironmentMaterials=new WeakSet,this.worldEnvironment=null,this.worldEnvironmentTexture=null,this.worldEnvironmentIntensity=0,this.worldEnvironmentRevision=0,this.cacheValues=new Set}setWorldEnvironment(e){const a=e?.texture??null,t=e?.intensity??0;if(this.worldEnvironmentTexture!==a||this.worldEnvironmentIntensity!==t){if(this.worldEnvironmentTexture!==a)this.worldEnvironmentRevision++;else if(null!=e)for(const e of this.cacheValues)e.inheritsWorldEnvironment&&null!=e.material.uniforms.envMapIntensity&&(e.material.uniforms.envMapIntensity.value=t,e.material.uniformValuesNeedsUpdate=!0);this.worldEnvironment=e,this.worldEnvironmentTexture=a,this.worldEnvironmentIntensity=t}}resolve(e,a=void 0){let i,s=!1;if(e instanceof n)i=e,this.observeNodeMaterial(i);else{const a=this.getOrCreateMappedNodeMaterial(e);if(null==a)return;i=a,s=!0}i.visible=e.visible;const o=a??"default",r=this.cache.get(i),l=r?.get(o);if(s&&null!=l&&l.sourceVersion===e.version&&l.worldEnvironmentRevision===this.worldEnvironmentRevision){const a=g(e),t=V(e);return l.material.uniformValuesAutoUpdate=a,this.syncInheritedWorldEnvironmentSource(i,l),a||l.sourceUniformValuesAutoVersion!==t?(W(e,i),l.compiled.syncLiveUniforms(l.material.uniforms),x(i,l.material.uniforms),T(i,l.material),l.sourceUniformValuesAutoVersion=t,a||(l.material.uniformValuesNeedsUpdate=!0),l.material):l.material}if(!s&&null!=l&&l.sourceVersion===e.version&&l.worldEnvironmentRevision===this.worldEnvironmentRevision&&E(i,l.compiled))return this.syncInheritedWorldEnvironmentSource(i,l),S(i,l),l.material;s&&W(e,i);const u=this.prepareWorldEnvironment(i),p=this.getNodeMaterialSignature(i,u);if(l?.signature===p&&E(i,l.compiled))return s?(l.material.uniformValuesAutoUpdate=g(e),l.compiled.syncLiveUniforms(l.material.uniforms),x(i,l.material.uniforms),T(i,l.material),l.sourceUniformValuesAutoVersion=V(e),l.material.uniformValuesAutoUpdate||(l.material.uniformValuesNeedsUpdate=!0)):S(i,l,!0),l.sourceVersion=e.version,l.worldEnvironmentRevision=this.worldEnvironmentRevision,l.material;try{const n=this.mrtResolver?.(i,a),m=t(i,y,n),c=new this.webGpu.WGSLShaderMaterial({vertexShader:m.vertexShader,fragmentShader:m.fragmentShader,depthVertexShader:m.depthVertexShader,depthFragmentShader:m.depthFragmentShader,pointShadowVertexShader:m.pointShadowVertexShader,pointShadowFragmentShader:m.pointShadowFragmentShader,uniforms:m.uniforms,textures:m.textures,sceneTextures:m.sceneTextures,graphTextures:m.graphTextures,vertexAttributes:withThreeDefaultVertexAttributeValues(m.vertexAttributes),uniformValuesAutoUpdate:s?g(e):i.uniformValuesAutoUpdate,transparent:m.renderState?.transparent,alphaTest:m.renderState?.alphaTest,depthTest:m.renderState?.depthTest,depthWrite:m.renderState?.depthWrite,side:m.renderState?.side,wireframe:i.wireframe});c.uniformValuesAutoUpdate=s?g(e):i.uniformValuesAutoUpdate,function(e,a){if(null==e)return;Object.assign(a,e)}(m.renderState,c),null!=l&&(l.material.dispose(),this.cacheValues.delete(l));const h={signature:p,compiled:m,material:c,inheritsWorldEnvironment:u,sourceVersion:e.version,sourceUniformValuesAutoVersion:s?V(e):i.uniformValuesAutoVersion,worldEnvironmentRevision:this.worldEnvironmentRevision},d=r??new Map;return d.set(o,h),this.cache.set(i,d),this.cacheValues.add(h),x(i,c.uniforms),T(i,c),c}catch(e){let a=this.failedSignatures.get(i);if(null==a&&(a=new Map,this.failedSignatures.set(i,a)),a.get(o)!==p){a.set(o,p);const t=e instanceof Error?e.message:String(e),n=i.name||i.uuid;console.warn(`[Hology WebGPU experiment] Falling back for NodeShaderMaterial "${n}": ${t}`,{material:i,error:e})}return}}compileFullscreen(e){const t=a({color:e.outputColor,wgslBindings:{...y,uniformExpressions:{},graphTextures:{...y.graphTextures,[M]:{resource:"hologyNormalRoughness",dimension:"2d",sampleType:"float",sampler:"filtering"}}}}),n=t.syncLiveUniforms;return{...t,syncLiveUniforms(a){n(a),x(e,a)}}}getOrCreateMappedNodeMaterial(a){const t=function(a){const t=[a.vertexColors,a.transparent,a.alphaTest,a.side,a.depthTest,a.depthWrite,a.wireframe??!1];a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.roughnessMap?a.roughnessMap.uuid:null,a.metalnessMap?a.metalnessMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshLambertMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshToonMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.gradientMap?a.gradientMap.uuid:null):a instanceof e.MeshBasicMaterial?t.push(a.map?a.map.uuid:null,a.aoMap?a.aoMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshPhongMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.SpriteMaterial&&t.push(a.map?a.map.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.sizeAttenuation);return t.join(",")}(a),n=this.mappedMaterialsCache.get(a),i=this.mappedMaterialsSignatures.get(a);if(null!=n&&i===t)return n;if(null!=n){n.dispose();const e=this.cache.get(n);if(null!=e){for(const a of e.values())a.material.dispose(),this.cacheValues.delete(a);this.cache.delete(n)}}const m=function(a){if(a instanceof e.SpriteMaterial){const e=new p;e.color=a.color,e.opacity=a.opacity,e.rotation=a.rotation,e.screenSpaceSize=a.sizeAttenuation?0:1,e.alphaTest=a.alphaTest,a.map&&(e.map=a.map),a.alphaMap&&(e.alphaMap=a.alphaMap);const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t}if(a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial){const e=new o;e.color=a.color,e.opacity=a.opacity,e.roughness=a.roughness,e.metalness=a.metalness,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.roughnessMap&&(e.roughnessMap=s(a.roughnessMap)),a.metalnessMap&&(e.metalnessMap=s(a.metalnessMap)),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.envMapIntensity=a.envMapIntensity,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshLambertMaterial){const e=new r;e.color=a.color,e.opacity=a.opacity,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshToonMaterial){const e=new l;e.color=a.color,e.opacity=a.opacity,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshBasicMaterial||a instanceof e.LineBasicMaterial){const t=new u;t.color=a.color,t.opacity=a.opacity,t.vertexColor=a.vertexColors,a instanceof e.MeshBasicMaterial&&(a.map&&(t.map=s(a.map)),a.aoMap&&(t.aoMap=s(a.aoMap),t.aoMapIntensity=a.aoMapIntensity),a.lightMap&&(t.lightMap=s(a.lightMap),t.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(t.alphaMap=s(a.alphaMap)),t.envMap=a.envMap),t.alphaTest=a.alphaTest;const n=t.build();return n.transparent=a.transparent,n.side=a.side,n.depthTest=a.depthTest,n.depthWrite=a.depthWrite,n.wireframe=a instanceof e.MeshBasicMaterial&&a.wireframe,n}if(a instanceof e.MeshPhongMaterial){const e=new o;e.color=a.color,e.opacity=a.opacity,e.roughness=Math.max(0,1-a.shininess/100),e.metalness=0,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}return null}(a);return null==m?null:(m.wireframe=a.wireframe??!1,this.mappedMaterialsCache.set(a,m),this.mappedMaterialsSignatures.set(a,t),a.addEventListener("dispose",()=>{const e=this.mappedMaterialsCache.get(a);if(null!=e){e.dispose(),this.mappedMaterialsCache.delete(a),this.mappedMaterialsSignatures.delete(a);const t=this.cache.get(e);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}}}),m)}canResolve(e){return null!=this.resolve(e)}dispose(){for(const[e,a]of this.observedNodeMaterials)e.removeEventListener("dispose",a);this.observedNodeMaterials.clear();for(const e of this.cacheValues)e.material.dispose();this.cacheValues.clear()}syncInheritedWorldEnvironmentSource(e,a){a.inheritsWorldEnvironment&&null!=this.worldEnvironment&&(e.uniforms.envMap.value=this.worldEnvironment.texture,e.uniforms.envMapIntensity.value=this.worldEnvironment.intensity)}getNodeMaterialSignature(e,a){const t=createNodeMaterialSignature(e);return a?`${t}|worldEnvironment:${this.worldEnvironmentRevision}`:t}prepareWorldEnvironment(a){var t,n,i;return null!=a.envMap?(this.worldEnvironmentMaterials.has(a)&&(a.uniforms.envMap={value:a.envMap},a.uniforms.envMapIntensity={value:1},a.uniforms.envMapRotation={value:new e.Matrix3},this.worldEnvironmentMaterials.delete(a)),!1):null==this.worldEnvironment?(this.worldEnvironmentMaterials.has(a)&&(delete a.uniforms.envMap,delete a.uniforms.envMapIntensity,delete a.uniforms.envMapRotation,this.worldEnvironmentMaterials.delete(a)),!1):((t=a.uniforms).envMap??(t.envMap={value:this.worldEnvironment.texture}),a.uniforms.envMap.value=this.worldEnvironment.texture,(n=a.uniforms).envMapIntensity??(n.envMapIntensity={value:this.worldEnvironment.intensity}),a.uniforms.envMapIntensity.value=this.worldEnvironment.intensity,(i=a.uniforms).envMapRotation??(i.envMapRotation={value:new e.Matrix3}),this.worldEnvironmentMaterials.add(a),!0)}observeNodeMaterial(e){if(this.observedNodeMaterials.has(e))return;const a=()=>{e.removeEventListener("dispose",a),this.observedNodeMaterials.delete(e);const t=this.cache.get(e);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}this.failedSignatures.delete(e),I.delete(e)};this.observedNodeMaterials.set(e,a),e.addEventListener("dispose",a)}}function S(e,a,t=!1){const n=a.material;n.uniformValuesAutoUpdate=e.uniformValuesAutoUpdate,(t||e.uniformValuesAutoUpdate||a.sourceUniformValuesAutoVersion!==e.uniformValuesAutoVersion)&&(a.compiled.syncLiveUniforms(n.uniforms),x(e,n.uniforms),T(e,n),a.sourceUniformValuesAutoVersion=e.uniformValuesAutoVersion,n.uniformValuesAutoUpdate||(n.uniformValuesNeedsUpdate=!0))}function x(e,a){let t=w.get(a);if(null==t){t=[];for(const e in a){const n=a[e],i=n.value,s=!0===i?.isVector2?2:!0===i?.isVector3?3:!0===i?.isVector4?4:!0===i?.isColor?5:0;t.push({name:e,target:n,copyKind:s})}w.set(a,t)}const n=e.uniforms;for(let e=0;e<t.length;e++){const a=t[e],i=n[a.name];if(null==i)continue;const s=i.value,o=a.target.value;if(s!==o){if(0!==a.copyKind){const e=s,t=o;if((2===a.copyKind?!0===e?.isVector2:3===a.copyKind?!0===e?.isVector3:4===a.copyKind?!0===e?.isVector4:!0===e?.isColor)&&"function"==typeof t?.copy){t.copy(s);continue}}a.target.value=s}}}function T(a,t){const n=a.uniforms.envMapIntensity,i=t.uniforms.envMapIntensity;null!=n&&null!=i&&(i.value=n.value);const s=a.uniforms.envMapRotation?.value,o=t.uniforms.envMapRotation?.value;s instanceof e.Matrix3&&o instanceof e.Matrix3&&o.copy(s)}function E(e,a){for(const t in a.textures){const n=a.textures[t],i=e.uniforms[t]?.value;if(C(i)&&i!==n)return!1}return!0}function C(e){return!0===e?.isTexture}function W(a,t){if(a instanceof e.SpriteMaterial){const n=t;t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),n.rotation=a.rotation,n.screenSpaceSize=a.sizeAttenuation?0:1}else a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.roughness&&(t.uniforms.roughness.value=a.roughness),t.uniforms.metalness&&(t.uniforms.metalness.value=a.metalness),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity),t.uniforms.envMapIntensity&&(t.uniforms.envMapIntensity.value=a.envMapIntensity)):a instanceof e.MeshLambertMaterial||a instanceof e.MeshToonMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity)):a instanceof e.MeshBasicMaterial||a instanceof e.LineBasicMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),a instanceof e.MeshBasicMaterial&&(t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity))):a instanceof e.MeshPhongMaterial&&(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.roughness&&(t.uniforms.roughness.value=Math.max(0,1-a.shininess/100)),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity))}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -2,13 +2,18 @@ import * as THREE from 'three';
2
2
  import { NodeMaterialWebGpuResolver } from './node-material-webgpu-resolver.js';
3
3
  import type { WorldEnvironmentState } from './environment.js';
4
4
  import type { PostProcessEffectStage } from './post-process-effect.js';
5
- import type { BloomOptions, ColorGradingOptions, DepthOfFieldOptions, FXAAOptions, GTAOOptions, OutlineOptions, OutlineInstanceSelection, SSROptions, RendererFrameProfile, TemporalAAOptions, VolumetricFogOptions } from '@hology/webgpu-renderer';
5
+ import type { BloomOptions, ColorGradingOptions, DepthOfFieldOptions, FXAAOptions, GTAOOptions, OutlineOptions, OutlineInstanceSelection, SSROptions, RendererFrameProfile, SMAAOptions, TemporalAAOptions, VolumetricFogOptions } from '@hology/webgpu-renderer';
6
6
  export type { RendererFrameProfile } from '@hology/webgpu-renderer';
7
7
  type SupportedCamera = THREE.PerspectiveCamera | THREE.OrthographicCamera;
8
8
  export interface ExperimentalWebGpuPostProcessingOptions {
9
9
  readonly bloom?: false | BloomOptions;
10
10
  /** Optional low-cost, stateless antialiasing pass. Enable with `fxaa: {}`. */
11
11
  readonly fxaa?: false | FXAAOptions;
12
+ /**
13
+ * Sharp three-pass SMAA 1x. When enabled it replaces FXAA, while TAA may
14
+ * still be composed before it when explicitly enabled.
15
+ */
16
+ readonly smaa?: false | SMAAOptions;
12
17
  readonly gtao?: false | GTAOOptions;
13
18
  /** Screen-space reflections using the opaque color, depth, normal and roughness buffers. */
14
19
  readonly ssr?: false | SSROptions;
@@ -61,6 +66,7 @@ export declare class ExperimentalWebGpuBackend {
61
66
  private readonly gBufferFallbackSource;
62
67
  private readonly bloom;
63
68
  private readonly fxaa;
69
+ private readonly smaa;
64
70
  private readonly gtao;
65
71
  private readonly ssr;
66
72
  private readonly taa;
@@ -1,4 +1,4 @@
1
- import*as e from"three";import{NodeMaterialWebGpuResolver as t}from"./node-material-webgpu-resolver.js";import{float as n,varyingTransformed as i,vec4 as r}from"three-shader-graph";import{NodeShaderMaterial as o}from"../shader-nodes/index.js";import{sceneMapUniformName as s}from"../shader-nodes/scene-sample.js";export class ExperimentalWebGpuBackend{constructor(e,t,n,i,r,o,s,a,l,d,c,u,h,p,m){this.renderer=e,this.fallbackMaterial=t,this.nodeMaterialResolver=n,this.gBufferFallbackSource=i,this.bloom=r,this.fxaa=o,this.gtao=s,this.ssr=a,this.taa=l,this.volumetricFog=d,this.colorGrading=c,this.depthOfField=u,this.outline=h,this.postProcessEffects=p,this.pmremGenerator=null,this.pmremResults=new WeakMap,this.ownedPmremResults=new Set,this.warnedUnsupportedPostProcessStages=new Set,this.canvas=m}static async create(d={}){const c=await import("@hology/webgpu-renderer"),u=document.createElement("canvas");u.dataset.hologyRenderer="webgpu-experimental";const h=new c.WGSLShaderMaterial({vertexShader:a,fragmentShader:l});h.side=c.DoubleSide;const p=new t(c,(e,t)=>"opaque"===t?[e.outputColor.xyz.rgba(e.alphaTest),r((e.outputNormal??i.normal).multiplyScalar(.5).addScalar(.5),e.outputRoughness??n(1))]:void 0),m=new e.MeshStandardMaterial({color:8688803,roughness:1});if(null==p.resolve(m,"opaque"))throw h.dispose(),m.dispose(),new Error("Failed to compile the WebGPU G-buffer fallback material.");const g=!1===d.gtao?null:new c.GTAOEffect({normalSpace:"view",resolutionScale:.5,...d.gtao??{}}),f=!1===d.ssr||null==d.ssr?null:new c.SSREffect({normalSpace:"view",resolutionScale:.5,...d.ssr??{}}),P=!1===d.bloom?null:new c.BloomEffect({threshold:1,strength:.9,radius:.2,...d.bloom??{}}),S=!1===d.fxaa||null==d.fxaa?null:new c.FXAAEffect(d.fxaa),x=!1===d.taa?null:new c.TemporalAAEffect({renderScale:.9,...d.taa??{}}),w=d.volumetricFog||void 0,b=!1===d.volumetricFog?null:new c.VolumetricFogEffect(void 0,{froxelPixelSize:8,maxDistance:64,depthSlices:64,integrationSubsteps:2,temporalJitter:!0,spatialJitter:!0,scatteringIntensity:Math.PI,...w,blur:!1!==w?.blur&&{depthAwareUpsample:!0,...w?.blur}}),v=!1===d.colorGrading?null:new c.ColorGradingEffect({enabled:!1,...d.colorGrading??{}}),C=!1===d.depthOfField?null:new c.DepthOfFieldEffect({enabled:!1,...d.depthOfField??{}}),L=!1===d.outline?null:new c.OutlineEffect({enabled:!1,...d.outline??{}}),y=[],F=new WeakMap,M=new Set,G=(e,t,n)=>{let i=n;const r=y.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`;M.has(e)||(M.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: only NodeShaderMaterial effects are supported.`));continue}try{let n=F.get(t.material);null!=n&&n.version===t.material.version||(n={version:t.material.version,shader:p.compileFullscreen(t.material)},F.set(t.material,n));const r=e.createColorTarget(`hologyCustomPostProcess${t.id}`);e.addNodeFullscreenPass({name:`HologyCustomPostProcess${t.id}`,shader:n.shader,inputOverrides:{[s]:i},outputs:r}),i=r}catch(e){const n=`${t.id}:compile:${t.material.version}`;M.has(n)||(M.add(n),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: ${e instanceof Error?e.message:String(e)}`,e))}}return i},R=new c.WebGpuRenderer({canvas:u,fallbackMaterial:h,materialResolver:(e,t)=>p.resolve(e,t),invokeObjectRenderCallbacks:!1,hiZOcclusionCulling:!0,renderGraphProfiling:!1,sampleCount:1,multiDrawIndirect:!1});R.setRenderScale(x?.renderScale??1),R.setRenderGraphBuilder((e,t)=>{const n=new c.FrameGraphBuilder(t),i=n.createColorTarget("hologyNormalRoughness",{format:"rgba16float"});n.addDirectionalShadowPass(),n.addPointShadowPass(),n.addSpotShadowPass(),n.addDepthPrepass(),n.addHiZPasses(),n.addVisibilityPass(),n.addMaterialPass({name:"OpaqueGBufferPass",outputs:[n.sceneColor,i],drawStage:"opaque",loadDepth:!0}),n.addHiZHistoryPass("OpaqueGBufferPass");let r=n.sceneColor;if(null!=g){const e=g.addPasses(n,{depth:n.mainDepth,normal:i});r=g.addCompositePass(n,r,e)}null!=f&&(r=f.addPasses(n,{sceneColor:r,depth:n.mainDepth,normalRoughness:i})),n.addSceneTextureCopyPass(r),n.addLatePass(r),r=G(n,"beforeFog",r),null!=b&&(r=b.addPasses(n,{sceneColor:r,depth:n.mainDepth})),null!=P&&(r=P.addPass(n,r)),r=G(n,"beforeOutline",r),null!=L&&(r=L.addPass(n,r)),r=G(n,"beforeDepthOfField",r),null!=C&&(r=C.addPass(n,r,n.mainDepth)),r=G(n,"beforeColorAdjustment",r),null!=v&&(r=v.addPass(n,r)),r=G(n,"beforeAntiAliasing",r);let o=x?.addPass(n,r,n.mainDepth)??r;null!=S&&(o=S.addPass(n,o)),o=G(n,"beforeOutput",o),n.present(o)});try{return await R.initialize(),new ExperimentalWebGpuBackend(R,h,p,m,P,S,g,f,x,b,v,C,L,y,u)}catch(e){throw R.destroy(),h.dispose(),p.dispose(),m.dispose(),g?.dispose(),b?.dispose(),L?.dispose(),e}}static supportsCamera(t){return t instanceof e.PerspectiveCamera||t instanceof e.OrthographicCamera}setSize(e,t,n){this.renderer.setSize(e,t,n)}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.`))}}setEnableOutlines(e){null!=this.outline&&(this.outline.enabled=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)}setWorldEnvironment(t){if(null==t)return void this.nodeMaterialResolver.setWorldEnvironment(null);let n=t.source;if(n.mapping!==e.CubeUVReflectionMapping){let e=this.pmremResults.get(n);null==e&&(this.pmremGenerator??(this.pmremGenerator=this.renderer.createPMREMGenerator()),e=this.pmremGenerator.fromEquirectangular(n),this.pmremResults.set(n,e),this.ownedPmremResults.add(e)),n=e.texture}this.nodeMaterialResolver.setWorldEnvironment({texture:n,intensity:t.intensity})}resetViewHistory(){this.renderer.resetViewHistory(),this.taa?.reset()}async compile(e,t){await this.renderer.compileAsync(e,t)}createStaticDrawSet(e,t){this.renderer.setHiZOcclusionCullingEnabled(!0);const n=this.renderer.createStaticDrawSet(e,{label:t,onUnsupported:"skip"});return 0===n.drawCount?(n.dispose(),null):n}render(e,t,n){this.volumetricFog?.setScene(e),this.taa?.prepareCamera(t,this.canvas.width,this.canvas.height);try{this.renderer.render(e,t,n)}finally{this.taa?.finishCamera(t)}}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()}inspect(e,t){return inspectWebGpuScene(e,t,this.nodeMaterialResolver)}destroy(){this.nodeMaterialResolver.dispose(),this.gBufferFallbackSource.dispose(),this.gtao?.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,n){const i={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 i.sprites++;if(e.isPoints)return void i.points++;if(e.isLine)return void i.lines++;if(!e.isMesh)return;const t=e;t.isBatchedMesh?i.batchedMeshes++:t.isInstancedMesh?i.instancedMeshes++:t.isSkinnedMesh?i.skinnedMeshes++:i.meshes++,null==t.geometry?.getAttribute("position")&&i.missingPositionGeometry++;const r=Array.isArray(t.material)?t.material:[t.material];for(const e of r){if(null==e)continue;e.transparent&&i.transparentMaterials++;const t=!0===e.isWGSLShaderMaterial||!0===e.isLineMaterial,r=!t&&!0===n?.canResolve(e);t||r||(i.materialsReplaced++,e.isShaderMaterial&&i.shaderMaterialsReplaced++)}}),i}export function formatWebGpuSceneCapabilitySummary(e){return`[Hology WebGPU experiment] ${JSON.stringify(e)}`}const a="\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",l="\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, range: f32) -> f32 {\n let linear = max(0.0, 1.0 - distanceToLight / max(range, 0.001));\n return linear * linear;\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)) * 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)) * 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{float as n,varyingTransformed as i,vec4 as r}from"three-shader-graph";import{NodeShaderMaterial as o}from"../shader-nodes/index.js";import{sceneMapUniformName as s}from"../shader-nodes/scene-sample.js";export class ExperimentalWebGpuBackend{constructor(e,t,n,i,r,o,s,a,l,d,c,u,h,p,m,g){this.renderer=e,this.fallbackMaterial=t,this.nodeMaterialResolver=n,this.gBufferFallbackSource=i,this.bloom=r,this.fxaa=o,this.smaa=s,this.gtao=a,this.ssr=l,this.taa=d,this.volumetricFog=c,this.colorGrading=u,this.depthOfField=h,this.outline=p,this.postProcessEffects=m,this.pmremGenerator=null,this.pmremResults=new WeakMap,this.ownedPmremResults=new Set,this.warnedUnsupportedPostProcessStages=new Set,this.canvas=g}static async create(d={}){const c=await import("@hology/webgpu-renderer"),u=document.createElement("canvas");u.dataset.hologyRenderer="webgpu-experimental";const h=new c.WGSLShaderMaterial({vertexShader:a,fragmentShader:l});h.side=c.DoubleSide;const p=new t(c,(e,t)=>"opaque"===t?[e.outputColor.xyz.rgba(e.alphaTest),r((e.outputNormal??i.normal).multiplyScalar(.5).addScalar(.5),e.outputRoughness??n(1))]:void 0),m=new e.MeshStandardMaterial({color:8688803,roughness:1});if(null==p.resolve(m,"opaque"))throw h.dispose(),m.dispose(),new Error("Failed to compile the WebGPU G-buffer fallback material.");const g=!1===d.gtao?null:new c.GTAOEffect({normalSpace:"view",resolutionScale:.5,...d.gtao??{}}),f=!1===d.ssr||null==d.ssr?null:new c.SSREffect({normalSpace:"view",resolutionScale:.5,...d.ssr??{}}),P=!1===d.bloom?null:new c.BloomEffect({threshold:1,strength:.9,radius:.2,...d.bloom??{}}),S=!1===d.fxaa||null==d.fxaa?null:new c.FXAAEffect(d.fxaa),x=!1===d.smaa||null==d.smaa?null:new c.SMAAEffect(d.smaa),w=!1===d.taa||null!=d.smaa&&!1!==d.smaa&&null==d.taa?null:new c.TemporalAAEffect({renderScale:.9,...d.taa??{}}),b=d.volumetricFog||void 0,v=!1===d.volumetricFog?null:new c.VolumetricFogEffect(void 0,{froxelPixelSize:8,maxDistance:64,depthSlices:64,integrationSubsteps:2,temporalJitter:!0,spatialJitter:!0,scatteringIntensity:Math.PI,...b,blur:!1!==b?.blur&&{depthAwareUpsample:!0,...b?.blur}}),C=!1===d.colorGrading?null:new c.ColorGradingEffect({enabled:!1,...d.colorGrading??{}}),L=!1===d.depthOfField?null:new c.DepthOfFieldEffect({enabled:!1,...d.depthOfField??{}}),y=!1===d.outline?null:new c.OutlineEffect({enabled:!1,...d.outline??{}}),F=[],M=new WeakMap,G=new Set,O=(e,t,n)=>{let i=n;const r=F.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`;G.has(e)||(G.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: only NodeShaderMaterial effects are supported.`));continue}try{let n=M.get(t.material);null!=n&&n.version===t.material.version||(n={version:t.material.version,shader:p.compileFullscreen(t.material)},M.set(t.material,n));const r=e.createColorTarget(`hologyCustomPostProcess${t.id}`);e.addNodeFullscreenPass({name:`HologyCustomPostProcess${t.id}`,shader:n.shader,inputOverrides:{[s]:i},outputs:r}),i=r}catch(e){const n=`${t.id}:compile:${t.material.version}`;G.has(n)||(G.add(n),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: ${e instanceof Error?e.message:String(e)}`,e))}}return i},R=new c.WebGpuRenderer({canvas:u,fallbackMaterial:h,materialResolver:(e,t)=>p.resolve(e,t),invokeObjectRenderCallbacks:!1,hiZOcclusionCulling:!0,renderGraphProfiling:!1,sampleCount:1,multiDrawIndirect:!1});R.setRenderScale(w?.renderScale??1),R.setRenderGraphBuilder((e,t)=>{const n=new c.FrameGraphBuilder(t),i=n.createColorTarget("hologyNormalRoughness",{format:"rgba16float"});n.addDirectionalShadowPass(),n.addPointShadowPass(),n.addSpotShadowPass(),n.addDepthPrepass(),n.addHiZPasses(),n.addVisibilityPass(),n.addMaterialPass({name:"OpaqueGBufferPass",outputs:[n.sceneColor,i],drawStage:"opaque",loadDepth:!0}),n.addHiZHistoryPass("OpaqueGBufferPass");let r=n.sceneColor;if(null!=g){const e=g.addPasses(n,{depth:n.mainDepth,normal:i});r=g.addCompositePass(n,r,e)}null!=f&&(r=f.addPasses(n,{sceneColor:r,depth:n.mainDepth,normalRoughness:i})),n.addSceneTextureCopyPass(r),n.addLatePass(r),r=O(n,"beforeFog",r),null!=v&&(r=v.addPasses(n,{sceneColor:r,depth:n.mainDepth,volumeObjects:t.fogVolumeObjects,lights:t.extractedLights})),null!=P&&(r=P.addPass(n,r)),r=O(n,"beforeOutline",r),null!=y&&(r=y.addPass(n,r)),r=O(n,"beforeDepthOfField",r),null!=L&&(r=L.addPass(n,r,n.mainDepth)),r=O(n,"beforeColorAdjustment",r),null!=C&&(r=C.addPass(n,r)),r=O(n,"beforeAntiAliasing",r);let o=w?.addPass(n,r,n.mainDepth)??r;null!=x?o=x.addPass(n,o):null!=S&&(o=S.addPass(n,o)),o=O(n,"beforeOutput",o),n.present(o)});try{return await R.initialize(),new ExperimentalWebGpuBackend(R,h,p,m,P,S,x,g,f,w,v,C,L,y,F,u)}catch(e){throw R.destroy(),h.dispose(),p.dispose(),m.dispose(),g?.dispose(),x?.dispose(),v?.dispose(),y?.dispose(),e}}static supportsCamera(t){return t instanceof e.PerspectiveCamera||t instanceof e.OrthographicCamera}setSize(e,t,n){this.renderer.setSize(e,t,n)}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.`))}}setEnableOutlines(e){null!=this.outline&&(this.outline.enabled=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)}setWorldEnvironment(t){if(null==t)return void this.nodeMaterialResolver.setWorldEnvironment(null);let n=t.source;if(n.mapping!==e.CubeUVReflectionMapping){let e=this.pmremResults.get(n);null==e&&(this.pmremGenerator??(this.pmremGenerator=this.renderer.createPMREMGenerator()),e=this.pmremGenerator.fromEquirectangular(n),this.pmremResults.set(n,e),this.ownedPmremResults.add(e)),n=e.texture}this.nodeMaterialResolver.setWorldEnvironment({texture:n,intensity:t.intensity})}resetViewHistory(){this.renderer.resetViewHistory(),this.taa?.reset()}async compile(e,t){await this.renderer.compileAsync(e,t)}createStaticDrawSet(e,t){this.renderer.setHiZOcclusionCullingEnabled(!0);const n=this.renderer.createStaticDrawSet(e,{label:t,onUnsupported:"skip"});return 0===n.drawCount?(n.dispose(),null):n}render(e,t,n){this.volumetricFog?.setScene(e),this.taa?.prepareCamera(t,this.canvas.width,this.canvas.height);try{this.renderer.render(e,t,n)}finally{this.taa?.finishCamera(t)}}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()}inspect(e,t){return inspectWebGpuScene(e,t,this.nodeMaterialResolver)}destroy(){this.nodeMaterialResolver.dispose(),this.gBufferFallbackSource.dispose(),this.gtao?.dispose(),this.smaa?.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,n){const i={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 i.sprites++;if(e.isPoints)return void i.points++;if(e.isLine)return void i.lines++;if(!e.isMesh)return;const t=e;t.isBatchedMesh?i.batchedMeshes++:t.isInstancedMesh?i.instancedMeshes++:t.isSkinnedMesh?i.skinnedMeshes++:i.meshes++,null==t.geometry?.getAttribute("position")&&i.missingPositionGeometry++;const r=Array.isArray(t.material)?t.material:[t.material];for(const e of r){if(null==e)continue;e.transparent&&i.transparentMaterials++;const t=!0===e.isWGSLShaderMaterial||!0===e.isLineMaterial,r=!t&&!0===n?.canResolve(e);t||r||(i.materialsReplaced++,e.isShaderMaterial&&i.shaderMaterialsReplaced++)}}),i}export function formatWebGpuSceneCapabilitySummary(e){return`[Hology WebGPU experiment] ${JSON.stringify(e)}`}const a="\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",l="\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, range: f32) -> f32 {\n let linear = max(0.0, 1.0 - distanceToLight / max(range, 0.001));\n return linear * linear;\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)) * 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)) * 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
  */