softbox 4.22.0 → 4.24.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 CHANGED
@@ -35,6 +35,8 @@ Balanced studio lighting, a baked soft contact shadow that grounds the model, au
35
35
  - **[Scenes](#scenes)** — `studio_dome · studio_soft · outdoor_concrete`, one word picks the set the model stands in
36
36
  - **[Turntable](#turntable)** — one-word showcase auto-rotate that pauses while the user drags
37
37
  - **[Animations](#animations)** — GLTF clips autoplay with one word; play/pause/clip-picker API
38
+ - **[Material variants](#material-variants)** — KHR_materials_variants colorways, switched live with one option
39
+ - **[AR](#ar)** — one option hands the model to AR Quick Look (iOS) / Scene Viewer (Android)
38
40
  - **[Photoreal mode](#photoreal-mode--stills)** — progressive path tracing + `captureStill()` PNG export
39
41
  - **[Video capture](#video-capture)** — `captureVideo()` records the canvas to WebM/MP4, zero dependencies
40
42
  - **[Hotspots & click selection](#hotspot-annotations--click-selection)** — DOM pins on world-space points, BVH-accelerated picking
@@ -114,6 +116,57 @@ switching one rebuilds the viewer.
114
116
  Scenes compose with presets — `scene` picks the set, `preset` grades it, and
115
117
  any explicit option you pass overrides both.
116
118
 
119
+ ## Material variants
120
+
121
+ Models that carry [KHR_materials_variants](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_variants)
122
+ (product colorways baked into one GLB) switch **live** — no rebuild, no
123
+ reload:
124
+
125
+ ```tsx
126
+ <SimpleViewer object={url} options={{ variant: 'beach' }} />
127
+ ```
128
+
129
+ Enumerate and switch imperatively via the handle:
130
+
131
+ ```tsx
132
+ viewerRef.current.getVariantNames(); // e.g. ['midnight', 'beach', 'street']
133
+ viewerRef.current.setVariant('street');
134
+ viewerRef.current.setVariant(null); // back to the authored materials
135
+ ```
136
+
137
+ Semantics worth knowing: `variant: null` is the declarative reset, while
138
+ *leaving the option out* is "uncontrolled" — an imperative `setVariant()`
139
+ pick survives unrelated option changes. Variant materials materialize in
140
+ the background right after load (first paint never waits for colorways
141
+ nobody opened); an early pick is applied the moment they're ready.
142
+
143
+ ## AR
144
+
145
+ One option puts an **AR** button over the canvas that opens the model in the
146
+ platform's native AR viewer — no WebXR session, no extra bundle:
147
+
148
+ ```tsx
149
+ <SimpleViewer object={url} options={{ ar: true }} />
150
+
151
+ // iOS AR Quick Look cannot read GLB — give it the USDZ counterpart:
152
+ <SimpleViewer object={url} options={{ ar: { iosSrc: '/shoe.usdz', title: 'Runner' } }} />
153
+ ```
154
+
155
+ - **Android** → Scene Viewer, straight from the model's own URL (`ar: true`
156
+ is enough). The model must be loaded from an **https** URL — a dropped
157
+ `blob:` file has no address a native app could fetch, and Scene Viewer
158
+ refuses plain http. Imperative `loadModel()` swaps are tracked — the
159
+ button always hands off the model that is on stage.
160
+ - **iOS** → AR Quick Look, from `iosSrc` (USDZ).
161
+ - **Desktop / unsupported** → the button simply never renders, so setting
162
+ `ar` unconditionally is safe. On an Android-UA device that turns out to
163
+ have no AR component (Quest, TV boxes), the failed handoff bounces back
164
+ reload-free and the button retires itself.
165
+
166
+ `placement` picks the corner (`bottom-left` by default; it lifts above the
167
+ built-in preset picker on its own). UI-only: toggling `ar` never rebuilds
168
+ the viewer or reloads the model.
169
+
117
170
  ## Turntable
118
171
 
119
172
  One word puts the model on a slowly rotating showcase turntable. It pauses while the user drags and resumes on release; toggling is live, like presets.
@@ -1,4 +1,4 @@
1
- const e=require("./smoothstep-DUhHZEuB.cjs"),t=require("./Pass-D0vYi-gB.cjs");let n=require("three");n=e.P(n,1);function r(e){switch(e){case 1:return`R`;case 2:return`RG`;case 3:return`RGBA`;case 4:return`RGBA`}throw Error()}function i(e){switch(e){case 1:return n.RedFormat;case 2:return n.RGFormat;case 3:return n.RGBAFormat;case 4:return n.RGBAFormat}}function a(e){switch(e){case 1:return n.RedIntegerFormat;case 2:return n.RGIntegerFormat;case 3:return n.RGBAIntegerFormat;case 4:return n.RGBAIntegerFormat}}var o=class extends n.DataTexture{constructor(){super(),this.minFilter=n.NearestFilter,this.magFilter=n.NearestFilter,this.generateMipmaps=!1,this.overrideItemSize=null,this._forcedType=null}updateFrom(e){let t=this.overrideItemSize,o=e.itemSize,s=e.count;if(t!==null){if(o*s%t!==0)throw Error(`VertexAttributeTexture: overrideItemSize must divide evenly into buffer length.`);e.itemSize=t,e.count=s*o/t}let c=e.itemSize,l=e.count,u=e.normalized,d=e.array.constructor,f=d.BYTES_PER_ELEMENT,p=this._forcedType,m=c;if(p===null)switch(d){case Float32Array:p=n.FloatType;break;case Uint8Array:case Uint16Array:case Uint32Array:p=n.UnsignedIntType;break;case Int8Array:case Int16Array:case Int32Array:p=n.IntType;break}let h,g,_,v,y=r(c);switch(p){case n.FloatType:_=1,g=i(c),u&&f===1?(v=d,y+=`8`,d===Uint8Array?h=n.UnsignedByteType:(h=n.ByteType,y+=`_SNORM`)):(v=Float32Array,y+=`32F`,h=n.FloatType);break;case n.IntType:y+=f*8+`I`,_=u?2**(d.BYTES_PER_ELEMENT*8-1):1,g=a(c),f===1?(v=Int8Array,h=n.ByteType):f===2?(v=Int16Array,h=n.ShortType):(v=Int32Array,h=n.IntType);break;case n.UnsignedIntType:y+=f*8+`UI`,_=u?2**(d.BYTES_PER_ELEMENT*8-1):1,g=a(c),f===1?(v=Uint8Array,h=n.UnsignedByteType):f===2?(v=Uint16Array,h=n.UnsignedShortType):(v=Uint32Array,h=n.UnsignedIntType);break}m===3&&(g===n.RGBAFormat||g===n.RGBAIntegerFormat)&&(m=4);let b=Math.ceil(Math.sqrt(l))||1,x=m*b*b,S=new v(x),C=e.normalized;e.normalized=!1;for(let t=0;t<l;t++){let n=m*t;S[n]=e.getX(t)/_,c>=2&&(S[n+1]=e.getY(t)/_),c>=3&&(S[n+2]=e.getZ(t)/_,m===4&&(S[n+3]=1)),c>=4&&(S[n+3]=e.getW(t)/_)}e.normalized=C,this.internalFormat=y,this.format=g,this.type=h,this.image.width=b,this.image.height=b,this.image.data=S,this.needsUpdate=!0,this.dispose(),e.itemSize=o,e.count=s}},s=class extends o{constructor(){super(),this._forcedType=n.UnsignedIntType}},c=class extends o{constructor(){super(),this._forcedType=n.FloatType}},l=class{constructor(){this.index=new s,this.position=new c,this.bvhBounds=new n.DataTexture,this.bvhContents=new n.DataTexture,this._cachedIndexAttr=null,this.index.overrideItemSize=3}updateFrom(t){let{geometry:r}=t;if(d(t,this.bvhBounds,this.bvhContents),this.position.updateFrom(r.attributes.position),t.indirect){let i=t._indirectBuffer;if(this._cachedIndexAttr===null||this._cachedIndexAttr.count!==i.length)if(r.index)this._cachedIndexAttr=r.index.clone();else{let t=e.b(e.x(r));this._cachedIndexAttr=new n.BufferAttribute(t,1,!1)}u(r,i,this._cachedIndexAttr),this.index.updateFrom(this._cachedIndexAttr)}else this.index.updateFrom(r.index)}dispose(){let{index:e,position:t,bvhBounds:n,bvhContents:r}=this;e&&e.dispose(),t&&t.dispose(),n&&n.dispose(),r&&r.dispose()}};function u(e,t,n){let r=n.array,i=e.index?e.index.array:null;for(let e=0,n=t.length;e<n;e++){let n=3*e,a=3*t[e];for(let e=0;e<3;e++)r[n+e]=i?i[a+e]:a+e}}function d(t,r,i){let a=t._roots;if(a.length!==1)throw Error(`MeshBVHUniformStruct: Multi-root BVHs not supported.`);let o=a[0],s=new Uint16Array(o),c=new Uint32Array(o),l=new Float32Array(o),u=o.byteLength/32,d=2*Math.ceil(Math.sqrt(u/2)),f=new Float32Array(4*d*d),p=Math.ceil(Math.sqrt(u)),m=new Uint32Array(2*p*p);for(let t=0;t<u;t++){let n=t*32/4,r=n*2,i=e.S(n);for(let e=0;e<3;e++)f[8*t+0+e]=l[i+0+e],f[8*t+4+e]=l[i+3+e];if(e.w(r,s)){let i=e.C(r,s),a=e.T(n,c),o=e.D|i;m[t*2+0]=o,m[t*2+1]=a}else{let r=c[n+6],i=e.E(n,c);m[t*2+0]=i,m[t*2+1]=r}}r.image.data=f,r.image.width=d,r.image.height=d,r.format=n.RGBAFormat,r.type=n.FloatType,r.internalFormat=`RGBA32F`,r.minFilter=n.NearestFilter,r.magFilter=n.NearestFilter,r.generateMipmaps=!1,r.needsUpdate=!0,r.dispose(),i.image.data=m,i.image.width=p,i.image.height=p,i.format=n.RGIntegerFormat,i.type=n.UnsignedIntType,i.internalFormat=`RG32UI`,i.minFilter=n.NearestFilter,i.magFilter=n.NearestFilter,i.generateMipmaps=!1,i.needsUpdate=!0,i.dispose()}var f=`
1
+ const e=require("./smoothstep-BsyRnZAu.cjs"),t=require("./Pass-D0vYi-gB.cjs");let n=require("three");n=e.I(n,1);function r(e){switch(e){case 1:return`R`;case 2:return`RG`;case 3:return`RGBA`;case 4:return`RGBA`}throw Error()}function i(e){switch(e){case 1:return n.RedFormat;case 2:return n.RGFormat;case 3:return n.RGBAFormat;case 4:return n.RGBAFormat}}function a(e){switch(e){case 1:return n.RedIntegerFormat;case 2:return n.RGIntegerFormat;case 3:return n.RGBAIntegerFormat;case 4:return n.RGBAIntegerFormat}}var o=class extends n.DataTexture{constructor(){super(),this.minFilter=n.NearestFilter,this.magFilter=n.NearestFilter,this.generateMipmaps=!1,this.overrideItemSize=null,this._forcedType=null}updateFrom(e){let t=this.overrideItemSize,o=e.itemSize,s=e.count;if(t!==null){if(o*s%t!==0)throw Error(`VertexAttributeTexture: overrideItemSize must divide evenly into buffer length.`);e.itemSize=t,e.count=s*o/t}let c=e.itemSize,l=e.count,u=e.normalized,d=e.array.constructor,f=d.BYTES_PER_ELEMENT,p=this._forcedType,m=c;if(p===null)switch(d){case Float32Array:p=n.FloatType;break;case Uint8Array:case Uint16Array:case Uint32Array:p=n.UnsignedIntType;break;case Int8Array:case Int16Array:case Int32Array:p=n.IntType;break}let h,g,_,v,y=r(c);switch(p){case n.FloatType:_=1,g=i(c),u&&f===1?(v=d,y+=`8`,d===Uint8Array?h=n.UnsignedByteType:(h=n.ByteType,y+=`_SNORM`)):(v=Float32Array,y+=`32F`,h=n.FloatType);break;case n.IntType:y+=f*8+`I`,_=u?2**(d.BYTES_PER_ELEMENT*8-1):1,g=a(c),f===1?(v=Int8Array,h=n.ByteType):f===2?(v=Int16Array,h=n.ShortType):(v=Int32Array,h=n.IntType);break;case n.UnsignedIntType:y+=f*8+`UI`,_=u?2**(d.BYTES_PER_ELEMENT*8-1):1,g=a(c),f===1?(v=Uint8Array,h=n.UnsignedByteType):f===2?(v=Uint16Array,h=n.UnsignedShortType):(v=Uint32Array,h=n.UnsignedIntType);break}m===3&&(g===n.RGBAFormat||g===n.RGBAIntegerFormat)&&(m=4);let b=Math.ceil(Math.sqrt(l))||1,x=m*b*b,S=new v(x),C=e.normalized;e.normalized=!1;for(let t=0;t<l;t++){let n=m*t;S[n]=e.getX(t)/_,c>=2&&(S[n+1]=e.getY(t)/_),c>=3&&(S[n+2]=e.getZ(t)/_,m===4&&(S[n+3]=1)),c>=4&&(S[n+3]=e.getW(t)/_)}e.normalized=C,this.internalFormat=y,this.format=g,this.type=h,this.image.width=b,this.image.height=b,this.image.data=S,this.needsUpdate=!0,this.dispose(),e.itemSize=o,e.count=s}},s=class extends o{constructor(){super(),this._forcedType=n.UnsignedIntType}},c=class extends o{constructor(){super(),this._forcedType=n.FloatType}},l=class{constructor(){this.index=new s,this.position=new c,this.bvhBounds=new n.DataTexture,this.bvhContents=new n.DataTexture,this._cachedIndexAttr=null,this.index.overrideItemSize=3}updateFrom(t){let{geometry:r}=t;if(d(t,this.bvhBounds,this.bvhContents),this.position.updateFrom(r.attributes.position),t.indirect){let i=t._indirectBuffer;if(this._cachedIndexAttr===null||this._cachedIndexAttr.count!==i.length)if(r.index)this._cachedIndexAttr=r.index.clone();else{let t=e.S(e.C(r));this._cachedIndexAttr=new n.BufferAttribute(t,1,!1)}u(r,i,this._cachedIndexAttr),this.index.updateFrom(this._cachedIndexAttr)}else this.index.updateFrom(r.index)}dispose(){let{index:e,position:t,bvhBounds:n,bvhContents:r}=this;e&&e.dispose(),t&&t.dispose(),n&&n.dispose(),r&&r.dispose()}};function u(e,t,n){let r=n.array,i=e.index?e.index.array:null;for(let e=0,n=t.length;e<n;e++){let n=3*e,a=3*t[e];for(let e=0;e<3;e++)r[n+e]=i?i[a+e]:a+e}}function d(t,r,i){let a=t._roots;if(a.length!==1)throw Error(`MeshBVHUniformStruct: Multi-root BVHs not supported.`);let o=a[0],s=new Uint16Array(o),c=new Uint32Array(o),l=new Float32Array(o),u=o.byteLength/32,d=2*Math.ceil(Math.sqrt(u/2)),f=new Float32Array(4*d*d),p=Math.ceil(Math.sqrt(u)),m=new Uint32Array(2*p*p);for(let t=0;t<u;t++){let n=t*32/4,r=n*2,i=e.w(n);for(let e=0;e<3;e++)f[8*t+0+e]=l[i+0+e],f[8*t+4+e]=l[i+3+e];if(e.E(r,s)){let i=e.T(r,s),a=e.D(n,c),o=e.k|i;m[t*2+0]=o,m[t*2+1]=a}else{let r=c[n+6],i=e.O(n,c);m[t*2+0]=i,m[t*2+1]=r}}r.image.data=f,r.image.width=d,r.image.height=d,r.format=n.RGBAFormat,r.type=n.FloatType,r.internalFormat=`RGBA32F`,r.minFilter=n.NearestFilter,r.magFilter=n.NearestFilter,r.generateMipmaps=!1,r.needsUpdate=!0,r.dispose(),i.image.data=m,i.image.width=p,i.image.height=p,i.format=n.RGIntegerFormat,i.type=n.UnsignedIntType,i.internalFormat=`RG32UI`,i.minFilter=n.NearestFilter,i.magFilter=n.NearestFilter,i.generateMipmaps=!1,i.needsUpdate=!0,i.dispose()}var f=`
2
2
 
3
3
  // A stack of uint32 indices can can store the indices for
4
4
  // a perfectly balanced tree with a depth up to 31. Lower stack
@@ -294,7 +294,7 @@ struct BVH {
294
294
  usampler2D bvhContents;
295
295
 
296
296
  };
297
- `;function h(e,t,n=0){if(e.isInterleavedBufferAttribute){let r=e.itemSize;for(let i=0,a=e.count;i<a;i++){let a=i+n;t.setX(a,e.getX(i)),r>=2&&t.setY(a,e.getY(i)),r>=3&&t.setZ(a,e.getZ(i)),r>=4&&t.setW(a,e.getW(i))}}else{let r=t.array,i=r.constructor,a=r.BYTES_PER_ELEMENT*e.itemSize*n;new i(r.buffer,a,e.array.length).set(e.array)}}function g(e,t=null){let r=e.array.constructor,i=e.normalized,a=e.itemSize;return new n.BufferAttribute(new r(a*(t===null?e.count:t)),a,i)}function _(e,t){if(!e&&!t)return!0;if(!!e!=!!t)return!1;let n=e.count===t.count,r=e.normalized===t.normalized,i=e.array.constructor===t.array.constructor,a=e.itemSize===t.itemSize;return!(!n||!r||!i||!a)}function v(e){let t=e[0].index!==null,n=new Set(Object.keys(e[0].attributes));if(!e[0].getAttribute(`position`))throw Error(`StaticGeometryGenerator: position attribute is required.`);for(let r=0;r<e.length;++r){let i=e[r],a=0;if(t!==(i.index!==null))throw Error(`StaticGeometryGenerator: All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.`);for(let e in i.attributes){if(!n.has(e))throw Error(`StaticGeometryGenerator: All geometries must have compatible attributes; make sure "`+e+`" attribute exists among all geometries, or in none of them.`);a++}if(a!==n.size)throw Error(`StaticGeometryGenerator: All geometries must have the same number of attributes.`)}}function y(e){let t=0;for(let n=0,r=e.length;n<r;n++)t+=e[n].getIndex().count;return t}function b(e){let t=0;for(let n=0,r=e.length;n<r;n++)t+=e[n].getAttribute(`position`).count;return t}function x(e,t,n){e.index&&e.index.count!==t&&e.setIndex(null);let r=e.attributes;for(let t in r)r[t].count!==n&&e.deleteAttribute(t)}function S(e,t={},r=new n.BufferGeometry){let{useGroups:i=!1,forceUpdate:a=!1,skipAssigningAttributes:o=[],overwriteIndex:s=!0}=t;v(e);let c=e[0].index!==null,l=c?y(e):-1,u=b(e);if(x(r,l,u),i){let t=0;for(let n=0,i=e.length;n<i;n++){let i=e[n],a;a=c?i.getIndex().count:i.getAttribute(`position`).count,r.addGroup(t,a,n),t+=a}}if(c){let t=!1;if(r.index||(r.setIndex(new n.BufferAttribute(new Uint32Array(l),1,!1)),t=!0),t||s){let n=0,i=0,s=r.getIndex();for(let r=0,c=e.length;r<c;r++){let c=e[r],l=c.getIndex();if(!(!a&&!t&&o[r]))for(let e=0;e<l.count;++e)s.setX(n+e,l.getX(e)+i);n+=l.count,i+=c.getAttribute(`position`).count}}}let d=Object.keys(e[0].attributes);for(let t=0,n=d.length;t<n;t++){let n=!1,i=d[t];if(!r.getAttribute(i)){let t=e[0].getAttribute(i);r.setAttribute(i,g(t,u)),n=!0}let s=0,c=r.getAttribute(i);for(let t=0,r=e.length;t<r;t++){let r=e[t],l=!a&&!n&&o[t],u=r.getAttribute(i);l||h(u,c,s),s+=u.count}}}function C(e,t,r){let i=e.index,a=e.attributes.position.count,o=i?i.count:a,s=e.groups;s.length===0&&(s=[{count:o,start:0,materialIndex:0}]);let c=e.getAttribute(`materialIndex`);if(!c||c.count!==a){let t;t=r.length<=255?new Uint8Array(a):new Uint16Array(a),c=new n.BufferAttribute(t,1,!1),e.deleteAttribute(`materialIndex`),e.setAttribute(`materialIndex`,c)}let l=c.array;for(let e=0;e<s.length;e++){let n=s[e],a=n.start,c=n.count,u=Math.min(c,o-a),d=Array.isArray(t)?t[n.materialIndex]:t,f=r.indexOf(d);for(let e=0;e<u;e++){let t=a+e;i&&(t=i.getX(t)),l[t]=f}}}function w(e,t){if(!e.index){let t=e.attributes.position.count,n=Array(t);for(let e=0;e<t;e++)n[e]=e;e.setIndex(n)}if(!e.attributes.normal&&t&&t.includes(`normal`)&&e.computeVertexNormals(),!e.attributes.uv&&t&&t.includes(`uv`)){let t=e.attributes.position.count;e.setAttribute(`uv`,new n.BufferAttribute(new Float32Array(t*2),2,!1))}if(!e.attributes.uv2&&t&&t.includes(`uv2`)){let t=e.attributes.position.count;e.setAttribute(`uv2`,new n.BufferAttribute(new Float32Array(t*2),2,!1))}if(!e.attributes.tangent&&t&&t.includes(`tangent`))if(e.attributes.uv&&e.attributes.normal)e.computeTangents();else{let t=e.attributes.position.count;e.setAttribute(`tangent`,new n.BufferAttribute(new Float32Array(t*4),4,!1))}if(!e.attributes.color&&t&&t.includes(`color`)){let t=e.attributes.position.count,r=new Float32Array(t*4);r.fill(1),e.setAttribute(`color`,new n.BufferAttribute(r,4))}}function T(e){let t=0;if(e.byteLength!==0){let n=new Uint8Array(e);for(let r=0;r<e.byteLength;r++){let e=n[r];t=(t<<5)-t+e,t|=0}}return t}function E(e){let t=e.uuid,n=Object.values(e.attributes);e.index&&(n.push(e.index),t+=`index|${e.index.version}`);let r=Object.keys(n).sort();for(let e of r){let r=n[e];t+=`${e}_${r.version}|`}return t}function D(e){let t=e.skeleton;return t?(t.boneTexture||t.computeBoneTexture(),`${T(t.boneTexture.image.data.buffer)}_${t.boneTexture.uuid}`):null}var O=class{constructor(e=null){this.matrixWorld=new n.Matrix4,this.geometryHash=null,this.skeletonHash=null,this.primitiveCount=-1,e!==null&&this.updateFrom(e)}updateFrom(e){let t=e.geometry,n=(t.index?t.index.count:t.attributes.position.count)/3;this.matrixWorld.copy(e.matrixWorld),this.geometryHash=E(t),this.primitiveCount=n,this.skeletonHash=D(e)}didChange(e){let t=e.geometry,n=(t.index?t.index.count:t.attributes.position.count)/3;return!(this.matrixWorld.equals(e.matrixWorld)&&this.geometryHash===E(t)&&this.skeletonHash===D(e)&&this.primitiveCount===n)}},k=new n.Vector3,A=new n.Vector3,j=new n.Vector3,M=new n.Vector4,N=new n.Vector3,P=new n.Vector3,ee=new n.Vector4,te=new n.Vector4,F=new n.Matrix4,I=new n.Matrix4;function ne(e,t,n){let r=e.skeleton,i=e.geometry,a=r.bones,o=r.boneInverses;ee.fromBufferAttribute(i.attributes.skinIndex,t),te.fromBufferAttribute(i.attributes.skinWeight,t),F.elements.fill(0);for(let e=0;e<4;e++){let t=te.getComponent(e);if(t!==0){let n=ee.getComponent(e);I.multiplyMatrices(a[n].matrixWorld,o[n]),re(F,I,t)}}return F.multiply(e.bindMatrix).premultiply(e.bindMatrixInverse),n.transformDirection(F),n}function L(e,t,n,r,i){N.set(0,0,0);for(let a=0,o=e.length;a<o;a++){let o=t[a],s=e[a];o!==0&&(P.fromBufferAttribute(s,r),n?N.addScaledVector(P,o):N.addScaledVector(P.sub(i),o))}i.add(N)}function re(e,t,n){let r=e.elements,i=t.elements;for(let e=0,t=i.length;e<t;e++)r[e]+=i[e]*n}function ie(e){let{index:t,attributes:n}=e;if(t)for(let e=0,n=t.count;e<n;e+=3){let n=t.getX(e),r=t.getX(e+2);t.setX(e,r),t.setX(e+2,n)}else for(let e in n){let t=n[e],r=t.itemSize;for(let e=0,n=t.count;e<n;e+=3)for(let n=0;n<r;n++){let r=t.getComponent(e,n),i=t.getComponent(e+2,n);t.setComponent(e,n,i),t.setComponent(e+2,n,r)}}return e}function ae(e,t={},r=new n.BufferGeometry){t={applyWorldTransforms:!0,attributes:[],...t};let i=e.geometry,a=t.applyWorldTransforms,o=t.attributes.includes(`normal`),s=t.attributes.includes(`tangent`),c=i.attributes,l=r.attributes;for(let e in r.attributes)(!t.attributes.includes(e)||!(e in i.attributes))&&r.deleteAttribute(e);!r.index&&i.index&&(r.index=i.index.clone()),l.position||r.setAttribute(`position`,g(c.position)),o&&!l.normal&&c.normal&&r.setAttribute(`normal`,g(c.normal)),s&&!l.tangent&&c.tangent&&r.setAttribute(`tangent`,g(c.tangent)),_(i.index,r.index),_(c.position,l.position),o&&_(c.normal,l.normal),s&&_(c.tangent,l.tangent);let u=c.position,d=o?c.normal:null,f=s?c.tangent:null,p=i.morphAttributes.position,m=i.morphAttributes.normal,v=i.morphAttributes.tangent,y=i.morphTargetsRelative,b=e.morphTargetInfluences,x=new n.Matrix3;x.getNormalMatrix(e.matrixWorld),i.index&&r.index.array.set(i.index.array);for(let t=0,n=c.position.count;t<n;t++)k.fromBufferAttribute(u,t),d&&A.fromBufferAttribute(d,t),f&&(M.fromBufferAttribute(f,t),j.fromBufferAttribute(f,t)),b&&(p&&L(p,b,y,t,k),m&&L(m,b,y,t,A),v&&L(v,b,y,t,j)),e.isSkinnedMesh&&(e.applyBoneTransform(t,k),d&&ne(e,t,A),f&&ne(e,t,j)),a&&k.applyMatrix4(e.matrixWorld),l.position.setXYZ(t,k.x,k.y,k.z),d&&(a&&A.applyNormalMatrix(x),l.normal.setXYZ(t,A.x,A.y,A.z)),f&&(a&&j.transformDirection(e.matrixWorld),l.tangent.setXYZW(t,j.x,j.y,j.z,M.w));for(let e in t.attributes){let n=t.attributes[e];n===`position`||n===`tangent`||n===`normal`||!(n in c)||(l[n]||r.setAttribute(n,g(c[n])),_(c[n],l[n]),h(c[n],l[n]))}return e.matrixWorld.determinant()<0&&ie(r),r}var oe=class extends n.BufferGeometry{constructor(){super(),this.version=0,this.hash=null,this._diff=new O}isCompatible(e,t){let n=e.geometry;for(let e=0;e<t.length;e++){let r=t[e],i=n.attributes[r],a=this.attributes[r];if(i&&!_(i,a))return!1}return!0}updateFrom(e,t){let n=this._diff;return n.didChange(e)?(ae(e,t,this),n.updateFrom(e),this.version++,this.hash=`${this.uuid}_${this.version}`,!0):!1}};function se(e,t){for(let n=0,r=e.length;n<r;n++)e[n].traverseVisible(e=>{e.isMesh&&t(e)})}function ce(e){let t=[];for(let n=0,r=e.length;n<r;n++){let r=e[n];Array.isArray(r.material)?t.push(...r.material):t.push(r.material)}return t}function le(e,t,r){if(e.length===0){t.setIndex(null);let e=t.attributes;for(let n in e)t.deleteAttribute(n);for(let e in r.attributes)t.setAttribute(r.attributes[e],new n.BufferAttribute(new Float32Array,4,!1))}else S(e,r,t);for(let e in t.attributes)t.attributes[e].needsUpdate=!0}var ue=class{constructor(e){this.objects=null,this.useGroups=!0,this.applyWorldTransforms=!0,this.generateMissingAttributes=!0,this.overwriteIndex=!0,this.attributes=[`position`,`normal`,`color`,`tangent`,`uv`,`uv2`],this._intermediateGeometry=new Map,this._geometryMergeSets=new WeakMap,this._mergeOrder=[],this._dummyMesh=null,this.setObjects(e||[])}_getDummyMesh(){if(!this._dummyMesh){let e=new n.MeshBasicMaterial,t=new n.BufferGeometry;t.setAttribute(`position`,new n.BufferAttribute(new Float32Array(9),3)),this._dummyMesh=new n.Mesh(t,e)}return this._dummyMesh}_getMeshes(){let e=[];return se(this.objects,t=>{e.push(t)}),e.sort((e,t)=>e.uuid>t.uuid?1:e.uuid<t.uuid?-1:0),e.length===0&&e.push(this._getDummyMesh()),e}_updateIntermediateGeometries(){let{_intermediateGeometry:e}=this,t=this._getMeshes(),n=new Set(e.keys()),r={attributes:this.attributes,applyWorldTransforms:this.applyWorldTransforms};for(let i=0,a=t.length;i<a;i++){let a=t[i],o=a.uuid;n.delete(o);let s=e.get(o);(!s||!s.isCompatible(a,this.attributes))&&(s&&s.dispose(),s=new oe,e.set(o,s)),s.updateFrom(a,r)&&this.generateMissingAttributes&&w(s,this.attributes)}n.forEach(t=>{e.delete(t)})}setObjects(e){Array.isArray(e)?this.objects=[...e]:this.objects=[e]}generate(e=new n.BufferGeometry){let{useGroups:t,overwriteIndex:r,_intermediateGeometry:i,_geometryMergeSets:a}=this,o=this._getMeshes(),s=[],c=[],l=a.get(e)||[];this._updateIntermediateGeometries();let u=!1;o.length!==l.length&&(u=!0);for(let e=0,t=o.length;e<t;e++){let t=o[e],n=i.get(t.uuid);c.push(n);let r=l[e];!r||r.uuid!==n.uuid?(s.push(!1),u=!0):r.version===n.version?s.push(!0):s.push(!1)}le(c,e,{useGroups:t,forceUpdate:u,skipAssigningAttributes:s,overwriteIndex:r}),u&&e.dispose(),a.set(e,c.map(e=>({version:e.version,uuid:e.uuid})));let d=0;return u?d=2:s.includes(!1)&&(d=1),{changeType:d,materials:ce(o),geometry:e}}};function de(e){let t=new Set;for(let n=0,r=e.length;n<r;n++){let r=e[n];for(let e in r){let n=r[e];n&&n.isTexture&&t.add(n)}}return Array.from(t)}function fe(e){let t=[],n=new Set;for(let r=0,i=e.length;r<i;r++)e[r].traverse(e=>{e.visible&&(e.isRectAreaLight||e.isSpotLight||e.isPointLight||e.isDirectionalLight)&&(t.push(e),e.iesMap&&n.add(e.iesMap))});return{lights:t,iesTextures:Array.from(n).sort((e,t)=>e.uuid<t.uuid?1:e.uuid>t.uuid?-1:0)}}var pe=class{get initialized(){return!!this.bvh}constructor(e){this.bvhOptions={},this.attributes=[`position`,`normal`,`tangent`,`color`,`uv`,`uv2`],this.generateBVH=!0,this.bvh=null,this.geometry=new n.BufferGeometry,this.staticGeometryGenerator=new ue(e),this._bvhWorker=null,this._pendingGenerate=null,this._buildAsync=!1}setObjects(e){this.staticGeometryGenerator.setObjects(e)}setBVHWorker(e){this._bvhWorker=e}async generateAsync(e=null){if(!this._bvhWorker)throw Error(`PathTracingSceneGenerator: "setBVHWorker" must be called before "generateAsync" can be called.`);if(this.bvh instanceof Promise)return this._pendingGenerate||=new Promise(async()=>(await this.bvh,this._pendingGenerate=null,this.generateAsync(e))),this._pendingGenerate;{this._buildAsync=!0;let t=this.generate(e);return this._buildAsync=!1,t.bvh=this.bvh=await t.bvh,t}}generate(t=null){let{staticGeometryGenerator:n,geometry:r,attributes:i}=this,a=n.objects;n.attributes=i,a.forEach(e=>{e.traverse(e=>{e.isSkinnedMesh&&e.skeleton&&e.skeleton.update()})});let o=n.generate(r),s=o.materials,c=de(s),{lights:l,iesTextures:u}=fe(a);if(o.changeType!==0&&C(r,s,s),this.generateBVH){if(this.bvh instanceof Promise)throw Error(`PathTracingSceneGenerator: BVH is already building asynchronously.`);if(o.changeType===2){let n={strategy:2,maxLeafTris:1,indirect:!0,onProgress:t,...this.bvhOptions};this._buildAsync?this.bvh=this._bvhWorker.generate(r,n):this.bvh=new e.y(r,n)}else o.changeType===1&&this.bvh.refit()}return{bvhChanged:o.changeType!==0,bvh:this.bvh,lights:l,iesTextures:u,geometry:r,materials:s,textures:c,objects:a}}},R=class extends n.ShaderMaterial{set needsUpdate(e){super.needsUpdate=!0,this.dispatchEvent({type:`recompilation`})}constructor(e){super(e);for(let e in this.uniforms)Object.defineProperty(this,e,{get(){return this.uniforms[e].value},set(t){this.uniforms[e].value=t}})}setDefine(e,t=void 0){if(t==null){if(e in this.defines)return delete this.defines[e],this.needsUpdate=!0,!0}else if(this.defines[e]!==t)return this.defines[e]=t,this.needsUpdate=!0,!0;return!1}},me=class extends R{constructor(e){super({blending:n.NoBlending,uniforms:{target1:{value:null},target2:{value:null},opacity:{value:1}},vertexShader:`
297
+ `;function h(e,t,n=0){if(e.isInterleavedBufferAttribute){let r=e.itemSize;for(let i=0,a=e.count;i<a;i++){let a=i+n;t.setX(a,e.getX(i)),r>=2&&t.setY(a,e.getY(i)),r>=3&&t.setZ(a,e.getZ(i)),r>=4&&t.setW(a,e.getW(i))}}else{let r=t.array,i=r.constructor,a=r.BYTES_PER_ELEMENT*e.itemSize*n;new i(r.buffer,a,e.array.length).set(e.array)}}function g(e,t=null){let r=e.array.constructor,i=e.normalized,a=e.itemSize;return new n.BufferAttribute(new r(a*(t===null?e.count:t)),a,i)}function _(e,t){if(!e&&!t)return!0;if(!!e!=!!t)return!1;let n=e.count===t.count,r=e.normalized===t.normalized,i=e.array.constructor===t.array.constructor,a=e.itemSize===t.itemSize;return!(!n||!r||!i||!a)}function v(e){let t=e[0].index!==null,n=new Set(Object.keys(e[0].attributes));if(!e[0].getAttribute(`position`))throw Error(`StaticGeometryGenerator: position attribute is required.`);for(let r=0;r<e.length;++r){let i=e[r],a=0;if(t!==(i.index!==null))throw Error(`StaticGeometryGenerator: All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.`);for(let e in i.attributes){if(!n.has(e))throw Error(`StaticGeometryGenerator: All geometries must have compatible attributes; make sure "`+e+`" attribute exists among all geometries, or in none of them.`);a++}if(a!==n.size)throw Error(`StaticGeometryGenerator: All geometries must have the same number of attributes.`)}}function y(e){let t=0;for(let n=0,r=e.length;n<r;n++)t+=e[n].getIndex().count;return t}function b(e){let t=0;for(let n=0,r=e.length;n<r;n++)t+=e[n].getAttribute(`position`).count;return t}function x(e,t,n){e.index&&e.index.count!==t&&e.setIndex(null);let r=e.attributes;for(let t in r)r[t].count!==n&&e.deleteAttribute(t)}function S(e,t={},r=new n.BufferGeometry){let{useGroups:i=!1,forceUpdate:a=!1,skipAssigningAttributes:o=[],overwriteIndex:s=!0}=t;v(e);let c=e[0].index!==null,l=c?y(e):-1,u=b(e);if(x(r,l,u),i){let t=0;for(let n=0,i=e.length;n<i;n++){let i=e[n],a;a=c?i.getIndex().count:i.getAttribute(`position`).count,r.addGroup(t,a,n),t+=a}}if(c){let t=!1;if(r.index||(r.setIndex(new n.BufferAttribute(new Uint32Array(l),1,!1)),t=!0),t||s){let n=0,i=0,s=r.getIndex();for(let r=0,c=e.length;r<c;r++){let c=e[r],l=c.getIndex();if(!(!a&&!t&&o[r]))for(let e=0;e<l.count;++e)s.setX(n+e,l.getX(e)+i);n+=l.count,i+=c.getAttribute(`position`).count}}}let d=Object.keys(e[0].attributes);for(let t=0,n=d.length;t<n;t++){let n=!1,i=d[t];if(!r.getAttribute(i)){let t=e[0].getAttribute(i);r.setAttribute(i,g(t,u)),n=!0}let s=0,c=r.getAttribute(i);for(let t=0,r=e.length;t<r;t++){let r=e[t],l=!a&&!n&&o[t],u=r.getAttribute(i);l||h(u,c,s),s+=u.count}}}function C(e,t,r){let i=e.index,a=e.attributes.position.count,o=i?i.count:a,s=e.groups;s.length===0&&(s=[{count:o,start:0,materialIndex:0}]);let c=e.getAttribute(`materialIndex`);if(!c||c.count!==a){let t;t=r.length<=255?new Uint8Array(a):new Uint16Array(a),c=new n.BufferAttribute(t,1,!1),e.deleteAttribute(`materialIndex`),e.setAttribute(`materialIndex`,c)}let l=c.array;for(let e=0;e<s.length;e++){let n=s[e],a=n.start,c=n.count,u=Math.min(c,o-a),d=Array.isArray(t)?t[n.materialIndex]:t,f=r.indexOf(d);for(let e=0;e<u;e++){let t=a+e;i&&(t=i.getX(t)),l[t]=f}}}function w(e,t){if(!e.index){let t=e.attributes.position.count,n=Array(t);for(let e=0;e<t;e++)n[e]=e;e.setIndex(n)}if(!e.attributes.normal&&t&&t.includes(`normal`)&&e.computeVertexNormals(),!e.attributes.uv&&t&&t.includes(`uv`)){let t=e.attributes.position.count;e.setAttribute(`uv`,new n.BufferAttribute(new Float32Array(t*2),2,!1))}if(!e.attributes.uv2&&t&&t.includes(`uv2`)){let t=e.attributes.position.count;e.setAttribute(`uv2`,new n.BufferAttribute(new Float32Array(t*2),2,!1))}if(!e.attributes.tangent&&t&&t.includes(`tangent`))if(e.attributes.uv&&e.attributes.normal)e.computeTangents();else{let t=e.attributes.position.count;e.setAttribute(`tangent`,new n.BufferAttribute(new Float32Array(t*4),4,!1))}if(!e.attributes.color&&t&&t.includes(`color`)){let t=e.attributes.position.count,r=new Float32Array(t*4);r.fill(1),e.setAttribute(`color`,new n.BufferAttribute(r,4))}}function T(e){let t=0;if(e.byteLength!==0){let n=new Uint8Array(e);for(let r=0;r<e.byteLength;r++){let e=n[r];t=(t<<5)-t+e,t|=0}}return t}function E(e){let t=e.uuid,n=Object.values(e.attributes);e.index&&(n.push(e.index),t+=`index|${e.index.version}`);let r=Object.keys(n).sort();for(let e of r){let r=n[e];t+=`${e}_${r.version}|`}return t}function D(e){let t=e.skeleton;return t?(t.boneTexture||t.computeBoneTexture(),`${T(t.boneTexture.image.data.buffer)}_${t.boneTexture.uuid}`):null}var O=class{constructor(e=null){this.matrixWorld=new n.Matrix4,this.geometryHash=null,this.skeletonHash=null,this.primitiveCount=-1,e!==null&&this.updateFrom(e)}updateFrom(e){let t=e.geometry,n=(t.index?t.index.count:t.attributes.position.count)/3;this.matrixWorld.copy(e.matrixWorld),this.geometryHash=E(t),this.primitiveCount=n,this.skeletonHash=D(e)}didChange(e){let t=e.geometry,n=(t.index?t.index.count:t.attributes.position.count)/3;return!(this.matrixWorld.equals(e.matrixWorld)&&this.geometryHash===E(t)&&this.skeletonHash===D(e)&&this.primitiveCount===n)}},k=new n.Vector3,A=new n.Vector3,j=new n.Vector3,M=new n.Vector4,N=new n.Vector3,P=new n.Vector3,ee=new n.Vector4,te=new n.Vector4,F=new n.Matrix4,I=new n.Matrix4;function ne(e,t,n){let r=e.skeleton,i=e.geometry,a=r.bones,o=r.boneInverses;ee.fromBufferAttribute(i.attributes.skinIndex,t),te.fromBufferAttribute(i.attributes.skinWeight,t),F.elements.fill(0);for(let e=0;e<4;e++){let t=te.getComponent(e);if(t!==0){let n=ee.getComponent(e);I.multiplyMatrices(a[n].matrixWorld,o[n]),re(F,I,t)}}return F.multiply(e.bindMatrix).premultiply(e.bindMatrixInverse),n.transformDirection(F),n}function L(e,t,n,r,i){N.set(0,0,0);for(let a=0,o=e.length;a<o;a++){let o=t[a],s=e[a];o!==0&&(P.fromBufferAttribute(s,r),n?N.addScaledVector(P,o):N.addScaledVector(P.sub(i),o))}i.add(N)}function re(e,t,n){let r=e.elements,i=t.elements;for(let e=0,t=i.length;e<t;e++)r[e]+=i[e]*n}function ie(e){let{index:t,attributes:n}=e;if(t)for(let e=0,n=t.count;e<n;e+=3){let n=t.getX(e),r=t.getX(e+2);t.setX(e,r),t.setX(e+2,n)}else for(let e in n){let t=n[e],r=t.itemSize;for(let e=0,n=t.count;e<n;e+=3)for(let n=0;n<r;n++){let r=t.getComponent(e,n),i=t.getComponent(e+2,n);t.setComponent(e,n,i),t.setComponent(e+2,n,r)}}return e}function ae(e,t={},r=new n.BufferGeometry){t={applyWorldTransforms:!0,attributes:[],...t};let i=e.geometry,a=t.applyWorldTransforms,o=t.attributes.includes(`normal`),s=t.attributes.includes(`tangent`),c=i.attributes,l=r.attributes;for(let e in r.attributes)(!t.attributes.includes(e)||!(e in i.attributes))&&r.deleteAttribute(e);!r.index&&i.index&&(r.index=i.index.clone()),l.position||r.setAttribute(`position`,g(c.position)),o&&!l.normal&&c.normal&&r.setAttribute(`normal`,g(c.normal)),s&&!l.tangent&&c.tangent&&r.setAttribute(`tangent`,g(c.tangent)),_(i.index,r.index),_(c.position,l.position),o&&_(c.normal,l.normal),s&&_(c.tangent,l.tangent);let u=c.position,d=o?c.normal:null,f=s?c.tangent:null,p=i.morphAttributes.position,m=i.morphAttributes.normal,v=i.morphAttributes.tangent,y=i.morphTargetsRelative,b=e.morphTargetInfluences,x=new n.Matrix3;x.getNormalMatrix(e.matrixWorld),i.index&&r.index.array.set(i.index.array);for(let t=0,n=c.position.count;t<n;t++)k.fromBufferAttribute(u,t),d&&A.fromBufferAttribute(d,t),f&&(M.fromBufferAttribute(f,t),j.fromBufferAttribute(f,t)),b&&(p&&L(p,b,y,t,k),m&&L(m,b,y,t,A),v&&L(v,b,y,t,j)),e.isSkinnedMesh&&(e.applyBoneTransform(t,k),d&&ne(e,t,A),f&&ne(e,t,j)),a&&k.applyMatrix4(e.matrixWorld),l.position.setXYZ(t,k.x,k.y,k.z),d&&(a&&A.applyNormalMatrix(x),l.normal.setXYZ(t,A.x,A.y,A.z)),f&&(a&&j.transformDirection(e.matrixWorld),l.tangent.setXYZW(t,j.x,j.y,j.z,M.w));for(let e in t.attributes){let n=t.attributes[e];n===`position`||n===`tangent`||n===`normal`||!(n in c)||(l[n]||r.setAttribute(n,g(c[n])),_(c[n],l[n]),h(c[n],l[n]))}return e.matrixWorld.determinant()<0&&ie(r),r}var oe=class extends n.BufferGeometry{constructor(){super(),this.version=0,this.hash=null,this._diff=new O}isCompatible(e,t){let n=e.geometry;for(let e=0;e<t.length;e++){let r=t[e],i=n.attributes[r],a=this.attributes[r];if(i&&!_(i,a))return!1}return!0}updateFrom(e,t){let n=this._diff;return n.didChange(e)?(ae(e,t,this),n.updateFrom(e),this.version++,this.hash=`${this.uuid}_${this.version}`,!0):!1}};function se(e,t){for(let n=0,r=e.length;n<r;n++)e[n].traverseVisible(e=>{e.isMesh&&t(e)})}function ce(e){let t=[];for(let n=0,r=e.length;n<r;n++){let r=e[n];Array.isArray(r.material)?t.push(...r.material):t.push(r.material)}return t}function le(e,t,r){if(e.length===0){t.setIndex(null);let e=t.attributes;for(let n in e)t.deleteAttribute(n);for(let e in r.attributes)t.setAttribute(r.attributes[e],new n.BufferAttribute(new Float32Array,4,!1))}else S(e,r,t);for(let e in t.attributes)t.attributes[e].needsUpdate=!0}var ue=class{constructor(e){this.objects=null,this.useGroups=!0,this.applyWorldTransforms=!0,this.generateMissingAttributes=!0,this.overwriteIndex=!0,this.attributes=[`position`,`normal`,`color`,`tangent`,`uv`,`uv2`],this._intermediateGeometry=new Map,this._geometryMergeSets=new WeakMap,this._mergeOrder=[],this._dummyMesh=null,this.setObjects(e||[])}_getDummyMesh(){if(!this._dummyMesh){let e=new n.MeshBasicMaterial,t=new n.BufferGeometry;t.setAttribute(`position`,new n.BufferAttribute(new Float32Array(9),3)),this._dummyMesh=new n.Mesh(t,e)}return this._dummyMesh}_getMeshes(){let e=[];return se(this.objects,t=>{e.push(t)}),e.sort((e,t)=>e.uuid>t.uuid?1:e.uuid<t.uuid?-1:0),e.length===0&&e.push(this._getDummyMesh()),e}_updateIntermediateGeometries(){let{_intermediateGeometry:e}=this,t=this._getMeshes(),n=new Set(e.keys()),r={attributes:this.attributes,applyWorldTransforms:this.applyWorldTransforms};for(let i=0,a=t.length;i<a;i++){let a=t[i],o=a.uuid;n.delete(o);let s=e.get(o);(!s||!s.isCompatible(a,this.attributes))&&(s&&s.dispose(),s=new oe,e.set(o,s)),s.updateFrom(a,r)&&this.generateMissingAttributes&&w(s,this.attributes)}n.forEach(t=>{e.delete(t)})}setObjects(e){Array.isArray(e)?this.objects=[...e]:this.objects=[e]}generate(e=new n.BufferGeometry){let{useGroups:t,overwriteIndex:r,_intermediateGeometry:i,_geometryMergeSets:a}=this,o=this._getMeshes(),s=[],c=[],l=a.get(e)||[];this._updateIntermediateGeometries();let u=!1;o.length!==l.length&&(u=!0);for(let e=0,t=o.length;e<t;e++){let t=o[e],n=i.get(t.uuid);c.push(n);let r=l[e];!r||r.uuid!==n.uuid?(s.push(!1),u=!0):r.version===n.version?s.push(!0):s.push(!1)}le(c,e,{useGroups:t,forceUpdate:u,skipAssigningAttributes:s,overwriteIndex:r}),u&&e.dispose(),a.set(e,c.map(e=>({version:e.version,uuid:e.uuid})));let d=0;return u?d=2:s.includes(!1)&&(d=1),{changeType:d,materials:ce(o),geometry:e}}};function de(e){let t=new Set;for(let n=0,r=e.length;n<r;n++){let r=e[n];for(let e in r){let n=r[e];n&&n.isTexture&&t.add(n)}}return Array.from(t)}function fe(e){let t=[],n=new Set;for(let r=0,i=e.length;r<i;r++)e[r].traverse(e=>{e.visible&&(e.isRectAreaLight||e.isSpotLight||e.isPointLight||e.isDirectionalLight)&&(t.push(e),e.iesMap&&n.add(e.iesMap))});return{lights:t,iesTextures:Array.from(n).sort((e,t)=>e.uuid<t.uuid?1:e.uuid>t.uuid?-1:0)}}var pe=class{get initialized(){return!!this.bvh}constructor(e){this.bvhOptions={},this.attributes=[`position`,`normal`,`tangent`,`color`,`uv`,`uv2`],this.generateBVH=!0,this.bvh=null,this.geometry=new n.BufferGeometry,this.staticGeometryGenerator=new ue(e),this._bvhWorker=null,this._pendingGenerate=null,this._buildAsync=!1}setObjects(e){this.staticGeometryGenerator.setObjects(e)}setBVHWorker(e){this._bvhWorker=e}async generateAsync(e=null){if(!this._bvhWorker)throw Error(`PathTracingSceneGenerator: "setBVHWorker" must be called before "generateAsync" can be called.`);if(this.bvh instanceof Promise)return this._pendingGenerate||=new Promise(async()=>(await this.bvh,this._pendingGenerate=null,this.generateAsync(e))),this._pendingGenerate;{this._buildAsync=!0;let t=this.generate(e);return this._buildAsync=!1,t.bvh=this.bvh=await t.bvh,t}}generate(t=null){let{staticGeometryGenerator:n,geometry:r,attributes:i}=this,a=n.objects;n.attributes=i,a.forEach(e=>{e.traverse(e=>{e.isSkinnedMesh&&e.skeleton&&e.skeleton.update()})});let o=n.generate(r),s=o.materials,c=de(s),{lights:l,iesTextures:u}=fe(a);if(o.changeType!==0&&C(r,s,s),this.generateBVH){if(this.bvh instanceof Promise)throw Error(`PathTracingSceneGenerator: BVH is already building asynchronously.`);if(o.changeType===2){let n={strategy:2,maxLeafTris:1,indirect:!0,onProgress:t,...this.bvhOptions};this._buildAsync?this.bvh=this._bvhWorker.generate(r,n):this.bvh=new e.x(r,n)}else o.changeType===1&&this.bvh.refit()}return{bvhChanged:o.changeType!==0,bvh:this.bvh,lights:l,iesTextures:u,geometry:r,materials:s,textures:c,objects:a}}},R=class extends n.ShaderMaterial{set needsUpdate(e){super.needsUpdate=!0,this.dispatchEvent({type:`recompilation`})}constructor(e){super(e);for(let e in this.uniforms)Object.defineProperty(this,e,{get(){return this.uniforms[e].value},set(t){this.uniforms[e].value=t}})}setDefine(e,t=void 0){if(t==null){if(e in this.defines)return delete this.defines[e],this.needsUpdate=!0,!0}else if(this.defines[e]!==t)return this.defines[e]=t,this.needsUpdate=!0,!0;return!1}},me=class extends R{constructor(e){super({blending:n.NoBlending,uniforms:{target1:{value:null},target2:{value:null},opacity:{value:1}},vertexShader:`
298
298
 
299
299
  varying vec2 vUv;
300
300
 
@@ -3974,7 +3974,7 @@ bool bvhIntersectFogVolumeHit(
3974
3974
  rayDirection.x *= flipEnvMap;
3975
3975
  gl_FragColor = textureCube( envMap, rayDirection );
3976
3976
 
3977
- }`}),this.depthWrite=!1,this.depthTest=!1}},Gt=class{constructor(e){this._renderer=e,this._quad=new t.t(new Wt)}generate(e,t=null,r=null){if(!e.isCubeTexture)throw Error(`CubeToEquirectMaterial: Source can only be cube textures.`);let i=e.images[0],a=this._renderer,o=this._quad;t===null&&(t=4*i.height),r===null&&(r=2*i.height);let s=new n.WebGLRenderTarget(t,r,{type:n.FloatType,colorSpace:i.colorSpace}),c=i.height,l=Math.log2(c)-2,u=1/c,d=1/(3*Math.max(2**l,112));o.material.defines.CUBEUV_MAX_MIP=`${l}.0`,o.material.defines.CUBEUV_TEXEL_WIDTH=d,o.material.defines.CUBEUV_TEXEL_HEIGHT=u,o.material.uniforms.envMap.value=e,o.material.uniforms.flipEnvMap.value=e.isRenderTargetTexture?1:-1,o.material.needsUpdate=!0;let f=a.getRenderTarget(),p=a.autoClear;a.autoClear=!0,a.setRenderTarget(s),o.render(a),a.setRenderTarget(f),a.autoClear=p;let m=new Uint16Array(t*r*4),h=new Float32Array(t*r*4);a.readRenderTargetPixels(s,0,0,t,r,h),s.dispose();for(let e=0,t=h.length;e<t;e++)m[e]=n.DataUtils.toHalfFloat(h[e]);let g=new n.DataTexture(m,t,r,n.RGBAFormat,n.HalfFloatType);return g.minFilter=n.LinearMipMapLinearFilter,g.magFilter=n.LinearFilter,g.wrapS=n.RepeatWrapping,g.wrapT=n.RepeatWrapping,g.mapping=n.EquirectangularReflectionMapping,g.needsUpdate=!0,g}dispose(){this._quad.dispose()}};function Kt(e){return e.extensions.get(`EXT_float_blend`)}var $=new n.Vector2,qt=class{get multipleImportanceSampling(){return!!this._pathTracer.material.defines.FEATURE_MIS}set multipleImportanceSampling(e){this._pathTracer.material.setDefine(`FEATURE_MIS`,+!!e)}get transmissiveBounces(){return this._pathTracer.material.transmissiveBounces}set transmissiveBounces(e){this._pathTracer.material.transmissiveBounces=e}get bounces(){return this._pathTracer.material.bounces}set bounces(e){this._pathTracer.material.bounces=e}get filterGlossyFactor(){return this._pathTracer.material.filterGlossyFactor}set filterGlossyFactor(e){this._pathTracer.material.filterGlossyFactor=e}get samples(){return this._pathTracer.samples}get target(){return this._pathTracer.target}get tiles(){return this._pathTracer.tiles}get stableNoise(){return this._pathTracer.stableNoise}set stableNoise(e){this._pathTracer.stableNoise=e}get isCompiling(){return!!this._pathTracer.isCompiling}constructor(e){this._renderer=e,this._generator=new pe,this._pathTracer=new Rt(e),this._queueReset=!1,this._clock=new n.Clock,this._compilePromise=null,this._lowResPathTracer=new Rt(e),this._lowResPathTracer.tiles.set(1,1),this._quad=new t.t(new Ut({map:null,transparent:!0,blending:n.NoBlending,premultipliedAlpha:e.getContextAttributes().premultipliedAlpha})),this._materials=null,this._previousEnvironment=null,this._previousBackground=null,this._internalBackground=null,this.renderDelay=100,this.minSamples=5,this.fadeDuration=500,this.enablePathTracing=!0,this.pausePathTracing=!1,this.dynamicLowRes=!1,this.lowResScale=.25,this.renderScale=1,this.synchronizeRenderSize=!0,this.rasterizeScene=!0,this.renderToCanvas=!0,this.textureSize=new n.Vector2(1024,1024),this.rasterizeSceneCallback=(e,t)=>{this._renderer.render(e,t)},this.renderToCanvasCallback=(e,t,n)=>{let r=t.autoClear;t.autoClear=!1,n.render(t),t.autoClear=r},this.setScene(new n.Scene,new n.PerspectiveCamera)}setBVHWorker(e){this._generator.setBVHWorker(e)}setScene(e,t,n={}){e.updateMatrixWorld(!0),t.updateMatrixWorld();let r=this._generator;if(r.setObjects(e),this._buildAsync)return r.generateAsync(n.onProgress).then(n=>this._updateFromResults(e,t,n));{let n=r.generate();return this._updateFromResults(e,t,n)}}setSceneAsync(...e){this._buildAsync=!0;let t=this.setScene(...e);return this._buildAsync=!1,t}setCamera(e){this.camera=e,this.updateCamera()}updateCamera(){let e=this.camera;e.updateMatrixWorld(),this._pathTracer.setCamera(e),this._lowResPathTracer.setCamera(e),this.reset()}updateMaterials(){let e=this._pathTracer.material,t=this._renderer,n=this._materials,r=this.textureSize,i=ze(n);e.textures.setTextures(t,i,r.x,r.y),e.materials.updateFrom(n,i),this.reset()}updateLights(){let e=this.scene,t=this._renderer,n=this._pathTracer.material,r=Be(e),i=Re(r);n.lights.updateFrom(r,i),n.iesProfiles.setTextures(t,i),this.reset()}updateEnvironment(){let e=this.scene,t=this._pathTracer.material;if(this._internalBackground&&=(this._internalBackground.dispose(),null),t.backgroundBlur=e.backgroundBlurriness,t.backgroundIntensity=e.backgroundIntensity??1,t.backgroundRotation.makeRotationFromEuler(e.backgroundRotation).invert(),e.background===null)t.backgroundMap=null,t.backgroundAlpha=0;else if(e.background.isColor){this._colorBackground=this._colorBackground||new Ht(16);let n=this._colorBackground;n.topColor.equals(e.background)||(n.topColor.set(e.background),n.bottomColor.set(e.background),n.update()),t.backgroundMap=n,t.backgroundAlpha=1}else if(e.background.isCubeTexture){if(e.background!==this._previousBackground){let n=new Gt(this._renderer).generate(e.background);this._internalBackground=n,t.backgroundMap=n,t.backgroundAlpha=1}}else t.backgroundMap=e.background,t.backgroundAlpha=1;if(t.environmentIntensity=e.environmentIntensity??1,t.environmentRotation.makeRotationFromEuler(e.environmentRotation).invert(),this._previousEnvironment!==e.environment)if(e.environment!==null)if(e.environment.isCubeTexture){let n=new Gt(this._renderer).generate(e.environment);t.envMapInfo.updateFrom(n)}else t.envMapInfo.updateFrom(e.environment);else t.environmentIntensity=0;this._previousEnvironment=e.environment,this._previousBackground=e.background,this.reset()}_updateFromResults(e,t,n){let{materials:r,geometry:i,bvh:a,bvhChanged:o}=n;this._materials=r;let s=this._pathTracer.material;return o&&(s.bvh.updateFrom(a),s.attributesArray.updateFrom(i.attributes.normal,i.attributes.tangent,i.attributes.uv,i.attributes.color),s.materialIndexAttribute.updateFrom(i.attributes.materialIndex)),this._previousScene=e,this.scene=e,this.camera=t,this.updateCamera(),this.updateMaterials(),this.updateEnvironment(),this.updateLights(),n}renderSample(){let e=this._lowResPathTracer,t=this._pathTracer,r=this._renderer,i=this._clock,a=this._quad;this._updateScale(),this._queueReset&&(t.reset(),e.reset(),this._queueReset=!1,a.material.opacity=0,i.start());let o=i.getDelta()*1e3,s=i.getElapsedTime()*1e3;if(!this.pausePathTracing&&this.enablePathTracing&&this.renderDelay<=s&&!this.isCompiling&&t.update(),t.alpha=t.material.backgroundAlpha!==1||!Kt(r),e.alpha=t.alpha,this.renderToCanvas){let r=this._renderer,i=this.minSamples;if(s>=this.renderDelay&&this.samples>=this.minSamples&&(this.fadeDuration===0?a.material.opacity=1:a.material.opacity=Math.min(a.material.opacity+o/this.fadeDuration,1)),!this.enablePathTracing||this.samples<i||a.material.opacity<1){if(this.dynamicLowRes&&!this.isCompiling){e.samples<1&&(e.material=t.material,e.update());let n=a.material.opacity;a.material.opacity=1-a.material.opacity,a.material.map=e.target.texture,a.render(r),a.material.opacity=n}(!this.dynamicLowRes&&this.rasterizeScene||this.dynamicLowRes&&this.isCompiling)&&this.rasterizeSceneCallback(this.scene,this.camera)}this.enablePathTracing&&a.material.opacity>0&&(a.material.opacity<1&&(a.material.blending=this.dynamicLowRes?n.AdditiveBlending:n.NormalBlending),a.material.map=t.target.texture,this.renderToCanvasCallback(t.target,r,a),a.material.blending=n.NoBlending)}}reset(){this._queueReset=!0,this._pathTracer.samples=0}dispose(){this._renderQuad.dispose(),this._renderQuad.material.dispose(),this._pathTracer.dispose()}_updateScale(){if(this.synchronizeRenderSize){this._renderer.getDrawingBufferSize($);let e=Math.floor(this.renderScale*$.x),t=Math.floor(this.renderScale*$.y);if(this._pathTracer.getSize($),$.x!==e||$.y!==t){let n=this.lowResScale;this._pathTracer.setSize(e,t),this._lowResPathTracer.setSize(Math.floor(e*n),Math.floor(t*n))}}}},Jt=class r{ingestSceneWithoutShadowHelpers(e,t){let n=[],r=[];e.traverse(e=>{e.userData?.softboxContactShadowHelper&&e.visible?n.push(e):e.userData?.softboxPathTracingFloor&&!e.visible&&r.push(e)}),n.forEach(e=>e.visible=!1),r.forEach(e=>e.visible=!0);try{this.pathTracer?.setScene(e,t)}finally{n.forEach(e=>e.visible=!0),r.forEach(e=>e.visible=!1)}}convertToDataTexture(e){if(!e.image||!(e.image instanceof HTMLImageElement))return null;let t=e.image,r=document.createElement(`canvas`);r.width=t.width,r.height=t.height;let i=r.getContext(`2d`);if(!i)return null;i.drawImage(t,0,0);let a=i.getImageData(0,0,r.width,r.height),o=new Float32Array(a.data.length);for(let e=0;e<a.data.length;e++)o[e]=a.data[e]/255;let s=new n.DataTexture(o,r.width,r.height,n.RGBAFormat,n.FloatType);return s.mapping=e.mapping,s.wrapS=e.wrapS,s.wrapT=e.wrapT,s.magFilter=e.magFilter,s.minFilter=e.minFilter,s.anisotropy=e.anisotropy,s.needsUpdate=!0,s}getThreeRenderer(){return e.a(this.renderer)}static{this.CAMERA_SETTLE_MS=200}static{this.FADE_SAMPLES=256}static{this.FADE_HOLD_SAMPLES=4}static{this.FADE_PREVIEW_OPACITY=.3}static{this.FADE_RELEASE_FRACTION=.5}constructor(){this.pathTracer=null,this.enabled=!1,this.renderer=null,this.sampleCount=0,this.createAttempts=0,this.maxCreateAttempts=10,this.sceneInitialized=!1,this.environmentWaitFrames=0,this.maxEnvironmentWaitFrames=300,this.disposed=!1,this.convertedEnvTexture=null,this.convertedEnvSourceUuid=null,this.resumable=!1,this.lastCameraMoveTime=-1/0,this.cameraDirty=!1,this.events=new e.A,this.rasterFadeTarget=null,this.fadeQuad=null,this.fadeToneMapping=null,this.fadeSupported=!0,this.settings={samples:300,bounces:4,transmissiveBounces:2,renderScale:1,lowResScale:.5,dynamicLowRes:!0,enablePathTracing:!0}}async initialize(t){try{return this.renderer=t.renderer,this.enabled=t.enabled,this.isSupported()?e.j.ok(void 0):e.j.err(new e.N(`Path tracing is not supported in this environment`,e.M.PATH_TRACING_INIT_FAILED,{reason:`WebGL2 or required extensions not available`}))}catch(t){return e.j.err(new e.N(`Failed to initialize path tracing`,e.M.PATH_TRACING_INIT_FAILED,{originalError:t}))}}createPathTracer(){if(this.disposed)return e.j.err(new e.N(`Instance is disposed`,e.M.INVALID_STATE));try{let t=this.getThreeRenderer();return t?(this.pathTracer=new qt(t),this.pathTracer.tiles&&`set`in this.pathTracer.tiles&&this.pathTracer.tiles.set(1,1),this.pathTracer.bounces=this.settings.bounces,this.settings.transmissiveBounces!==void 0&&(this.pathTracer.transmissiveBounces=this.settings.transmissiveBounces),this.pathTracer.renderScale=this.settings.renderScale,this.pathTracer.dynamicLowRes=this.settings.dynamicLowRes,this.pathTracer.lowResScale=this.settings.lowResScale,t.setRenderTarget(null),e.j.ok(void 0)):e.j.err(new e.N(`Renderer not ready, will retry`,e.M.RENDERER_NOT_INITIALIZED))}catch(t){return e.j.err(new e.N(`Failed to create path tracer`,e.M.PATH_TRACING_INIT_FAILED,{originalError:t}))}}setEnabled(e){if(this.enabled!==e&&(this.enabled=e,!e)){this.resumable=!1,this.reset(),this.sceneInitialized=!1;let e=this.getThreeRenderer();e&&(e.autoClear=!0)}}disableAfterSelfPause(e){this.enabled=!1,this.resumable=e===`completed`,this.events.emit(`pathtracing:paused`,{samples:this.sampleCount,reason:e})}updateSettings(e){this.settings={...this.settings,...e},e.enablePathTracing!==void 0&&this.setEnabled(e.enablePathTracing),this.pathTracer&&(e.bounces!==void 0&&(this.pathTracer.bounces=e.bounces),e.transmissiveBounces!==void 0&&(this.pathTracer.transmissiveBounces=e.transmissiveBounces),e.renderScale!==void 0&&(this.pathTracer.renderScale=e.renderScale),e.lowResScale!==void 0&&(this.pathTracer.lowResScale=e.lowResScale),e.dynamicLowRes!==void 0&&(this.pathTracer.dynamicLowRes=e.dynamicLowRes))}async render(t,n){if(this.disposed)return e.j.ok(void 0);let r=this.renderer;if(!r)return e.j.ok(void 0);if(!this.enabled)return this.renderWhileDisabled(t,n);if(!this.pathTracer){let e=this.ensurePathTracerCreated(r,t,n);if(e)return e}try{let i=this.extractThreeObjects(t,n);if(!i)return e.j.err(new e.N(`Could not extract Three.js scene or camera`,e.M.INVALID_PARAMETER));let{threeScene:a,threeCamera:o}=i;if(!this.sceneInitialized){let e=await this.initializeSceneForPathTracing(r,t,n,a,o);if(e)return e}return this.sceneInitialized?this.accumulateSample(r,t,n):r.render(t,n)}catch(t){return e.j.err(new e.N(`Failed to render with path tracing`,e.M.RENDER_FAILED,{originalError:t}))}}ensurePathTracerCreated(e,t,n){this.createAttempts++;let r=this.createPathTracer();return r.ok?(this.createAttempts=0,null):this.createAttempts<this.maxCreateAttempts&&r.error?.message===`Renderer not ready, will retry`?e.render(t,n):(this.disableAfterSelfPause(`gave-up`),this.createAttempts=0,e.render(t,n))}extractThreeObjects(t,n){let r=e.o(t),i=e.n(n);return!r||!i?null:{threeScene:r,threeCamera:i}}async initializeSceneForPathTracing(e,t,r,i,a){try{let o=i.__originalEnvironmentTexture;if(!i.environment&&!o)return this.environmentWaitFrames++,this.environmentWaitFrames>=this.maxEnvironmentWaitFrames&&(this.disableAfterSelfPause(`gave-up`),this.environmentWaitFrames=0),e.render(t,r);if(this.environmentWaitFrames=0,o&&o.isCubeTexture){let e=i.environment;i.environment=o;try{this.ingestSceneWithoutShadowHelpers(i,a),this.sceneInitialized=!0}finally{i.environment=e}}else if(o&&o.mapping===n.EquirectangularReflectionMapping){let e=o;if(o.image instanceof HTMLImageElement)if(this.convertedEnvTexture&&this.convertedEnvSourceUuid===o.uuid)e=this.convertedEnvTexture;else{this.convertedEnvTexture?.dispose(),this.convertedEnvTexture=null,this.convertedEnvSourceUuid=null;let t=this.convertToDataTexture(o);if(!t)throw Error(`Failed to convert environment texture to DataTexture`);this.convertedEnvTexture=t,this.convertedEnvSourceUuid=o.uuid,e=t}let t=i.environment;i.environment=e;try{let e=o.image;e&&!(`data`in e&&e.data)&&e instanceof HTMLImageElement&&!e.complete&&await new Promise(t=>{e.onload=()=>{o.needsUpdate=!0,t()},e.onerror=()=>{t()},e.complete&&t()}),this.ingestSceneWithoutShadowHelpers(i,a),this.sceneInitialized=!0,i.environment=t}catch(e){throw i.environment=t,e}}else if(i.environment?.mapping===n.EquirectangularReflectionMapping)this.ingestSceneWithoutShadowHelpers(i,a),this.sceneInitialized=!0;else return this.disableAfterSelfPause(`gave-up`),e.render(t,r)}catch(n){return console.warn(`Scene initialization error:`,n),e.render(t,r)}return null}accumulateSample(t,n,i){if(this.sampleCount===0)try{this.pathTracer?.updateLights()}catch(e){console.warn(`Failed to update lights for path tracing:`,e)}let a=t.render(n,i);if(!a.ok)return a;if(performance.now()-this.lastCameraMoveTime<r.CAMERA_SETTLE_MS)return e.j.ok(void 0);if(this.cameraDirty&&(this.cameraDirty=!1,this.pathTracer?.updateCamera()),this.fadeSupported&&this.sampleCount===0&&this.runFadeStep(()=>this.captureRasterFade(t,n,i)),this.accumulateOneSample(),this.sampleCount++,this.fadeSupported&&this.sampleCount<this.fadeWindowSamples()){let e=1-this.pathTracedLayerOpacity(this.sampleCount);this.runFadeStep(()=>this.renderRasterFade(e))}return this.sampleCount===this.settings.samples?this.captureCompletedFrame():e.j.ok(void 0)}runFadeStep(e){try{e()}catch(e){console.warn(`Path-tracing startup dissolve unavailable; showing samples directly:`,e),this.fadeSupported=!1}}fadeWindowSamples(){let e=r.FADE_HOLD_SAMPLES+2;return Math.max(e,Math.min(r.FADE_SAMPLES,this.settings.samples))}pathTracedLayerOpacity(e){let t=r.FADE_HOLD_SAMPLES,n=this.fadeWindowSamples(),i=r.FADE_PREVIEW_OPACITY,a=t+(n-t)*r.FADE_RELEASE_FRACTION;return e<a?i*r.smoothstep(t,a,e):i+(1-i)*r.smoothstep(a,n,e)}static smoothstep(t,n,r){return e.t(Math.min(1,Math.max(0,(r-t)/(n-t))))}captureRasterFade(e,t,r){let i=this.getThreeRenderer();if(!i)return;let a=i.getDrawingBufferSize(new n.Vector2);this.rasterFadeTarget?(this.rasterFadeTarget.width!==a.x||this.rasterFadeTarget.height!==a.y)&&this.rasterFadeTarget.setSize(a.x,a.y):(this.rasterFadeTarget=new n.WebGLRenderTarget(a.x,a.y,{type:n.HalfFloatType}),this.rasterFadeTarget.texture.colorSpace=n.LinearSRGBColorSpace);let o=i.getRenderTarget();i.setRenderTarget(this.rasterFadeTarget),e.render(t,r),i.setRenderTarget(o)}renderRasterFade(e){let n=this.getThreeRenderer();if(!n||!this.rasterFadeTarget)return;(!this.fadeQuad||this.fadeToneMapping!==n.toneMapping)&&((this.fadeQuad?.material)?.dispose(),this.fadeToneMapping=n.toneMapping,this.fadeQuad=new t.t(this.createFadeMaterial(n.toneMapping)));let r=this.fadeQuad.material;r.uniforms.tRaster.value=this.rasterFadeTarget.texture,r.uniforms.uOpacity.value=e;let i=n.autoClear,a=n.getRenderTarget();n.setRenderTarget(null),n.autoClear=!1;try{this.fadeQuad.render(n)}finally{n.autoClear=i,n.setRenderTarget(a)}}createFadeMaterial(e){let t={[n.LinearToneMapping]:`LINEAR_TONE_MAPPING`,[n.ReinhardToneMapping]:`REINHARD_TONE_MAPPING`,[n.CineonToneMapping]:`CINEON_TONE_MAPPING`,[n.ACESFilmicToneMapping]:`ACES_FILMIC_TONE_MAPPING`,[n.AgXToneMapping]:`AGX_TONE_MAPPING`,[n.NeutralToneMapping]:`NEUTRAL_TONE_MAPPING`},r={},i=t[e];return i&&(r[i]=``),new n.ShaderMaterial({defines:r,uniforms:{tRaster:{value:null},uOpacity:{value:1}},vertexShader:`
3977
+ }`}),this.depthWrite=!1,this.depthTest=!1}},Gt=class{constructor(e){this._renderer=e,this._quad=new t.t(new Wt)}generate(e,t=null,r=null){if(!e.isCubeTexture)throw Error(`CubeToEquirectMaterial: Source can only be cube textures.`);let i=e.images[0],a=this._renderer,o=this._quad;t===null&&(t=4*i.height),r===null&&(r=2*i.height);let s=new n.WebGLRenderTarget(t,r,{type:n.FloatType,colorSpace:i.colorSpace}),c=i.height,l=Math.log2(c)-2,u=1/c,d=1/(3*Math.max(2**l,112));o.material.defines.CUBEUV_MAX_MIP=`${l}.0`,o.material.defines.CUBEUV_TEXEL_WIDTH=d,o.material.defines.CUBEUV_TEXEL_HEIGHT=u,o.material.uniforms.envMap.value=e,o.material.uniforms.flipEnvMap.value=e.isRenderTargetTexture?1:-1,o.material.needsUpdate=!0;let f=a.getRenderTarget(),p=a.autoClear;a.autoClear=!0,a.setRenderTarget(s),o.render(a),a.setRenderTarget(f),a.autoClear=p;let m=new Uint16Array(t*r*4),h=new Float32Array(t*r*4);a.readRenderTargetPixels(s,0,0,t,r,h),s.dispose();for(let e=0,t=h.length;e<t;e++)m[e]=n.DataUtils.toHalfFloat(h[e]);let g=new n.DataTexture(m,t,r,n.RGBAFormat,n.HalfFloatType);return g.minFilter=n.LinearMipMapLinearFilter,g.magFilter=n.LinearFilter,g.wrapS=n.RepeatWrapping,g.wrapT=n.RepeatWrapping,g.mapping=n.EquirectangularReflectionMapping,g.needsUpdate=!0,g}dispose(){this._quad.dispose()}};function Kt(e){return e.extensions.get(`EXT_float_blend`)}var $=new n.Vector2,qt=class{get multipleImportanceSampling(){return!!this._pathTracer.material.defines.FEATURE_MIS}set multipleImportanceSampling(e){this._pathTracer.material.setDefine(`FEATURE_MIS`,+!!e)}get transmissiveBounces(){return this._pathTracer.material.transmissiveBounces}set transmissiveBounces(e){this._pathTracer.material.transmissiveBounces=e}get bounces(){return this._pathTracer.material.bounces}set bounces(e){this._pathTracer.material.bounces=e}get filterGlossyFactor(){return this._pathTracer.material.filterGlossyFactor}set filterGlossyFactor(e){this._pathTracer.material.filterGlossyFactor=e}get samples(){return this._pathTracer.samples}get target(){return this._pathTracer.target}get tiles(){return this._pathTracer.tiles}get stableNoise(){return this._pathTracer.stableNoise}set stableNoise(e){this._pathTracer.stableNoise=e}get isCompiling(){return!!this._pathTracer.isCompiling}constructor(e){this._renderer=e,this._generator=new pe,this._pathTracer=new Rt(e),this._queueReset=!1,this._clock=new n.Clock,this._compilePromise=null,this._lowResPathTracer=new Rt(e),this._lowResPathTracer.tiles.set(1,1),this._quad=new t.t(new Ut({map:null,transparent:!0,blending:n.NoBlending,premultipliedAlpha:e.getContextAttributes().premultipliedAlpha})),this._materials=null,this._previousEnvironment=null,this._previousBackground=null,this._internalBackground=null,this.renderDelay=100,this.minSamples=5,this.fadeDuration=500,this.enablePathTracing=!0,this.pausePathTracing=!1,this.dynamicLowRes=!1,this.lowResScale=.25,this.renderScale=1,this.synchronizeRenderSize=!0,this.rasterizeScene=!0,this.renderToCanvas=!0,this.textureSize=new n.Vector2(1024,1024),this.rasterizeSceneCallback=(e,t)=>{this._renderer.render(e,t)},this.renderToCanvasCallback=(e,t,n)=>{let r=t.autoClear;t.autoClear=!1,n.render(t),t.autoClear=r},this.setScene(new n.Scene,new n.PerspectiveCamera)}setBVHWorker(e){this._generator.setBVHWorker(e)}setScene(e,t,n={}){e.updateMatrixWorld(!0),t.updateMatrixWorld();let r=this._generator;if(r.setObjects(e),this._buildAsync)return r.generateAsync(n.onProgress).then(n=>this._updateFromResults(e,t,n));{let n=r.generate();return this._updateFromResults(e,t,n)}}setSceneAsync(...e){this._buildAsync=!0;let t=this.setScene(...e);return this._buildAsync=!1,t}setCamera(e){this.camera=e,this.updateCamera()}updateCamera(){let e=this.camera;e.updateMatrixWorld(),this._pathTracer.setCamera(e),this._lowResPathTracer.setCamera(e),this.reset()}updateMaterials(){let e=this._pathTracer.material,t=this._renderer,n=this._materials,r=this.textureSize,i=ze(n);e.textures.setTextures(t,i,r.x,r.y),e.materials.updateFrom(n,i),this.reset()}updateLights(){let e=this.scene,t=this._renderer,n=this._pathTracer.material,r=Be(e),i=Re(r);n.lights.updateFrom(r,i),n.iesProfiles.setTextures(t,i),this.reset()}updateEnvironment(){let e=this.scene,t=this._pathTracer.material;if(this._internalBackground&&=(this._internalBackground.dispose(),null),t.backgroundBlur=e.backgroundBlurriness,t.backgroundIntensity=e.backgroundIntensity??1,t.backgroundRotation.makeRotationFromEuler(e.backgroundRotation).invert(),e.background===null)t.backgroundMap=null,t.backgroundAlpha=0;else if(e.background.isColor){this._colorBackground=this._colorBackground||new Ht(16);let n=this._colorBackground;n.topColor.equals(e.background)||(n.topColor.set(e.background),n.bottomColor.set(e.background),n.update()),t.backgroundMap=n,t.backgroundAlpha=1}else if(e.background.isCubeTexture){if(e.background!==this._previousBackground){let n=new Gt(this._renderer).generate(e.background);this._internalBackground=n,t.backgroundMap=n,t.backgroundAlpha=1}}else t.backgroundMap=e.background,t.backgroundAlpha=1;if(t.environmentIntensity=e.environmentIntensity??1,t.environmentRotation.makeRotationFromEuler(e.environmentRotation).invert(),this._previousEnvironment!==e.environment)if(e.environment!==null)if(e.environment.isCubeTexture){let n=new Gt(this._renderer).generate(e.environment);t.envMapInfo.updateFrom(n)}else t.envMapInfo.updateFrom(e.environment);else t.environmentIntensity=0;this._previousEnvironment=e.environment,this._previousBackground=e.background,this.reset()}_updateFromResults(e,t,n){let{materials:r,geometry:i,bvh:a,bvhChanged:o}=n;this._materials=r;let s=this._pathTracer.material;return o&&(s.bvh.updateFrom(a),s.attributesArray.updateFrom(i.attributes.normal,i.attributes.tangent,i.attributes.uv,i.attributes.color),s.materialIndexAttribute.updateFrom(i.attributes.materialIndex)),this._previousScene=e,this.scene=e,this.camera=t,this.updateCamera(),this.updateMaterials(),this.updateEnvironment(),this.updateLights(),n}renderSample(){let e=this._lowResPathTracer,t=this._pathTracer,r=this._renderer,i=this._clock,a=this._quad;this._updateScale(),this._queueReset&&(t.reset(),e.reset(),this._queueReset=!1,a.material.opacity=0,i.start());let o=i.getDelta()*1e3,s=i.getElapsedTime()*1e3;if(!this.pausePathTracing&&this.enablePathTracing&&this.renderDelay<=s&&!this.isCompiling&&t.update(),t.alpha=t.material.backgroundAlpha!==1||!Kt(r),e.alpha=t.alpha,this.renderToCanvas){let r=this._renderer,i=this.minSamples;if(s>=this.renderDelay&&this.samples>=this.minSamples&&(this.fadeDuration===0?a.material.opacity=1:a.material.opacity=Math.min(a.material.opacity+o/this.fadeDuration,1)),!this.enablePathTracing||this.samples<i||a.material.opacity<1){if(this.dynamicLowRes&&!this.isCompiling){e.samples<1&&(e.material=t.material,e.update());let n=a.material.opacity;a.material.opacity=1-a.material.opacity,a.material.map=e.target.texture,a.render(r),a.material.opacity=n}(!this.dynamicLowRes&&this.rasterizeScene||this.dynamicLowRes&&this.isCompiling)&&this.rasterizeSceneCallback(this.scene,this.camera)}this.enablePathTracing&&a.material.opacity>0&&(a.material.opacity<1&&(a.material.blending=this.dynamicLowRes?n.AdditiveBlending:n.NormalBlending),a.material.map=t.target.texture,this.renderToCanvasCallback(t.target,r,a),a.material.blending=n.NoBlending)}}reset(){this._queueReset=!0,this._pathTracer.samples=0}dispose(){this._renderQuad.dispose(),this._renderQuad.material.dispose(),this._pathTracer.dispose()}_updateScale(){if(this.synchronizeRenderSize){this._renderer.getDrawingBufferSize($);let e=Math.floor(this.renderScale*$.x),t=Math.floor(this.renderScale*$.y);if(this._pathTracer.getSize($),$.x!==e||$.y!==t){let n=this.lowResScale;this._pathTracer.setSize(e,t),this._lowResPathTracer.setSize(Math.floor(e*n),Math.floor(t*n))}}}},Jt=class r{ingestSceneWithoutShadowHelpers(e,t){let n=[],r=[];e.traverse(e=>{e.userData?.softboxContactShadowHelper&&e.visible?n.push(e):e.userData?.softboxPathTracingFloor&&!e.visible&&r.push(e)}),n.forEach(e=>e.visible=!1),r.forEach(e=>e.visible=!0);try{this.pathTracer?.setScene(e,t)}finally{n.forEach(e=>e.visible=!0),r.forEach(e=>e.visible=!1)}}convertToDataTexture(e){if(!e.image||!(e.image instanceof HTMLImageElement))return null;let t=e.image,r=document.createElement(`canvas`);r.width=t.width,r.height=t.height;let i=r.getContext(`2d`);if(!i)return null;i.drawImage(t,0,0);let a=i.getImageData(0,0,r.width,r.height),o=new Float32Array(a.data.length);for(let e=0;e<a.data.length;e++)o[e]=a.data[e]/255;let s=new n.DataTexture(o,r.width,r.height,n.RGBAFormat,n.FloatType);return s.mapping=e.mapping,s.wrapS=e.wrapS,s.wrapT=e.wrapT,s.magFilter=e.magFilter,s.minFilter=e.minFilter,s.anisotropy=e.anisotropy,s.needsUpdate=!0,s}getThreeRenderer(){return e.a(this.renderer)}static{this.CAMERA_SETTLE_MS=200}static{this.FADE_SAMPLES=256}static{this.FADE_HOLD_SAMPLES=4}static{this.FADE_PREVIEW_OPACITY=.3}static{this.FADE_RELEASE_FRACTION=.5}constructor(){this.pathTracer=null,this.enabled=!1,this.renderer=null,this.sampleCount=0,this.createAttempts=0,this.maxCreateAttempts=10,this.sceneInitialized=!1,this.environmentWaitFrames=0,this.maxEnvironmentWaitFrames=300,this.disposed=!1,this.convertedEnvTexture=null,this.convertedEnvSourceUuid=null,this.resumable=!1,this.lastCameraMoveTime=-1/0,this.cameraDirty=!1,this.events=new e.M,this.rasterFadeTarget=null,this.fadeQuad=null,this.fadeToneMapping=null,this.fadeSupported=!0,this.settings={samples:300,bounces:4,transmissiveBounces:2,renderScale:1,lowResScale:.5,dynamicLowRes:!0,enablePathTracing:!0}}async initialize(t){try{return this.renderer=t.renderer,this.enabled=t.enabled,this.isSupported()?e.N.ok(void 0):e.N.err(new e.F(`Path tracing is not supported in this environment`,e.P.PATH_TRACING_INIT_FAILED,{reason:`WebGL2 or required extensions not available`}))}catch(t){return e.N.err(new e.F(`Failed to initialize path tracing`,e.P.PATH_TRACING_INIT_FAILED,{originalError:t}))}}createPathTracer(){if(this.disposed)return e.N.err(new e.F(`Instance is disposed`,e.P.INVALID_STATE));try{let t=this.getThreeRenderer();return t?(this.pathTracer=new qt(t),this.pathTracer.tiles&&`set`in this.pathTracer.tiles&&this.pathTracer.tiles.set(1,1),this.pathTracer.bounces=this.settings.bounces,this.settings.transmissiveBounces!==void 0&&(this.pathTracer.transmissiveBounces=this.settings.transmissiveBounces),this.pathTracer.renderScale=this.settings.renderScale,this.pathTracer.dynamicLowRes=this.settings.dynamicLowRes,this.pathTracer.lowResScale=this.settings.lowResScale,t.setRenderTarget(null),e.N.ok(void 0)):e.N.err(new e.F(`Renderer not ready, will retry`,e.P.RENDERER_NOT_INITIALIZED))}catch(t){return e.N.err(new e.F(`Failed to create path tracer`,e.P.PATH_TRACING_INIT_FAILED,{originalError:t}))}}setEnabled(e){if(this.enabled!==e&&(this.enabled=e,!e)){this.resumable=!1,this.reset(),this.sceneInitialized=!1;let e=this.getThreeRenderer();e&&(e.autoClear=!0)}}disableAfterSelfPause(e){this.enabled=!1,this.resumable=e===`completed`,this.events.emit(`pathtracing:paused`,{samples:this.sampleCount,reason:e})}updateSettings(e){this.settings={...this.settings,...e},e.enablePathTracing!==void 0&&this.setEnabled(e.enablePathTracing),this.pathTracer&&(e.bounces!==void 0&&(this.pathTracer.bounces=e.bounces),e.transmissiveBounces!==void 0&&(this.pathTracer.transmissiveBounces=e.transmissiveBounces),e.renderScale!==void 0&&(this.pathTracer.renderScale=e.renderScale),e.lowResScale!==void 0&&(this.pathTracer.lowResScale=e.lowResScale),e.dynamicLowRes!==void 0&&(this.pathTracer.dynamicLowRes=e.dynamicLowRes))}async render(t,n){if(this.disposed)return e.N.ok(void 0);let r=this.renderer;if(!r)return e.N.ok(void 0);if(!this.enabled)return this.renderWhileDisabled(t,n);if(!this.pathTracer){let e=this.ensurePathTracerCreated(r,t,n);if(e)return e}try{let i=this.extractThreeObjects(t,n);if(!i)return e.N.err(new e.F(`Could not extract Three.js scene or camera`,e.P.INVALID_PARAMETER));let{threeScene:a,threeCamera:o}=i;if(!this.sceneInitialized){let e=await this.initializeSceneForPathTracing(r,t,n,a,o);if(e)return e}return this.sceneInitialized?this.accumulateSample(r,t,n):r.render(t,n)}catch(t){return e.N.err(new e.F(`Failed to render with path tracing`,e.P.RENDER_FAILED,{originalError:t}))}}ensurePathTracerCreated(e,t,n){this.createAttempts++;let r=this.createPathTracer();return r.ok?(this.createAttempts=0,null):this.createAttempts<this.maxCreateAttempts&&r.error?.message===`Renderer not ready, will retry`?e.render(t,n):(this.disableAfterSelfPause(`gave-up`),this.createAttempts=0,e.render(t,n))}extractThreeObjects(t,n){let r=e.o(t),i=e.n(n);return!r||!i?null:{threeScene:r,threeCamera:i}}async initializeSceneForPathTracing(e,t,r,i,a){try{let o=i.__originalEnvironmentTexture;if(!i.environment&&!o)return this.environmentWaitFrames++,this.environmentWaitFrames>=this.maxEnvironmentWaitFrames&&(this.disableAfterSelfPause(`gave-up`),this.environmentWaitFrames=0),e.render(t,r);if(this.environmentWaitFrames=0,o&&o.isCubeTexture){let e=i.environment;i.environment=o;try{this.ingestSceneWithoutShadowHelpers(i,a),this.sceneInitialized=!0}finally{i.environment=e}}else if(o&&o.mapping===n.EquirectangularReflectionMapping){let e=o;if(o.image instanceof HTMLImageElement)if(this.convertedEnvTexture&&this.convertedEnvSourceUuid===o.uuid)e=this.convertedEnvTexture;else{this.convertedEnvTexture?.dispose(),this.convertedEnvTexture=null,this.convertedEnvSourceUuid=null;let t=this.convertToDataTexture(o);if(!t)throw Error(`Failed to convert environment texture to DataTexture`);this.convertedEnvTexture=t,this.convertedEnvSourceUuid=o.uuid,e=t}let t=i.environment;i.environment=e;try{let e=o.image;e&&!(`data`in e&&e.data)&&e instanceof HTMLImageElement&&!e.complete&&await new Promise(t=>{e.onload=()=>{o.needsUpdate=!0,t()},e.onerror=()=>{t()},e.complete&&t()}),this.ingestSceneWithoutShadowHelpers(i,a),this.sceneInitialized=!0,i.environment=t}catch(e){throw i.environment=t,e}}else if(i.environment?.mapping===n.EquirectangularReflectionMapping)this.ingestSceneWithoutShadowHelpers(i,a),this.sceneInitialized=!0;else return this.disableAfterSelfPause(`gave-up`),e.render(t,r)}catch(n){return console.warn(`Scene initialization error:`,n),e.render(t,r)}return null}accumulateSample(t,n,i){if(this.sampleCount===0)try{this.pathTracer?.updateLights()}catch(e){console.warn(`Failed to update lights for path tracing:`,e)}let a=t.render(n,i);if(!a.ok)return a;if(performance.now()-this.lastCameraMoveTime<r.CAMERA_SETTLE_MS)return e.N.ok(void 0);if(this.cameraDirty&&(this.cameraDirty=!1,this.pathTracer?.updateCamera()),this.fadeSupported&&this.sampleCount===0&&this.runFadeStep(()=>this.captureRasterFade(t,n,i)),this.accumulateOneSample(),this.sampleCount++,this.fadeSupported&&this.sampleCount<this.fadeWindowSamples()){let e=1-this.pathTracedLayerOpacity(this.sampleCount);this.runFadeStep(()=>this.renderRasterFade(e))}return this.sampleCount===this.settings.samples?this.captureCompletedFrame():e.N.ok(void 0)}runFadeStep(e){try{e()}catch(e){console.warn(`Path-tracing startup dissolve unavailable; showing samples directly:`,e),this.fadeSupported=!1}}fadeWindowSamples(){let e=r.FADE_HOLD_SAMPLES+2;return Math.max(e,Math.min(r.FADE_SAMPLES,this.settings.samples))}pathTracedLayerOpacity(e){let t=r.FADE_HOLD_SAMPLES,n=this.fadeWindowSamples(),i=r.FADE_PREVIEW_OPACITY,a=t+(n-t)*r.FADE_RELEASE_FRACTION;return e<a?i*r.smoothstep(t,a,e):i+(1-i)*r.smoothstep(a,n,e)}static smoothstep(t,n,r){return e.t(Math.min(1,Math.max(0,(r-t)/(n-t))))}captureRasterFade(e,t,r){let i=this.getThreeRenderer();if(!i)return;let a=i.getDrawingBufferSize(new n.Vector2);this.rasterFadeTarget?(this.rasterFadeTarget.width!==a.x||this.rasterFadeTarget.height!==a.y)&&this.rasterFadeTarget.setSize(a.x,a.y):(this.rasterFadeTarget=new n.WebGLRenderTarget(a.x,a.y,{type:n.HalfFloatType}),this.rasterFadeTarget.texture.colorSpace=n.LinearSRGBColorSpace);let o=i.getRenderTarget();i.setRenderTarget(this.rasterFadeTarget),e.render(t,r),i.setRenderTarget(o)}renderRasterFade(e){let n=this.getThreeRenderer();if(!n||!this.rasterFadeTarget)return;(!this.fadeQuad||this.fadeToneMapping!==n.toneMapping)&&((this.fadeQuad?.material)?.dispose(),this.fadeToneMapping=n.toneMapping,this.fadeQuad=new t.t(this.createFadeMaterial(n.toneMapping)));let r=this.fadeQuad.material;r.uniforms.tRaster.value=this.rasterFadeTarget.texture,r.uniforms.uOpacity.value=e;let i=n.autoClear,a=n.getRenderTarget();n.setRenderTarget(null),n.autoClear=!1;try{this.fadeQuad.render(n)}finally{n.autoClear=i,n.setRenderTarget(a)}}createFadeMaterial(e){let t={[n.LinearToneMapping]:`LINEAR_TONE_MAPPING`,[n.ReinhardToneMapping]:`REINHARD_TONE_MAPPING`,[n.CineonToneMapping]:`CINEON_TONE_MAPPING`,[n.ACESFilmicToneMapping]:`ACES_FILMIC_TONE_MAPPING`,[n.AgXToneMapping]:`AGX_TONE_MAPPING`,[n.NeutralToneMapping]:`NEUTRAL_TONE_MAPPING`},r={},i=t[e];return i&&(r[i]=``),new n.ShaderMaterial({defines:r,uniforms:{tRaster:{value:null},uOpacity:{value:1}},vertexShader:`
3978
3978
  varying vec2 vUv;
3979
3979
  void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }
3980
3980
  `,fragmentShader:`
@@ -3998,4 +3998,4 @@ bool bvhIntersectFogVolumeHit(
3998
3998
  #endif
3999
3999
  gl_FragColor = vec4( sRGBTransferOETF( vec4( color, 1.0 ) ).rgb, uOpacity );
4000
4000
  }
4001
- `,transparent:!0,depthTest:!1,depthWrite:!1})}renderWhileDisabled(t,n){if(!this.renderer)return e.j.ok(void 0);if(this.sampleCount>=this.settings.samples&&this.sampleCount>0){let t=this.getThreeRenderer();return this.pathTracer&&t&&t.setRenderTarget(null),e.j.ok(void 0)}return this.renderer.render(t,n)}accumulateOneSample(){let e=this.getThreeRenderer();if(!e)throw Error(`Three.js renderer not available`);let t=e.autoClear,n=e.getRenderTarget();e.autoClear=!1,this.pathTracer&&this.pathTracer.renderSample(),e.autoClear=t,e.setRenderTarget(n)}captureCompletedFrame(){let t=this.getThreeRenderer();if(t&&this.pathTracer)try{let e=t.autoClear;t.autoClear=!0,t.setRenderTarget(null),t.clear(!0,!0,!0);let n=this.pathTracer.copyQuad;n&&typeof n.render==`function`?n.render(t):(t.autoClear=!1,this.pathTracer.renderSample()),t.autoClear=e}catch(e){console.warn(`Failed to present path traced result:`,e)}return this.disableAfterSelfPause(`completed`),e.j.ok(void 0)}getSampleCount(){return this.sampleCount}isEnabled(){return this.enabled}isPathTracerDisposed(){return this.disposed}canResume(){return this.resumable&&this.pathTracer!==null&&!this.disposed}reset(e=!1){if(this.sampleCount=0,this.pathTracer){if(e){this.pathTracer.reset(),this.sceneInitialized=!1;return}this.lastCameraMoveTime=performance.now(),this.cameraDirty=!0,this.pathTracer.reset()}}dispose(){if(this.disposed=!0,this.events.removeAllListeners(),this.pathTracer){try{this.pathTracer.dispose()}catch(e){console.warn(`Failed to dispose path tracer during service disposal:`,e)}this.pathTracer=null}this.convertedEnvTexture&&(this.convertedEnvTexture.dispose(),this.convertedEnvTexture=null,this.convertedEnvSourceUuid=null),this.fadeQuad&&=(this.fadeQuad.material.dispose(),null),this.fadeToneMapping=null,this.rasterFadeTarget&&=(this.rasterFadeTarget.dispose(),null),this.sampleCount=0,this.sceneInitialized=!1,this.createAttempts=0,this.renderer=null}isSupported(){return document.createElement(`canvas`).getContext(`webgl2`)!==null}};exports.ThreePathTracingService=Jt;
4001
+ `,transparent:!0,depthTest:!1,depthWrite:!1})}renderWhileDisabled(t,n){if(!this.renderer)return e.N.ok(void 0);if(this.sampleCount>=this.settings.samples&&this.sampleCount>0){let t=this.getThreeRenderer();return this.pathTracer&&t&&t.setRenderTarget(null),e.N.ok(void 0)}return this.renderer.render(t,n)}accumulateOneSample(){let e=this.getThreeRenderer();if(!e)throw Error(`Three.js renderer not available`);let t=e.autoClear,n=e.getRenderTarget();e.autoClear=!1,this.pathTracer&&this.pathTracer.renderSample(),e.autoClear=t,e.setRenderTarget(n)}captureCompletedFrame(){let t=this.getThreeRenderer();if(t&&this.pathTracer)try{let e=t.autoClear;t.autoClear=!0,t.setRenderTarget(null),t.clear(!0,!0,!0);let n=this.pathTracer.copyQuad;n&&typeof n.render==`function`?n.render(t):(t.autoClear=!1,this.pathTracer.renderSample()),t.autoClear=e}catch(e){console.warn(`Failed to present path traced result:`,e)}return this.disableAfterSelfPause(`completed`),e.N.ok(void 0)}getSampleCount(){return this.sampleCount}isEnabled(){return this.enabled}isPathTracerDisposed(){return this.disposed}canResume(){return this.resumable&&this.pathTracer!==null&&!this.disposed}reset(e=!1){if(this.sampleCount=0,this.pathTracer){if(e){this.pathTracer.reset(),this.sceneInitialized=!1;return}this.lastCameraMoveTime=performance.now(),this.cameraDirty=!0,this.pathTracer.reset()}}dispose(){if(this.disposed=!0,this.events.removeAllListeners(),this.pathTracer){try{this.pathTracer.dispose()}catch(e){console.warn(`Failed to dispose path tracer during service disposal:`,e)}this.pathTracer=null}this.convertedEnvTexture&&(this.convertedEnvTexture.dispose(),this.convertedEnvTexture=null,this.convertedEnvSourceUuid=null),this.fadeQuad&&=(this.fadeQuad.material.dispose(),null),this.fadeToneMapping=null,this.rasterFadeTarget&&=(this.rasterFadeTarget.dispose(),null),this.sampleCount=0,this.sceneInitialized=!1,this.createAttempts=0,this.renderer=null}isSupported(){return document.createElement(`canvas`).getContext(`webgl2`)!==null}};exports.ThreePathTracingService=Jt;
@@ -1,4 +1,4 @@
1
- import { A as e, C as t, D as n, E as r, M as i, N as a, S as o, T as s, a as c, b as l, j as u, n as d, o as f, t as p, w as m, x as h, y as g } from "./smoothstep-DR5B0_eF.js";
1
+ import { C as e, D as t, E as n, F as r, M as i, N as a, O as o, P as s, S as c, T as l, a as u, k as d, n as f, o as p, t as m, w as h, x as g } from "./smoothstep-gC155W8-.js";
2
2
  import { t as _ } from "./Pass-CSHIrJrV.js";
3
3
  import * as v from "three";
4
4
  import { AdditiveBlending as y, BackSide as b, BufferAttribute as x, BufferGeometry as S, ByteType as C, ClampToEdgeWrapping as w, Clock as ee, Color as T, DataArrayTexture as te, DataTexture as E, DataUtils as D, DoubleSide as ne, EquirectangularReflectionMapping as re, FloatType as O, FrontSide as ie, HalfFloatType as k, IntType as ae, LinearFilter as A, LinearMipMapLinearFilter as oe, Matrix3 as se, Matrix4 as j, Mesh as ce, MeshBasicMaterial as le, NearestFilter as M, NoBlending as N, NoToneMapping as ue, NormalBlending as de, PerspectiveCamera as fe, Quaternion as pe, RGBAFormat as P, RGBAIntegerFormat as me, RGFormat as he, RGIntegerFormat as ge, RedFormat as F, RedIntegerFormat as _e, RepeatWrapping as I, Scene as ve, ShaderMaterial as ye, ShortType as be, Source as xe, Spherical as Se, UnsignedByteType as Ce, UnsignedIntType as L, UnsignedShortType as we, Vector2 as R, Vector3 as z, Vector4 as B, WebGLArrayRenderTarget as Te, WebGLRenderTarget as V } from "three";
@@ -87,17 +87,17 @@ var ke = class extends E {
87
87
  constructor() {
88
88
  this.index = new Ae(), this.position = new je(), this.bvhBounds = new E(), this.bvhContents = new E(), this._cachedIndexAttr = null, this.index.overrideItemSize = 3;
89
89
  }
90
- updateFrom(e) {
91
- let { geometry: t } = e;
92
- if (Pe(e, this.bvhBounds, this.bvhContents), this.position.updateFrom(t.attributes.position), e.indirect) {
93
- let n = e._indirectBuffer;
94
- if (this._cachedIndexAttr === null || this._cachedIndexAttr.count !== n.length) if (t.index) this._cachedIndexAttr = t.index.clone();
90
+ updateFrom(t) {
91
+ let { geometry: n } = t;
92
+ if (Pe(t, this.bvhBounds, this.bvhContents), this.position.updateFrom(n.attributes.position), t.indirect) {
93
+ let r = t._indirectBuffer;
94
+ if (this._cachedIndexAttr === null || this._cachedIndexAttr.count !== r.length) if (n.index) this._cachedIndexAttr = n.index.clone();
95
95
  else {
96
- let e = l(h(t));
97
- this._cachedIndexAttr = new x(e, 1, !1);
96
+ let t = c(e(n));
97
+ this._cachedIndexAttr = new x(t, 1, !1);
98
98
  }
99
- Ne(t, n, this._cachedIndexAttr), this.index.updateFrom(this._cachedIndexAttr);
100
- } else this.index.updateFrom(t.index);
99
+ Ne(n, r, this._cachedIndexAttr), this.index.updateFrom(this._cachedIndexAttr);
100
+ } else this.index.updateFrom(n.index);
101
101
  }
102
102
  dispose() {
103
103
  let { index: e, position: t, bvhBounds: n, bvhContents: r } = this;
@@ -111,22 +111,22 @@ function Ne(e, t, n) {
111
111
  for (let e = 0; e < 3; e++) r[n + e] = i ? i[a + e] : a + e;
112
112
  }
113
113
  }
114
- function Pe(e, i, a) {
115
- let c = e._roots;
116
- if (c.length !== 1) throw Error("MeshBVHUniformStruct: Multi-root BVHs not supported.");
117
- let l = c[0], u = new Uint16Array(l), d = new Uint32Array(l), f = new Float32Array(l), p = l.byteLength / 32, h = 2 * Math.ceil(Math.sqrt(p / 2)), g = new Float32Array(4 * h * h), _ = Math.ceil(Math.sqrt(p)), v = new Uint32Array(2 * _ * _);
114
+ function Pe(e, r, i) {
115
+ let a = e._roots;
116
+ if (a.length !== 1) throw Error("MeshBVHUniformStruct: Multi-root BVHs not supported.");
117
+ let s = a[0], c = new Uint16Array(s), u = new Uint32Array(s), f = new Float32Array(s), p = s.byteLength / 32, m = 2 * Math.ceil(Math.sqrt(p / 2)), g = new Float32Array(4 * m * m), _ = Math.ceil(Math.sqrt(p)), v = new Uint32Array(2 * _ * _);
118
118
  for (let e = 0; e < p; e++) {
119
- let i = e * 32 / 4, a = i * 2, c = o(i);
120
- for (let t = 0; t < 3; t++) g[8 * e + 0 + t] = f[c + 0 + t], g[8 * e + 4 + t] = f[c + 3 + t];
121
- if (m(a, u)) {
122
- let r = t(a, u), o = s(i, d), c = n | r;
123
- v[e * 2 + 0] = c, v[e * 2 + 1] = o;
119
+ let r = e * 32 / 4, i = r * 2, a = h(r);
120
+ for (let t = 0; t < 3; t++) g[8 * e + 0 + t] = f[a + 0 + t], g[8 * e + 4 + t] = f[a + 3 + t];
121
+ if (n(i, c)) {
122
+ let n = l(i, c), a = t(r, u), o = d | n;
123
+ v[e * 2 + 0] = o, v[e * 2 + 1] = a;
124
124
  } else {
125
- let t = d[i + 6], n = r(i, d);
125
+ let t = u[r + 6], n = o(r, u);
126
126
  v[e * 2 + 0] = n, v[e * 2 + 1] = t;
127
127
  }
128
128
  }
129
- i.image.data = g, i.image.width = h, i.image.height = h, i.format = P, i.type = O, i.internalFormat = "RGBA32F", i.minFilter = M, i.magFilter = M, i.generateMipmaps = !1, i.needsUpdate = !0, i.dispose(), a.image.data = v, a.image.width = _, a.image.height = _, a.format = ge, a.type = L, a.internalFormat = "RG32UI", a.minFilter = M, a.magFilter = M, a.generateMipmaps = !1, a.needsUpdate = !0, a.dispose();
129
+ r.image.data = g, r.image.width = m, r.image.height = m, r.format = P, r.type = O, r.internalFormat = "RGBA32F", r.minFilter = M, r.magFilter = M, r.generateMipmaps = !1, r.needsUpdate = !0, r.dispose(), i.image.data = v, i.image.width = _, i.image.height = _, i.format = ge, i.type = L, i.internalFormat = "RG32UI", i.minFilter = M, i.magFilter = M, i.generateMipmaps = !1, i.needsUpdate = !0, i.dispose();
130
130
  }
131
131
  //#endregion
132
132
  //#region node_modules/three-mesh-bvh/src/webgl/glsl/common_functions.glsl.js
@@ -2238,7 +2238,7 @@ var $ = new R(), ar = class {
2238
2238
  }
2239
2239
  }
2240
2240
  }
2241
- }, or = class t {
2241
+ }, or = class e {
2242
2242
  ingestSceneWithoutShadowHelpers(e, t) {
2243
2243
  let n = [], r = [];
2244
2244
  e.traverse((e) => {
@@ -2263,7 +2263,7 @@ var $ = new R(), ar = class {
2263
2263
  return o.mapping = e.mapping, o.wrapS = e.wrapS, o.wrapT = e.wrapT, o.magFilter = e.magFilter, o.minFilter = e.minFilter, o.anisotropy = e.anisotropy, o.needsUpdate = !0, o;
2264
2264
  }
2265
2265
  getThreeRenderer() {
2266
- return c(this.renderer);
2266
+ return u(this.renderer);
2267
2267
  }
2268
2268
  static {
2269
2269
  this.CAMERA_SETTLE_MS = 200;
@@ -2281,7 +2281,7 @@ var $ = new R(), ar = class {
2281
2281
  this.FADE_RELEASE_FRACTION = .5;
2282
2282
  }
2283
2283
  constructor() {
2284
- this.pathTracer = null, this.enabled = !1, this.renderer = null, this.sampleCount = 0, this.createAttempts = 0, this.maxCreateAttempts = 10, this.sceneInitialized = !1, this.environmentWaitFrames = 0, this.maxEnvironmentWaitFrames = 300, this.disposed = !1, this.convertedEnvTexture = null, this.convertedEnvSourceUuid = null, this.resumable = !1, this.lastCameraMoveTime = -Infinity, this.cameraDirty = !1, this.events = new e(), this.rasterFadeTarget = null, this.fadeQuad = null, this.fadeToneMapping = null, this.fadeSupported = !0, this.settings = {
2284
+ this.pathTracer = null, this.enabled = !1, this.renderer = null, this.sampleCount = 0, this.createAttempts = 0, this.maxCreateAttempts = 10, this.sceneInitialized = !1, this.environmentWaitFrames = 0, this.maxEnvironmentWaitFrames = 300, this.disposed = !1, this.convertedEnvTexture = null, this.convertedEnvSourceUuid = null, this.resumable = !1, this.lastCameraMoveTime = -Infinity, this.cameraDirty = !1, this.events = new i(), this.rasterFadeTarget = null, this.fadeQuad = null, this.fadeToneMapping = null, this.fadeSupported = !0, this.settings = {
2285
2285
  samples: 300,
2286
2286
  bounces: 4,
2287
2287
  transmissiveBounces: 2,
@@ -2293,18 +2293,18 @@ var $ = new R(), ar = class {
2293
2293
  }
2294
2294
  async initialize(e) {
2295
2295
  try {
2296
- return this.renderer = e.renderer, this.enabled = e.enabled, this.isSupported() ? u.ok(void 0) : u.err(new a("Path tracing is not supported in this environment", i.PATH_TRACING_INIT_FAILED, { reason: "WebGL2 or required extensions not available" }));
2296
+ return this.renderer = e.renderer, this.enabled = e.enabled, this.isSupported() ? a.ok(void 0) : a.err(new r("Path tracing is not supported in this environment", s.PATH_TRACING_INIT_FAILED, { reason: "WebGL2 or required extensions not available" }));
2297
2297
  } catch (e) {
2298
- return u.err(new a("Failed to initialize path tracing", i.PATH_TRACING_INIT_FAILED, { originalError: e }));
2298
+ return a.err(new r("Failed to initialize path tracing", s.PATH_TRACING_INIT_FAILED, { originalError: e }));
2299
2299
  }
2300
2300
  }
2301
2301
  createPathTracer() {
2302
- if (this.disposed) return u.err(new a("Instance is disposed", i.INVALID_STATE));
2302
+ if (this.disposed) return a.err(new r("Instance is disposed", s.INVALID_STATE));
2303
2303
  try {
2304
2304
  let e = this.getThreeRenderer();
2305
- return e ? (this.pathTracer = new ar(e), this.pathTracer.tiles && "set" in this.pathTracer.tiles && this.pathTracer.tiles.set(1, 1), this.pathTracer.bounces = this.settings.bounces, this.settings.transmissiveBounces !== void 0 && (this.pathTracer.transmissiveBounces = this.settings.transmissiveBounces), this.pathTracer.renderScale = this.settings.renderScale, this.pathTracer.dynamicLowRes = this.settings.dynamicLowRes, this.pathTracer.lowResScale = this.settings.lowResScale, e.setRenderTarget(null), u.ok(void 0)) : u.err(new a("Renderer not ready, will retry", i.RENDERER_NOT_INITIALIZED));
2305
+ return e ? (this.pathTracer = new ar(e), this.pathTracer.tiles && "set" in this.pathTracer.tiles && this.pathTracer.tiles.set(1, 1), this.pathTracer.bounces = this.settings.bounces, this.settings.transmissiveBounces !== void 0 && (this.pathTracer.transmissiveBounces = this.settings.transmissiveBounces), this.pathTracer.renderScale = this.settings.renderScale, this.pathTracer.dynamicLowRes = this.settings.dynamicLowRes, this.pathTracer.lowResScale = this.settings.lowResScale, e.setRenderTarget(null), a.ok(void 0)) : a.err(new r("Renderer not ready, will retry", s.RENDERER_NOT_INITIALIZED));
2306
2306
  } catch (e) {
2307
- return u.err(new a("Failed to create path tracer", i.PATH_TRACING_INIT_FAILED, { originalError: e }));
2307
+ return a.err(new r("Failed to create path tracer", s.PATH_TRACING_INIT_FAILED, { originalError: e }));
2308
2308
  }
2309
2309
  }
2310
2310
  setEnabled(e) {
@@ -2327,25 +2327,25 @@ var $ = new R(), ar = class {
2327
2327
  }, e.enablePathTracing !== void 0 && this.setEnabled(e.enablePathTracing), this.pathTracer && (e.bounces !== void 0 && (this.pathTracer.bounces = e.bounces), e.transmissiveBounces !== void 0 && (this.pathTracer.transmissiveBounces = e.transmissiveBounces), e.renderScale !== void 0 && (this.pathTracer.renderScale = e.renderScale), e.lowResScale !== void 0 && (this.pathTracer.lowResScale = e.lowResScale), e.dynamicLowRes !== void 0 && (this.pathTracer.dynamicLowRes = e.dynamicLowRes));
2328
2328
  }
2329
2329
  async render(e, t) {
2330
- if (this.disposed) return u.ok(void 0);
2330
+ if (this.disposed) return a.ok(void 0);
2331
2331
  let n = this.renderer;
2332
- if (!n) return u.ok(void 0);
2332
+ if (!n) return a.ok(void 0);
2333
2333
  if (!this.enabled) return this.renderWhileDisabled(e, t);
2334
2334
  if (!this.pathTracer) {
2335
2335
  let r = this.ensurePathTracerCreated(n, e, t);
2336
2336
  if (r) return r;
2337
2337
  }
2338
2338
  try {
2339
- let r = this.extractThreeObjects(e, t);
2340
- if (!r) return u.err(new a("Could not extract Three.js scene or camera", i.INVALID_PARAMETER));
2341
- let { threeScene: o, threeCamera: s } = r;
2339
+ let i = this.extractThreeObjects(e, t);
2340
+ if (!i) return a.err(new r("Could not extract Three.js scene or camera", s.INVALID_PARAMETER));
2341
+ let { threeScene: o, threeCamera: c } = i;
2342
2342
  if (!this.sceneInitialized) {
2343
- let r = await this.initializeSceneForPathTracing(n, e, t, o, s);
2343
+ let r = await this.initializeSceneForPathTracing(n, e, t, o, c);
2344
2344
  if (r) return r;
2345
2345
  }
2346
2346
  return this.sceneInitialized ? this.accumulateSample(n, e, t) : n.render(e, t);
2347
2347
  } catch (e) {
2348
- return u.err(new a("Failed to render with path tracing", i.RENDER_FAILED, { originalError: e }));
2348
+ return a.err(new r("Failed to render with path tracing", s.RENDER_FAILED, { originalError: e }));
2349
2349
  }
2350
2350
  }
2351
2351
  ensurePathTracerCreated(e, t, n) {
@@ -2354,7 +2354,7 @@ var $ = new R(), ar = class {
2354
2354
  return r.ok ? (this.createAttempts = 0, null) : this.createAttempts < this.maxCreateAttempts && r.error?.message === "Renderer not ready, will retry" ? e.render(t, n) : (this.disableAfterSelfPause("gave-up"), this.createAttempts = 0, e.render(t, n));
2355
2355
  }
2356
2356
  extractThreeObjects(e, t) {
2357
- let n = f(e), r = d(t);
2357
+ let n = p(e), r = f(t);
2358
2358
  return !n || !r ? null : {
2359
2359
  threeScene: n,
2360
2360
  threeCamera: r
@@ -2402,20 +2402,20 @@ var $ = new R(), ar = class {
2402
2402
  }
2403
2403
  return null;
2404
2404
  }
2405
- accumulateSample(e, n, r) {
2405
+ accumulateSample(t, n, r) {
2406
2406
  if (this.sampleCount === 0) try {
2407
2407
  this.pathTracer?.updateLights();
2408
2408
  } catch (e) {
2409
2409
  console.warn("Failed to update lights for path tracing:", e);
2410
2410
  }
2411
- let i = e.render(n, r);
2411
+ let i = t.render(n, r);
2412
2412
  if (!i.ok) return i;
2413
- if (performance.now() - this.lastCameraMoveTime < t.CAMERA_SETTLE_MS) return u.ok(void 0);
2414
- if (this.cameraDirty && (this.cameraDirty = !1, this.pathTracer?.updateCamera()), this.fadeSupported && this.sampleCount === 0 && this.runFadeStep(() => this.captureRasterFade(e, n, r)), this.accumulateOneSample(), this.sampleCount++, this.fadeSupported && this.sampleCount < this.fadeWindowSamples()) {
2413
+ if (performance.now() - this.lastCameraMoveTime < e.CAMERA_SETTLE_MS) return a.ok(void 0);
2414
+ if (this.cameraDirty && (this.cameraDirty = !1, this.pathTracer?.updateCamera()), this.fadeSupported && this.sampleCount === 0 && this.runFadeStep(() => this.captureRasterFade(t, n, r)), this.accumulateOneSample(), this.sampleCount++, this.fadeSupported && this.sampleCount < this.fadeWindowSamples()) {
2415
2415
  let e = 1 - this.pathTracedLayerOpacity(this.sampleCount);
2416
2416
  this.runFadeStep(() => this.renderRasterFade(e));
2417
2417
  }
2418
- return this.sampleCount === this.settings.samples ? this.captureCompletedFrame() : u.ok(void 0);
2418
+ return this.sampleCount === this.settings.samples ? this.captureCompletedFrame() : a.ok(void 0);
2419
2419
  }
2420
2420
  runFadeStep(e) {
2421
2421
  try {
@@ -2425,15 +2425,15 @@ var $ = new R(), ar = class {
2425
2425
  }
2426
2426
  }
2427
2427
  fadeWindowSamples() {
2428
- let e = t.FADE_HOLD_SAMPLES + 2;
2429
- return Math.max(e, Math.min(t.FADE_SAMPLES, this.settings.samples));
2428
+ let t = e.FADE_HOLD_SAMPLES + 2;
2429
+ return Math.max(t, Math.min(e.FADE_SAMPLES, this.settings.samples));
2430
2430
  }
2431
- pathTracedLayerOpacity(e) {
2432
- let n = t.FADE_HOLD_SAMPLES, r = this.fadeWindowSamples(), i = t.FADE_PREVIEW_OPACITY, a = n + (r - n) * t.FADE_RELEASE_FRACTION;
2433
- return e < a ? i * t.smoothstep(n, a, e) : i + (1 - i) * t.smoothstep(a, r, e);
2431
+ pathTracedLayerOpacity(t) {
2432
+ let n = e.FADE_HOLD_SAMPLES, r = this.fadeWindowSamples(), i = e.FADE_PREVIEW_OPACITY, a = n + (r - n) * e.FADE_RELEASE_FRACTION;
2433
+ return t < a ? i * e.smoothstep(n, a, t) : i + (1 - i) * e.smoothstep(a, r, t);
2434
2434
  }
2435
2435
  static smoothstep(e, t, n) {
2436
- return p(Math.min(1, Math.max(0, (n - e) / (t - e))));
2436
+ return m(Math.min(1, Math.max(0, (n - e) / (t - e))));
2437
2437
  }
2438
2438
  captureRasterFade(e, t, n) {
2439
2439
  let r = this.getThreeRenderer();
@@ -2480,10 +2480,10 @@ var $ = new R(), ar = class {
2480
2480
  });
2481
2481
  }
2482
2482
  renderWhileDisabled(e, t) {
2483
- if (!this.renderer) return u.ok(void 0);
2483
+ if (!this.renderer) return a.ok(void 0);
2484
2484
  if (this.sampleCount >= this.settings.samples && this.sampleCount > 0) {
2485
2485
  let e = this.getThreeRenderer();
2486
- return this.pathTracer && e && e.setRenderTarget(null), u.ok(void 0);
2486
+ return this.pathTracer && e && e.setRenderTarget(null), a.ok(void 0);
2487
2487
  }
2488
2488
  return this.renderer.render(e, t);
2489
2489
  }
@@ -2503,7 +2503,7 @@ var $ = new R(), ar = class {
2503
2503
  } catch (e) {
2504
2504
  console.warn("Failed to present path traced result:", e);
2505
2505
  }
2506
- return this.disableAfterSelfPause("completed"), u.ok(void 0);
2506
+ return this.disableAfterSelfPause("completed"), a.ok(void 0);
2507
2507
  }
2508
2508
  getSampleCount() {
2509
2509
  return this.sampleCount;
package/dist/index.d.cts CHANGED
@@ -31,6 +31,33 @@ export declare interface AnimationOptions {
31
31
  speed?: number;
32
32
  }
33
33
 
34
+ /**
35
+ * AR handoff configuration: a small button over the canvas that opens the
36
+ * model in the platform's native AR viewer — AR Quick Look on iOS, Scene
37
+ * Viewer on Android. UI-only: the button never touches the WebGL viewer, and
38
+ * toggling it never rebuilds anything. The button only renders on devices
39
+ * that can actually hand off (never on desktop).
40
+ */
41
+ export declare interface AROptions {
42
+ /**
43
+ * USDZ counterpart of the model, for iOS AR Quick Look — Quick Look cannot
44
+ * read GLB, so without this the button stays hidden on iOS. Android Scene
45
+ * Viewer instead reuses the loaded model's own URL and needs nothing here
46
+ * (but requires the model to be loaded from a network URL — a dropped
47
+ * `blob:` file has no address a native app could fetch).
48
+ */
49
+ iosSrc?: string;
50
+ /** Title shown on Android Scene Viewer's info card. */
51
+ title?: string;
52
+ /**
53
+ * Corner the button floats in (default `bottom-left`). When the built-in
54
+ * preset picker is enabled, a bottom-placed button lifts above the chip
55
+ * row on its own — pick a top corner if it must clear other chrome (e.g.
56
+ * a `bottom-left` gizmo).
57
+ */
58
+ placement?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
59
+ }
60
+
34
61
  export declare interface AxesHelperOptions {
35
62
  size?: number;
36
63
  }
@@ -581,6 +608,14 @@ export declare interface SimpleViewerHandle {
581
608
  captureVideo: (options?: CaptureVideoOptions) => Promise<Blob>;
582
609
  /** Clip names of the loaded model, in file order (empty when none). */
583
610
  getAnimationNames: () => string[];
611
+ /** KHR_materials_variants names of the loaded model (empty when none). */
612
+ getVariantNames: () => string[];
613
+ /**
614
+ * Switch the loaded model to a material variant; `null` restores the
615
+ * authored materials. Applies live (no reload). Throws `INVALID_PARAMETER`
616
+ * on a variant name the model does not carry.
617
+ */
618
+ setVariant: (variant: string | null) => void;
584
619
  /**
585
620
  * Plays one clip by name, or ALL clips when no name is given (looped).
586
621
  * Throws `INVALID_PARAMETER` on a clip name the model does not carry.
@@ -624,6 +659,16 @@ export declare interface SimpleViewerOptions {
624
659
  * Any other option you pass overrides the scene's values.
625
660
  */
626
661
  scene?: ViewerScene;
662
+ /**
663
+ * KHR_materials_variants variant to show (e.g. a product colorway baked
664
+ * into the GLB). Applies LIVE — switching never rebuilds the viewer or
665
+ * reloads the model. `null` shows the authored default materials; leaving
666
+ * the option out is "uncontrolled" (an imperative `handle.setVariant()`
667
+ * pick survives other option changes); an unknown name warns and keeps
668
+ * the defaults. Enumerate the model's variants via
669
+ * `handle.getVariantNames()`.
670
+ */
671
+ variant?: string | null;
627
672
  /**
628
673
  * Length unit the model geometry is authored in (default `'meters'`).
629
674
  * Non-meter models are rescaled on load — without touching the model's own
@@ -712,6 +757,14 @@ export declare interface SimpleViewerOptions {
712
757
  * live preset picker). All opt-in; UI-only — never rebuilds the viewer.
713
758
  */
714
759
  ui?: UIOptions;
760
+ /**
761
+ * AR handoff button: opens the model in the platform's native AR viewer —
762
+ * AR Quick Look on iOS (needs `iosSrc`, a USDZ counterpart), Scene Viewer
763
+ * on Android (reuses the model's own URL). `true` enables with defaults.
764
+ * The button renders only on devices that can actually hand off, so it is
765
+ * safe to set unconditionally. UI-only — never rebuilds the viewer.
766
+ */
767
+ ar?: boolean | AROptions;
715
768
  /**
716
769
  * Click-picking / hotspot-occlusion raycast tuning (e.g. `selection: { bvh:
717
770
  * false }` to skip the load-time BVH build on memory-constrained targets).