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.
- package/README.md +4 -1
- package/dist/index.d.ts +190 -0
- package/dist/three-author-engine.js +171 -163
- package/dist/three-author.cjs +145 -163
- package/dist/three-author.d.ts +190 -0
- package/dist/three-author.js +145 -163
- package/dist/three-convert.cjs +142 -160
- package/dist/three-convert.d.ts +190 -0
- package/dist/three-convert.js +142 -160
- package/dist/three-live-ai.cjs +41 -0
- package/dist/three-live-ai.d.ts +759 -0
- package/dist/three-live-ai.js +41 -0
- package/dist/three-live-ai.min.js +41 -0
- package/dist/three-live-animation.cjs +6 -6
- package/dist/three-live-animation.d.ts +190 -0
- package/dist/three-live-animation.js +5 -5
- package/dist/three-live-animation.min.js +5 -5
- package/dist/three-live-cad.cjs +2 -2
- package/dist/three-live-cad.d.ts +190 -0
- package/dist/three-live-cad.js +2 -2
- package/dist/three-live-cad.min.js +2 -2
- package/dist/three-live-element.cjs +50 -85
- package/dist/three-live-element.d.ts +190 -0
- package/dist/three-live-element.js +50 -85
- package/dist/three-live-full.cjs +907 -189
- package/dist/three-live-full.js +907 -189
- package/dist/three-live-full.min.js +907 -189
- package/dist/three-live-procedural.cjs +16 -0
- package/dist/three-live-procedural.d.ts +759 -0
- package/dist/three-live-procedural.js +16 -0
- package/dist/three-live-procedural.min.js +16 -0
- package/dist/three-live-sandbox.html +11 -1
- package/dist/three-live-studio.cjs +72 -17
- package/dist/three-live-studio.d.ts +190 -0
- package/dist/three-live-studio.js +72 -17
- package/dist/three-live-studio.min.js +73 -18
- package/dist/three-live-tsl.cjs +103 -0
- package/dist/three-live-tsl.d.ts +759 -0
- package/dist/three-live-tsl.js +103 -0
- package/dist/three-live-tsl.min.js +103 -0
- package/dist/three-live-viewer.cjs +50 -85
- package/dist/three-live-viewer.d.ts +190 -0
- package/dist/three-live-viewer.js +50 -85
- package/dist/three-live-viewer.min.js +50 -85
- package/dist/three-live-webgpu.cjs +585 -0
- package/dist/three-live-webgpu.d.ts +759 -0
- package/dist/three-live-webgpu.js +585 -0
- package/dist/three-live-webgpu.min.js +585 -0
- package/dist/three-live.cjs +147 -165
- package/dist/three-live.js +147 -165
- package/dist/three-live.min.js +147 -165
- package/dist/three-view.cjs +49 -84
- package/dist/three-view.d.ts +190 -0
- package/dist/three-view.js +50 -85
- package/dist/three-xr.cjs +141 -159
- package/dist/three-xr.d.ts +190 -0
- package/dist/three-xr.js +140 -158
- 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)})();
|