three-live 1.3.2 → 1.4.0

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.
Files changed (58) hide show
  1. package/README.md +4 -1
  2. package/dist/index.d.ts +190 -0
  3. package/dist/three-author-engine.js +171 -163
  4. package/dist/three-author.cjs +145 -163
  5. package/dist/three-author.d.ts +190 -0
  6. package/dist/three-author.js +145 -163
  7. package/dist/three-convert.cjs +142 -160
  8. package/dist/three-convert.d.ts +190 -0
  9. package/dist/three-convert.js +142 -160
  10. package/dist/three-live-ai.cjs +41 -0
  11. package/dist/three-live-ai.d.ts +759 -0
  12. package/dist/three-live-ai.js +41 -0
  13. package/dist/three-live-ai.min.js +41 -0
  14. package/dist/three-live-animation.cjs +6 -6
  15. package/dist/three-live-animation.d.ts +190 -0
  16. package/dist/three-live-animation.js +5 -5
  17. package/dist/three-live-animation.min.js +5 -5
  18. package/dist/three-live-cad.cjs +2 -2
  19. package/dist/three-live-cad.d.ts +190 -0
  20. package/dist/three-live-cad.js +2 -2
  21. package/dist/three-live-cad.min.js +2 -2
  22. package/dist/three-live-element.cjs +50 -85
  23. package/dist/three-live-element.d.ts +190 -0
  24. package/dist/three-live-element.js +50 -85
  25. package/dist/three-live-full.cjs +907 -189
  26. package/dist/three-live-full.js +907 -189
  27. package/dist/three-live-full.min.js +907 -189
  28. package/dist/three-live-procedural.cjs +16 -0
  29. package/dist/three-live-procedural.d.ts +759 -0
  30. package/dist/three-live-procedural.js +16 -0
  31. package/dist/three-live-procedural.min.js +16 -0
  32. package/dist/three-live-sandbox.html +11 -1
  33. package/dist/three-live-studio.cjs +72 -17
  34. package/dist/three-live-studio.d.ts +190 -0
  35. package/dist/three-live-studio.js +72 -17
  36. package/dist/three-live-studio.min.js +73 -18
  37. package/dist/three-live-tsl.cjs +103 -0
  38. package/dist/three-live-tsl.d.ts +759 -0
  39. package/dist/three-live-tsl.js +103 -0
  40. package/dist/three-live-tsl.min.js +103 -0
  41. package/dist/three-live-viewer.cjs +50 -85
  42. package/dist/three-live-viewer.d.ts +190 -0
  43. package/dist/three-live-viewer.js +50 -85
  44. package/dist/three-live-viewer.min.js +50 -85
  45. package/dist/three-live-webgpu.cjs +585 -0
  46. package/dist/three-live-webgpu.d.ts +759 -0
  47. package/dist/three-live-webgpu.js +585 -0
  48. package/dist/three-live-webgpu.min.js +585 -0
  49. package/dist/three-live.cjs +147 -165
  50. package/dist/three-live.js +147 -165
  51. package/dist/three-live.min.js +147 -165
  52. package/dist/three-view.cjs +49 -84
  53. package/dist/three-view.d.ts +190 -0
  54. package/dist/three-view.js +50 -85
  55. package/dist/three-xr.cjs +141 -159
  56. package/dist/three-xr.d.ts +190 -0
  57. package/dist/three-xr.js +140 -158
  58. package/package.json +21 -1
@@ -0,0 +1,585 @@
1
+ "use strict";/**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */var ThreeLiveWebGPU=(()=>{var ze=Object.defineProperty,Tt=Object.getOwnPropertyDescriptor,Vt=Object.getOwnPropertyNames,Ct=Object.prototype.hasOwnProperty,Dt=(e,t)=>{for(var r in t)ze(e,r,{get:t[r],enumerable:!0})},It=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Vt(t))!Ct.call(e,i)&&i!==r&&ze(e,i,{get:()=>t[i],enumerable:!(a=Tt(t,i))||a.enumerable});return e},Rt=e=>It(ze({},"__esModule",{value:!0}),e),$e={};Dt($e,{PART_STRIDE_BYTES:()=>Xt,PART_STRIDE_WORDS:()=>Ht,SCENE_PBR_WGSL:()=>Ge,SCENE_PICK_WGSL:()=>it,SCENE_SHADOW_WGSL:()=>at,SCENE_UNIFORM_BYTES:()=>Wt,VERTEX_STRIDE_BYTES:()=>Zt,VERTEX_STRIDE_FLOATS:()=>Yt,WebGPUSceneAccelerator:()=>Mt,acquireSceneWebGPUDevice:()=>fe,getWebGPUSceneAccelerator:()=>we,normalizeRendererPreference:()=>dt,remapClipDepthToZeroOne:()=>Le,resetSceneWebGPUDevice:()=>ar,resolveSceneRenderBackend:()=>He,setSceneWebGPUDeviceForTests:()=>rr,webgpuScenePlugin:()=>Pt,writeSceneUniforms:()=>Ue});var Me="__THREE_LIVE_REGISTRY__";function $(){let e=typeof globalThis<"u"?globalThis:{};if(!e[Me]){let t={plugins:[],decoders:new Map};try{Object.defineProperty(e,Me,{value:t,writable:!1,configurable:!1,enumerable:!1})}catch{e[Me]=t}}return e[Me]}var Sr=$().plugins;function At(e){let t=$().plugins;t.some(r=>r.name===e.name)||t.push(e),e.onRegister?.()}function H(){let e=new Float32Array(16);return e[0]=1,e[5]=1,e[10]=1,e[15]=1,e}function zt(e,t,r,a,i){let n=1/Math.tan(t/2);e.fill(0),e[0]=n/r,e[5]=n,e[11]=-1;let s=1/(a-i);return e[10]=(i+a)*s,e[14]=2*i*a*s,e}function Ft(e,t,r,a,i,n,s){let c=1/(t-r),l=1/(a-i),p=1/(n-s);return e.fill(0),e[0]=-2*c,e[5]=-2*l,e[10]=2*p,e[12]=(t+r)*c,e[13]=(i+a)*l,e[14]=(s+n)*p,e[15]=1,e}function Ke(e,t,r,a){let[i,n,s]=t,[c,l,p]=a,[m,f,u]=r,v=i-m,g=n-f,d=s-u,w=Math.hypot(v,g,d);w<=1e-5?(v=0,g=0,d=1):(v/=w,g/=w,d/=w);let S=l*d-p*g,B=p*v-c*d,o=c*g-l*v;w=Math.hypot(S,B,o),w<=1e-5?(S=0,B=0,o=0):(S/=w,B/=w,o/=w);let h=g*o-d*B,x=d*S-v*o,y=v*B-g*S;return w=Math.hypot(h,x,y),w<=1e-5?(h=0,x=0,y=0):(h/=w,x/=w,y/=w),e[0]=S,e[1]=h,e[2]=v,e[3]=0,e[4]=B,e[5]=x,e[6]=g,e[7]=0,e[8]=o,e[9]=y,e[10]=d,e[11]=0,e[12]=-(S*i+B*n+o*s),e[13]=-(h*i+x*n+y*s),e[14]=-(v*i+g*n+d*s),e[15]=1,e}function ae(e,t,r){let a=t[0],i=t[1],n=t[2],s=t[3],c=t[4],l=t[5],p=t[6],m=t[7],f=t[8],u=t[9],v=t[10],g=t[11],d=t[12],w=t[13],S=t[14],B=t[15],o=r[0],h=r[1],x=r[2],y=r[3];return e[0]=o*a+h*c+x*f+y*d,e[1]=o*i+h*l+x*u+y*w,e[2]=o*n+h*p+x*v+y*S,e[3]=o*s+h*m+x*g+y*B,o=r[4],h=r[5],x=r[6],y=r[7],e[4]=o*a+h*c+x*f+y*d,e[5]=o*i+h*l+x*u+y*w,e[6]=o*n+h*p+x*v+y*S,e[7]=o*s+h*m+x*g+y*B,o=r[8],h=r[9],x=r[10],y=r[11],e[8]=o*a+h*c+x*f+y*d,e[9]=o*i+h*l+x*u+y*w,e[10]=o*n+h*p+x*v+y*S,e[11]=o*s+h*m+x*g+y*B,o=r[12],h=r[13],x=r[14],y=r[15],e[12]=o*a+h*c+x*f+y*d,e[13]=o*i+h*l+x*u+y*w,e[14]=o*n+h*p+x*v+y*S,e[15]=o*s+h*m+x*g+y*B,e}var Fe=4,_t=32*1024*1024,_e=H(),Mr=new Int32Array([-1,-1]);function Ne(e,t,r,a){let i=Number(e);return Number.isFinite(i)?Math.max(t,Math.min(r,i)):a}var Je=new WeakMap,ue=H(),Pe=H(),xe=H(),Be=H(),Qe=new Float32Array(1),Nt=new Uint32Array(Qe.buffer);function Et(e){if(typeof e!="string")return"auto";let t=e.trim().toLowerCase();return t==="pcf"||t==="off"?t:"auto"}function Ot(e){let t=Je.get(e);if(t)return t;let r=1/0,a=1/0,i=1/0,n=-1/0,s=-1/0,c=-1/0;for(let p=0;p+2<e.length;p+=3){let m=e[p],f=e[p+1],u=e[p+2];m<r&&(r=m),m>n&&(n=m),f<a&&(a=f),f>s&&(s=f),u<i&&(i=u),u>c&&(c=u)}let l=Number.isFinite(r)?[r,a,i,n,s,c]:[-.5,-.5,-.5,.5,.5,.5];return Je.set(e,l),l}function de(e,t,r,a){let i=(e[0]+e[3])*.5,n=(e[1]+e[4])*.5,s=(e[2]+e[5])*.5,c=Math.max(0,(e[3]-e[0])*.5),l=Math.max(0,(e[4]-e[1])*.5),p=Math.max(0,(e[5]-e[2])*.5),m=t[0]*i+t[4]*n+t[8]*s+t[12],f=t[1]*i+t[5]*n+t[9]*s+t[13],u=t[2]*i+t[6]*n+t[10]*s+t[14],v=Math.abs(t[0])*c+Math.abs(t[4])*l+Math.abs(t[8])*p,g=Math.abs(t[1])*c+Math.abs(t[5])*l+Math.abs(t[9])*p,d=Math.abs(t[2])*c+Math.abs(t[6])*l+Math.abs(t[10])*p;m-v<r[0]&&(r[0]=m-v),f-g<r[1]&&(r[1]=f-g),u-d<r[2]&&(r[2]=u-d),m+v>a[0]&&(a[0]=m+v),f+g>a[1]&&(a[1]=f+g),u+d>a[2]&&(a[2]=u+d)}function Ut(e){let t=e||{},r=t.modelRootMatrix??_e,a=[1/0,1/0,1/0],i=[-1/0,-1/0,-1/0];for(let f of t.meshes??[]){if(!Ee(f))continue;f.worldSpace===!0?xe.set(f.transform):ae(xe,r,f.transform);let u=f.instanceMatrices;for(let v of f.primitives??[]){if(!v.positions||v.positions.length<3)continue;let g=Ot(v.positions);if(u&&u.length>=16){let d=u.length>>4,w=d>64?Math.ceil(d/64):1;for(let S=0;S<d;S+=w)ae(Be,xe,u.subarray(S*16,S*16+16)),de(g,Be,a,i);if(w>1){let S=d-1;ae(Be,xe,u.subarray(S*16,S*16+16)),de(g,Be,a,i)}}else de(g,xe,a,i)}}if(!Number.isFinite(a[0])){let f=t.bounds;f&&Array.isArray(f.min)&&Array.isArray(f.max)&&de([f.min[0],f.min[1],f.min[2],f.max[0],f.max[1],f.max[2]],r,a,i)}Number.isFinite(a[0])||(a[0]=a[1]=a[2]=-1,i[0]=i[1]=i[2]=1);let n=(a[0]+i[0])*.5,s=(a[1]+i[1])*.5,c=(a[2]+i[2])*.5,l=Math.max(.03,(i[0]-a[0])*.5),p=Math.max(.03,(i[1]-a[1])*.5),m=Math.max(.03,(i[2]-a[2])*.5);return{center:[n,s,c],radius:Math.max(.05,Math.hypot(l,p,m)),min:[n-l,s-p,c-m],max:[n+l,s+p,c+m]}}function qt(e,t,r){let a=Number(t[0])||0,i=Number(t[1])||0,n=Number(t[2])||0,s=Math.hypot(a,i,n);s>1e-6?(a/=s,i/=s,n/=s):(a=.37139067,i=.74278135,n=.59422508);let c=Math.max(.05,r.radius),[l,p,m]=r.center,f=c*2.2,u=[l+a*f,p+i*f,m+n*f],v=Math.abs(i)>.99?[0,0,1]:[0,1,0];Ke(ue,u,r.center,v);let g=[1/0,1/0,1/0],d=[-1/0,-1/0,-1/0];de([...r.min,...r.max],ue,g,d);let w=Math.max(.02,c*.05),S=Math.max(.01,-d[2]-w),B=Math.max(S+.1,-g[2]+w);return Ft(Pe,g[0]-w,Math.max(g[0]+.05,d[0])+w,g[1]-w,Math.max(g[1]+.05,d[1])+w,S,B),ae(e,Pe,ue)}function et(e,t,r,a,i,n){let s=Number(t[0])||0,c=Number(t[1])||0,l=Number(t[2])||0,p=Number(r[0])||0,m=Number(r[1])||0,f=Number(r[2])||0,u=Math.hypot(p,m,f);u<=1e-6&&(p=n.center[0]-s,m=n.center[1]-c,f=n.center[2]-l,u=Math.hypot(p,m,f)),u>1e-6?(p/=u,m/=u,f/=u):(p=0,m=-1,f=0);let v=Math.abs(m)>.99?[0,0,1]:[0,1,0];Ke(ue,[s,c,l],[s+p,c+m,l+f],v);let g=[1/0,1/0,1/0],d=[-1/0,-1/0,-1/0];de([...n.min,...n.max],ue,g,d);let w=-d[2],S=-g[2],B=Math.max(.05,n.radius),o=Math.hypot(n.center[0]-s,n.center[1]-c,n.center[2]-l),h=Math.max(.5,S+B*.25,o+B),x=i&&i>0?Math.max(.25,Math.min(i,h)):h,y=Math.max(.02,x/1500),k=Math.min(x*.4,Math.max(y,Number.isFinite(w)?w-B*.05:y)),V=Math.max(.08,Math.min(2.35,a*2*1.04));return zt(Pe,V,1,k,Math.max(k+.1,x)),ae(e,Pe,ue)}function tt(e){let t=e||{};for(let o of t.meshes??[])if(o.name==="__xr_section_gizmo__"&&o.visible!==!1&&o.worldMatrix&&o.worldMatrix.length>=16){let h=o.worldMatrix,x=Math.hypot(h[8],h[9],h[10])||1,y=h[8]/x,k=h[9]/x,V=h[10]/x;return{enabled:!0,normal:[y,k,V],constant:y*h[12]+k*h[13]+V*h[14]}}let r=(t.container?.getAttribute?.("section-plane")??"").trim().toLowerCase();if(!r||r==="none"||r==="false")return null;let a=[1,0,0],i=0;if(r==="interactive")i=t.bounds?.center[0]??0;else{let o=/^([+-]?[xyz])\s*:\s*([+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?)$/.exec(r);if(!o)return null;let h=o[1].startsWith("-")?-1:1,x=o[1].replace(/^[+-]/,""),y=Math.max(-1e3,Math.min(1e3,Number(o[2])||0));a=x==="x"?[h,0,0]:x==="y"?[0,h,0]:[0,0,h],i=y*h}let n=t.modelRootMatrix??_e,s=n[0]*a[0]+n[4]*a[1]+n[8]*a[2],c=n[1]*a[0]+n[5]*a[1]+n[9]*a[2],l=n[2]*a[0]+n[6]*a[1]+n[10]*a[2],p=Math.hypot(s,c,l)||1,m=s/p,f=c/p,u=l/p,v=a[0]*i,g=a[1]*i,d=a[2]*i,w=n[0]*v+n[4]*g+n[8]*d+n[12],S=n[1]*v+n[5]*g+n[9]*d+n[13],B=n[2]*v+n[6]*g+n[10]*d+n[14];return{enabled:!0,normal:[m,f,u],constant:m*w+f*S+u*B}}function Ee(e){if(e.visible===!1||e.isPluginMesh||e.name==="__contact_shadow__"||e.name==="__xr_reticle__"||e.name==="__xr_section_gizmo__")return!1;let t=e.extras?.xr??e.userData?.xr;return!(t?.splatUrl||t?.splat)}function Oe(e,t){if(!Ee(e))return!1;let r=e.castShadow??e.extras?.shadow?.cast;return r===!1?!1:t?!0:r===!0}function Gt(e,t){if(!e||typeof e!="object")return!1;let r=e;if(!Ee(r))return!1;let a=r.receiveShadow??r.extras?.shadow?.receive;return a!==void 0?!!a:t}function rt(e){return!(e.isTransmissive||e.alphaMode==="BLEND"||(e.baseColor?.[3]??1)<.98)}function K(e,t){return Math.imul((e^t>>>0)>>>0,16777619)>>>0}function J(e,t){return Qe[0]=t||0,K(e,Nt[0])}function ve(e,t,r=64){let a=t.length;if(e=K(e,a),a<=r)for(let i=0;i<a;i++)e=J(e,t[i]);else{let i=Math.max(1,Math.floor(a/r));for(let n=0;n<a;n+=i)e=J(e,t[n]);e=J(e,t[a-1])}return e}function jt(e){let t=e||{},r=t.shadowMaps??t.container?.getAttribute?.("shadow-maps")??"auto",a=Et(r),i=[-1,-1],n=[-1,-1],s=(M=!1)=>({mode:a,mapSize:0,slices:[],dirSlots:i,ptSlots:n,promoteAllCasters:M,promoteAllReceivers:M,digest:0,sectionPlane:null});if(a==="off")return s();let c=[],l=null,p=null,m=!1,f=0,u=0;for(let M of t.lights??[])M.type==="hemisphere"?m=!0:M.type==="directional"&&f<2?(l||(l=M),M.shadow?.cast&&c.length<Fe&&c.push({kind:"directional",subIdx:f,light:M}),f++):(M.type==="spot"||M.type==="point")&&u<2&&(p||(p={kind:M.type,light:M}),M.shadow?.cast&&c.length<Fe&&c.push({kind:M.type,subIdx:u,light:M}),u++);if(a==="pcf"&&c.length===0&&(l?c.push({kind:"directional",subIdx:0,light:l}):m?p&&c.push({kind:p.kind,subIdx:0,light:p.light}):c.push({kind:"directional",subIdx:0,light:{type:"directional",direction:[.5,1,.8]}})),c.length===0)return s();let v=t.meshes??[],g=!1;for(let M of v)if(M.castShadow!==void 0||M.receiveShadow!==void 0||M.extras?.shadow!==void 0){g=!0;break}let d=a==="pcf"||!g,w=d,S=!1;for(let M of v)if(Oe(M,d)){for(let L of M.primitives??[])if(rt(L)&&L.indexCount>0){S=!0;break}if(S)break}if(!S)return s(d);let B=1024;for(let M of c){let L=M.light.shadow?.mapSize;typeof L=="number"&&Number.isFinite(L)&&(B=Math.max(B,Math.round(L)))}let o=Math.max(256,Math.min(2048,B)),h=c.length;for(;o>256&&o*o*h*4>_t;)o=Math.max(256,o>>1);let x=Ut(t),y=x.radius*2.2/o,k=[];for(let M=0;M<c.length;M++){let L=c[M],I=L.light,z=I.shadow,_=H(),R;if(L.kind==="directional"){i[L.subIdx]=M;let T=I.direction??[.5,1,.8],C=Math.hypot(T[0]??.5,T[1]??1,T[2]??.8)||1;R=[-(T[0]??.5)/C,-(T[1]??1)/C,-(T[2]??.8)/C],qt(_,T,x)}else{n[L.subIdx]=M;let T=I.position??[0,2,0];if(L.kind==="spot"){let C=I.direction??[0,-1,0],G=Math.hypot(C[0]??0,C[1]??-1,C[2]??0)||1;R=[(C[0]??0)/G,(C[1]??-1)/G,(C[2]??0)/G];let ee=Math.max(.02,Math.min(Math.PI/2,I.outerConeAngle??Math.PI/3));et(_,T,R,ee,I.range,x)}else{let C=x.center[0]-(T[0]??0),G=x.center[1]-(T[1]??0),ee=x.center[2]-(T[2]??0),te=Math.hypot(C,G,ee);R=te>1e-6?[C/te,G/te,ee/te]:[0,-1,0],et(_,T,R,Math.PI/3,I.range,x)}}let W=Ne(z?.bias,-.05,.05,-5e-4),Z=Ne(z?.normalBias,0,.5,.015),E=Ne(z?.radius,0,16,1.5);k.push({slot:M,viewProj:_,rayDir:R,depthBias:W,normalBiasWorld:Z/.015*1.75*y,uvRadius:E*1.35/o})}let V=tt(t),P=2166136261;P=K(P,a==="pcf"?2:1),P=K(P,o),P=K(P,k.length);for(let M of k)P=ve(P,M.viewProj,16),P=J(P,M.depthBias),P=J(P,M.normalBiasWorld);V?.enabled?(P=K(P,1),P=J(P,V.normal[0]),P=J(P,V.normal[1]),P=J(P,V.normal[2]),P=J(P,V.constant)):P=K(P,0);let F=t.modelRootMatrix??_e;P=ve(P,F,16);let N=0;for(let M of v){if(!Oe(M,d)){N++;continue}P=K(P,N++),P=ve(P,M.transform,16),M.instanceMatrices&&(P=ve(P,M.instanceMatrices,64));for(let L of M.primitives??[])rt(L)&&(P=K(P,L.indexCount),L.translations&&(P=ve(P,L.translations,48)))}return P===0&&(P=1),{mode:a,mapSize:o,slices:k,dirSlots:i,ptSlots:n,promoteAllCasters:d,promoteAllReceivers:w,digest:P,sectionPlane:V}}var Wt=800,Ht=32,Xt=128,Yt=8,Zt=32;function Le(e,t){for(let r=0;r<4;r++){let a=r*4,i=t[a+2],n=t[a+3];e[a]=t[a],e[a+1]=t[a+1],e[a+2]=.5*(i+n),e[a+3]=n}return e}function Ue(e,t){let r=new Float32Array(e,0,200),a=new Uint32Array(e,0,200),i=new Int32Array(e,0,200);r.fill(0),Le(r.subarray(0,16),t.vp);for(let d=0;d<16;d++)r[16+d]=t.modelRoot[d]??(d%5===0?1:0);r[32]=t.eyePos[0],r[33]=t.eyePos[1],r[34]=t.eyePos[2],r[35]=Number.isFinite(t.exposure)?Math.max(0,t.exposure):1;let n=.28,s=.28,c=.28,l=!1,p=0,m=1,f=0,u=0,v=0;for(let d of t.lights){let w=d.color??[1,1,1],S=d.intensity!==void 0?d.intensity:1;if(d.type==="ambient")n=(w[0]??1)*S,s=(w[1]??1)*S,c=(w[2]??1)*S;else if(d.type==="hemisphere"){l=!0;let B=d.groundColor??[.2,.2,.2],o=S*.65;r[40]+=(w[0]??1)*o,r[41]+=(w[1]??1)*o,r[42]+=(w[2]??1)*o,r[44]+=(B[0]??.2)*o,r[45]+=(B[1]??.2)*o,r[46]+=(B[2]??.2)*o;let h=d.position??[0,1,0],x=Math.hypot(h[0]??0,h[1]??1,h[2]??0);x>1e-5&&(p=(h[0]??0)/x,m=(h[1]??1)/x,f=(h[2]??0)/x)}else if(d.type==="directional"&&u<2){let B=d.direction??[.5,1,.8],o=52+u*8;r[o]=B[0]??.5,r[o+1]=B[1]??1,r[o+2]=B[2]??.8,r[o+4]=(w[0]??1)*S,r[o+5]=(w[1]??1)*S,r[o+6]=(w[2]??1)*S,u++}else if((d.type==="point"||d.type==="spot")&&v<2){let B=d.position??[0,0,0],o=68+v*16;if(r[o]=B[0]??0,r[o+1]=B[1]??0,r[o+2]=B[2]??0,r[o+4]=(w[0]??1)*S,r[o+5]=(w[1]??1)*S,r[o+6]=(w[2]??1)*S,d.type==="spot"){let h=d.direction??[0,-1,0],x=Math.max(.01,Math.min(Math.PI/2,d.outerConeAngle??Math.PI/3)),y=Math.max(0,Math.min(x-1e-4,d.innerConeAngle??0)),k=Math.hypot(h[0]??0,h[1]??-1,h[2]??0)||1;r[o+8]=(h[0]??0)/k,r[o+9]=(h[1]??-1)/k,r[o+10]=(h[2]??0)/k,r[o+12]=Math.cos(y),r[o+13]=Math.cos(x)}else r[o+9]=-1,r[o+12]=-2,r[o+13]=-3;v++}}u===0&&!l&&(r[52]=.5,r[53]=1,r[54]=.8,r[56]=1,r[57]=1,r[58]=1,u=1),r[36]=n,r[37]=s,r[38]=c,r[39]=Number.isFinite(t.envIntensity)?Math.max(0,t.envIntensity):1,r[48]=p,r[49]=m,r[50]=f;let g=0;if(t.hasEnvMap&&(g|=1),t.sectionPlane?.enabled&&(g|=2,r[100]=t.sectionPlane.normal[0],r[101]=t.sectionPlane.normal[1],r[102]=t.sectionPlane.normal[2],r[103]=t.sectionPlane.constant),t.isRightEye&&(g|=4),t.contactShadow&&t.contactShadow.intensity>0&&(r[104]=t.contactShadow.centerX,r[105]=t.contactShadow.floorY,r[106]=t.contactShadow.centerZ,r[107]=Math.max(.01,t.contactShadow.halfExtentX),r[108]=Math.max(.01,t.contactShadow.halfExtentZ),r[109]=Math.min(1,Math.max(0,t.contactShadow.intensity)),r[110]=Math.min(1,Math.max(0,t.contactShadow.softness))),a[112]=Math.max(0,t.toneMappingIndex|0)>>>0,a[113]=u>>>0,a[114]=v>>>0,a[115]=g>>>0,i[196]=-1,i[197]=-1,i[198]=-1,i[199]=-1,t.shadowMap&&t.shadowMap.slices.length>0){for(let d of t.shadowMap.slices){if(d.slot<0||d.slot>=4)continue;Le(r.subarray(116+d.slot*16,132+d.slot*16),d.viewProj);let w=180+d.slot*4;r[w]=d.depthBias,r[w+1]=d.normalBiasWorld*.5,r[w+2]=d.uvRadius}i[196]=t.shadowMap.dirSlots[0]|0,i[197]=t.shadowMap.dirSlots[1]|0,i[198]=t.shadowMap.ptSlots[0]|0,i[199]=t.shadowMap.ptSlots[1]|0}}function $t(e,t,r,a,i,n){let s=new Float32Array(e,0,44),c=new Uint32Array(e,0,44);s.fill(0),Le(s.subarray(0,16),t);for(let l=0;l<16;l++)s[16+l]=r[l]??(l%5===0?1:0);s[32]=a[0],s[33]=a[1],s[34]=a[2],s[35]=i,n?.enabled&&(s[36]=n.normal[0],s[37]=n.normal[1],s[38]=n.normal[2],s[39]=n.constant,c[40]=1)}var qe=`
17
+ struct SceneUniforms {
18
+ viewProj: mat4x4<f32>,
19
+ modelRoot: mat4x4<f32>,
20
+ camAndExp: vec4<f32>,
21
+ ambAndEnv: vec4<f32>,
22
+ hemiSky: vec4<f32>,
23
+ hemiGround: vec4<f32>,
24
+ hemiAxis: vec4<f32>,
25
+ dirDir0: vec4<f32>,
26
+ dirCol0: vec4<f32>,
27
+ dirDir1: vec4<f32>,
28
+ dirCol1: vec4<f32>,
29
+ ptPos0: vec4<f32>,
30
+ ptCol0: vec4<f32>,
31
+ ptSpotDir0: vec4<f32>,
32
+ ptSpotCone0: vec4<f32>,
33
+ ptPos1: vec4<f32>,
34
+ ptCol1: vec4<f32>,
35
+ ptSpotDir1: vec4<f32>,
36
+ ptSpotCone1: vec4<f32>,
37
+ sectionPlane: vec4<f32>,
38
+ shadowBox: vec4<f32>,
39
+ shadowParams: vec4<f32>,
40
+ flags: vec4<u32>,
41
+ shdVP0: mat4x4<f32>,
42
+ shdVP1: mat4x4<f32>,
43
+ shdVP2: mat4x4<f32>,
44
+ shdVP3: mat4x4<f32>,
45
+ shdParams0: vec4<f32>,
46
+ shdParams1: vec4<f32>,
47
+ shdParams2: vec4<f32>,
48
+ shdParams3: vec4<f32>,
49
+ shdSlots: vec4<i32>,
50
+ };
51
+
52
+ struct PartInstance {
53
+ model: mat4x4<f32>,
54
+ baseColor: vec4<f32>,
55
+ pbr: vec4<f32>,
56
+ emissive: vec4<f32>,
57
+ aux: vec2<f32>,
58
+ flags: u32,
59
+ pickId: u32,
60
+ };
61
+
62
+ @group(0) @binding(0) var<uniform> sc: SceneUniforms;
63
+ @group(0) @binding(1) var<storage, read> parts: array<PartInstance>;
64
+ @group(0) @binding(2) var linSampler: sampler;
65
+ @group(0) @binding(3) var envTex: texture_2d<f32>;
66
+ @group(0) @binding(4) var shadowSampler: sampler_comparison;
67
+ @group(0) @binding(5) var shadowTex: texture_depth_2d_array;
68
+ `,Ge=qe+`
69
+ @group(1) @binding(0) var baseTex: texture_2d<f32>;
70
+ @group(1) @binding(1) var mrTex: texture_2d<f32>;
71
+ @group(1) @binding(2) var normTex: texture_2d<f32>;
72
+ @group(1) @binding(3) var occTex: texture_2d<f32>;
73
+ @group(1) @binding(4) var emTex: texture_2d<f32>;
74
+
75
+ struct VsOut {
76
+ @builtin(position) clipPos: vec4<f32>,
77
+ @location(0) worldPos: vec3<f32>,
78
+ @location(1) normal: vec3<f32>,
79
+ @location(2) uv: vec2<f32>,
80
+ @location(3) @interpolate(flat) instIdx: u32,
81
+ };
82
+
83
+ @vertex
84
+ fn vsMain(
85
+ @location(0) aPos: vec3<f32>,
86
+ @location(1) aNormal: vec3<f32>,
87
+ @location(2) aUV: vec2<f32>,
88
+ @builtin(instance_index) instIdx: u32,
89
+ ) -> VsOut {
90
+ let p = parts[instIdx];
91
+ var out: VsOut;
92
+ if ((p.flags & 128u) != 0u) {
93
+ out.clipPos = vec4<f32>(2.0, 2.0, 2.0, 1.0);
94
+ out.worldPos = vec3<f32>(0.0);
95
+ out.normal = vec3<f32>(0.0, 1.0, 0.0);
96
+ out.uv = vec2<f32>(0.0);
97
+ out.instIdx = instIdx;
98
+ return out;
99
+ }
100
+ var m: mat4x4<f32>;
101
+ if ((p.flags & 1u) != 0u) {
102
+ m = p.model;
103
+ } else {
104
+ m = sc.modelRoot * p.model;
105
+ }
106
+ let world = m * vec4<f32>(aPos, 1.0);
107
+
108
+ let c0 = m[0].xyz;
109
+ let c1 = m[1].xyz;
110
+ let c2 = m[2].xyz;
111
+ let adj0 = cross(c1, c2);
112
+ let adj1 = cross(c2, c0);
113
+ let adj2 = cross(c0, c1);
114
+ let det = dot(c0, adj0);
115
+ var rawN = vec3<f32>(0.0);
116
+ if (abs(det) > 1e-12) {
117
+ let sgn = select(-1.0, 1.0, det > 0.0);
118
+ rawN = (adj0 * aNormal.x + adj1 * aNormal.y + adj2 * aNormal.z) * sgn;
119
+ } else {
120
+ rawN = c0 * aNormal.x + c1 * aNormal.y + c2 * aNormal.z;
121
+ }
122
+ let nLen = length(rawN);
123
+
124
+ let stereoMode = (p.flags >> 8u) & 3u;
125
+ let isRight = (sc.flags.w & 4u) != 0u;
126
+ var uv = aUV;
127
+ if (stereoMode == 1u) {
128
+ uv = vec2<f32>(aUV.x * 0.5 + select(0.0, 0.5, isRight), aUV.y);
129
+ } else if (stereoMode == 2u) {
130
+ uv = vec2<f32>(aUV.x, aUV.y * 0.5 + select(0.0, 0.5, isRight));
131
+ }
132
+
133
+ out.clipPos = sc.viewProj * world;
134
+ out.worldPos = world.xyz;
135
+ out.normal = select(vec3<f32>(0.0), rawN / nLen, nLen > 1e-5);
136
+ out.uv = uv;
137
+ out.instIdx = instIdx;
138
+ return out;
139
+ }
140
+
141
+ fn envBRDF(r: f32, n: f32) -> vec2<f32> {
142
+ let c0 = vec4<f32>(-1.0, -0.0275, -0.572, 0.022);
143
+ let c1 = vec4<f32>(1.0, 0.0425, 1.04, -0.04);
144
+ let rv = r * c0 + c1;
145
+ let a = min(rv.x * rv.x, exp2(-9.28 * n)) * rv.x + rv.y;
146
+ return vec2<f32>(-1.04, 1.04) * a + rv.zw;
147
+ }
148
+
149
+ fn fSchlickRoughness(f0: vec3<f32>, r: f32, n: f32) -> vec3<f32> {
150
+ return f0 + (max(vec3<f32>(1.0 - r), f0) - f0) * pow(clamp(1.0 - n, 0.0, 1.0), 5.0);
151
+ }
152
+
153
+ fn getStudioRadiance(rDir: vec3<f32>, r: f32) -> vec3<f32> {
154
+ let kd = normalize(vec3<f32>(0.0, 1.0, 0.35));
155
+ let fd = normalize(vec3<f32>(-0.85, 0.45, -0.35));
156
+ let ki = pow(max(dot(rDir, kd), 0.0), mix(96.0, 1.5, r)) * mix(2.4, 0.5, r);
157
+ let fi = pow(max(dot(rDir, fd), 0.0), mix(36.0, 1.2, r)) * mix(1.3, 0.35, r);
158
+ let ri = pow(clamp(1.0 - abs(rDir.y), 0.0, 1.0), 3.5) * mix(0.55, 0.22, r);
159
+ return mix(vec3<f32>(0.06, 0.06, 0.08), vec3<f32>(0.48, 0.50, 0.55), rDir.y * 0.5 + 0.5)
160
+ + vec3<f32>(1.0, 0.98, 0.94) * ki
161
+ + vec3<f32>(0.85, 0.92, 1.0) * fi
162
+ + vec3<f32>(0.65, 0.72, 0.85) * ri;
163
+ }
164
+
165
+ fn equirectangularUV(dir: vec3<f32>) -> vec2<f32> {
166
+ let d = normalize(dir);
167
+ return vec2<f32>(
168
+ atan2(d.z, d.x) * 0.15915494309 + 0.5,
169
+ 0.5 - asin(clamp(d.y, -1.0, 1.0)) * 0.31830988618,
170
+ );
171
+ }
172
+
173
+ fn neutralToneMapping(cIn: vec3<f32>) -> vec3<f32> {
174
+ var c = cIn;
175
+ let x = min(c.r, min(c.g, c.b));
176
+ c -= select(0.04, x - 6.25 * x * x, x < 0.08);
177
+ let p = max(c.r, max(c.g, c.b));
178
+ if (p < 0.76) {
179
+ return clamp(c, vec3<f32>(0.0), vec3<f32>(1.0));
180
+ }
181
+ let n = 1.0 - 0.0576 / (p - 0.52);
182
+ c *= n / p;
183
+ return clamp(mix(c, vec3<f32>(n), 1.0 - 1.0 / (0.15 * (p - n) + 1.0)), vec3<f32>(0.0), vec3<f32>(1.0));
184
+ }
185
+
186
+ fn acesToneMapping(cIn: vec3<f32>) -> vec3<f32> {
187
+ let c = cIn * 0.6;
188
+ return clamp((c * (2.51 * c + 0.03)) / (c * (2.43 * c + 0.59) + 0.14), vec3<f32>(0.0), vec3<f32>(1.0));
189
+ }
190
+
191
+ fn agxToneMapping(cIn: vec3<f32>) -> vec3<f32> {
192
+ let c = max(cIn, vec3<f32>(0.0));
193
+ let inset = mat3x3<f32>(
194
+ vec3<f32>(0.84247906, 0.04232824, 0.04237565),
195
+ vec3<f32>(0.0784336, 0.87846864, 0.0784336),
196
+ vec3<f32>(0.07922375, 0.07916613, 0.87914297),
197
+ ) * c;
198
+ let e = clamp((log2(max(inset, vec3<f32>(1e-6))) + 12.47393) / 16.5, vec3<f32>(0.0), vec3<f32>(1.0));
199
+ let x2 = e * e;
200
+ let x4 = x2 * x2;
201
+ let s = 15.5 * x4 * x2 - 40.14 * x4 * e + 31.96 * x4 - 6.868 * x2 * e + 0.4298 * x2 + 0.1191 * e - 0.00232;
202
+ let outset = mat3x3<f32>(
203
+ vec3<f32>(1.196879, -0.05289685, -0.05297164),
204
+ vec3<f32>(-0.09802088, 1.15190313, -0.09804345),
205
+ vec3<f32>(-0.09902974, -0.09896118, 1.15107367),
206
+ ) * s;
207
+ return clamp(pow(max(outset, vec3<f32>(0.0)), vec3<f32>(2.2)), vec3<f32>(0.0), vec3<f32>(1.0));
208
+ }
209
+
210
+ fn applyToneMapping(c: vec3<f32>, mode: u32) -> vec3<f32> {
211
+ if (mode == 0u) { return neutralToneMapping(c); }
212
+ if (mode == 1u) { return c / (c + vec3<f32>(1.0)); }
213
+ if (mode == 3u) { return acesToneMapping(c); }
214
+ if (mode == 4u) { return agxToneMapping(c); }
215
+ return clamp(c, vec3<f32>(0.0), vec3<f32>(1.0));
216
+ }
217
+
218
+ fn evalLight(lDir: vec3<f32>, vDir: vec3<f32>, nDir: vec3<f32>, baseRgb: vec3<f32>, specExp: f32, specW: f32, cc: vec2<f32>) -> vec3<f32> {
219
+ let h = max(dot(nDir, normalize(lDir + vDir)), 0.0);
220
+ return baseRgb * max(dot(nDir, lDir), 0.0) * 0.75
221
+ + vec3<f32>(pow(h, specExp) * specW + cc.x * pow(h, mix(64.0, 512.0, 1.0 - cc.y)) * 0.35);
222
+ }
223
+
224
+ const VOGEL_DISK = array<vec2<f32>, 8>(
225
+ vec2<f32>(0.1768, 0.0),
226
+ vec2<f32>(-0.2265, 0.2078),
227
+ vec2<f32>(0.0355, -0.4150),
228
+ vec2<f32>(0.3204, 0.3888),
229
+ vec2<f32>(-0.5562, -0.1455),
230
+ vec2<f32>(0.4916, -0.3806),
231
+ vec2<f32>(-0.1419, 0.6596),
232
+ vec2<f32>(-0.5177, -0.5150),
233
+ );
234
+
235
+ fn evalShadow(slot: i32, recv: bool, wp: vec3<f32>, nDir: vec3<f32>, lDir: vec3<f32>, fragXY: vec2<f32>) -> f32 {
236
+ if (!recv || slot < 0) {
237
+ return 1.0;
238
+ }
239
+ let nl = dot(nDir, lDir);
240
+ if (nl <= 0.0) {
241
+ return 0.0;
242
+ }
243
+ var vp: mat4x4<f32>;
244
+ var sp: vec4<f32>;
245
+ if (slot == 0) {
246
+ vp = sc.shdVP0;
247
+ sp = sc.shdParams0;
248
+ } else if (slot == 1) {
249
+ vp = sc.shdVP1;
250
+ sp = sc.shdParams1;
251
+ } else if (slot == 2) {
252
+ vp = sc.shdVP2;
253
+ sp = sc.shdParams2;
254
+ } else {
255
+ vp = sc.shdVP3;
256
+ sp = sc.shdParams3;
257
+ }
258
+ let scPos = vp * vec4<f32>(wp + nDir * (sp.y * (1.0 - nl)), 1.0);
259
+ if (scPos.w <= 1e-6) {
260
+ return 1.0;
261
+ }
262
+ let ndc = scPos.xyz / scPos.w;
263
+ let suv = vec2<f32>(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);
264
+ if (suv.x <= 0.002 || suv.x >= 0.998 || suv.y <= 0.002 || suv.y >= 0.998 || ndc.z > 1.0 || ndc.z < 0.0) {
265
+ return 1.0;
266
+ }
267
+ let refZ = clamp(ndc.z + sp.x, 0.0, 1.0);
268
+ if (sp.z <= 1e-6) {
269
+ return textureSampleCompareLevel(shadowTex, shadowSampler, suv, slot, refZ);
270
+ }
271
+ let ang = fract(52.9829189 * fract(dot(fragXY, vec2<f32>(0.06711056, 0.00583715)))) * 6.2831853;
272
+ let ca = cos(ang);
273
+ let sa = sin(ang);
274
+ var sum = 0.0;
275
+ for (var k = 0; k < 8; k = k + 1) {
276
+ let t = VOGEL_DISK[k];
277
+ let rot = vec2<f32>(ca * t.x - sa * t.y, sa * t.x + ca * t.y) * sp.z;
278
+ sum += textureSampleCompareLevel(shadowTex, shadowSampler, suv + rot, slot, refZ);
279
+ }
280
+ return sum * 0.125;
281
+ }
282
+
283
+ @fragment
284
+ fn fsMain(in: VsOut, @builtin(front_facing) frontFacing: bool) -> @location(0) vec4<f32> {
285
+ let p1 = dpdx(in.worldPos);
286
+ let p2 = -dpdy(in.worldPos);
287
+ let u1 = dpdx(in.uv);
288
+ let u2 = -dpdy(in.uv);
289
+ let baseTexel = textureSample(baseTex, linSampler, in.uv);
290
+ let mrTexel = textureSample(mrTex, linSampler, in.uv);
291
+ let normTexel = textureSample(normTex, linSampler, in.uv);
292
+ let occTexel = textureSample(occTex, linSampler, in.uv);
293
+ let emTexel = textureSample(emTex, linSampler, in.uv);
294
+
295
+ let p = parts[in.instIdx];
296
+ let pFlags = p.flags;
297
+ let secOn = (sc.flags.w & 2u) != 0u && (pFlags & 64u) == 0u;
298
+ if (secOn && dot(in.worldPos, sc.sectionPlane.xyz) > sc.sectionPlane.w) {
299
+ discard;
300
+ }
301
+
302
+ var base = p.baseColor;
303
+ if ((pFlags & 2u) != 0u) {
304
+ base *= baseTexel;
305
+ }
306
+ if (base.a < 0.004) {
307
+ discard;
308
+ }
309
+
310
+ var em = p.emissive.xyz;
311
+ if ((pFlags & 32u) != 0u) {
312
+ em *= emTexel.rgb;
313
+ }
314
+ let selGlow = vec3<f32>(p.emissive.w * 0.35, p.emissive.w * 0.5, p.emissive.w * 0.7);
315
+
316
+ let nInLen = length(in.normal);
317
+ if (nInLen < 1e-4 && (pFlags & 2u) != 0u) {
318
+ let unlit = clamp(base.rgb + em + selGlow, vec3<f32>(0.0), vec3<f32>(1.0));
319
+ return vec4<f32>(unlit * base.a, base.a);
320
+ }
321
+
322
+ var N: vec3<f32>;
323
+ if (nInLen < 1e-4) {
324
+ let flatCross = cross(p1, p2);
325
+ let fLen = length(flatCross);
326
+ N = select(vec3<f32>(0.0, 1.0, 0.0), flatCross / fLen, fLen > 1e-8);
327
+ } else {
328
+ N = in.normal / nInLen;
329
+ }
330
+ if (!frontFacing) {
331
+ N = -N;
332
+ }
333
+
334
+ let toCam = sc.camAndExp.xyz - in.worldPos;
335
+ let camDist = length(toCam);
336
+ let V = select(vec3<f32>(0.0, 0.0, 1.0), toCam / camDist, camDist > 1e-6);
337
+
338
+ if ((pFlags & 8u) != 0u) {
339
+ var q = normTexel.xyz * 2.0 - 1.0;
340
+ q = vec3<f32>(q.xy * p.aux.x, q.z);
341
+ let c2 = cross(p2, N);
342
+ let c1 = cross(N, p1);
343
+ let T = c2 * u1.x + c1 * u2.x;
344
+ let B = c2 * u1.y + c1 * u2.y;
345
+ let maxTB = max(dot(T, T), dot(B, B));
346
+ if (maxTB > 1e-12 && length(q) > 1e-5) {
347
+ let k = inverseSqrt(maxTB);
348
+ N = normalize(mat3x3<f32>(T * k, B * k, N) * normalize(q));
349
+ }
350
+ }
351
+
352
+ var metallic = p.pbr.x;
353
+ var roughness = p.pbr.y;
354
+ if ((pFlags & 4u) != 0u) {
355
+ roughness *= mrTexel.g;
356
+ metallic *= mrTexel.b;
357
+ }
358
+ roughness = clamp(roughness, 0.04, 1.0);
359
+ metallic = clamp(metallic, 0.0, 1.0);
360
+
361
+ var occ = 1.0;
362
+ if ((pFlags & 16u) != 0u) {
363
+ occ = mix(1.0, occTexel.r, p.aux.y);
364
+ }
365
+
366
+ let gloss = 1.0 - roughness;
367
+ let specExp = mix(16.0, 256.0, gloss * gloss);
368
+ let specWeight = mix(0.22 * gloss, 1.0, metallic);
369
+ let cc = p.pbr.zw;
370
+
371
+ let recvShd = (pFlags & 2048u) != 0u;
372
+ var directLight = vec3<f32>(0.0);
373
+ let numDir = sc.flags.y;
374
+ if (numDir > 0u) {
375
+ let dL0 = normalize(sc.dirDir0.xyz);
376
+ let sh0 = evalShadow(sc.shdSlots.x, recvShd, in.worldPos, N, dL0, in.clipPos.xy);
377
+ directLight += evalLight(dL0, V, N, base.rgb, specExp, specWeight, cc) * sc.dirCol0.xyz * sh0;
378
+ }
379
+ if (numDir > 1u) {
380
+ let dL1 = normalize(sc.dirDir1.xyz);
381
+ let sh1 = evalShadow(sc.shdSlots.y, recvShd, in.worldPos, N, dL1, in.clipPos.xy);
382
+ directLight += evalLight(dL1, V, N, base.rgb, specExp, specWeight, cc) * sc.dirCol1.xyz * sh1;
383
+ }
384
+
385
+ let numPt = sc.flags.z;
386
+ if (numPt > 0u) {
387
+ let toL = sc.ptPos0.xyz - in.worldPos;
388
+ let dist = length(toL);
389
+ let L = toL / max(dist, 0.0001);
390
+ var spotAtt = clamp((dot(-L, sc.ptSpotDir0.xyz) - sc.ptSpotCone0.y) / max(sc.ptSpotCone0.x - sc.ptSpotCone0.y, 0.0001), 0.0, 1.0);
391
+ spotAtt *= spotAtt;
392
+ let shP0 = evalShadow(sc.shdSlots.z, recvShd, in.worldPos, N, L, in.clipPos.xy);
393
+ directLight += evalLight(L, V, N, base.rgb, specExp, specWeight, cc) * sc.ptCol0.xyz * spotAtt / (1.0 + 0.09 * dist + 0.032 * dist * dist) * shP0;
394
+ }
395
+ if (numPt > 1u) {
396
+ let toL = sc.ptPos1.xyz - in.worldPos;
397
+ let dist = length(toL);
398
+ let L = toL / max(dist, 0.0001);
399
+ var spotAtt = clamp((dot(-L, sc.ptSpotDir1.xyz) - sc.ptSpotCone1.y) / max(sc.ptSpotCone1.x - sc.ptSpotCone1.y, 0.0001), 0.0, 1.0);
400
+ spotAtt *= spotAtt;
401
+ let shP1 = evalShadow(sc.shdSlots.w, recvShd, in.worldPos, N, L, in.clipPos.xy);
402
+ directLight += evalLight(L, V, N, base.rgb, specExp, specWeight, cc) * sc.ptCol1.xyz * spotAtt / (1.0 + 0.09 * dist + 0.032 * dist * dist) * shP1;
403
+ }
404
+
405
+ let R = reflect(-V, N);
406
+ let NoV = clamp(dot(N, V), 0.001, 1.0);
407
+ let F0 = mix(vec3<f32>(0.04), base.rgb, metallic);
408
+ let F = fSchlickRoughness(F0, roughness, NoV);
409
+ let brdf = envBRDF(roughness, NoV);
410
+
411
+ var specularIBL: vec3<f32>;
412
+ var envDiffuse: vec3<f32>;
413
+ if ((sc.flags.w & 1u) != 0u) {
414
+ specularIBL = textureSampleLevel(envTex, linSampler, equirectangularUV(R), 0.0).rgb * (F * brdf.x + brdf.y);
415
+ envDiffuse = textureSampleLevel(envTex, linSampler, equirectangularUV(N), 0.0).rgb;
416
+ } else {
417
+ specularIBL = getStudioRadiance(R, roughness) * (F * brdf.x + brdf.y);
418
+ envDiffuse = mix(vec3<f32>(0.10, 0.10, 0.12), vec3<f32>(0.52, 0.54, 0.58), N.y * 0.5 + 0.5);
419
+ }
420
+
421
+ let kD = (vec3<f32>(1.0) - F) * (1.0 - metallic);
422
+ directLight += kD * base.rgb * mix(sc.hemiGround.xyz, sc.hemiSky.xyz, dot(N, sc.hemiAxis.xyz) * 0.5 + 0.5) * occ;
423
+ let diffuseIBL = kD * base.rgb * (sc.ambAndEnv.xyz + envDiffuse * 0.5) * occ;
424
+ var color = directLight + (diffuseIBL + specularIBL) * sc.ambAndEnv.w + em + selGlow;
425
+ if (cc.x > 0.0) {
426
+ let ccF = fSchlickRoughness(vec3<f32>(0.04), cc.y, NoV) * cc.x;
427
+ color = color * (vec3<f32>(1.0) - ccF) + getStudioRadiance(R, cc.y) * ccF * sc.ambAndEnv.w;
428
+ }
429
+ color = applyToneMapping(color * sc.camAndExp.w, sc.flags.x);
430
+ return vec4<f32>(color * base.a, base.a);
431
+ }
432
+ `,at=qe+`
433
+ struct ShadowVsOut {
434
+ @builtin(position) clipPos: vec4<f32>,
435
+ @location(0) localUv: vec2<f32>,
436
+ };
437
+
438
+ @vertex
439
+ fn vsShadow(@builtin(vertex_index) vid: u32) -> ShadowVsOut {
440
+ let sx = select(-1.0, 1.0, (vid & 1u) != 0u);
441
+ let sz = select(-1.0, 1.0, (vid & 2u) != 0u);
442
+ let world = vec4<f32>(
443
+ sc.shadowBox.x + sx * sc.shadowBox.w,
444
+ sc.shadowBox.y,
445
+ sc.shadowBox.z + sz * sc.shadowParams.x,
446
+ 1.0,
447
+ );
448
+ var out: ShadowVsOut;
449
+ out.clipPos = sc.viewProj * world;
450
+ out.localUv = vec2<f32>(sx, sz);
451
+ return out;
452
+ }
453
+
454
+ @fragment
455
+ fn fsShadow(in: ShadowVsOut) -> @location(0) vec4<f32> {
456
+ let r2 = dot(in.localUv, in.localUv);
457
+ if (r2 >= 1.0) {
458
+ discard;
459
+ }
460
+ let softness = sc.shadowParams.z;
461
+ let falloff = mix(6.5, 2.2, softness);
462
+ let edgeFade = 1.0 - smoothstep(0.55, 1.0, sqrt(r2));
463
+ let alpha = clamp(exp(-r2 * falloff) * edgeFade * sc.shadowParams.y * 0.72, 0.0, 1.0);
464
+ return vec4<f32>(0.0, 0.0, 0.0, alpha);
465
+ }
466
+ `,it=qe+`
467
+ struct PickVsOut {
468
+ @builtin(position) clipPos: vec4<f32>,
469
+ @location(0) worldPos: vec3<f32>,
470
+ @location(1) @interpolate(flat) instIdx: u32,
471
+ };
472
+
473
+ @vertex
474
+ fn vsPick(
475
+ @location(0) aPos: vec3<f32>,
476
+ @builtin(instance_index) instIdx: u32,
477
+ ) -> PickVsOut {
478
+ let p = parts[instIdx];
479
+ var out: PickVsOut;
480
+ if (p.pickId == 0u || (p.flags & 128u) != 0u) {
481
+ out.clipPos = vec4<f32>(2.0, 2.0, 2.0, 1.0);
482
+ out.worldPos = vec3<f32>(0.0);
483
+ out.instIdx = instIdx;
484
+ return out;
485
+ }
486
+ var m: mat4x4<f32>;
487
+ if ((p.flags & 1u) != 0u) {
488
+ m = p.model;
489
+ } else {
490
+ m = sc.modelRoot * p.model;
491
+ }
492
+ let world = m * vec4<f32>(aPos, 1.0);
493
+ out.clipPos = sc.viewProj * world;
494
+ out.worldPos = world.xyz;
495
+ out.instIdx = instIdx;
496
+ return out;
497
+ }
498
+
499
+ @fragment
500
+ fn fsPick(in: PickVsOut) -> @location(0) vec4<f32> {
501
+ let p = parts[in.instIdx];
502
+ let secOn = (sc.flags.w & 2u) != 0u && (p.flags & 64u) == 0u;
503
+ if (secOn && dot(in.worldPos, sc.sectionPlane.xyz) > sc.sectionPlane.w) {
504
+ discard;
505
+ }
506
+ let id = p.pickId;
507
+ return vec4<f32>(
508
+ f32(id & 255u) / 255.0,
509
+ f32((id >> 8u) & 255u) / 255.0,
510
+ f32((id >> 16u) & 255u) / 255.0,
511
+ 1.0,
512
+ );
513
+ }
514
+ `,nt=`
515
+ struct ShadowSliceUniforms {
516
+ lightVP: mat4x4<f32>,
517
+ modelRoot: mat4x4<f32>,
518
+ biasRay: vec4<f32>,
519
+ sectionPlane: vec4<f32>,
520
+ flags: vec4<u32>,
521
+ };
522
+
523
+ struct PartInstance {
524
+ model: mat4x4<f32>,
525
+ baseColor: vec4<f32>,
526
+ pbr: vec4<f32>,
527
+ emissive: vec4<f32>,
528
+ aux: vec2<f32>,
529
+ flags: u32,
530
+ pickId: u32,
531
+ };
532
+
533
+ @group(0) @binding(0) var<uniform> shd: ShadowSliceUniforms;
534
+ @group(0) @binding(1) var<storage, read> parts: array<PartInstance>;
535
+
536
+ struct ShadowDepthOut {
537
+ @builtin(position) clipPos: vec4<f32>,
538
+ @location(0) worldPos: vec3<f32>,
539
+ @location(1) @interpolate(flat) instIdx: u32,
540
+ };
541
+
542
+ @vertex
543
+ fn vsShadowDepth(
544
+ @location(0) aPos: vec3<f32>,
545
+ @location(1) aNormal: vec3<f32>,
546
+ @builtin(instance_index) instIdx: u32,
547
+ ) -> ShadowDepthOut {
548
+ let p = parts[instIdx];
549
+ var out: ShadowDepthOut;
550
+ if ((p.flags & 128u) != 0u || (p.flags & 1024u) == 0u) {
551
+ out.clipPos = vec4<f32>(2.0, 2.0, 2.0, 1.0);
552
+ out.worldPos = vec3<f32>(0.0);
553
+ out.instIdx = instIdx;
554
+ return out;
555
+ }
556
+ var m: mat4x4<f32>;
557
+ if ((p.flags & 1u) != 0u) {
558
+ m = p.model;
559
+ } else {
560
+ m = shd.modelRoot * p.model;
561
+ }
562
+ var wp = m * vec4<f32>(aPos, 1.0);
563
+ let wn = m[0].xyz * aNormal.x + m[1].xyz * aNormal.y + m[2].xyz * aNormal.z;
564
+ let nl = length(wn);
565
+ if (nl > 1e-5 && shd.biasRay.w > 0.0) {
566
+ let un = wn / nl;
567
+ wp = vec4<f32>(
568
+ wp.xyz + un * (shd.biasRay.w * max(1.0 - abs(dot(un, shd.biasRay.xyz)), 0.15)),
569
+ 1.0,
570
+ );
571
+ }
572
+ out.clipPos = shd.lightVP * wp;
573
+ out.worldPos = wp.xyz;
574
+ out.instIdx = instIdx;
575
+ return out;
576
+ }
577
+
578
+ @fragment
579
+ fn fsShadowDepth(in: ShadowDepthOut) {
580
+ let p = parts[in.instIdx];
581
+ if (shd.flags.x != 0u && (p.flags & 64u) == 0u && dot(in.worldPos, shd.sectionPlane.xyz) > shd.sectionPlane.w) {
582
+ discard;
583
+ }
584
+ }
585
+ `,st=1,Q=8,Kt=16,Jt=32,ke=64,Qt=128,er=1,lt=2,Te=4,ie=16,tr=1,ge=1,X=2,je=4,ne=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),O=null,U=null,Y=!1,q="bgra8unorm",Ve=null,Ce=new WeakMap;function D(e){try{e()}catch{}}function ot(e){return Math.max(16,e+3&-4)}function De(){let e=globalThis.navigator?.gpu;return e&&typeof e.requestAdapter=="function"?e:null}function ct(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.createBuffer=="function"&&typeof t.createTexture=="function"&&typeof t.createSampler=="function"&&typeof t.createRenderBundleEncoder=="function"&&typeof t.createRenderPipeline=="function"}function fe(){if(O)return Promise.resolve(O);let e=$(),t=e.webgpuDeviceProvider?.peekDevice?.();return ct(t)?(O=t,q=e.webgpuDeviceProvider?.getCanvasFormat?.()||q,Promise.resolve(t)):Y?Promise.resolve(null):U||(e.webgpuDeviceProvider&&e.webgpuDeviceProvider!==ut?(U=e.webgpuDeviceProvider.acquireDevice().then(r=>(U=null,ct(r)?(O=r,q=e.webgpuDeviceProvider?.getCanvasFormat?.()||q,r):We())).catch(()=>(U=null,We())),U):We())}function We(){let e=De();if(!e)return Y=!0,Promise.resolve(null);try{q=e.getPreferredCanvasFormat?.()||"bgra8unorm"}catch{q="bgra8unorm"}return U=e.requestAdapter({powerPreference:"high-performance"}).then(async t=>{if(!t)return Y=!0,U=null,null;let r=t.limits,a={};for(let[n,s]of[["maxStorageBufferBindingSize",134217728],["maxBufferSize",268435456]])(r?.[n]??0)>s&&(a[n]=r[n]);let i=await(a.maxBufferSize||a.maxStorageBufferBindingSize?t.requestDevice({requiredLimits:a}).catch(()=>t.requestDevice()):t.requestDevice());return O=i,U=null,i.lost?.then?.(()=>{O===i&&(O=null,U=null,Y=!1,Ve?.onDeviceLost(i))}),i}).catch(()=>(Y=!0,U=null,null)),U}var ut={acquireDevice:()=>fe(),peekDevice:()=>O,getCanvasFormat:()=>q};function rr(e,t="bgra8unorm"){O=e,U=null,Y=e===null,q=t}function ar(){O=null,U=null,Y=!1,q="bgra8unorm"}function dt(e){let t=String(e??"").trim().toLowerCase();return t==="webgpu"||t==="webgl2"?t:"auto"}function ir(e){let t=e.container?.getAttribute?.("renderer")??e.renderer??"auto";return dt(t)}function nr(e){let t=e.container,r=t?.hasAttribute?.("bloom")?t.getAttribute?.("bloom")??"":t?.getAttribute?.("bloom")??null;if(r!==null&&!e.stereoSBS){let s=r.trim().toLowerCase();if(s===""||s==="true"||s!=="false"&&s!=="0"&&s!=="none"&&Number(s)>0)return!0}let a=t?.hasAttribute?.("outline")?t.getAttribute?.("outline")??"":t?.getAttribute?.("outline")??null;if(a!==null){let s=a.trim().toLowerCase();if(s!=="false"&&s!=="0"&&s!=="none")return!0}let i=t?.hasAttribute?.("outline-selected")?t.getAttribute?.("outline-selected"):null;if(i!==null&&i!=="false"&&e.selectedMeshName||e.skyboxTexture)return!0;let n=[e.backdropMeshes??[],e.meshes??[]];for(let s of n)for(let c of s){if(c.visible===!1)continue;let l=c.extras?.xr??c.userData?.xr;if(l&&(l.bloom||l.outline||l.splatUrl||l.splat))return!0;for(let p of c.primitives??[])if(p.isTransmissive||p.customProgram&&e.renderProg&&p.customProgram!==e.renderProg&&!($().tslWgslCompiler&&$().tslMaterialResolver?.(e,p.materialIndex))||p.pluginData?.morph||p.pluginData?.skinning||p.instanceCount!==void 0)return!0}return!1}function He(e,t=!!(O||De())){let r=e;if(!r||r.xrSessionActive)return"webgl2";let a=ir(r);if(a==="webgl2"||!t)return"webgl2";let i=!1;for(let n of[r.backdropMeshes??[],r.meshes??[]]){for(let s of n){if(s.visible===!1)continue;let c=s.extras?.xr??s.userData?.xr;if(!(c?.splatUrl||c?.splat)){for(let l of s.primitives??[])if(l.positions&&l.positions.length>=3){i=!0;break}if(i)break}}if(i)break}return!i||a==="auto"&&nr(r)?"webgl2":"webgpu"}function ft(e){let t=Ce.get(e);if(t)return t;let r=e.createBindGroupLayout({entries:[{binding:0,visibility:ge|X,buffer:{type:"uniform"}},{binding:1,visibility:ge|X,buffer:{type:"read-only-storage"}},{binding:2,visibility:X,sampler:{type:"filtering"}},{binding:3,visibility:X,texture:{sampleType:"float"}},{binding:4,visibility:X,sampler:{type:"comparison"}},{binding:5,visibility:X,texture:{sampleType:"depth",viewDimension:"2d-array"}}]}),a=e.createBindGroupLayout({entries:[0,1,2,3,4].map(V=>({binding:V,visibility:X,texture:{sampleType:"float"}}))}),i=e.createBindGroupLayout({entries:[{binding:0,visibility:ge|X,buffer:{type:"uniform"}}]}),n=e.createBindGroupLayout({entries:[{binding:0,visibility:ge|X,buffer:{type:"uniform"}},{binding:1,visibility:ge|X,buffer:{type:"read-only-storage"}}]}),s=e.createPipelineLayout({bindGroupLayouts:[r,a]}),c=e.createPipelineLayout({bindGroupLayouts:[r,a,i]}),l=e.createPipelineLayout({bindGroupLayouts:[r]}),p=e.createPipelineLayout({bindGroupLayouts:[n]}),m=e.createPipelineLayout({bindGroupLayouts:[n,i]}),f=e.createShaderModule({code:Ge}),u=e.createShaderModule({code:at}),v=e.createShaderModule({code:nt}),g=e.createShaderModule({code:it}),d=e.createSampler({magFilter:"linear",minFilter:"linear",mipmapFilter:"linear",addressModeU:"repeat",addressModeV:"repeat"}),w=e.createSampler({compare:"less-equal",magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),S=e.createTexture({size:{width:1,height:1,depthOrArrayLayers:1},format:"rgba8unorm",usage:Te|lt|ie});D(()=>e.queue.writeTexture?.({texture:S},new Uint8Array([255,255,255,255]),{bytesPerRow:256,rowsPerImage:1},{width:1,height:1,depthOrArrayLayers:1}));let B=S.createView(),o=e.createTexture({size:{width:1,height:1,depthOrArrayLayers:1},format:"depth24plus",usage:Te|ie}),h=o.createView({dimension:"2d-array",baseArrayLayer:0,arrayLayerCount:1}),x=e.createBindGroup({layout:a,entries:[0,1,2,3,4].map(V=>({binding:V,resource:B}))}),y=e.createRenderPipeline({layout:l,vertex:{module:g,entryPoint:"vsPick",buffers:[{arrayStride:32,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},fragment:{module:g,entryPoint:"fsPick",targets:[{format:"rgba8unorm"}]},primitive:{topology:"triangle-list",cullMode:"none"},depthStencil:{format:"depth24plus",depthWriteEnabled:!0,depthCompare:"less-equal"},multisample:{count:1}}),k=e.createRenderPipeline({layout:p,vertex:{module:v,entryPoint:"vsShadowDepth",buffers:[{arrayStride:32,attributes:[{shaderLocation:0,offset:0,format:"float32x3"},{shaderLocation:1,offset:12,format:"float32x3"}]}]},fragment:{module:v,entryPoint:"fsShadowDepth",targets:[]},primitive:{topology:"triangle-list",cullMode:"none"},depthStencil:{format:"depth24plus",depthWriteEnabled:!0,depthCompare:"less-equal",depthBias:2,depthBiasSlopeScale:1.5},multisample:{count:1}});return t={sceneBgl:r,matBgl:a,tslBgl:i,shadowSliceBgl:n,scenePipeLayout:s,tslScenePipeLayout:c,auxPipeLayout:l,shadowDepthPipeLayout:p,tslShadowDepthPipeLayout:m,shaderMod:f,shadowMod:u,shadowDepthMod:v,pickMod:g,pickPipeline:y,shadowDepthPipeline:k,sampler:d,shadowSampler:w,whiteTex:S,whiteView:B,dummyShadowTex:o,dummyShadowView:h,defaultMatBg:x,byFormat:new Map,tslShaders:new Map,tslPipelinesByFormat:new Map,texCache:new WeakMap,ownedTextures:new Set([S,o])},Ce.set(e,t),t}function sr(e,t,r,a){let i=t.tslShaders.get(r);if(i)return i;let n=$().tslWgslCompiler;if(!n)return null;let s=n(a,Ge,nt);if(!s)return null;let c=e.createShaderModule({code:s.pbrWgsl}),l=null,p=null;return s.shadowDepthWgsl&&(l=e.createShaderModule({code:s.shadowDepthWgsl}),p=e.createRenderPipeline({layout:t.tslShadowDepthPipeLayout,vertex:{module:l,entryPoint:"vsShadowDepth",buffers:[{arrayStride:32,attributes:[{shaderLocation:0,offset:0,format:"float32x3"},{shaderLocation:1,offset:12,format:"float32x3"},{shaderLocation:2,offset:24,format:"float32x2"}]}]},fragment:{module:l,entryPoint:"fsShadowDepth",targets:[]},primitive:{topology:"triangle-list",cullMode:"none"},depthStencil:{format:"depth24plus",depthWriteEnabled:!0,depthCompare:"less-equal",depthBias:2,depthBiasSlopeScale:1.5},multisample:{count:1}})),i={pbrMod:c,shadowDepthMod:l,shadowDepthPipe:p},t.tslShaders.set(r,i),i}var lr=[{arrayStride:32,attributes:[{shaderLocation:0,offset:0,format:"float32x3"},{shaderLocation:1,offset:12,format:"float32x3"},{shaderLocation:2,offset:24,format:"float32x2"}]}];function pt(e,t,r,a,i){let n=s=>e.createRenderPipeline({layout:t,vertex:{module:r,entryPoint:"vsMain",buffers:lr},fragment:{module:r,entryPoint:"fsMain",targets:[s?{format:a,blend:{color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}:{format:a}]},primitive:{topology:"triangle-list",cullMode:"none"},depthStencil:{format:"depth24plus",depthWriteEnabled:!s,depthCompare:"less-equal"},multisample:{count:i}});return{opaque:n(!1),blend:n(!0)}}function or(e,t,r,a,i,n){let s=t.tslShaders.get(r);if(!s)return null;let c=`${r}:${a}:${i}`,l=t.tslPipelinesByFormat.get(c);return l||(l=pt(e,t.tslScenePipeLayout,s.pbrMod,a,i),t.tslPipelinesByFormat.set(c,l)),n?l.blend:l.opaque}function ht(e,t,r,a){let i=`${r}:${a}`,n=t.byFormat.get(i);if(n)return n;let{opaque:s,blend:c}=pt(e,t.scenePipeLayout,t.shaderMod,r,a),l=e.createRenderPipeline({layout:t.auxPipeLayout,vertex:{module:t.shadowMod,entryPoint:"vsShadow"},fragment:{module:t.shadowMod,entryPoint:"fsShadow",targets:[{format:r,blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-strip",cullMode:"none"},depthStencil:{format:"depth24plus",depthWriteEnabled:!1,depthCompare:"less-equal"},multisample:{count:a}});return n={opaque:s,blend:c,shadow:l},t.byFormat.set(i,n),n}function mt(e){if(!e||typeof e!="object")return null;let t=e,r=Math.floor(t.naturalWidth||t.videoWidth||t.width||0),a=Math.floor(t.naturalHeight||t.videoHeight||t.height||0);return r>0&&a>0?[r,a]:null}function se(e){return!e||typeof e!="object"?null:e.__gpuImageSource||(mt(e)?e:null)}function oe(e,t,r){if(!r)return{view:t.whiteView,src:null,valid:!1};let a=se(r),i=t.texCache.get(r);if(i&&i.src===a)return{view:i.view,src:a,valid:a!==null};if(!a)return{view:t.whiteView,src:null,valid:!1};let n=mt(a);if(!n)return{view:t.whiteView,src:null,valid:!1};i&&(t.ownedTextures.delete(i.tex),D(()=>i.tex.destroy()));let[s,c]=n,l=e.createTexture({size:{width:s,height:c,depthOrArrayLayers:1},format:"rgba8unorm",usage:Te|lt|ie}),p=!1;if(typeof e.queue.copyExternalImageToTexture=="function"&&D(()=>{e.queue.copyExternalImageToTexture({source:a},{texture:l},{width:s,height:c,depthOrArrayLayers:1}),p=!0}),!p&&typeof e.queue.writeTexture=="function"&&a.data){let f=a.data,u=Math.ceil(s*4/256)*256,v=new Uint8Array(u*c);for(let g=0;g<c;g++)v.set(f.subarray(g*s*4,(g+1)*s*4),g*u);D(()=>{e.queue.writeTexture({texture:l},v,{bytesPerRow:u,rowsPerImage:c},{width:s,height:c,depthOrArrayLayers:1}),p=!0})}if(!p)return D(()=>l.destroy()),{view:t.whiteView,src:null,valid:!1};let m=l.createView();return t.ownedTextures.add(l),t.texCache.set(r,{tex:l,view:m,src:a}),{view:m,src:a,valid:!0}}function xt(e,t,r){let a=oe(e,t,r.texture),i=oe(e,t,r.metallicRoughnessTexture),n=oe(e,t,r.normalTexture),s=oe(e,t,r.occlusionTexture),c=oe(e,t,r.emissiveTexture),l=0;return a.valid&&(l|=2),i.valid&&(l|=4),n.valid&&(l|=8),s.valid&&(l|=16),c.valid&&(l|=32),l===0?{bg:t.defaultMatBg,texFlags:0,src0:a.src,src1:i.src,src2:n.src,src3:s.src,src4:c.src}:{bg:e.createBindGroup({layout:t.matBgl,entries:[{binding:0,resource:a.view},{binding:1,resource:i.view},{binding:2,resource:n.view},{binding:3,resource:s.view},{binding:4,resource:c.view}]}),texFlags:l,src0:a.src,src1:i.src,src2:n.src,src3:s.src,src4:c.src}}function cr(e,t){let r=e,a=[],i=()=>{if(!t.visible||!t.canvas)return null;try{let s=document.createElement("canvas"),c=s.width=t.canvas.width||e.width||1,l=s.height=t.canvas.height||e.height||1,p=s.getContext?.("2d");if(!p)return null;p.drawImage(e,0,0,c,l),p.drawImage(t.canvas,0,0,c,l);let m=e.parentElement?.querySelector?.("canvas.xr-live-webgpu-splat");return m&&m.style?.display!=="none"&&p.drawImage(m,0,0,c,l),s}catch{return null}},n=(s,c)=>{let l=r[s];if(typeof l!="function")return;let p=Object.prototype.hasOwnProperty.call(e,s);r[s]=c(l.bind(e)),a.push(()=>{p?r[s]=l:delete r[s]})};return n("toDataURL",s=>(c,l)=>{let p=i();return p?p.toDataURL(c,l):s(c,l)}),n("toBlob",s=>(c,l,p)=>{let m=i();m&&typeof m.toBlob=="function"?m.toBlob(c,l,p):s(c,l,p)}),()=>a.forEach(s=>s())}function vt(e){return tt(e)}function ur(e,t){let r=Number(e.shadowIntensity??0);if(!(r>0)||t||!e.bounds)return null;let a=e.bounds,i=Math.max(0,Math.min(1,Number(e.shadowSoftness??.5))),n=e.modelRootMatrix??ne,s=a.center[0],c=a.center[1],l=a.center[2],p=Math.max(.02,(a.max[0]-a.min[0])*.5),m=Math.max(.02,(a.max[1]-a.min[1])*.5),f=Math.max(.02,(a.max[2]-a.min[2])*.5),u=n[0]*s+n[4]*c+n[8]*l+n[12],v=n[1]*s+n[5]*c+n[9]*l+n[13],g=n[2]*s+n[6]*c+n[10]*l+n[14],d=Math.abs(n[0])*p+Math.abs(n[4])*m+Math.abs(n[8])*f,w=Math.abs(n[1])*p+Math.abs(n[5])*m+Math.abs(n[9])*f,S=Math.abs(n[2])*p+Math.abs(n[6])*m+Math.abs(n[10])*f,B=1.35+i*.5;return{centerX:u,floorY:v-w-5e-4,centerZ:g,halfExtentX:Math.max(.05,d*B),halfExtentZ:Math.max(.05,S*B),intensity:Math.min(1,r),softness:i}}function gt(e){return e.environmentTexture&&typeof e.environmentTexture=="object"?e.environmentTexture:e.environmentSource&&typeof e.environmentSource=="object"?e.environmentSource:null}function pe(e){if(e){D(()=>e.vertexBuf.destroy()),D(()=>e.indexBuf?.destroy()),D(()=>e.partBuf.destroy()),D(()=>e.uniformBuf.destroy()),D(()=>e.pickUniformBuf?.destroy());for(let t of e.shadowSliceBufs)D(()=>t?.destroy());for(let t of e.tslSlots.values())D(()=>t.buf.destroy())}}function wt(e,t,r,a,i){let n=$().tslMaterialResolver;if(!n||i===void 0||i<0)return{tslHash:null,tslBg:null,tslShadowPipe:null};let s=n(r,i);if(!s)return{tslHash:null,tslBg:null,tslShadowPipe:null};let c=sr(e,t,s.hash,s.graph);if(!c)return{tslHash:null,tslBg:null,tslShadowPipe:null};let l=a.get(i);if(!l||l.hash!==s.hash){D(()=>l?.buf.destroy());let p=e.createBuffer({size:s.buf68.byteLength,usage:ke|Q});e.queue.writeBuffer(p,0,s.buf68);let m=e.createBindGroup({layout:t.tslBgl,entries:[{binding:0,resource:{buffer:p}}]});l={buf:p,bg:m,hash:s.hash,usesVertexPosition:s.usesVertexPosition,uploadedVersion:s.version},a.set(i,l)}return{tslHash:s.hash,tslBg:l.bg,tslShadowPipe:c.shadowDepthPipe}}function Xe(e){D(()=>e.shadowTex?.destroy()),e.shadowTex=null,e.shadowArrayView=null,e.shadowLayerViews=[],e.shadowSize=0,e.shadowLayers=0,e.lastShadowDigest=0}function Ie(e){D(()=>e.msaaTex?.destroy()),D(()=>e.depthTex?.destroy()),e.msaaTex=null,e.msaaView=null,e.depthTex=null,e.depthView=null,e.width=0,e.height=0}function Re(e){D(()=>e.pickColorTex?.destroy()),D(()=>e.pickDepthTex?.destroy()),D(()=>e.pickReadBuf?.destroy()),e.pickColorTex=null,e.pickColorView=null,e.pickDepthTex=null,e.pickDepthView=null,e.pickReadBuf=null,e.pickBusy=!1}function yt(e,t,r){if(e.backdropCount!==t.length||e.meshRefs.length!==t.length+r.length)return!1;for(let a=0;a<t.length;a++)if(e.meshRefs[a]!==t[a])return!1;for(let a=0;a<r.length;a++)if(e.meshRefs[t.length+a]!==r[a])return!1;for(let a of e.groups){if(a.prim.positions!==a.posRef||(a.prim.indices??null)!==a.idxRef)return!1;let i=a.mesh.instanceMatrices;if((i&&i.length>=16?i.length>>4:a.prim.instanceCount!==void 0&&a.prim.translations?a.prim.instanceCount:1)!==a.instanceCount)return!1}return!0}function bt(e,t,r,a){let i=a?r.backdropMeshes??[]:[],n=r.meshes??[],s=[...i,...n],c=0,l=0,p=0,m=[],f=new Map;for(let k=0;k<s.length;k++){let V=s[k],P=V.extras?.xr??V.userData?.xr;if(P?.splatUrl||P?.splat)continue;let F=k<i.length,N=F||V.isPluginMesh||P?.pointerEvents==="none"?-1:k-i.length,M=V.instanceMatrices;for(let L of V.primitives??[]){let I=L.positions;if(!I||I.length<3)continue;let z=Math.floor(I.length/3);if(z<=0)continue;let _=L.indices??null,R=!!(_&&_.length>0),W=R?_.length:Math.min(z,L.indexCount??z);if(W<=0)continue;let Z=M&&M.length>=16?M.length>>4:L.instanceCount!==void 0&&L.translations?Math.max(1,L.instanceCount|0):1,E=xt(e,t,L),T=wt(e,t,r,f,L.materialIndex);m.push({mesh:V,prim:L,posRef:I,idxRef:_,meshIndex:N,isBackdrop:F,firstVertex:c,vertexCount:z,indexed:R,firstIndex:l,indexCount:W,firstInstance:p,instanceCount:Z,isBlend:L.alphaMode==="BLEND"||(L.baseColor?.[3]??1)<.999,matIndex:L.materialIndex,tslHash:T.tslHash,tslBg:T.tslBg,tslShadowPipe:T.tslShadowPipe,tex0:L.texture??null,tex1:L.metallicRoughnessTexture??null,tex2:L.normalTexture??null,tex3:L.occlusionTexture??null,tex4:L.emissiveTexture??null,src0:E.src0,src1:E.src1,src2:E.src2,src3:E.src3,src4:E.src4,matBg:E.bg}),c+=z,R&&(l+=W),p+=Z}}if(m.length===0||c===0||p===0)return null;let u=new Float32Array(c*8),v=l>0?new Uint32Array(l):null;for(let k of m){let V=k.posRef,P=k.prim.normals,F=k.prim.uvs,N=k.vertexCount,M=k.firstVertex*8;for(let L=0;L<N;L++){let I=L*3,z=L*2;u[M]=V[I],u[M+1]=V[I+1],u[M+2]=V[I+2],P&&I+2<P.length&&(u[M+3]=P[I],u[M+4]=P[I+1],u[M+5]=P[I+2]),F&&z+1<F.length&&(u[M+6]=F[z],u[M+7]=F[z+1]),M+=8}if(k.indexed&&v&&k.idxRef){let L=k.idxRef,I=k.firstIndex;for(let z=0;z<k.indexCount;z++)v[I+z]=L[z]}}let g=e.createBuffer({size:ot(u.byteLength),usage:Jt|Q});e.queue.writeBuffer(g,0,u);let d=null;v&&(d=e.createBuffer({size:ot(v.byteLength),usage:Kt|Q}),e.queue.writeBuffer(d,0,v));let w=Math.max(128,p*128),S=e.createBuffer({size:w,usage:Qt|Q}),B=e.createBuffer({size:800,usage:ke|Q}),o=gt(r),h=oe(e,t,o),x=e.createBindGroup({layout:t.sceneBgl,entries:[{binding:0,resource:{buffer:B}},{binding:1,resource:{buffer:S}},{binding:2,resource:t.sampler},{binding:3,resource:h.view},{binding:4,resource:t.shadowSampler},{binding:5,resource:t.dummyShadowView}]}),y=new ArrayBuffer(w);return{meshRefs:s,backdropCount:i.length,groups:m,totalVertices:c,totalIndices:l,totalInstances:p,vertexBuf:g,indexBuf:d,partBuf:S,uniformBuf:B,pickUniformBuf:null,pickSceneBg:null,cpuPartBuf:y,cpuPartF32:new Float32Array(y),cpuPartU32:new Uint32Array(y),gpuPartU32:new Uint32Array(w>>>2),partsUploadedOnce:!1,envSourceRef:se(o),envView:h.view,shadowViewRef:t.dummyShadowView,sceneBg:x,tslSlots:f,tslVertexDirty:!1,shadowSliceBufs:[null,null,null,null],shadowSliceBgs:[null,null,null,null],shadowBundles:[null,null,null,null],opaqueBundle:null,blendBundle:null,pickBundle:null,bundleFormat:"",bundleSamples:0,bundlesDirty:!0}}function dr(e,t,r,a,i){let n=ht(e,t,a,i),s=(c,l)=>{let p=r.groups.filter(d=>d.isBlend===c);if(p.length===0)return null;let m=c?p:[...p.filter(d=>d.isBackdrop),...p.filter(d=>!d.isBackdrop&&d.matBg===t.defaultMatBg),...p.filter(d=>!d.isBackdrop&&d.matBg!==t.defaultMatBg)],f=e.createRenderBundleEncoder({colorFormats:[a],depthStencilFormat:"depth24plus",sampleCount:i});f.setPipeline(l),f.setBindGroup(0,r.sceneBg),f.setVertexBuffer(0,r.vertexBuf),r.indexBuf&&f.setIndexBuffer(r.indexBuf,"uint32");let u=l,v=null,g=null;for(let d of m){let w=d.tslHash?or(e,t,d.tslHash,a,i,c)??l:l;w!==u&&(f.setPipeline(w),u=w),d.matBg!==v&&(f.setBindGroup(1,d.matBg),v=d.matBg),d.tslBg&&d.tslBg!==g&&(f.setBindGroup(2,d.tslBg),g=d.tslBg),d.indexed?f.drawIndexed(d.indexCount,d.instanceCount,d.firstIndex,d.firstVertex,d.firstInstance):f.draw(d.indexCount,d.instanceCount,d.firstVertex,d.firstInstance)}return f.finish()};r.opaqueBundle=s(!1,n.opaque),r.blendBundle=s(!0,n.blend),r.pickBundle=null,r.bundleFormat=a,r.bundleSamples=i,r.bundlesDirty=!1}function fr(e,t,r){if(r.pickUniformBuf||(r.pickUniformBuf=e.createBuffer({size:800,usage:ke|Q})),r.pickSceneBg||(r.pickSceneBg=e.createBindGroup({layout:t.sceneBgl,entries:[{binding:0,resource:{buffer:r.pickUniformBuf}},{binding:1,resource:{buffer:r.partBuf}},{binding:2,resource:t.sampler},{binding:3,resource:t.whiteView},{binding:4,resource:t.shadowSampler},{binding:5,resource:t.dummyShadowView}]})),r.pickBundle)return r.pickBundle;let a=e.createRenderBundleEncoder({colorFormats:["rgba8unorm"],depthStencilFormat:"depth24plus",sampleCount:1});a.setPipeline(t.pickPipeline),a.setBindGroup(0,r.pickSceneBg),a.setVertexBuffer(0,r.vertexBuf),r.indexBuf&&a.setIndexBuffer(r.indexBuf,"uint32");for(let i of r.groups)i.meshIndex<0||(i.indexed?a.drawIndexed(i.indexCount,i.instanceCount,i.firstIndex,i.firstVertex,i.firstInstance):a.draw(i.indexCount,i.instanceCount,i.firstVertex,i.firstInstance));return r.pickBundle=a.finish(),r.pickBundle}function pr(e,t,r,a){if(a<0||a>=Fe)return null;if(r.shadowSliceBufs[a]||(r.shadowSliceBufs[a]=e.createBuffer({size:176,usage:ke|Q})),r.shadowSliceBgs[a]||(r.shadowSliceBgs[a]=e.createBindGroup({layout:t.shadowSliceBgl,entries:[{binding:0,resource:{buffer:r.shadowSliceBufs[a]}},{binding:1,resource:{buffer:r.partBuf}}]})),r.shadowBundles[a])return r.shadowBundles[a];let i=e.createRenderBundleEncoder({colorFormats:[],depthStencilFormat:"depth24plus",sampleCount:1});i.setPipeline(t.shadowDepthPipeline),i.setBindGroup(0,r.shadowSliceBgs[a]),i.setVertexBuffer(0,r.vertexBuf),r.indexBuf&&i.setIndexBuffer(r.indexBuf,"uint32");let n=t.shadowDepthPipeline,s=null;for(let l of r.groups){if(l.isBackdrop||l.isBlend||l.prim.isTransmissive)continue;let p=l.tslShadowPipe??t.shadowDepthPipeline;p!==n&&(i.setPipeline(p),n=p),l.tslShadowPipe&&l.tslBg&&l.tslBg!==s&&(i.setBindGroup(1,l.tslBg),s=l.tslBg),l.indexed?i.drawIndexed(l.indexCount,l.instanceCount,l.firstIndex,l.firstVertex,l.firstInstance):i.draw(l.indexCount,l.instanceCount,l.firstVertex,l.firstInstance)}let c=i.finish();return r.shadowBundles[a]=c,c}var Ye=H(),ce=H();function St(e,t,r,a,i,n,s){let c=gt(r),l=se(c),p=a.envView;if(l!==a.envSourceRef){let o=oe(e,t,c);a.envSourceRef=o.src,p=o.view}let m=s??a.shadowViewRef;(p!==a.envView||m!==a.shadowViewRef)&&(a.envView=p,a.shadowViewRef=m,a.sceneBg=e.createBindGroup({layout:t.sceneBgl,entries:[{binding:0,resource:{buffer:a.uniformBuf}},{binding:1,resource:{buffer:a.partBuf}},{binding:2,resource:t.sampler},{binding:3,resource:p},{binding:4,resource:t.shadowSampler},{binding:5,resource:m}]}),a.bundlesDirty=!0);let f=a.cpuPartF32,u=a.cpuPartU32,v=r.selectedMeshNames,g=r.selectedMeshName||"",d=r.modelRootMatrix??ne,w=i.eye==="none"&&!r.stereoSBS;a.tslVertexDirty=!1;let S=$().tslMaterialResolver;if(S)for(let[o,h]of a.tslSlots.entries()){let x=S(r,o);x&&x.hash===h.hash&&x.version!==h.uploadedVersion&&(e.queue.writeBuffer(h.buf,0,x.buf68),h.uploadedVersion=x.version,h.usesVertexPosition&&(a.tslVertexDirty=!0))}for(let o of a.groups){let h=o.mesh,x=o.prim;if(x.materialIndex!==o.matIndex){o.matIndex=x.materialIndex;let b=wt(e,t,r,a.tslSlots,x.materialIndex);(b.tslHash!==o.tslHash||b.tslBg!==o.tslBg||b.tslShadowPipe!==o.tslShadowPipe)&&(b.tslShadowPipe!==o.tslShadowPipe&&(a.tslVertexDirty=!0),o.tslHash=b.tslHash,o.tslBg=b.tslBg,o.tslShadowPipe=b.tslShadowPipe,a.bundlesDirty=!0,a.shadowBundles=[null,null,null,null])}let y=x.texture??null,k=x.metallicRoughnessTexture??null,V=x.normalTexture??null,P=x.occlusionTexture??null,F=x.emissiveTexture??null;if(y!==o.tex0||k!==o.tex1||V!==o.tex2||P!==o.tex3||F!==o.tex4||se(y)!==o.src0||se(k)!==o.src1||se(V)!==o.src2||se(P)!==o.src3||se(F)!==o.src4){let b=xt(e,t,x);o.tex0=y,o.tex1=k,o.tex2=V,o.tex3=P,o.tex4=F,o.src0=b.src0,o.src1=b.src1,o.src2=b.src2,o.src3=b.src3,o.src4=b.src4,o.matBg!==b.bg&&(o.matBg=b.bg,a.bundlesDirty=!0)}let N=x.baseColor??[1,1,1,1],M=N[0]??1,L=N[1]??1,I=N[2]??1,z=N[3]??1,_=x.alphaMode==="BLEND"||z<.999;_!==o.isBlend&&(o.isBlend=_,a.bundlesDirty=!0,a.shadowBundles=[null,null,null,null]);let R=0;o.src0&&(R|=2),o.src1&&(R|=4),o.src2&&(R|=8),o.src3&&(R|=16),o.src4&&(R|=32),(o.isBackdrop||h.isPluginMesh)&&(R|=64),h.visible===!1&&(R|=128),n&&n.slices.length>0&&!o.isBackdrop&&!_&&!x.isTransmissive&&Oe(h,n.promoteAllCasters)&&(R|=1024),n&&n.slices.length>0&&!o.isBackdrop&&Gt(h,n.promoteAllReceivers)&&(R|=2048);let W=h.extras?.xr??h.userData?.xr,Z=W?.stereo;Z==="sbs"?R|=256:Z==="ou"&&(R|=512);let E=w?W?.billboard:void 0;(o.isBackdrop||h.worldSpace===!0||h.name==="__xr_reticle__"||E)&&(R|=1);let T=h.transform;if(E){o.isBackdrop||h.worldSpace===!0||h.name==="__xr_reticle__"?Ye.set(h.transform):ae(Ye,d,h.transform);let b=Ye,A=Math.hypot(b[0],b[1],b[2])||1,le=Math.hypot(b[4],b[5],b[6])||1,j=Math.hypot(b[8],b[9],b[10])||1,Se=E==="y"||E==="cylindrical"||E==="capsule",me=i.eyePos[0]-b[12],Bt=i.eyePos[2]-b[14],Ae=Math.hypot(me,Bt),Lt=Ae>1e-5?me/Ae:0,kt=Ae>1e-5?Bt/Ae:1;if(Se)b[0]=kt*A,b[1]=0,b[2]=-Lt*A,b[3]=0,b[4]=0,b[5]=le,b[6]=0,b[7]=0,b[8]=Lt*j,b[9]=0,b[10]=kt*j,b[11]=0;else{let re=i.view;b[0]=re[0]*A,b[1]=re[4]*A,b[2]=re[8]*A,b[3]=0,b[4]=re[1]*le,b[5]=re[5]*le,b[6]=re[9]*le,b[7]=0,b[8]=re[2]*j,b[9]=re[6]*j,b[10]=re[10]*j,b[11]=0}T=b}let C=x.metallic??0,G=x.roughness??.5,ee=x.clearcoat??0,te=x.clearcoatRoughness??.04,he=x.emissiveFactor,mr=he?.[0]??0,xr=he?.[1]??0,vr=he?.[2]??0,gr=(v?v.has(h.name):g!==""&&h.name===g)?1:0,wr=x.normalScale??1,yr=x.occlusionStrength??1,br=o.meshIndex>=0?o.meshIndex+1>>>0:0,Ze=h.instanceMatrices,ye=h.instanceColors,be=x.translations;for(let b=0;b<o.instanceCount;b++){let A=(o.firstInstance+b)*32,le=T;if(Ze&&Ze.length>=(b+1)*16)ae(ce,T,Ze.subarray(b*16,b*16+16)),le=ce;else if(be&&be.length>=(b+1)*3){ce.set(T);let j=be[b*3],Se=be[b*3+1],me=be[b*3+2];ce[12]+=T[0]*j+T[4]*Se+T[8]*me,ce[13]+=T[1]*j+T[5]*Se+T[9]*me,ce[14]+=T[2]*j+T[6]*Se+T[10]*me,le=ce}for(let j=0;j<16;j++)f[A+j]=le[j];ye&&ye.length>=(b+1)*3?(f[A+16]=M*ye[b*3],f[A+17]=L*ye[b*3+1],f[A+18]=I*ye[b*3+2]):(f[A+16]=M,f[A+17]=L,f[A+18]=I),f[A+19]=z,f[A+20]=C,f[A+21]=G,f[A+22]=ee,f[A+23]=te,f[A+24]=mr,f[A+25]=xr,f[A+26]=vr,f[A+27]=gr,f[A+28]=wr,f[A+29]=yr,u[A+30]=R>>>0,u[A+31]=br}}let B=a.totalInstances*32;if(!a.partsUploadedOnce)e.queue.writeBuffer(a.partBuf,0,u,0,B),a.gpuPartU32.set(u.subarray(0,B)),a.partsUploadedOnce=!0;else{let o=a.gpuPartU32,h=-1,x=-1;for(let y=0;y<B;y++)u[y]!==o[y]&&(h<0&&(h=y),x=y,o[y]=u[y]);if(h>=0){let y=x-h+1;e.queue.writeBuffer(a.partBuf,h*4,u,h,y)}}}function hr(e,t,r,a,i,n){let s=Math.max(1,i),c=Math.max(1,n),l=(r+.5)/s*2-1,p=1-(a+.5)/c*2;for(let m=0;m<4;m++){let f=m*4,u=t[f],v=t[f+1],g=t[f+2],d=t[f+3];e[f]=s*(u-l*d),e[f+1]=c*(v-p*d),e[f+2]=g,e[f+3]=d}return e}var Mt=class{constructor(){this.states=new WeakMap,this.trackedViewers=new Set,this.renderedFrames=0,this.bundleRecordCount=0,this.shadowPassCount=0,this.shadowCacheHits=0}getState(e){let t=this.states.get(e);return t||(t={dev:null,canvas:null,ctx:null,configuredFormat:"",visible:!1,width:0,height:0,sampleCount:je,msaaTex:null,msaaView:null,depthTex:null,depthView:null,shadowTex:null,shadowArrayView:null,shadowLayerViews:[],shadowSize:0,shadowLayers:0,lastShadowDigest:0,pickColorTex:null,pickColorView:null,pickDepthTex:null,pickDepthView:null,pickReadBuf:null,pickBusy:!1,scene:null,unhookSnapshot:null,gen:0,uniformScratch:new ArrayBuffer(800),shadowSliceScratch:new ArrayBuffer(176)},this.states.set(e,t),this.trackedViewers.add(e)),t}ensureCanvas(e,t,r){let a=e.canvas??e.gl?.canvas;if(!a||typeof document>"u")return null;if(!t.canvas){let c=a.parentElement;if(!c||typeof c.insertBefore!="function")return null;let l=document.createElement("canvas");l.className="three-live-webgpu-scene",l.style&&(l.style.cssText="position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none;z-index:0"),c.insertBefore(l,a.nextSibling);let p=l.getContext?.("webgpu");if(!p||typeof p.configure!="function")return D(()=>l.remove?.()),null;t.canvas=l,t.ctx=p,t.visible=!0,t.unhookSnapshot=cr(a,t)}let i=Math.max(1,a.width||1),n=Math.max(1,a.height||1),s=t.canvas.width!==i||t.canvas.height!==n;if(s&&(t.canvas.width=i,t.canvas.height=n),(t.dev!==r||t.configuredFormat!==q||s)&&(t.ctx.configure({device:r,format:q,alphaMode:"premultiplied"}),t.dev=r,t.configuredFormat=q),t.width!==i||t.height!==n||!t.depthTex){Ie(t),t.width=i,t.height=n;let c=je,l=null;D(()=>{l=r.createTexture({size:{width:i,height:n,depthOrArrayLayers:1},format:q,sampleCount:je,usage:ie})}),l||(c=1);let p=r.createTexture({size:{width:i,height:n,depthOrArrayLayers:1},format:"depth24plus",sampleCount:c,usage:ie});t.sampleCount=c,t.msaaTex=l,t.msaaView=l?l.createView():null,t.depthTex=p,t.depthView=p.createView()}return!t.visible&&t.canvas?.style&&(t.canvas.style.display="block",t.visible=!0),t.ctx}renderScene(e,t,r,a,i,n,s,c,l,p){let m={viewer:e,vp:t,proj:r,view:a,eyePos:i,toneMappingIndex:n,viewport:s,eye:c,clear:l,isAR:p},f=m.viewer,u=this.getState(m.viewer);if(!O){if(!Y&&!U){let T=u.gen;fe().then(C=>{C&&u.gen===T&&this.trackedViewers.has(m.viewer)&&D(()=>m.viewer.render?.())})}return this.hideLayer(m.viewer),!1}let v=O;if(He(f,!0)!=="webgpu")return this.hideLayer(m.viewer),!1;u.dev&&u.dev!==v&&(pe(u.scene),u.scene=null,Ie(u),Xe(u),Re(u));let g=this.ensureCanvas(f,u,v);if(!g)return!1;let d=ft(v),w=!m.isAR,S=w?f.backdropMeshes??[]:[],B=f.meshes??[];if((!u.scene||!yt(u.scene,S,B))&&(pe(u.scene),u.scene=bt(v,d,f,w),u.lastShadowDigest=0,!u.scene))return this.hideLayer(m.viewer),!1;let o=u.scene,h=jt(f),x=d.dummyShadowView,y=h.slices.length;if(y>0){if(!u.shadowTex||u.shadowSize!==h.mapSize||u.shadowLayers<y){D(()=>u.shadowTex?.destroy());let T=Math.max(u.shadowLayers,y),C=v.createTexture({size:{width:h.mapSize,height:h.mapSize,depthOrArrayLayers:T},format:"depth24plus",usage:ie|Te});u.shadowTex=C,u.shadowSize=h.mapSize,u.shadowLayers=T,u.shadowArrayView=C.createView({dimension:"2d-array",baseArrayLayer:0,arrayLayerCount:T}),u.shadowLayerViews=[];for(let G=0;G<T;G++)u.shadowLayerViews.push(C.createView({dimension:"2d",baseArrayLayer:G,arrayLayerCount:1}));u.lastShadowDigest=0}x=u.shadowArrayView}St(v,d,f,o,m,h,x),(o.bundlesDirty||o.bundleFormat!==q||o.bundleSamples!==u.sampleCount)&&(dr(v,d,o,q,u.sampleCount),this.bundleRecordCount++);let k=h.sectionPlane??vt(f),V=ur(f,m.isAR);Ue(u.uniformScratch,{vp:m.vp,modelRoot:f.modelRootMatrix??ne,eyePos:m.eyePos,exposure:f.exposure??1,envIntensity:f.envIntensity??1,toneMappingIndex:m.toneMappingIndex,lights:f.lights??[],hasEnvMap:o.envSourceRef!==null,isRightEye:m.eye==="right",sectionPlane:k,contactShadow:V,shadowMap:y>0?{slices:h.slices,dirSlots:h.dirSlots,ptSlots:h.ptSlots}:null}),v.queue.writeBuffer(o.uniformBuf,0,u.uniformScratch);let P=g.getCurrentTexture().createView(),F=m.isAR?[0,0,0,0]:f.clearColor??[0,0,0,0],N=F[3]??0,M={r:(F[0]??0)*N,g:(F[1]??0)*N,b:(F[2]??0)*N,a:N},L=!!f.stereoSBS,I=u.sampleCount>1&&!!u.msaaView,z=v.createCommandEncoder();if(y>0&&u.shadowTex)if(!o.tslVertexDirty&&u.lastShadowDigest===h.digest)this.shadowCacheHits++;else{u.lastShadowDigest=h.digest;let T=f.modelRootMatrix??ne;for(let C of h.slices){let G=pr(v,d,o,C.slot),ee=o.shadowSliceBufs[C.slot],te=u.shadowLayerViews[C.slot];if(!ee||!te)continue;$t(u.shadowSliceScratch,C.viewProj,T,C.rayDir,C.normalBiasWorld,k),v.queue.writeBuffer(ee,0,u.shadowSliceScratch);let he=z.beginRenderPass({colorAttachments:[],depthStencilAttachment:{view:te,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});G&&he.executeBundles([G]),he.end(),this.shadowPassCount++}}let _=z.beginRenderPass({colorAttachments:[I?{view:u.msaaView,resolveTarget:P,loadOp:m.clear?"clear":"load",storeOp:L?"store":"discard",clearValue:M}:{view:P,loadOp:m.clear?"clear":"load",storeOp:"store",clearValue:M}],depthStencilAttachment:{view:u.depthView,depthClearValue:1,depthLoadOp:m.clear?"clear":"load",depthStoreOp:L?"store":"discard"}}),[R,W,Z,E]=m.viewport;if(_.setViewport&&(R!==0||W!==0||Z!==u.width||E!==u.height)){let T=Math.max(0,Math.min(u.width-1,R)),C=Math.max(0,Math.min(u.height-1,u.height-W-E));_.setViewport(T,C,Math.max(1,Math.min(u.width-T,Z)),Math.max(1,Math.min(u.height-C,E)),0,1)}if(o.opaqueBundle&&_.executeBundles([o.opaqueBundle]),V){let T=ht(v,d,q,u.sampleCount);_.setPipeline(T.shadow),_.setBindGroup(0,o.sceneBg),_.draw(4,1,0,0)}return o.blendBundle&&_.executeBundles([o.blendBundle]),_.end(),v.queue.submit([z.finish()]),this.renderedFrames++,!0}async pickMeshGPU(e,t,r,a){let i=e,n=i.meshes??[];if(n.length===0)return-1;let s=O??await fe();if(!s||typeof s.createCommandEncoder!="function")return-1;let c=this.getState(e),l=c.gen,p=ft(s),m=i.backdropMeshes??[];if((!c.scene||!yt(c.scene,m,n))&&(pe(c.scene),c.scene=bt(s,p,i,!0),!c.scene))return-1;let f=c.scene,u=Math.max(1,i.canvas?.width||c.width||300),v=Math.max(1,i.canvas?.height||c.height||300),g=t;if(i.stereoSBS&&!i.xrSessionActive&&u>=2){let k=Math.max(1,Math.floor(u*.5)),V=t>=k,P=V?t-k:t,F=V?Math.max(1,u-k):k,N=(P+.5)/F*2-1;g=Math.floor((N*.5+1)*.5*u)}let d=Math.max(0,Math.min(u-1,Math.floor(g))),w=Math.max(0,Math.min(v-1,Math.floor(r))),S=H();a?S.set(a):i.projMatrix&&i.viewMatrix?ae(S,i.projMatrix,i.viewMatrix):S.set(ne),St(s,p,i,f,{viewer:e,vp:S,proj:i.projMatrix??ne,view:i.viewMatrix??ne,eyePos:[0,0,3],toneMappingIndex:0,viewport:[0,0,u,v],eye:"none",clear:!0,isAR:!1}),(!c.pickColorTex||!c.pickDepthTex)&&(Re(c),c.pickColorTex=s.createTexture({size:{width:1,height:1,depthOrArrayLayers:1},format:"rgba8unorm",usage:ie|er}),c.pickColorView=c.pickColorTex.createView(),c.pickDepthTex=s.createTexture({size:{width:1,height:1,depthOrArrayLayers:1},format:"depth24plus",usage:ie}),c.pickDepthView=c.pickDepthTex.createView(),c.pickReadBuf=s.createBuffer({size:256,usage:Q|st}));let B=hr(H(),S,d,w,u,v),o=fr(s,p,f),h=new ArrayBuffer(800);Ue(h,{vp:B,modelRoot:i.modelRootMatrix??ne,eyePos:[0,0,0],exposure:1,envIntensity:1,toneMappingIndex:2,lights:[],hasEnvMap:!1,sectionPlane:vt(i)}),s.queue.writeBuffer(f.pickUniformBuf,0,h);let x=!!(c.pickReadBuf&&!c.pickBusy),y=x?c.pickReadBuf:s.createBuffer({size:256,usage:Q|st});x&&(c.pickBusy=!0);try{let k=s.createCommandEncoder(),V=k.beginRenderPass({colorAttachments:[{view:c.pickColorView,loadOp:"clear",storeOp:"store",clearValue:{r:0,g:0,b:0,a:0}}],depthStencilAttachment:{view:c.pickDepthView,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"discard"}});if(V.executeBundles([o]),V.end(),k.copyTextureToBuffer?.({texture:c.pickColorTex},{buffer:y,bytesPerRow:256,rowsPerImage:1},{width:1,height:1,depthOrArrayLayers:1}),s.queue.submit([k.finish()]),await y.mapAsync(tr,0,4),c.gen!==l)return D(()=>y.unmap()),-1;let P=new Uint8Array(y.getMappedRange(0,4)),F=P[0],N=P[1],M=P[2];y.unmap();let L=F+(N<<8)+(M<<16);return L>0&&L<=n.length?L-1:-1}finally{x?c.pickBusy=!1:D(()=>y.destroy())}}willRenderScene(e){if(!O)return!1;let t=e;if(t.xrSessionActive||He(t,!0)!=="webgpu")return!1;if(this.states.get(e)?.ctx)return!0;let r=t.canvas??t.gl?.canvas;return!!(r&&typeof document<"u"&&typeof r.parentElement?.insertBefore=="function")}hideLayer(e){let t=this.states.get(e);t&&t.canvas&&t.visible&&(t.canvas.style&&(t.canvas.style.display="none"),t.visible=!1)}clearViewerScene(e){let t=this.states.get(e);t&&(t.gen++,pe(t.scene),t.scene=null,t.lastShadowDigest=0,this.hideLayer(e))}disposeViewer(e){let t=this.states.get(e);t&&(t.gen++,this.trackedViewers.delete(e),this.states.delete(e),t.unhookSnapshot?.(),t.unhookSnapshot=null,pe(t.scene),t.scene=null,Ie(t),Xe(t),Re(t),D(()=>t.ctx?.unconfigure?.()),D(()=>t.canvas?.remove?.()),t.ctx=null,t.canvas=null,t.dev=null,t.visible=!1)}onDeviceLost(e){let t=Ce.get(e);if(t){for(let r of t.ownedTextures)D(()=>r.destroy());t.ownedTextures.clear(),Ce.delete(e)}for(let r of this.trackedViewers){let a=this.states.get(r);a&&a.dev===e&&(a.gen++,pe(a.scene),a.scene=null,Ie(a),Xe(a),Re(a),a.dev=null,a.configuredFormat="")}}};function we(){return Ve||(Ve=new Mt),Ve}var Pt={name:"three-live-webgpu-scene",onRegister(){let e=$();e.gpuSceneAccelerator=we(),e.webgpuDeviceProvider||(e.webgpuDeviceProvider=ut),!O&&!Y&&!U&&De()&&fe()},onElementConnected(e){let t=e;!O&&!Y&&!U&&De()&&fe().then(r=>{r&&t?.viewer&&D(()=>t.viewer.render?.())})},onAttributeChanged(e,t){(t==="renderer"||t==="section-plane"||t==="shadow-maps")&&e?.viewer?.render?.()},onLoadModel(e){e&&typeof e=="object"&&we().clearViewerScene(e)},onClearScene(e){e&&typeof e=="object"&&we().clearViewerScene(e)},onXRSessionEnd(e){e&&typeof e=="object"&&D(()=>e.render?.())},onDestroy(e,t){t&&typeof t=="object"&&we().disposeViewer(t)}};return At(Pt),Rt($e)})();