rayzee 7.30.1 → 7.31.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/dist/rayzee.es.js CHANGED
@@ -675,7 +675,8 @@ var X = {
675
675
  edgePhiDepth: .1,
676
676
  enableOIDN: !1,
677
677
  oidnQuality: "fast",
678
- debugGbufferMaps: !1,
678
+ continuousDenoise: !1,
679
+ continuousDenoiseInterval: 8,
679
680
  enableUpscaler: !1,
680
681
  upscalerScale: 2,
681
682
  upscalerQuality: "fast",
@@ -9397,7 +9398,7 @@ function xd(e) {
9397
9398
  }
9398
9399
  //#endregion
9399
9400
  //#region src/TSL/BVHTraversal.js
9400
- var Sd = 32, Cd = 512, wd = 4, Td = 8, Ed = 1e8, Dd = () => y("int", Sd).toVar(), Od = K("\n fn RayTriangleGeometry( rayOrigin: vec3f, rayDir: vec3f, pA: vec3f, pB: vec3f, pC: vec3f, closestHitDst: f32, woopParams: vec4f ) -> vec4f {\n\n // Returns vec4(t, u, v, hit) where hit > 0.5 means intersection.\n // woopParams: (Sx, Sy, Sz, bitcast<f32>(packed kx|ky<<2|kz<<4))\n var result = vec4f( 1e20f, 0.0f, 0.0f, 0.0f );\n\n let Sx = woopParams.x;\n let Sy = woopParams.y;\n let Sz = woopParams.z;\n // Packed as regular f32 (values 0–42), not bitcast — avoids subnormal FTZ on Apple GPUs.\n let packed = i32( woopParams.w );\n let kx = packed & 3;\n let ky = ( packed >> 2 ) & 3;\n let kz = ( packed >> 4 ) & 3;\n\n let A = pA - rayOrigin;\n let B = pB - rayOrigin;\n let C = pC - rayOrigin;\n\n let Akz = A[ kz ];\n let Bkz = B[ kz ];\n let Ckz = C[ kz ];\n\n let Ax = A[ kx ] - Sx * Akz;\n let Ay = A[ ky ] - Sy * Akz;\n let Bx = B[ kx ] - Sx * Bkz;\n let By = B[ ky ] - Sy * Bkz;\n let Cx = C[ kx ] - Sx * Ckz;\n let Cy = C[ ky ] - Sy * Ckz;\n\n // Edge function tests — all three must share sign (or be exactly zero) for hit.\n let U = Cx * By - Cy * Bx;\n let V = Ax * Cy - Ay * Cx;\n let W = Bx * Ay - By * Ax;\n\n let neg = U < 0.0f || V < 0.0f || W < 0.0f;\n let pos = U > 0.0f || V > 0.0f || W > 0.0f;\n if ( !( neg && pos ) ) {\n\n let det = U + V + W;\n if ( det != 0.0f ) {\n\n let T = U * ( Sz * Akz ) + V * ( Sz * Bkz ) + W * ( Sz * Ckz );\n\n // Sign-aware bounds check on t (multiply both sides by sign(det) once).\n let detSign = select( -1.0f, 1.0f, det > 0.0f );\n let tSigned = T * detSign;\n let detAbs = abs( det );\n\n if ( tSigned > 0.0f && tSigned < closestHitDst * detAbs ) {\n\n // Match Möller-Trumbore convention: u = weight of B, v = weight of C.\n // In Woop's edge functions, U → weight of A, V → weight of B, W → weight of C.\n let invDet = 1.0f / det;\n result = vec4f( T * invDet, V * invDet, W * invDet, 1.0f );\n\n }\n\n }\n\n }\n\n return result;\n\n }\n"), kd = K("\n fn computeWoopRayParams( rayDir: vec3f ) -> vec4f {\n\n let absDir = abs( rayDir );\n\n // kz = argmax(|dir|)\n var kz: i32 = 0;\n if ( absDir.y >= absDir.x ) { kz = 1; }\n if ( absDir.z >= absDir[ u32( kz ) ] ) { kz = 2; }\n\n var kx: i32 = ( kz + 1 ) % 3;\n var ky: i32 = ( kx + 1 ) % 3;\n\n // Preserve triangle winding when the dominant axis component is negative.\n if ( rayDir[ u32( kz ) ] < 0.0f ) {\n let tmp = kx;\n kx = ky;\n ky = tmp;\n }\n\n let dz = rayDir[ u32( kz ) ];\n let Sx = rayDir[ u32( kx ) ] / dz;\n let Sy = rayDir[ u32( ky ) ] / dz;\n let Sz = 1.0f / dz;\n\n let packed = kx | ( ky << 2 ) | ( kz << 4 );\n return vec4f( Sx, Sy, Sz, f32( packed ) );\n\n }\n"), Ad = K("\n fn fastRayAABBDst( rayOrigin: vec3f, invDir: vec3f, boxMin: vec3f, boxMax: vec3f ) -> f32 {\n\n let t1 = ( boxMin - rayOrigin ) * invDir;\n let t2 = ( boxMax - rayOrigin ) * invDir;\n\n let tmin = min( t1, t2 );\n let tmax = max( t1, t2 );\n\n let tNear = max( max( tmin.x, tmin.y ), tmin.z );\n let tFar = min( min( tmax.x, tmax.y ), tmax.z ) * 1.00000024f; // Robust traversal: 2 ULP padding (Ize 2013)\n\n let isHit = tNear <= tFar && tFar > 0.0f;\n return select( 1e20f, max( tNear, 0.0f ), isHit );\n\n }\n"), jd = (e) => f(([t, n, r, i]) => {
9401
+ var Sd = 32, Cd = 4096, wd = 4, Td = 8, Ed = 1e8, Dd = () => y("int", Sd).toVar(), Od = K("\n fn RayTriangleGeometry( rayOrigin: vec3f, rayDir: vec3f, pA: vec3f, pB: vec3f, pC: vec3f, closestHitDst: f32, woopParams: vec4f ) -> vec4f {\n\n // Returns vec4(t, u, v, hit) where hit > 0.5 means intersection.\n // woopParams: (Sx, Sy, Sz, bitcast<f32>(packed kx|ky<<2|kz<<4))\n var result = vec4f( 1e20f, 0.0f, 0.0f, 0.0f );\n\n let Sx = woopParams.x;\n let Sy = woopParams.y;\n let Sz = woopParams.z;\n // Packed as regular f32 (values 0–42), not bitcast — avoids subnormal FTZ on Apple GPUs.\n let packed = i32( woopParams.w );\n let kx = packed & 3;\n let ky = ( packed >> 2 ) & 3;\n let kz = ( packed >> 4 ) & 3;\n\n let A = pA - rayOrigin;\n let B = pB - rayOrigin;\n let C = pC - rayOrigin;\n\n let Akz = A[ kz ];\n let Bkz = B[ kz ];\n let Ckz = C[ kz ];\n\n let Ax = A[ kx ] - Sx * Akz;\n let Ay = A[ ky ] - Sy * Akz;\n let Bx = B[ kx ] - Sx * Bkz;\n let By = B[ ky ] - Sy * Bkz;\n let Cx = C[ kx ] - Sx * Ckz;\n let Cy = C[ ky ] - Sy * Ckz;\n\n // Edge function tests — all three must share sign (or be exactly zero) for hit.\n let U = Cx * By - Cy * Bx;\n let V = Ax * Cy - Ay * Cx;\n let W = Bx * Ay - By * Ax;\n\n let neg = U < 0.0f || V < 0.0f || W < 0.0f;\n let pos = U > 0.0f || V > 0.0f || W > 0.0f;\n if ( !( neg && pos ) ) {\n\n let det = U + V + W;\n if ( det != 0.0f ) {\n\n let T = U * ( Sz * Akz ) + V * ( Sz * Bkz ) + W * ( Sz * Ckz );\n\n // Sign-aware bounds check on t (multiply both sides by sign(det) once).\n let detSign = select( -1.0f, 1.0f, det > 0.0f );\n let tSigned = T * detSign;\n let detAbs = abs( det );\n\n if ( tSigned > 0.0f && tSigned < closestHitDst * detAbs ) {\n\n // Match Möller-Trumbore convention: u = weight of B, v = weight of C.\n // In Woop's edge functions, U → weight of A, V → weight of B, W → weight of C.\n let invDet = 1.0f / det;\n result = vec4f( T * invDet, V * invDet, W * invDet, 1.0f );\n\n }\n\n }\n\n }\n\n return result;\n\n }\n"), kd = K("\n fn computeWoopRayParams( rayDir: vec3f ) -> vec4f {\n\n let absDir = abs( rayDir );\n\n // kz = argmax(|dir|)\n var kz: i32 = 0;\n if ( absDir.y >= absDir.x ) { kz = 1; }\n if ( absDir.z >= absDir[ u32( kz ) ] ) { kz = 2; }\n\n var kx: i32 = ( kz + 1 ) % 3;\n var ky: i32 = ( kx + 1 ) % 3;\n\n // Preserve triangle winding when the dominant axis component is negative.\n if ( rayDir[ u32( kz ) ] < 0.0f ) {\n let tmp = kx;\n kx = ky;\n ky = tmp;\n }\n\n let dz = rayDir[ u32( kz ) ];\n let Sx = rayDir[ u32( kx ) ] / dz;\n let Sy = rayDir[ u32( ky ) ] / dz;\n let Sz = 1.0f / dz;\n\n let packed = kx | ( ky << 2 ) | ( kz << 4 );\n return vec4f( Sx, Sy, Sz, f32( packed ) );\n\n }\n"), Ad = K("\n fn fastRayAABBDst( rayOrigin: vec3f, invDir: vec3f, boxMin: vec3f, boxMax: vec3f ) -> f32 {\n\n let t1 = ( boxMin - rayOrigin ) * invDir;\n let t2 = ( boxMax - rayOrigin ) * invDir;\n\n let tmin = min( t1, t2 );\n let tmax = max( t1, t2 );\n\n let tNear = max( max( tmin.x, tmin.y ), tmin.z );\n let tFar = min( min( tmax.x, tmax.y ), tmax.z ) * 1.00000024f; // Robust traversal: 2 ULP padding (Ize 2013)\n\n let isHit = tNear <= tFar && tFar > 0.0f;\n return select( 1e20f, max( tNear, 0.0f ), isHit );\n\n }\n"), jd = (e) => f(([t, n, r, i]) => {
9401
9402
  let a = i ?? T(!1), o = ja({
9402
9403
  didHit: !1,
9403
9404
  dst: A(0x56bc75e2d63100000),
@@ -17154,12 +17155,24 @@ function Jh(e) {
17154
17155
  return Math.max(0, Math.min(1, e));
17155
17156
  }
17156
17157
  //#endregion
17157
- //#region src/Passes/OIDNDenoiser.js
17158
- var Yh = ki("oidn"), Xh = null;
17159
- async function Zh() {
17160
- return Xh ||= (await import("oidn-web")).initUNetFromURL, Xh;
17158
+ //#region src/Processor/ToneMapWGSL.js
17159
+ var Yh = new Set([
17160
+ jt,
17161
+ _t,
17162
+ Kt,
17163
+ $e,
17164
+ We,
17165
+ Ke,
17166
+ kt
17167
+ ]);
17168
+ function Xh(e) {
17169
+ return Yh.has(e) ? e : We;
17161
17170
  }
17162
- var Qh = new Float32Array(3), $h = {
17171
+ var Zh = "\nfn tmSaturation( c: vec3f, saturation: f32 ) -> vec3f {\n if ( saturation == 1.0 ) { return c; }\n let luma = dot( c, vec3f( 0.2126, 0.7152, 0.0722 ) );\n return vec3f( luma ) + ( c - vec3f( luma ) ) * saturation;\n}\n\nfn tmSrgb1( c: f32 ) -> f32 {\n if ( c <= 0.0031308 ) { return 12.92 * c; }\n return 1.055 * pow( c, 1.0 / 2.4 ) - 0.055;\n}\n\nfn tmSrgb( c: vec3f ) -> vec3f {\n return vec3f( tmSrgb1( c.r ), tmSrgb1( c.g ), tmSrgb1( c.b ) );\n}\n\nfn tmReinhard( c: vec3f ) -> vec3f {\n return clamp( c / ( c + vec3f( 1.0 ) ), vec3f( 0.0 ), vec3f( 1.0 ) );\n}\n\nfn tmCineon1( x: f32 ) -> f32 {\n let c = max( x - 0.004, 0.0 );\n return pow( ( c * ( 6.2 * c + 0.5 ) ) / ( c * ( 6.2 * c + 1.7 ) + 0.06 ), 2.2 );\n}\n\nfn tmCineon( c: vec3f ) -> vec3f {\n return vec3f( tmCineon1( c.r ), tmCineon1( c.g ), tmCineon1( c.b ) );\n}\n\nfn tmAcesFit( c: f32 ) -> f32 {\n return ( c * ( c + 0.0245786 ) - 0.000090537 ) / ( c * ( 0.983729 * c + 0.4329510 ) + 0.238081 );\n}\n\nfn tmAces( cIn: vec3f ) -> vec3f {\n let c = cIn / 0.6;\n var i = vec3f(\n 0.59719 * c.r + 0.35458 * c.g + 0.04823 * c.b,\n 0.07600 * c.r + 0.90834 * c.g + 0.01566 * c.b,\n 0.02840 * c.r + 0.13383 * c.g + 0.83777 * c.b\n );\n i = vec3f( tmAcesFit( i.r ), tmAcesFit( i.g ), tmAcesFit( i.b ) );\n let o = vec3f(\n 1.60475 * i.r - 0.53108 * i.g - 0.07367 * i.b,\n -0.10208 * i.r + 1.10813 * i.g - 0.00605 * i.b,\n -0.00327 * i.r - 0.07276 * i.g + 1.07602 * i.b\n );\n return clamp( o, vec3f( 0.0 ), vec3f( 1.0 ) );\n}\n\nfn tmAgxApprox( x: f32 ) -> f32 {\n let x2 = x * x;\n let x4 = x2 * x2;\n return 15.5 * x4 * x2 - 40.14 * x4 * x + 31.96 * x4 - 6.868 * x2 * x + 0.4298 * x2 + 0.1191 * x - 0.00232;\n}\n\nfn tmAgx( r: vec3f ) -> vec3f {\n let c = vec3f(\n 0.6274 * r.r + 0.3293 * r.g + 0.0433 * r.b,\n 0.0691 * r.r + 0.9195 * r.g + 0.0113 * r.b,\n 0.0164 * r.r + 0.0880 * r.g + 0.8956 * r.b\n );\n var a = vec3f(\n 0.856627153315983 * c.r + 0.0951212405381588 * c.g + 0.0482516061458583 * c.b,\n 0.137318972929847 * c.r + 0.761241990602591 * c.g + 0.101439036467562 * c.b,\n 0.11189821299995 * c.r + 0.0767994186031903 * c.g + 0.811302368396859 * c.b\n );\n\n let agxMinEv = -12.47393;\n let agxMaxEv = 4.026069;\n let range = agxMaxEv - agxMinEv;\n a = clamp( ( log2( max( a, vec3f( 1e-10 ) ) ) - vec3f( agxMinEv ) ) / range, vec3f( 0.0 ), vec3f( 1.0 ) );\n a = vec3f( tmAgxApprox( a.r ), tmAgxApprox( a.g ), tmAgxApprox( a.b ) );\n\n var o = vec3f(\n 1.1271005818144368 * a.r - 0.11060664309660323 * a.g - 0.016493938717834573 * a.b,\n -0.1413297634984383 * a.r + 1.157823702216272 * a.g - 0.016493938717834257 * a.b,\n -0.14132976349843826 * a.r - 0.11060664309660294 * a.g + 1.2519364065950405 * a.b\n );\n o = pow( max( o, vec3f( 0.0 ) ), vec3f( 2.2 ) );\n\n return clamp( vec3f(\n 1.6605 * o.r - 0.5876 * o.g - 0.0728 * o.b,\n -0.1246 * o.r + 1.1329 * o.g - 0.0083 * o.b,\n -0.0182 * o.r - 0.1006 * o.g + 1.1187 * o.b\n ), vec3f( 0.0 ), vec3f( 1.0 ) );\n}\n\nfn tmNeutral( cIn: vec3f ) -> vec3f {\n let startCompression = 0.8 - 0.04;\n let desaturation = 0.15;\n\n let x = min( cIn.r, min( cIn.g, cIn.b ) );\n var offset = 0.04;\n if ( x < 0.08 ) { offset = x - 6.25 * x * x; }\n\n var c = cIn - vec3f( offset );\n let peak = max( c.r, max( c.g, c.b ) );\n if ( peak < startCompression ) { return c; }\n\n let d = 1.0 - startCompression;\n let newPeak = 1.0 - d * d / ( peak + d - startCompression );\n c = c * ( newPeak / peak );\n let gFactor = 1.0 - 1.0 / ( desaturation * ( peak - newPeak ) + 1.0 );\n\n return c + ( vec3f( newPeak ) - c ) * gFactor;\n}\n\nfn tmCurve( cIn: vec3f, mode: u32 ) -> vec3f {\n // Three.js clamps the fragment output before tone mapping (\"force unsigned floats\"), and\n // AgX/Neutral mix negatives across channels rather than clipping them.\n let c = max( cIn, vec3f( 0.0 ) );\n switch mode {\n case 0u, 1u: { return clamp( c, vec3f( 0.0 ), vec3f( 1.0 ) ); }\n case 2u: { return tmReinhard( c ); }\n case 3u: { return tmCineon( c ); }\n case 6u: { return tmAgx( c ); }\n case 7u: { return tmNeutral( c ); }\n default: { return tmAces( c ); }\n }\n}\n\nfn toneMapPixel( linear: vec3f, gain: f32, saturation: f32, mode: u32 ) -> vec3f {\n var c = linear * gain;\n c = tmSaturation( c, saturation );\n c = tmCurve( c, mode );\n return tmSrgb( c );\n}\n", Qh = ki("oidn"), $h = null;
17172
+ async function eg() {
17173
+ return $h ||= (await import("oidn-web")).initUNetFromURL, $h;
17174
+ }
17175
+ var tg = {
17163
17176
  QUALITY_MODELS: {
17164
17177
  fast: {
17165
17178
  model: "rt_hdr_alb_nrm_small",
@@ -17181,38 +17194,125 @@ var Qh = new Float32Array(3), $h = {
17181
17194
  DEFAULT_OPTIONS: {
17182
17195
  enableOIDN: !0,
17183
17196
  oidnQuality: "fast",
17184
- debugGbufferMaps: !0,
17185
17197
  tileSize: 1024
17186
17198
  }
17187
- }, eg = "\n@group(0) @binding(0) var<storage, read_write> col: array<vec4<f32>>;\n@group(0) @binding(1) var<uniform> scale: f32;\n\n@compute @workgroup_size(64)\nfn main( @builtin(global_invocation_id) gid: vec3<u32>,\n @builtin(num_workgroups) nwg: vec3<u32> ) {\n let i = gid.y * nwg.x * 64u + gid.x;\n if ( i >= arrayLength( &col ) ) { return; }\n let c = col[ i ];\n col[ i ] = vec4<f32>( c.xyz * scale, c.w );\n}\n", tg = 64, ng = 32768, rg = .18;
17188
- function ig(e, t) {
17189
- let n = 0;
17190
- for (let r = 0; r < t; r++) {
17191
- let t = r * 4, i = .212671 * e[t] + .71516 * e[t + 1] + .072169 * e[t + 2];
17192
- n += Math.log2(Math.max(i, 0) + 1e-4);
17199
+ }, ng = .18, rg = 256, ig = 256, ag = `
17200
+ const WG: u32 = ${rg}u;
17201
+ const GROUPS: u32 = ${ig}u;
17202
+
17203
+ @group(0) @binding(0) var<storage, read> col: array<vec4<f32>>;
17204
+ @group(0) @binding(1) var<storage, read_write> partials: array<f32>;
17205
+ @group(0) @binding(2) var<uniform> params: vec4<u32>;
17206
+ @group(0) @binding(3) var<storage, read_write> scaleOut: array<f32>;
17207
+
17208
+ var<workgroup> sdata: array<f32, WG>;
17209
+
17210
+ fn treeSum( lid: u32 ) {
17211
+ var s: u32 = WG >> 1u;
17212
+ loop {
17213
+ if ( s == 0u ) { break; }
17214
+ if ( lid < s ) { sdata[ lid ] = sdata[ lid ] + sdata[ lid + s ]; }
17215
+ workgroupBarrier();
17216
+ s = s >> 1u;
17217
+ }
17218
+ }
17219
+
17220
+ @compute @workgroup_size(${rg})
17221
+ fn reduce( @builtin(global_invocation_id) gid: vec3<u32>,
17222
+ @builtin(local_invocation_id) lid: vec3<u32>,
17223
+ @builtin(workgroup_id) wid: vec3<u32> ) {
17224
+
17225
+ let total = params.x;
17226
+ var sum = 0.0;
17227
+ var i = gid.x;
17228
+ loop {
17229
+ if ( i >= total ) { break; }
17230
+ let c = col[ i ].xyz;
17231
+ let lum = 0.212671 * c.r + 0.71516 * c.g + 0.072169 * c.b;
17232
+ sum = sum + log2( max( lum, 0.0 ) + 0.0001 );
17233
+ i = i + WG * GROUPS;
17234
+ }
17235
+
17236
+ sdata[ lid.x ] = sum;
17237
+ workgroupBarrier();
17238
+ treeSum( lid.x );
17239
+
17240
+ if ( lid.x == 0u ) { partials[ wid.x ] = sdata[ 0 ]; }
17241
+ }
17242
+
17243
+ @compute @workgroup_size(${rg})
17244
+ fn finalize( @builtin(local_invocation_id) lid: vec3<u32> ) {
17245
+
17246
+ var v = 0.0;
17247
+ if ( lid.x < GROUPS ) { v = partials[ lid.x ]; }
17248
+ sdata[ lid.x ] = v;
17249
+ workgroupBarrier();
17250
+ treeSum( lid.x );
17251
+
17252
+ if ( lid.x == 0u ) {
17253
+ let scale = ${ng} / exp2( sdata[ 0 ] / f32( params.x ) );
17254
+ // Mirrors the CPU guard: a non-finite or non-positive scale means no scaling at all.
17255
+ scaleOut[ 0 ] = select( 1.0, scale, scale > 0.0 && scale < 3.4e38 );
17193
17256
  }
17194
- let r = rg / 2 ** (n / t);
17195
- return Number.isFinite(r) && r > 0 ? r : 1;
17196
17257
  }
17197
- var ag = class extends dt {
17258
+ `, og = "\n@group(0) @binding(0) var<storage, read_write> col: array<vec4<f32>>;\n@group(0) @binding(1) var<storage, read> scaleBuf: array<f32>;\n\n@compute @workgroup_size(64)\nfn main( @builtin(global_invocation_id) gid: vec3<u32>,\n @builtin(num_workgroups) nwg: vec3<u32> ) {\n let i = gid.y * nwg.x * 64u + gid.x;\n if ( i >= arrayLength( &col ) ) { return; }\n let c = col[ i ];\n col[ i ] = vec4<f32>( c.xyz * scaleBuf[ 0 ], c.w );\n}\n", sg = 64, cg = 32768, lg = 16, ug = 48, dg = `
17259
+ ${Zh}
17260
+
17261
+ struct PackParams {
17262
+ srcWidth: u32,
17263
+ tileX: u32,
17264
+ tileY: u32,
17265
+ tileW: u32,
17266
+ tileH: u32,
17267
+ mode: u32,
17268
+ useAlpha: u32,
17269
+ pad0: u32,
17270
+ exposure: f32,
17271
+ saturation: f32,
17272
+ pad1: vec2<f32>,
17273
+ };
17274
+
17275
+ @group(0) @binding(0) var<storage, read> src: array<vec4<f32>>;
17276
+ @group(0) @binding(1) var<storage, read_write> dst: array<u32>;
17277
+ @group(0) @binding(2) var<uniform> P: PackParams;
17278
+ @group(0) @binding(3) var<storage, read> scaleBuf: array<f32>;
17279
+ @group(0) @binding(4) var<storage, read> inColor: array<vec4<f32>>;
17280
+
17281
+ @compute @workgroup_size(${lg}, ${lg})
17282
+ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
17283
+
17284
+ if ( gid.x >= P.tileW || gid.y >= P.tileH ) { return; }
17285
+
17286
+ let si = ( P.tileY + gid.y ) * P.srcWidth + ( P.tileX + gid.x );
17287
+ let di = gid.y * P.tileW + gid.x;
17288
+
17289
+ let rgb = toneMapPixel( src[ si ].xyz, P.exposure / scaleBuf[ 0 ], P.saturation, P.mode );
17290
+
17291
+ var a: u32 = 255u;
17292
+ if ( P.useAlpha == 1u ) { a = u32( clamp( inColor[ si ].w, 0.0, 1.0 ) * 255.0 + 0.5 ); }
17293
+
17294
+ let q = vec3<u32>( clamp( rgb, vec3f( 0.0 ), vec3f( 1.0 ) ) * 255.0 + vec3f( 0.5 ) );
17295
+ dst[ di ] = q.x | ( q.y << 8u ) | ( q.z << 16u ) | ( a << 24u );
17296
+ }
17297
+ `, fg = class extends dt {
17198
17298
  constructor(e, t, n, r, i = {}) {
17199
17299
  if (super(), !e || !t || !n || !r) throw Error("OIDNDenoiser requires output canvas, renderer, scene, and camera");
17200
- this.renderer = t, this.scene = n, this.camera = r, this.input = t.domElement, this.output = e, this.extractGBufferData = i.extractGBufferData || null, this.getMRTRenderTarget = i.getMRTRenderTarget || null, this.backendParamsGetter = i.backendParams || null, this.getGPUTextures = i.getGPUTextures || null, this.refreshInput = i.refreshInput || null, this.getExposure = i.getExposure || (() => 1), this.getToneMapping = i.getToneMapping || (() => We), this.getSaturation = i.getSaturation || (() => 1), this.getTransparentBackground = i.getTransparentBackground || (() => !1), this.isGPUMode = !!this.backendParamsGetter, this.gpuDevice = null, this._gpuInputBuffers = {
17300
+ this.renderer = t, this.scene = n, this.camera = r, this.input = t.domElement, this.output = e, this.backendParamsGetter = i.backendParams || null, this.getGPUTextures = i.getGPUTextures || null, this.refreshInput = i.refreshInput || null, this.getExposure = i.getExposure || (() => 1), this.getToneMapping = i.getToneMapping || (() => We), this.getSaturation = i.getSaturation || (() => 1), this.getTransparentBackground = i.getTransparentBackground || (() => !1), this.isGPUMode = !!this.backendParamsGetter, this.gpuDevice = null, this._gpuInputBuffers = {
17201
17301
  color: null,
17202
17302
  albedo: null,
17203
17303
  normal: null
17204
17304
  }, this._gpuInputBufferSize = {
17205
17305
  width: 0,
17206
17306
  height: 0
17207
- }, this._gpuInputPadBuffer = null, this._gpuInputPaddedRowBytes = 0, this._colorScalePipeline = null, this._colorScaleBindGroup = null, this._colorScaleUniform = null, this._oidnInputScale = 1, this._alphaReadbackBuffer = null, this._alphaReadbackMapped = !1, this._cachedAlpha = null, this._cachedAlphaWidth = 0, this.config = {
17208
- ...$h.DEFAULT_OPTIONS,
17307
+ }, this._gpuInputPadBuffer = null, this._gpuInputPaddedRowBytes = 0, this._lumReducePipeline = null, this._lumFinalizePipeline = null, this._lumLayout = null, this._lumBindGroup = null, this._lumPartials = null, this._lumParams = null, this._inputScaleBuffer = null, this._colorScalePipeline = null, this._colorScaleBindGroup = null, this._packPipeline = null, this.config = {
17308
+ ...tg.DEFAULT_OPTIONS,
17209
17309
  ...i
17210
- }, this.enabled = this.config.enableOIDN, this.quality = this.config.oidnQuality, this.debugGbufferMaps = this.config.debugGbufferMaps, this.maxTileSize = this.config.tileSize, this._activeTileSize = 0, this.state = {
17310
+ }, this.enabled = this.config.enableOIDN, this.quality = this.config.oidnQuality, this.maxTileSize = this.config.tileSize, this._activeTileSize = 0, this.state = {
17211
17311
  isDenoising: !1,
17212
17312
  isLoading: !1,
17213
17313
  abortController: null
17214
- }, this._pendingStagingBuffers = /* @__PURE__ */ new Set(), this._pendingTileBlits = [], this.currentTZAUrl = null, this.unet = null, this._pendingStart = !1, this._initialize().catch((e) => {
17215
- Yh.error("init failed:", e), this.dispatchEvent({
17314
+ }, this._pendingStagingBuffers = /* @__PURE__ */ new Set(), this._pendingTileBlits = [], this._runId = 0, this._hasLatchedFrame = !1, this.lastDenoiseMs = 0, this.currentTZAUrl = null, this.unet = null, this._pendingStart = !1, this._pendingStartContinuous = !1, this._reloadPending = !1, this._initialize().catch((e) => {
17315
+ Qh.error("init failed:", e), this.dispatchEvent({
17216
17316
  type: "error",
17217
17317
  error: e
17218
17318
  });
@@ -17241,7 +17341,7 @@ var ag = class extends dt {
17241
17341
  });
17242
17342
  }
17243
17343
  expectsCleanAux(e = this.quality) {
17244
- let { QUALITY_MODELS: t } = $h;
17344
+ let { QUALITY_MODELS: t } = tg;
17245
17345
  return (t[e] || t.balance).cleanAux;
17246
17346
  }
17247
17347
  getRuntimeInfo() {
@@ -17258,136 +17358,147 @@ var ag = class extends dt {
17258
17358
  return e ? Math.min(e, this.maxTileSize) : this.maxTileSize;
17259
17359
  }
17260
17360
  async _setupUNetDenoiser() {
17261
- if (this.state.isLoading) return;
17262
- this.state.isLoading = !0;
17263
- let e = this._generateTzaUrl(), t = this._resolveTileSize();
17264
- if (this.currentTZAUrl === e && this._activeTileSize === t && this.unet) {
17265
- this.state.isLoading = !1;
17361
+ if (this.state.isLoading) {
17362
+ this._reloadPending = !0;
17266
17363
  return;
17267
17364
  }
17268
- try {
17269
- this.dispatchEvent({
17270
- type: "loading",
17271
- message: "Loading UNet denoiser..."
17272
- }), this.unet &&= (this.unet.dispose(), null);
17273
- let n;
17274
- if (this.isGPUMode && this.backendParamsGetter) {
17275
- let e = this.backendParamsGetter();
17276
- this.gpuDevice = e?.device ?? null, n = e?.device ? e : void 0;
17365
+ do {
17366
+ this._reloadPending = !1, this.state.isLoading = !0;
17367
+ try {
17368
+ await this._loadUNetWeights();
17369
+ } catch (e) {
17370
+ Qh.error("UNet weights failed to load:", e), this.dispatchEvent({
17371
+ type: "error",
17372
+ error: /* @__PURE__ */ Error(`Denoiser loading failed: ${e.message}`)
17373
+ });
17374
+ } finally {
17375
+ this.state.isLoading = !1;
17277
17376
  }
17278
- this.unet = await (await Zh())(e, n, {
17279
- aux: !0,
17280
- hdr: !0,
17281
- maxTileSize: t,
17282
- dynamicTile: !1
17283
- }), this.currentTZAUrl = e, this._activeTileSize = t, this.dispatchEvent({ type: "loaded" }), Yh.debug("UNet weights loaded:", e);
17284
- } catch (e) {
17285
- Yh.error("UNet weights failed to load:", e), this.dispatchEvent({
17286
- type: "error",
17287
- error: /* @__PURE__ */ Error(`Denoiser loading failed: ${e.message}`)
17288
- });
17289
- } finally {
17290
- this.state.isLoading = !1, this._pendingStart && this.unet && this.enabled && (this._pendingStart = !1, this.start());
17377
+ } while (this._reloadPending);
17378
+ if (this._pendingStart && this.unet && this.enabled) {
17379
+ let e = this._pendingStartContinuous;
17380
+ this._pendingStart = !1, this._pendingStartContinuous = !1, this.start({ continuous: e });
17291
17381
  }
17292
17382
  }
17383
+ async _loadUNetWeights() {
17384
+ let e = this._generateTzaUrl(), t = this._resolveTileSize();
17385
+ if (this.currentTZAUrl === e && this._activeTileSize === t && this.unet) return;
17386
+ this.dispatchEvent({
17387
+ type: "loading",
17388
+ message: "Loading UNet denoiser..."
17389
+ }), this.unet &&= (this.unet.dispose(), null);
17390
+ let n;
17391
+ if (this.isGPUMode && this.backendParamsGetter) {
17392
+ let e = this.backendParamsGetter();
17393
+ this.gpuDevice = e?.device ?? null, n = e?.device ? e : void 0;
17394
+ }
17395
+ this.unet = await (await eg())(e, n, {
17396
+ aux: !0,
17397
+ hdr: !0,
17398
+ maxTileSize: t,
17399
+ dynamicTile: !1
17400
+ }), this.currentTZAUrl = e, this._activeTileSize = t, this.dispatchEvent({ type: "loaded" }), Qh.debug("UNet weights loaded:", e);
17401
+ }
17293
17402
  _generateTzaUrl() {
17294
- let { oidnWeightsBaseUrl: e } = du(), { QUALITY_MODELS: t } = $h;
17403
+ let { oidnWeightsBaseUrl: e } = du(), { QUALITY_MODELS: t } = tg;
17295
17404
  return `${e}${(t[this.quality] || t.balance).model}.tza`;
17296
17405
  }
17297
17406
  async updateConfiguration(e) {
17298
- Object.keys(e).some((t) => this.config[t] !== e[t]) && (Object.assign(this.config, e), this.quality = this.config.oidnQuality, this.debugGbufferMaps = this.config.debugGbufferMaps, this.maxTileSize = this.config.tileSize, await this._setupUNetDenoiser());
17407
+ Object.keys(e).some((t) => this.config[t] !== e[t]) && (Object.assign(this.config, e), this.quality = this.config.oidnQuality, this.maxTileSize = this.config.tileSize, await this._setupUNetDenoiser());
17299
17408
  }
17300
17409
  async updateQuality(e) {
17301
- if (!Object.prototype.hasOwnProperty.call($h.QUALITY_MODELS, e)) throw Error(`Invalid quality setting: ${e}. Must be one of: ${Object.keys($h.QUALITY_MODELS).join(", ")}`);
17410
+ if (!Object.prototype.hasOwnProperty.call(tg.QUALITY_MODELS, e)) throw Error(`Invalid quality setting: ${e}. Must be one of: ${Object.keys(tg.QUALITY_MODELS).join(", ")}`);
17302
17411
  await this.updateConfiguration({ oidnQuality: e });
17303
17412
  }
17304
- async start() {
17413
+ async start({ continuous: e = !1 } = {}) {
17305
17414
  if (!this.enabled || this.state.isDenoising) return !1;
17306
- if (this.unet && !this.state.isLoading && this._activeTileSize !== this._resolveTileSize() && await this._setupUNetDenoiser(), this.state.isLoading) return this._pendingStart = !0, !1;
17307
- this.dispatchEvent({ type: "start" });
17308
- let e = performance.now(), t = await this.execute();
17309
- if (t) {
17310
- this.renderer?.resetState?.(), this.input.style.opacity = "0";
17311
- let t = performance.now() - e;
17312
- Yh.debug(`denoise complete in ${Di.ms(t)} · quality ${this.quality}`);
17313
- }
17314
- return t;
17415
+ if (this.unet && !this.state.isLoading && this._activeTileSize !== this._resolveTileSize() && await this._setupUNetDenoiser(), this.state.isLoading) return this._pendingStartContinuous = this._pendingStart ? this._pendingStartContinuous && e : e, this._pendingStart = !0, !1;
17416
+ this.dispatchEvent({
17417
+ type: "start",
17418
+ continuous: e
17419
+ });
17420
+ let t = performance.now(), n = await this.execute(e);
17421
+ return n && (this._hasLatchedFrame = !0, this.renderer?.resetState?.(), this.input.style.opacity = "0", this.lastDenoiseMs = performance.now() - t, Qh.debug(`denoise complete in ${Di.ms(this.lastDenoiseMs)} · quality ${this.quality}`)), n;
17315
17422
  }
17316
17423
  _revealOutput() {
17317
17424
  this.output.style.display = "block", this.input.style.opacity = "0";
17318
17425
  }
17319
- async execute() {
17426
+ async execute(e = !1) {
17320
17427
  if (!this.enabled || !this.unet) return !1;
17428
+ let t = ++this._runId;
17321
17429
  this.state.abortController = new AbortController(), this.state.isDenoising = !0;
17322
17430
  try {
17323
- return await this._executeUNet(), !0;
17431
+ return await this._executeUNet(e), !0;
17324
17432
  } catch (e) {
17325
- return e.name === "AbortError" ? Yh.debug("denoise aborted") : Yh.error("denoise error:", e), this.input.style.opacity = "1", !1;
17433
+ return e.name === "AbortError" ? Qh.debug("denoise aborted") : Qh.error("denoise error:", e), this._hasLatchedFrame || (this.input.style.opacity = "1"), !1;
17326
17434
  } finally {
17327
- this.state.isDenoising = !1, this.state.abortController = null, this.dispatchEvent({ type: "end" });
17435
+ this._runId === t && (this.state.isDenoising = !1, this.state.abortController = null), this.dispatchEvent({
17436
+ type: "end",
17437
+ continuous: e
17438
+ });
17328
17439
  }
17329
17440
  }
17330
- async _executeUNet() {
17331
- return this._executeUNetGPU();
17441
+ async _executeUNet(e = !1) {
17442
+ return this._executeUNetGPU(e);
17332
17443
  }
17333
- async _executeUNetGPU() {
17334
- let { width: e, height: t } = this.output;
17335
- if (!this.getGPUTextures) return Yh.warn("GPU mode enabled but getGPUTextures not provided"), !1;
17336
- let n = this.getGPUTextures();
17337
- if (!n?.color) return Yh.warn("GPU textures not ready yet"), !1;
17338
- let r = this.gpuDevice;
17339
- if (!r) return Yh.warn("gpuDevice not available"), !1;
17340
- this.refreshInput?.(), this.ctx.drawImage(this.input, 0, 0, e, t), this._revealOutput(), this._ensureGPUInputBuffers(e, t);
17341
- let i = r.createCommandEncoder({ label: "oidn-tex-to-buf" }), a = e * 16, o = this._gpuInputPaddedRowBytes, s = o > a, c = this._gpuInputPadBuffer, l = (n, r) => {
17342
- if (!s) i.copyTextureToBuffer({
17343
- texture: n,
17444
+ async _executeUNetGPU(e = !1) {
17445
+ let { width: t, height: n } = this.output;
17446
+ if (!this.getGPUTextures) return Qh.warn("GPU mode enabled but getGPUTextures not provided"), !1;
17447
+ let r = this.getGPUTextures();
17448
+ if (!r?.color) return Qh.warn("GPU textures not ready yet"), !1;
17449
+ let i = this.gpuDevice;
17450
+ if (!i) return Qh.warn("gpuDevice not available"), !1;
17451
+ this._hasLatchedFrame || (this.refreshInput?.(), this.ctx.drawImage(this.input, 0, 0, t, n)), this._revealOutput(), this._ensureGPUInputBuffers(t, n);
17452
+ let a = i.createCommandEncoder({ label: "oidn-tex-to-buf" }), o = t * 16, s = this._gpuInputPaddedRowBytes, c = s > o, l = this._gpuInputPadBuffer, u = (e, r) => {
17453
+ if (!c) a.copyTextureToBuffer({
17454
+ texture: e,
17344
17455
  mipLevel: 0
17345
17456
  }, {
17346
17457
  buffer: r,
17347
17458
  offset: 0,
17348
- bytesPerRow: a,
17349
- rowsPerImage: t
17459
+ bytesPerRow: o,
17460
+ rowsPerImage: n
17350
17461
  }, {
17351
- width: e,
17352
- height: t,
17462
+ width: t,
17463
+ height: n,
17353
17464
  depthOrArrayLayers: 1
17354
17465
  });
17355
17466
  else {
17356
- i.copyTextureToBuffer({
17357
- texture: n,
17467
+ a.copyTextureToBuffer({
17468
+ texture: e,
17358
17469
  mipLevel: 0
17359
17470
  }, {
17360
- buffer: c,
17471
+ buffer: l,
17361
17472
  offset: 0,
17362
- bytesPerRow: o,
17363
- rowsPerImage: t
17473
+ bytesPerRow: s,
17474
+ rowsPerImage: n
17364
17475
  }, {
17365
- width: e,
17366
- height: t,
17476
+ width: t,
17477
+ height: n,
17367
17478
  depthOrArrayLayers: 1
17368
17479
  });
17369
- for (let e = 0; e < t; e++) i.copyBufferToBuffer(c, e * o, r, e * a, a);
17480
+ for (let e = 0; e < n; e++) a.copyBufferToBuffer(l, e * s, r, e * o, o);
17370
17481
  }
17371
17482
  };
17372
- l(n.color, this._gpuInputBuffers.color), l(n.albedo, this._gpuInputBuffers.albedo), l(n.normal, this._gpuInputBuffers.normal), r.queue.submit([i.finish()]), await this._readbackColor(r, e, t), globalThis.__OIDN_NO_INPUT_SCALE && (this._oidnInputScale = 1), this._applyColorScale(r, e * t);
17373
- let u = {
17483
+ u(r.color, this._gpuInputBuffers.color), u(r.albedo, this._gpuInputBuffers.albedo), u(r.normal, this._gpuInputBuffers.normal), i.queue.submit([a.finish()]), this._computeInputScale(i, t * n), this._applyColorScale(i, t * n);
17484
+ let d = {
17374
17485
  color: {
17375
17486
  data: this._gpuInputBuffers.color,
17376
- width: e,
17377
- height: t
17487
+ width: t,
17488
+ height: n
17378
17489
  },
17379
17490
  albedo: {
17380
17491
  data: this._gpuInputBuffers.albedo,
17381
- width: e,
17382
- height: t
17492
+ width: t,
17493
+ height: n
17383
17494
  },
17384
17495
  normal: {
17385
17496
  data: this._gpuInputBuffers.normal,
17386
- width: e,
17387
- height: t
17497
+ width: t,
17498
+ height: n
17388
17499
  }
17389
17500
  };
17390
- return this._executeWithAbortGPU(u);
17501
+ return this._executeWithAbortGPU(d, e);
17391
17502
  }
17392
17503
  _ensureGPUInputBuffers(e, t) {
17393
17504
  let { width: n, height: r } = this._gpuInputBufferSize;
@@ -17418,68 +17529,117 @@ var ag = class extends dt {
17418
17529
  }), this._gpuInputPaddedRowBytes = c);
17419
17530
  }
17420
17531
  _destroyGPUInputBuffers() {
17421
- if (this._gpuInputBuffers.color?.destroy(), this._gpuInputBuffers.albedo?.destroy(), this._gpuInputBuffers.normal?.destroy(), this._gpuInputPadBuffer?.destroy(), this._alphaReadbackMapped && this._alphaReadbackBuffer) try {
17422
- this._alphaReadbackBuffer.unmap();
17423
- } catch {}
17424
- this._alphaReadbackBuffer?.destroy(), this._alphaReadbackMapped = !1, this._colorScaleBindGroup = null, this._colorScaleUniform?.destroy(), this._colorScaleUniform = null, this._gpuInputBuffers = {
17532
+ this._gpuInputBuffers.color?.destroy(), this._gpuInputBuffers.albedo?.destroy(), this._gpuInputBuffers.normal?.destroy(), this._gpuInputPadBuffer?.destroy(), this._colorScaleBindGroup = null, this._lumBindGroup = null, this._lumPartials?.destroy(), this._lumPartials = null, this._lumParams?.destroy(), this._lumParams = null, this._inputScaleBuffer?.destroy(), this._inputScaleBuffer = null, this._gpuInputBuffers = {
17425
17533
  color: null,
17426
17534
  albedo: null,
17427
17535
  normal: null
17428
- }, this._gpuInputPadBuffer = null, this._gpuInputPaddedRowBytes = 0, this._alphaReadbackBuffer = null, this._gpuInputBufferSize = {
17536
+ }, this._gpuInputPadBuffer = null, this._gpuInputPaddedRowBytes = 0, this._gpuInputBufferSize = {
17429
17537
  width: 0,
17430
17538
  height: 0
17431
17539
  };
17432
17540
  }
17433
- async _readbackColor(e, t, n) {
17434
- let r = t * n * 16;
17435
- this._alphaReadbackBuffer === null && (this._alphaReadbackBuffer = e.createBuffer({
17436
- label: "oidn-alpha-readback",
17437
- size: r,
17438
- usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST
17439
- }));
17440
- let i = this._alphaReadbackBuffer, a = e.createCommandEncoder();
17441
- a.copyBufferToBuffer(this._gpuInputBuffers.color, 0, i, 0, r), e.queue.submit([a.finish()]), this._alphaReadbackMapped = !0;
17442
- try {
17443
- await i.mapAsync(GPUMapMode.READ);
17444
- } catch {
17445
- this._alphaReadbackMapped = !1;
17446
- return;
17447
- }
17448
- let o = new Float32Array(i.getMappedRange()), s = t * n;
17449
- this._oidnInputScale = ig(o, s);
17450
- let c = null;
17451
- if (this.getTransparentBackground()) {
17452
- c = new Uint8Array(s);
17453
- for (let e = 0; e < s; e++) c[e] = Math.min(Math.max(o[e * 4 + 3] * 255, 0), 255) | 0;
17454
- }
17455
- i.unmap(), this._alphaReadbackMapped = !1, this._cachedAlpha = c, this._cachedAlphaWidth = t;
17456
- }
17457
- _outputExposure() {
17458
- return Dl(this.getExposure(), this.getToneMapping()) / this._oidnInputScale;
17459
- }
17460
- _applyColorScale(e, t) {
17461
- let n = this._oidnInputScale;
17462
- if (!this._ensureColorScalePipeline(e)) return;
17463
- e.queue.writeBuffer(this._colorScaleUniform, 0, new Float32Array([n]));
17464
- let r = Math.ceil(t / tg), i = Math.min(r, ng), a = Math.ceil(r / i), o = e.createCommandEncoder({ label: "oidn-color-scale" }), s = o.beginComputePass({ label: "oidn-color-scale" });
17465
- s.setPipeline(this._colorScalePipeline), s.setBindGroup(0, this._colorScaleBindGroup), s.dispatchWorkgroups(i, a, 1), s.end(), e.queue.submit([o.finish()]);
17466
- }
17467
- _ensureColorScalePipeline(e) {
17541
+ _ensureScalePipelines(e) {
17468
17542
  let t = this._gpuInputBuffers.color;
17469
- return !e || !t ? null : (this._colorScalePipeline ||= e.createComputePipeline({
17543
+ if (!e || !t) return !1;
17544
+ if (!this._lumLayout) {
17545
+ this._lumLayout = e.createBindGroupLayout({
17546
+ label: "oidn-autoexposure",
17547
+ entries: [
17548
+ {
17549
+ binding: 0,
17550
+ visibility: GPUShaderStage.COMPUTE,
17551
+ buffer: { type: "read-only-storage" }
17552
+ },
17553
+ {
17554
+ binding: 1,
17555
+ visibility: GPUShaderStage.COMPUTE,
17556
+ buffer: { type: "storage" }
17557
+ },
17558
+ {
17559
+ binding: 2,
17560
+ visibility: GPUShaderStage.COMPUTE,
17561
+ buffer: { type: "uniform" }
17562
+ },
17563
+ {
17564
+ binding: 3,
17565
+ visibility: GPUShaderStage.COMPUTE,
17566
+ buffer: { type: "storage" }
17567
+ }
17568
+ ]
17569
+ });
17570
+ let t = e.createShaderModule({
17571
+ label: "oidn-autoexposure",
17572
+ code: ag
17573
+ }), n = e.createPipelineLayout({ bindGroupLayouts: [this._lumLayout] });
17574
+ this._lumReducePipeline = e.createComputePipeline({
17575
+ label: "oidn-autoexposure-reduce",
17576
+ layout: n,
17577
+ compute: {
17578
+ module: t,
17579
+ entryPoint: "reduce"
17580
+ }
17581
+ }), this._lumFinalizePipeline = e.createComputePipeline({
17582
+ label: "oidn-autoexposure-finalize",
17583
+ layout: n,
17584
+ compute: {
17585
+ module: t,
17586
+ entryPoint: "finalize"
17587
+ }
17588
+ });
17589
+ }
17590
+ return this._colorScalePipeline ||= e.createComputePipeline({
17470
17591
  label: "oidn-color-scale",
17471
17592
  layout: "auto",
17472
17593
  compute: {
17473
17594
  module: e.createShaderModule({
17474
17595
  label: "oidn-color-scale",
17475
- code: eg
17596
+ code: og
17597
+ }),
17598
+ entryPoint: "main"
17599
+ }
17600
+ }), this._packPipeline ||= e.createComputePipeline({
17601
+ label: "oidn-output-pack",
17602
+ layout: "auto",
17603
+ compute: {
17604
+ module: e.createShaderModule({
17605
+ label: "oidn-output-pack",
17606
+ code: dg
17476
17607
  }),
17477
17608
  entryPoint: "main"
17478
17609
  }
17479
- }), this._colorScaleUniform ||= e.createBuffer({
17480
- label: "oidn-color-scale-uniform",
17610
+ }), this._inputScaleBuffer || (this._inputScaleBuffer = e.createBuffer({
17611
+ label: "oidn-input-scale",
17612
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
17613
+ size: 4
17614
+ }), this._lumPartials = e.createBuffer({
17615
+ label: "oidn-autoexposure-partials",
17616
+ size: ig * 4,
17617
+ usage: GPUBufferUsage.STORAGE
17618
+ }), this._lumParams = e.createBuffer({
17619
+ label: "oidn-autoexposure-params",
17481
17620
  size: 16,
17482
17621
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
17622
+ })), this._lumBindGroup ||= e.createBindGroup({
17623
+ label: "oidn-autoexposure",
17624
+ layout: this._lumLayout,
17625
+ entries: [
17626
+ {
17627
+ binding: 0,
17628
+ resource: { buffer: t }
17629
+ },
17630
+ {
17631
+ binding: 1,
17632
+ resource: { buffer: this._lumPartials }
17633
+ },
17634
+ {
17635
+ binding: 2,
17636
+ resource: { buffer: this._lumParams }
17637
+ },
17638
+ {
17639
+ binding: 3,
17640
+ resource: { buffer: this._inputScaleBuffer }
17641
+ }
17642
+ ]
17483
17643
  }), this._colorScaleBindGroup ||= e.createBindGroup({
17484
17644
  label: "oidn-color-scale",
17485
17645
  layout: this._colorScalePipeline.getBindGroupLayout(0),
@@ -17488,105 +17648,167 @@ var ag = class extends dt {
17488
17648
  resource: { buffer: t }
17489
17649
  }, {
17490
17650
  binding: 1,
17491
- resource: { buffer: this._colorScaleUniform }
17651
+ resource: { buffer: this._inputScaleBuffer }
17492
17652
  }]
17493
- }), this._colorScalePipeline);
17653
+ }), !0;
17494
17654
  }
17495
- _executeWithAbortGPU(e) {
17496
- return new Promise((t, n) => {
17655
+ _computeInputScale(e, t) {
17656
+ if (!this._ensureScalePipelines(e)) return;
17657
+ if (globalThis.__OIDN_NO_INPUT_SCALE) {
17658
+ e.queue.writeBuffer(this._inputScaleBuffer, 0, new Float32Array([1]));
17659
+ return;
17660
+ }
17661
+ e.queue.writeBuffer(this._lumParams, 0, new Uint32Array([
17662
+ t,
17663
+ 0,
17664
+ 0,
17665
+ 0
17666
+ ]));
17667
+ let n = e.createCommandEncoder({ label: "oidn-autoexposure" }), r = n.beginComputePass({ label: "oidn-autoexposure-reduce" });
17668
+ r.setPipeline(this._lumReducePipeline), r.setBindGroup(0, this._lumBindGroup), r.dispatchWorkgroups(ig, 1, 1), r.end();
17669
+ let i = n.beginComputePass({ label: "oidn-autoexposure-finalize" });
17670
+ i.setPipeline(this._lumFinalizePipeline), i.setBindGroup(0, this._lumBindGroup), i.dispatchWorkgroups(1, 1, 1), i.end(), e.queue.submit([n.finish()]);
17671
+ }
17672
+ _applyColorScale(e, t) {
17673
+ if (!this._ensureScalePipelines(e)) return;
17674
+ let n = Math.ceil(t / sg), r = Math.min(n, cg), i = Math.ceil(n / r), a = e.createCommandEncoder({ label: "oidn-color-scale" }), o = a.beginComputePass({ label: "oidn-color-scale" });
17675
+ o.setPipeline(this._colorScalePipeline), o.setBindGroup(0, this._colorScaleBindGroup), o.dispatchWorkgroups(r, i, 1), o.end(), e.queue.submit([a.finish()]);
17676
+ }
17677
+ async _packAndBlit(e, t, n) {
17678
+ let r = this.gpuDevice;
17679
+ if (!r || !this._ensureScalePipelines(r)) return;
17680
+ let { x: i, y: a, width: o, height: s } = n, c = o * s * 4, l = r.createBuffer({
17681
+ label: "oidn-pack-out",
17682
+ size: c,
17683
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
17684
+ }), u = r.createBuffer({
17685
+ label: "oidn-pack-staging",
17686
+ size: c,
17687
+ usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST
17688
+ }), d = r.createBuffer({
17689
+ label: "oidn-pack-params",
17690
+ size: ug,
17691
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
17692
+ });
17693
+ this._pendingStagingBuffers.add(l), this._pendingStagingBuffers.add(u), this._pendingStagingBuffers.add(d);
17694
+ let f = () => {
17695
+ for (let e of [
17696
+ l,
17697
+ u,
17698
+ d
17699
+ ]) e.destroy(), this._pendingStagingBuffers.delete(e);
17700
+ };
17701
+ try {
17702
+ let n = new ArrayBuffer(ug);
17703
+ new Uint32Array(n, 0, 8).set([
17704
+ t,
17705
+ i,
17706
+ a,
17707
+ o,
17708
+ s,
17709
+ Xh(this.getToneMapping()),
17710
+ +!!this.getTransparentBackground(),
17711
+ 0
17712
+ ]), new Float32Array(n, 32, 2).set([Dl(this.getExposure(), this.getToneMapping()), this.getSaturation()]), r.queue.writeBuffer(d, 0, n);
17713
+ let f = r.createBindGroup({
17714
+ label: "oidn-output-pack",
17715
+ layout: this._packPipeline.getBindGroupLayout(0),
17716
+ entries: [
17717
+ {
17718
+ binding: 0,
17719
+ resource: { buffer: e }
17720
+ },
17721
+ {
17722
+ binding: 1,
17723
+ resource: { buffer: l }
17724
+ },
17725
+ {
17726
+ binding: 2,
17727
+ resource: { buffer: d }
17728
+ },
17729
+ {
17730
+ binding: 3,
17731
+ resource: { buffer: this._inputScaleBuffer }
17732
+ },
17733
+ {
17734
+ binding: 4,
17735
+ resource: { buffer: this._gpuInputBuffers.color }
17736
+ }
17737
+ ]
17738
+ }), p = r.createCommandEncoder({ label: "oidn-output-pack" }), m = p.beginComputePass({ label: "oidn-output-pack" });
17739
+ m.setPipeline(this._packPipeline), m.setBindGroup(0, f), m.dispatchWorkgroups(Math.ceil(o / lg), Math.ceil(s / lg), 1), m.end(), p.copyBufferToBuffer(l, 0, u, 0, c), r.queue.submit([p.finish()]), await u.mapAsync(GPUMapMode.READ);
17740
+ let h = new Uint8ClampedArray(u.getMappedRange().slice(0));
17741
+ u.unmap(), this.ctx.putImageData(new ImageData(h, o, s), i, a);
17742
+ } finally {
17743
+ f();
17744
+ }
17745
+ }
17746
+ _executeWithAbortGPU(e, t = !1) {
17747
+ return new Promise((n, r) => {
17497
17748
  if (this.state.abortController?.signal.aborted) {
17498
- n(new DOMException("Aborted", "AbortError"));
17749
+ r(new DOMException("Aborted", "AbortError"));
17499
17750
  return;
17500
17751
  }
17501
- let r = null;
17752
+ let i = null;
17502
17753
  this._pendingTileBlits = [];
17503
- let i = () => {
17504
- r &&= (r(), null), n(new DOMException("Aborted", "AbortError"));
17754
+ let a = () => {
17755
+ i &&= (i(), null), r(new DOMException("Aborted", "AbortError"));
17505
17756
  };
17506
- this.state.abortController.signal.addEventListener("abort", i, { once: !0 }), r = this.unet.tileExecute({
17757
+ this.state.abortController.signal.addEventListener("abort", a, { once: !0 }), i = this.unet.tileExecute({
17507
17758
  ...e,
17508
17759
  done: async (e) => {
17509
- this.state.abortController.signal.removeEventListener("abort", i), r = null;
17760
+ this.state.abortController.signal.removeEventListener("abort", a), i = null;
17510
17761
  try {
17511
- this._pendingTileBlits.length > 0 ? await Promise.allSettled(this._pendingTileBlits) : await this._displayGPUOutput(e), t();
17762
+ this._pendingTileBlits.length > 0 ? await Promise.allSettled(this._pendingTileBlits) : await this._displayGPUOutput(e), n();
17512
17763
  } catch (e) {
17513
- n(e);
17764
+ r(e);
17514
17765
  }
17515
17766
  },
17516
- progress: (e, t, n) => {
17517
- if (!e?.data || !n) return;
17518
- let r = this.gpuDevice, i = e.width, a = e.height, o = Math.min(n.width, i - n.x), s = Math.min(n.height, a - n.y);
17767
+ progress: (e, n, r) => {
17768
+ if (!e?.data || !r) return;
17769
+ let i = e.width, a = e.height, o = Math.min(r.width, i - r.x), s = Math.min(r.height, a - r.y);
17519
17770
  if (o <= 0 || s <= 0) return;
17520
- let c = o * 16, l = o * s * 16, u = r.createBuffer({
17521
- size: l,
17522
- usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST
17523
- });
17524
- this._pendingStagingBuffers.add(u);
17525
- let d = r.createCommandEncoder();
17526
- for (let t = 0; t < s; t++) {
17527
- let r = ((n.y + t) * i + n.x) * 16, a = t * c;
17528
- d.copyBufferToBuffer(e.data, r, u, a, c);
17529
- }
17530
- r.queue.submit([d.finish()]);
17531
- let f = u.mapAsync(GPUMapMode.READ).then(() => {
17532
- let e = new Float32Array(u.getMappedRange()), t = new ImageData(o, s), r = this._outputExposure(), c = this.getSaturation(), l = wl.get(this.getToneMapping()) || wl.get(We), d = this._cachedAlpha, f = this._cachedAlphaWidth;
17533
- for (let i = 0, a = e.length; i < a; i += 4) {
17534
- let a = e[i] * r, s = e[i + 1] * r, u = e[i + 2] * r;
17535
- if (c !== 1 && (Qh[0] = a, Qh[1] = s, Qh[2] = u, jl(Qh, c), a = Qh[0], s = Qh[1], u = Qh[2]), l(a, s, u, 1, Qh), t.data[i] = El(Qh[0]) * 255 + .5 | 0, t.data[i + 1] = El(Qh[1]) * 255 + .5 | 0, t.data[i + 2] = El(Qh[2]) * 255 + .5 | 0, d) {
17536
- let e = (i >> 2) % o, r = (i >> 2) / o | 0;
17537
- t.data[i + 3] = d[(n.y + r) * f + n.x + e];
17538
- } else t.data[i + 3] = 255;
17539
- }
17540
- u.unmap(), u.destroy(), this._pendingStagingBuffers.delete(u), this.ctx.putImageData(t, n.x, n.y), this.dispatchEvent({
17771
+ let c = {
17772
+ x: r.x,
17773
+ y: r.y,
17774
+ width: o,
17775
+ height: s
17776
+ }, l = this._packAndBlit(e.data, i, c).then(() => {
17777
+ this.dispatchEvent({
17541
17778
  type: "tileProgress",
17542
- tile: {
17543
- x: n.x,
17544
- y: n.y,
17545
- width: o,
17546
- height: s
17547
- },
17779
+ tile: c,
17548
17780
  imageWidth: i,
17549
- imageHeight: a
17781
+ imageHeight: a,
17782
+ continuous: t
17550
17783
  });
17551
- }).catch(() => {
17552
- u.destroy(), this._pendingStagingBuffers.delete(u);
17553
- });
17554
- this._pendingTileBlits.push(f);
17784
+ }).catch(() => {});
17785
+ this._pendingTileBlits.push(l);
17555
17786
  }
17556
17787
  });
17557
17788
  });
17558
17789
  }
17559
17790
  async _displayGPUOutput({ data: e, width: t, height: n }) {
17560
- let r = this.gpuDevice;
17561
- if (!r) {
17562
- Yh.error("gpuDevice not available for output readback");
17791
+ if (!this.gpuDevice) {
17792
+ Qh.error("gpuDevice not available for output readback");
17563
17793
  return;
17564
17794
  }
17565
- let i = t * n * 4 * 4, a = r.createBuffer({
17566
- label: "oidn-output-staging",
17567
- size: i,
17568
- usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST
17795
+ await this._packAndBlit(e, t, {
17796
+ x: 0,
17797
+ y: 0,
17798
+ width: t,
17799
+ height: n
17569
17800
  });
17570
- try {
17571
- let o = r.createCommandEncoder({ label: "oidn-readback" });
17572
- o.copyBufferToBuffer(e, 0, a, 0, i), r.queue.submit([o.finish()]), await a.mapAsync(GPUMapMode.READ);
17573
- let s = new Float32Array(a.getMappedRange()), c = new ImageData(t, n), l = this._outputExposure(), u = this.getSaturation(), d = wl.get(this.getToneMapping()) || wl.get(We), f = this._cachedAlpha;
17574
- for (let e = 0, t = s.length; e < t; e += 4) {
17575
- let t = s[e] * l, n = s[e + 1] * l, r = s[e + 2] * l;
17576
- u !== 1 && (Qh[0] = t, Qh[1] = n, Qh[2] = r, jl(Qh, u), t = Qh[0], n = Qh[1], r = Qh[2]), d(t, n, r, 1, Qh), c.data[e] = El(Qh[0]) * 255 + .5 | 0, c.data[e + 1] = El(Qh[1]) * 255 + .5 | 0, c.data[e + 2] = El(Qh[2]) * 255 + .5 | 0, c.data[e + 3] = f ? f[e >> 2] : 255;
17577
- }
17578
- a.unmap(), this.ctx.putImageData(c, 0, 0);
17579
- } finally {
17580
- a.destroy();
17581
- }
17582
17801
  }
17583
17802
  abort() {
17584
- this._pendingStart = !1, !(!this.enabled || !this.state.isDenoising) && (this.state.abortController?.abort(), this._destroyPendingStagingBuffers(), this.input.style.opacity = "1", this.state.isDenoising = !1, this.dispatchEvent({ type: "end" }), Yh.debug("denoise aborted"));
17803
+ this._pendingStart = !1, this._pendingStartContinuous = !1, !(!this.enabled || !this.state.isDenoising) && (this.state.abortController?.abort(), this._destroyPendingStagingBuffers(), this.input.style.opacity = "1", this.state.isDenoising = !1, Qh.debug("denoise aborted"));
17804
+ }
17805
+ invalidateLatch() {
17806
+ this._hasLatchedFrame = !1;
17585
17807
  }
17586
17808
  setSize(e, t) {
17587
17809
  if (e <= 0 || t <= 0) throw Error(`Invalid dimensions: ${e}x${t}`);
17588
- this.output.width = e, this.output.height = t, this._setupUNetDenoiser().catch((e) => {
17589
- Yh.error("reinitialize after size change failed:", e);
17810
+ this.output.width = e, this.output.height = t, this._hasLatchedFrame = !1, this._setupUNetDenoiser().catch((e) => {
17811
+ Qh.error("reinitialize after size change failed:", e);
17590
17812
  });
17591
17813
  }
17592
17814
  _destroyPendingStagingBuffers() {
@@ -17594,13 +17816,13 @@ var ag = class extends dt {
17594
17816
  this._pendingStagingBuffers.clear();
17595
17817
  }
17596
17818
  dispose() {
17597
- this.abort(), this._destroyPendingStagingBuffers(), this.unet?.dispose(), this._destroyGPUInputBuffers(), this._colorScalePipeline = null, this.output?.parentNode && this.output.remove(), this.unet = null, this.ctx = null, this.state.abortController = null, this.removeAllListeners?.(), Yh.debug("disposed");
17819
+ this.abort(), this._destroyPendingStagingBuffers(), this.unet?.dispose(), this._destroyGPUInputBuffers(), this._colorScalePipeline = null, this._lumReducePipeline = null, this._lumFinalizePipeline = null, this._lumLayout = null, this._packPipeline = null, this.output?.parentNode && this.output.remove(), this.unet = null, this.ctx = null, this.state.abortController = null, this.removeAllListeners?.(), Qh.debug("disposed");
17598
17820
  }
17599
- }, og = "let e={ortRuntimeUrl:`https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/ort.webgpu.bundle.min.mjs`,ortWasmPaths:`https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/`,cacheNamespace:`rayzee`},t=null;async function n(){return t||(t=await import(e.ortRuntimeUrl),t.env.wasm.wasmPaths=e.ortWasmPaths,t.env.logLevel=`error`,t)}function r(){return`${e.cacheNamespace}:ai-upscaler-models`}const i=`models`;let a=null,o=null;function s(){return new Promise((e,t)=>{let n=indexedDB.open(r(),1);n.onupgradeneeded=()=>n.result.createObjectStore(i),n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}async function c(e){try{let t=await s();return await new Promise((n,r)=>{let a=t.transaction(i,`readonly`).objectStore(i).get(e);a.onsuccess=()=>n(a.result||null),a.onerror=()=>r(a.error)})}catch{return null}}async function l(e,t){try{let n=await s();await new Promise((r,a)=>{let o=n.transaction(i,`readwrite`);o.objectStore(i).put(t,e),o.oncomplete=()=>r(),o.onerror=()=>a(o.error)})}catch{}}async function u(e){let t=await c(e);if(t)return console.log(`AI Upscaler Worker: model loaded from cache (${(t.byteLength/1024/1024).toFixed(1)}MB)`),t;let n=await fetch(e);if(!n.ok)throw Error(`Failed to fetch model: ${n.status}`);let r=await n.arrayBuffer();return l(e,r.slice(0)),r}async function d(e,t){if(a&&o===e){self.postMessage({type:`loaded`,backend:`webgpu`});return}a&&=(await a.release(),null);let[r,i]=await Promise.all([u(e),n()]);a=await i.InferenceSession.create(r,t),o=e;let s=512;try{let e=await navigator.gpu?.requestAdapter(),t=await e?.requestAdapterInfo?.()||e?.info,n=/apple|swiftshader|llvmpipe/i.test(t?.vendor||``)||/apple|swiftshader/i.test(t?.architecture||``),r=t?.device?.toLowerCase?.()?.includes(`integrated`)||/intel.*iris|intel.*uhd|intel.*hd|amd.*vega|radeon.*graphics/i.test(t?.description||``);s=n?128:r?256:512,console.log(`AI Upscaler Worker: GPU=\"${t?.description||t?.device||`unknown`}\", tileSize=${s}`)}catch{}let c=(r.byteLength/1024/1024).toFixed(1);console.log(`AI Upscaler Worker: model loaded (${c}MB), backend: webgpu`),self.postMessage({type:`loaded`,backend:`webgpu`,tileSize:s})}async function f(e,t,r,i){let o=await n(),s=a.inputNames[0],c=a.outputNames[0],l=new o.Tensor(`float32`,e,[1,3,r,t]),u=(await a.run({[s]:l}))[c].data;self.postMessage({type:`inferred`,outputData:u,id:i},[u.buffer])}self.onmessage=async t=>{let{type:n}=t.data;try{n===`load`?(t.data.ortRuntimeUrl&&(e.ortRuntimeUrl=t.data.ortRuntimeUrl),t.data.ortWasmPaths&&(e.ortWasmPaths=t.data.ortWasmPaths),t.data.cacheNamespace&&(e.cacheNamespace=t.data.cacheNamespace),await d(t.data.url,t.data.sessionOptions)):n===`infer`?await f(t.data.tileData,t.data.width,t.data.height,t.data.id):n===`dispose`&&a&&(await a.release(),a=null,o=null)}catch(e){self.postMessage({type:`error`,message:e.message,id:t.data?.id})}};", sg = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", og], { type: "text/javascript;charset=utf-8" });
17600
- function cg(e) {
17821
+ }, pg = "let e={ortRuntimeUrl:`https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/ort.webgpu.bundle.min.mjs`,ortWasmPaths:`https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/`,cacheNamespace:`rayzee`},t=null;async function n(){return t||(t=await import(e.ortRuntimeUrl),t.env.wasm.wasmPaths=e.ortWasmPaths,t.env.logLevel=`error`,t)}function r(){return`${e.cacheNamespace}:ai-upscaler-models`}const i=`models`;let a=null,o=null;function s(){return new Promise((e,t)=>{let n=indexedDB.open(r(),1);n.onupgradeneeded=()=>n.result.createObjectStore(i),n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}async function c(e){try{let t=await s();return await new Promise((n,r)=>{let a=t.transaction(i,`readonly`).objectStore(i).get(e);a.onsuccess=()=>n(a.result||null),a.onerror=()=>r(a.error)})}catch{return null}}async function l(e,t){try{let n=await s();await new Promise((r,a)=>{let o=n.transaction(i,`readwrite`);o.objectStore(i).put(t,e),o.oncomplete=()=>r(),o.onerror=()=>a(o.error)})}catch{}}async function u(e){let t=await c(e);if(t)return console.log(`AI Upscaler Worker: model loaded from cache (${(t.byteLength/1024/1024).toFixed(1)}MB)`),t;let n=await fetch(e);if(!n.ok)throw Error(`Failed to fetch model: ${n.status}`);let r=await n.arrayBuffer();return l(e,r.slice(0)),r}async function d(e,t){if(a&&o===e){self.postMessage({type:`loaded`,backend:`webgpu`});return}a&&=(await a.release(),null);let[r,i]=await Promise.all([u(e),n()]);a=await i.InferenceSession.create(r,t),o=e;let s=512;try{let e=await navigator.gpu?.requestAdapter(),t=await e?.requestAdapterInfo?.()||e?.info,n=/apple|swiftshader|llvmpipe/i.test(t?.vendor||``)||/apple|swiftshader/i.test(t?.architecture||``),r=t?.device?.toLowerCase?.()?.includes(`integrated`)||/intel.*iris|intel.*uhd|intel.*hd|amd.*vega|radeon.*graphics/i.test(t?.description||``);s=n?128:r?256:512,console.log(`AI Upscaler Worker: GPU=\"${t?.description||t?.device||`unknown`}\", tileSize=${s}`)}catch{}let c=(r.byteLength/1024/1024).toFixed(1);console.log(`AI Upscaler Worker: model loaded (${c}MB), backend: webgpu`),self.postMessage({type:`loaded`,backend:`webgpu`,tileSize:s})}async function f(e,t,r,i){let o=await n(),s=a.inputNames[0],c=a.outputNames[0],l=new o.Tensor(`float32`,e,[1,3,r,t]),u=(await a.run({[s]:l}))[c].data;self.postMessage({type:`inferred`,outputData:u,id:i},[u.buffer])}self.onmessage=async t=>{let{type:n}=t.data;try{n===`load`?(t.data.ortRuntimeUrl&&(e.ortRuntimeUrl=t.data.ortRuntimeUrl),t.data.ortWasmPaths&&(e.ortWasmPaths=t.data.ortWasmPaths),t.data.cacheNamespace&&(e.cacheNamespace=t.data.cacheNamespace),await d(t.data.url,t.data.sessionOptions)):n===`infer`?await f(t.data.tileData,t.data.width,t.data.height,t.data.id):n===`dispose`&&a&&(await a.release(),a=null,o=null)}catch(e){self.postMessage({type:`error`,message:e.message,id:t.data?.id})}};", mg = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", pg], { type: "text/javascript;charset=utf-8" });
17822
+ function hg(e) {
17601
17823
  let t;
17602
17824
  try {
17603
- if (t = sg && (self.URL || self.webkitURL).createObjectURL(sg), !t) throw "";
17825
+ if (t = mg && (self.URL || self.webkitURL).createObjectURL(mg), !t) throw "";
17604
17826
  let n = new Worker(t, {
17605
17827
  type: "module",
17606
17828
  name: e?.name
@@ -17609,7 +17831,7 @@ function cg(e) {
17609
17831
  (self.URL || self.webkitURL).revokeObjectURL(t);
17610
17832
  }), n;
17611
17833
  } catch {
17612
- return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(og), {
17834
+ return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(pg), {
17613
17835
  type: "module",
17614
17836
  name: e?.name
17615
17837
  });
@@ -17617,7 +17839,7 @@ function cg(e) {
17617
17839
  }
17618
17840
  //#endregion
17619
17841
  //#region src/Passes/AIUpscaler.js
17620
- var lg = {
17842
+ var gg = {
17621
17843
  fast: {
17622
17844
  2: "2x-spanx2-ch48.onnx",
17623
17845
  4: "4xNomos8k_span_otf_strong_fp32_opset17.onnx"
@@ -17631,17 +17853,17 @@ var lg = {
17631
17853
  4: "4xNomos2_hq_mosr_fp32.onnx"
17632
17854
  }
17633
17855
  };
17634
- function ug() {
17856
+ function _g() {
17635
17857
  let { upscalerModelBaseUrl: e } = du(), t = {};
17636
- for (let n in lg) {
17858
+ for (let n in gg) {
17637
17859
  t[n] = {};
17638
- for (let r in lg[n]) t[n][r] = e + lg[n][r];
17860
+ for (let r in gg[n]) t[n][r] = e + gg[n][r];
17639
17861
  }
17640
17862
  return t;
17641
17863
  }
17642
- var dg = {
17864
+ var vg = {
17643
17865
  get QUALITY_PRESETS() {
17644
- return ug();
17866
+ return _g();
17645
17867
  },
17646
17868
  TILE_SIZE: 512,
17647
17869
  TILE_OVERLAP: 16,
@@ -17652,17 +17874,17 @@ var dg = {
17652
17874
  }],
17653
17875
  graphOptimizationLevel: "all"
17654
17876
  }
17655
- }, fg = class extends dt {
17877
+ }, yg = class extends dt {
17656
17878
  constructor(e, t, n = {}) {
17657
17879
  if (super(), !e || !t) throw Error("AIUpscaler requires output canvas and renderer");
17658
- this.renderer = t, this.input = t.domElement, this.output = e, this.getSourceCanvas = n.getSourceCanvas || null, this.getGPUTextures = n.getGPUTextures || null, this.getExposure = n.getExposure || (() => 1), this.getToneMapping = n.getToneMapping || (() => We), this.getSaturation = n.getSaturation || (() => 1), this.enabled = !1, this.hdr = !1, this.scaleFactor = n.scaleFactor || 2, this.quality = n.quality || "fast", this.refreshInput = n.refreshInput || null, this.tileSize = n.tileSize || dg.TILE_SIZE, this._tileSizeOverride = !!n.tileSize, this.state = {
17880
+ this.renderer = t, this.input = t.domElement, this.output = e, this.getSourceCanvas = n.getSourceCanvas || null, this.getGPUTextures = n.getGPUTextures || null, this.getExposure = n.getExposure || (() => 1), this.getToneMapping = n.getToneMapping || (() => We), this.getSaturation = n.getSaturation || (() => 1), this.enabled = !1, this.hdr = !1, this.scaleFactor = n.scaleFactor || 2, this.quality = n.quality || "fast", this.refreshInput = n.refreshInput || null, this.tileSize = n.tileSize || vg.TILE_SIZE, this._tileSizeOverride = !!n.tileSize, this.state = {
17659
17881
  isUpscaling: !1,
17660
17882
  isLoading: !1,
17661
17883
  abortController: null
17662
17884
  }, this._worker = null, this._currentModelUrl = null, this._tileId = 0, this._pendingWorkerHandlers = /* @__PURE__ */ new Set(), this._upscaledAlpha = null, this._upscaledAlphaWidth = 0, this._backupCanvas = null, this._baseWidth = e.width, this._baseHeight = e.height, this._hdrStagingBuffer = null, this._hdrStagingWidth = 0, this._hdrStagingHeight = 0;
17663
17885
  }
17664
17886
  async _ensureSession() {
17665
- let e = dg.QUALITY_PRESETS[this.quality];
17887
+ let e = vg.QUALITY_PRESETS[this.quality];
17666
17888
  if (!e) throw Error(`Unknown quality preset: ${this.quality}`);
17667
17889
  let t = e[this.scaleFactor];
17668
17890
  if (!t) throw Error(`No model for ${this.quality}/${this.scaleFactor}x`);
@@ -17672,14 +17894,14 @@ var dg = {
17672
17894
  message: `Loading ${this.scaleFactor}x upscale model...`
17673
17895
  });
17674
17896
  try {
17675
- this._worker ||= new cg(), await new Promise((e, n) => {
17897
+ this._worker ||= new hg(), await new Promise((e, n) => {
17676
17898
  let r = (t) => {
17677
17899
  t.data.type === "loaded" ? (this._worker.removeEventListener("message", r), t.data.tileSize && !this._tileSizeOverride && (this.tileSize = t.data.tileSize), console.log(`AI Upscaler: ${this.scaleFactor}x model loaded, backend: ${t.data.backend}, tileSize: ${this.tileSize}`), e()) : t.data.type === "error" && (this._worker.removeEventListener("message", r), n(Error(t.data.message)));
17678
17900
  }, { ortRuntimeUrl: i, ortWasmPaths: a, cacheNamespace: o } = du();
17679
17901
  this._worker.addEventListener("message", r), this._worker.postMessage({
17680
17902
  type: "load",
17681
17903
  url: t,
17682
- sessionOptions: dg.SESSION_OPTIONS,
17904
+ sessionOptions: vg.SESSION_OPTIONS,
17683
17905
  ortRuntimeUrl: i,
17684
17906
  ortWasmPaths: a,
17685
17907
  cacheNamespace: o
@@ -17753,7 +17975,7 @@ var dg = {
17753
17975
  alpha: !0
17754
17976
  });
17755
17977
  this._cacheUpscaledAlpha(t, n * i, r * i), t.isHDR && (this._hdrToneMapFn = wl.get(this.getToneMapping()) || wl.get(We), this._hdrExposure = Dl(this.getExposure(), this.getToneMapping()), this._hdrSaturation = this.getSaturation(), this._tmOut = new Float32Array(3));
17756
- let o = dg.TILE_OVERLAP, s = this.tileSize, c = s - o * 2, l = Math.ceil(n / c), u = Math.ceil(r / c), d = l * u, f = 0;
17978
+ let o = vg.TILE_OVERLAP, s = this.tileSize, c = s - o * 2, l = Math.ceil(n / c), u = Math.ceil(r / c), d = l * u, f = 0;
17757
17979
  for (let o = 0; o < u; o++) for (let u = 0; u < l; u++) {
17758
17980
  if (e.aborted) throw new DOMException("Aborted", "AbortError");
17759
17981
  let l = Math.min(u * c, Math.max(0, n - s)), p = Math.min(o * c, Math.max(0, r - s)), m = Math.min(s, n - l), h = Math.min(s, r - p), g = this._extractTile(t, l, p, m, h), _ = await this._inferTile(g, m, h), v = l * i, y = p * i, b = m * i, x = h * i, S = this._tensorToImageData(_, b, x, v, y);
@@ -17900,7 +18122,7 @@ var dg = {
17900
18122
  this.hdr = !!e;
17901
18123
  }
17902
18124
  setQuality(e) {
17903
- if (!dg.QUALITY_PRESETS[e]) {
18125
+ if (!vg.QUALITY_PRESETS[e]) {
17904
18126
  console.warn(`AIUpscaler: Invalid quality "${e}", must be fast/balanced/quality`);
17905
18127
  return;
17906
18128
  }
@@ -17923,9 +18145,9 @@ var dg = {
17923
18145
  async dispose() {
17924
18146
  this.abort(), this._cleanupPendingWorkerHandlers(), this._worker &&= (this._worker.postMessage({ type: "dispose" }), this._worker.terminate(), null), this._currentModelUrl = null, this._backupCanvas = null, this._upscaledAlpha = null, this.state.abortController = null, this._hdrStagingBuffer?.destroy(), this._hdrStagingBuffer = null, this._hdrStagingWidth = 0, this._hdrStagingHeight = 0, console.log("AIUpscaler disposed");
17925
18147
  }
17926
- }, pg = class extends dt {
18148
+ }, bg = 120, xg = 2, Sg = class extends dt {
17927
18149
  constructor({ renderer: e, mainCanvas: t, scene: n, camera: r, stages: i, pipeline: a, getExposure: o, getSaturation: s, getTransparentBg: c }) {
17928
- super(), this.renderer = e, this.mainCanvas = t, this.denoiserCanvas = this._createDenoiserCanvas(t), this.scene = n, this.camera = r, this.pipeline = a, this._stages = i, this._getExposure = o, this._getSaturation = s, this._getTransparentBg = c, this.denoiser = null, this.upscaler = null, this._onReset = null, this._onPostProcessRefresh = null, this._lastRenderWidth = 0, this._lastRenderHeight = 0, this._pendingStartUpscaler = null, this._denoiserStartHandler = null, this._denoiserEndHandler = null, this._upscalerResChangedHandler = null, this._upscalerStartHandler = null, this._upscalerProgressHandler = null, this._upscalerEndHandler = null;
18150
+ super(), this.renderer = e, this.mainCanvas = t, this.denoiserCanvas = this._createDenoiserCanvas(t), this.scene = n, this.camera = r, this.pipeline = a, this._stages = i, this._getExposure = o, this._getSaturation = s, this._getTransparentBg = c, this.denoiser = null, this.upscaler = null, this._finalQuality = X.oidnQuality, this.finalDenoise = X.enableOIDN, this.continuousDenoise = X.continuousDenoise, this.continuousDenoiseInterval = X.continuousDenoiseInterval, this._lastCadenceAt = -Infinity, this._lastCadenceSamples = 0, this._onReset = null, this._onPostProcessRefresh = null, this._lastRenderWidth = 0, this._lastRenderHeight = 0, this._pendingStartUpscaler = null, this._pendingCloseDenoise = null, this._denoiserStartHandler = null, this._denoiserEndHandler = null, this._upscalerResChangedHandler = null, this._upscalerStartHandler = null, this._upscalerProgressHandler = null, this._upscalerEndHandler = null;
17929
18151
  }
17930
18152
  _createDenoiserCanvas(e) {
17931
18153
  let t = e.parentNode;
@@ -17934,7 +18156,7 @@ var dg = {
17934
18156
  return n.width = e.width, n.height = e.height, n.style.position = "absolute", n.style.inset = "0", n.style.width = "100%", n.style.height = "100%", t.insertBefore(n, e), n;
17935
18157
  }
17936
18158
  setRenderSize(e, t) {
17937
- this._lastRenderWidth = e, this._lastRenderHeight = t, this.denoiser?.setSize(e, t), this.upscaler?.setBaseSize(e, t);
18159
+ this._lastRenderWidth = e, this._lastRenderHeight = t, this._cadenceDowngraded = !1, this.denoiser?.setSize(e, t), this.upscaler?.setBaseSize(e, t);
17938
18160
  }
17939
18161
  restoreBaseResolution() {
17940
18162
  if (!this.denoiserCanvas || !this._lastRenderWidth || !this._lastRenderHeight) return !1;
@@ -17944,7 +18166,7 @@ var dg = {
17944
18166
  setupDenoiser() {
17945
18167
  if (!this.denoiserCanvas) return;
17946
18168
  let e = this._stages.pathTracer;
17947
- this.denoiser = new ag(this.denoiserCanvas, this.renderer, this.scene, this.camera, {
18169
+ this.denoiser = new fg(this.denoiserCanvas, this.renderer, this.scene, this.camera, {
17948
18170
  ...X,
17949
18171
  backendParams: () => ({
17950
18172
  device: this.renderer.backend.device,
@@ -17966,14 +18188,19 @@ var dg = {
17966
18188
  getExposure: () => this._getEffectiveExposure(),
17967
18189
  getToneMapping: () => this._getToneMapping(),
17968
18190
  getSaturation: () => this._getSaturation(),
17969
- getTransparentBackground: () => this._getTransparentBg(),
17970
- getMRTRenderTarget: () => e?.storageTextures?.readTarget ?? null
17971
- }), this.denoiser.enabled = X.enableOIDN, this._denoiserStartHandler = () => this.dispatchEvent({ type: mr.DENOISING_START }), this._denoiserEndHandler = () => this.dispatchEvent({ type: mr.DENOISING_END }), this.denoiser.addEventListener("start", this._denoiserStartHandler), this.denoiser.addEventListener("end", this._denoiserEndHandler);
18191
+ getTransparentBackground: () => this._getTransparentBg()
18192
+ }), this._syncOIDNInUse(), this._denoiserStartHandler = (e) => this.dispatchEvent({
18193
+ type: mr.DENOISING_START,
18194
+ continuous: !!e.continuous
18195
+ }), this._denoiserEndHandler = (e) => this.dispatchEvent({
18196
+ type: mr.DENOISING_END,
18197
+ continuous: !!e.continuous
18198
+ }), this.denoiser.addEventListener("start", this._denoiserStartHandler), this.denoiser.addEventListener("end", this._denoiserEndHandler);
17972
18199
  }
17973
18200
  setupUpscaler() {
17974
18201
  if (!this.denoiserCanvas) return;
17975
18202
  let e = this._stages.pathTracer;
17976
- this.upscaler = new fg(this.denoiserCanvas, this.renderer, {
18203
+ this.upscaler = new yg(this.denoiserCanvas, this.renderer, {
17977
18204
  scaleFactor: X.upscalerScale || 2,
17978
18205
  quality: X.upscalerQuality || "fast",
17979
18206
  getSourceCanvas: () => this.denoiser?.enabled ? null : this.renderer.domElement,
@@ -17999,11 +18226,11 @@ var dg = {
17999
18226
  }), this._upscalerEndHandler = () => this.dispatchEvent({ type: mr.UPSCALING_END }), this.upscaler.addEventListener("resolution_changed", this._upscalerResChangedHandler), this.upscaler.addEventListener("start", this._upscalerStartHandler), this.upscaler.addEventListener("progress", this._upscalerProgressHandler), this.upscaler.addEventListener("end", this._upscalerEndHandler);
18000
18227
  }
18001
18228
  get denoiserStrategy() {
18002
- return this._stages.asvgf?.enabled ? "asvgf" : this._stages.nrd?.enabled ? "nrd" : this._stages.edgeFilter?.enabled ? "edgeaware" : "none";
18229
+ return this.continuousDenoise ? "oidn" : this._stages.asvgf?.enabled ? "asvgf" : this._stages.nrd?.enabled ? "nrd" : this._stages.edgeFilter?.enabled ? "edgeaware" : "none";
18003
18230
  }
18004
18231
  setDenoiserStrategy(e, t) {
18005
18232
  let n = this._stages;
18006
- switch (n.asvgf && (n.asvgf.enabled = !1), n.nrd && (n.nrd.enabled = !1), n.variance && (n.variance.enabled = !1), n.bilateralFilter && (n.bilateralFilter.enabled = !1), n.edgeFilter && n.edgeFilter.setFilteringEnabled(!1), this._clearDenoiserTextures(), e) {
18233
+ switch (n.asvgf && (n.asvgf.enabled = !1), n.nrd && (n.nrd.enabled = !1), n.variance && (n.variance.enabled = !1), n.bilateralFilter && (n.bilateralFilter.enabled = !1), n.edgeFilter && n.edgeFilter.setFilteringEnabled(!1), this._clearDenoiserTextures(), this.setContinuousDenoise(e === "oidn"), e) {
18007
18234
  case "asvgf":
18008
18235
  n.asvgf.enabled = !0, n.variance && (n.variance.enabled = !0), n.bilateralFilter && (n.bilateralFilter.enabled = !0), n.asvgf.setTemporalEnabled?.(!0), this._applyASVGFPreset(t || "medium");
18009
18236
  break;
@@ -18032,7 +18259,7 @@ var dg = {
18032
18259
  }
18033
18260
  _syncGBufferStages() {
18034
18261
  let e = this._stages, t = e.normalDepth, n = e.motionVector, r = this.requiresMotionVectors, i = r || !!(e.edgeFilter?.enabled || e.bilateralFilter?.enabled);
18035
- t && (i && !t.enabled && t.reset(), t.enabled = i), n && (r && !n.enabled && (n.matricesInitialized = !1, n.isFirstFrame = !0, n.frameCount = 0), n.enabled = r), e.pathTracer?.setAuxGBufferEnabled?.(i || !!this.denoiser?.enabled), e.pathTracer?.setCleanAuxNormal?.(!!this.denoiser?.enabled && this.denoiser?.quality !== "fast");
18262
+ t && (i && !t.enabled && t.reset(), t.enabled = i), n && (r && !n.enabled && (n.matricesInitialized = !1, n.isFirstFrame = !0, n.frameCount = 0), n.enabled = r), e.pathTracer?.setAuxGBufferEnabled?.(i || !!this.denoiser?.enabled), e.pathTracer?.setCleanAuxNormal?.(!!this.denoiser?.enabled && !!this.denoiser?.expectsCleanAux(this._finalQuality));
18036
18263
  for (let r of [
18037
18264
  e.asvgf,
18038
18265
  e.nrd,
@@ -18044,17 +18271,51 @@ var dg = {
18044
18271
  ]) r && !r.enabled && r.releaseGPUMemory?.();
18045
18272
  }
18046
18273
  _cleanupCompletionListener() {
18047
- this._pendingStartUpscaler && this.denoiser && this.denoiser.removeEventListener("end", this._pendingStartUpscaler), this._pendingStartUpscaler = null;
18274
+ this.denoiser && (this._pendingStartUpscaler && this.denoiser.removeEventListener("end", this._pendingStartUpscaler), this._pendingCloseDenoise && this.denoiser.removeEventListener("end", this._pendingCloseDenoise)), this._pendingStartUpscaler = null, this._pendingCloseDenoise = null;
18275
+ }
18276
+ tickContinuousDenoise(e) {
18277
+ let t = this.denoiser;
18278
+ if (!this.continuousDenoise || !t || t.state.isDenoising || t.state.isLoading || this._stages.pathTracer?.interactionMode || e <= this._lastCadenceSamples) return !1;
18279
+ let n = performance.now(), r = Math.max(this.continuousDenoiseInterval, t.lastDenoiseMs * xg);
18280
+ if (n - this._lastCadenceAt < r) return !1;
18281
+ this._lastCadenceAt = n, this._lastCadenceSamples = e, t.lastDenoiseMs > bg && (this._cadenceDowngraded = !0);
18282
+ let i = this._cadenceDowngraded ? this.previewQuality() : this._finalQuality;
18283
+ return t.quality !== i && t.updateQuality(i), t.start({ continuous: !0 }), !0;
18284
+ }
18285
+ previewQuality() {
18286
+ return this.denoiser?.expectsCleanAux(this._finalQuality) ? "fast-clean" : "fast";
18287
+ }
18288
+ setContinuousDenoise(e) {
18289
+ this.continuousDenoise = !!e, this._syncOIDNInUse(), this._lastCadenceAt = -Infinity, this._resetCadence();
18290
+ }
18291
+ _useFinalQuality() {
18292
+ let e = this.denoiser;
18293
+ e && e.quality !== this._finalQuality && e.updateQuality(this._finalQuality);
18294
+ }
18295
+ _resetCadence() {
18296
+ this._lastCadenceSamples = 0;
18048
18297
  }
18049
18298
  onRenderComplete({ isStillComplete: e, context: t }) {
18050
18299
  this._cleanupCompletionListener();
18051
- let n = () => {
18052
- this._pendingStartUpscaler = null, e() && this.upscaler?.enabled && this.upscaler.start();
18300
+ let n = this.finalDenoise ? "final" : this.continuousDenoise ? "refresh" : null, r = () => {
18301
+ this.denoiser?.removeEventListener("end", r), this._pendingStartUpscaler = null, e() && this.upscaler?.enabled && this.upscaler.start();
18302
+ };
18303
+ if (!n) {
18304
+ r();
18305
+ return;
18306
+ }
18307
+ let i = () => {
18308
+ e() && (this._pendingStartUpscaler = r, this.denoiser.addEventListener("end", r), n === "final" ? (this._useFinalQuality(), this.denoiser.start()) : this.denoiser.start({ continuous: !0 }));
18053
18309
  };
18054
- this.denoiser?.enabled ? (this._pendingStartUpscaler = n, this.denoiser.addEventListener("end", n, { once: !0 }), this.denoiser.start()) : n();
18310
+ if (this._resetCadence(), this.denoiser.state.isDenoising) {
18311
+ let e = () => {
18312
+ this.denoiser?.removeEventListener("end", e), this._pendingCloseDenoise === e && (this._pendingCloseDenoise = null), i();
18313
+ };
18314
+ this._pendingCloseDenoise = e, this.denoiser.addEventListener("end", e);
18315
+ } else i();
18055
18316
  }
18056
18317
  abort(e) {
18057
- this._cleanupCompletionListener(), e && (e.style.opacity = "1"), this.upscaler && this.upscaler.abort(), this.denoiser && (this.denoiser.enabled && this.denoiser.abort(), this.denoiser.output && (this.denoiser.output.style.display = "none"));
18318
+ this._cleanupCompletionListener(), e && (e.style.opacity = "1"), this.upscaler && this.upscaler.abort(), this.denoiser && (this.denoiser.enabled && this.denoiser.abort(), this.denoiser.output && (this.denoiser.output.style.display = "none"), this.denoiser.invalidateLatch()), this._resetCadence();
18058
18319
  }
18059
18320
  dispose() {
18060
18321
  this._cleanupCompletionListener(), this.denoiser &&= (this._denoiserStartHandler && this.denoiser.removeEventListener("start", this._denoiserStartHandler), this._denoiserEndHandler && this.denoiser.removeEventListener("end", this._denoiserEndHandler), this.denoiser.dispose(), null), this.upscaler &&= (this._upscalerResChangedHandler && this.upscaler.removeEventListener("resolution_changed", this._upscalerResChangedHandler), this._upscalerStartHandler && this.upscaler.removeEventListener("start", this._upscalerStartHandler), this._upscalerProgressHandler && this.upscaler.removeEventListener("progress", this._upscalerProgressHandler), this._upscalerEndHandler && this.upscaler.removeEventListener("end", this._upscalerEndHandler), this.upscaler.dispose(), null), this._denoiserStartHandler = null, this._denoiserEndHandler = null, this._upscalerResChangedHandler = null, this._upscalerStartHandler = null, this._upscalerProgressHandler = null, this._upscalerEndHandler = null, this.denoiserCanvas?.parentNode && (this.denoiserCanvas.parentNode.removeChild(this.denoiserCanvas), this.denoiserCanvas = null);
@@ -18086,11 +18347,23 @@ var dg = {
18086
18347
  setAutoExposureParams(e) {
18087
18348
  this._stages.autoExposure?.updateParameters(e);
18088
18349
  }
18350
+ applyOIDNEnabled(e) {
18351
+ this.finalDenoise = !!e, this._syncOIDNInUse();
18352
+ }
18353
+ get oidnQuality() {
18354
+ return this._finalQuality;
18355
+ }
18089
18356
  setOIDNEnabled(e) {
18090
- this.denoiser && (this.denoiser.enabled = e), this._syncGBufferStages(), this._onPostProcessRefresh?.();
18357
+ this.applyOIDNEnabled(e), this._syncGBufferStages(), this._onPostProcessRefresh?.();
18358
+ }
18359
+ _syncOIDNInUse() {
18360
+ this.denoiser && (this.denoiser.enabled = this.finalDenoise || this.continuousDenoise);
18361
+ }
18362
+ applyOIDNQuality(e) {
18363
+ this._finalQuality = e, this._cadenceDowngraded = !1, this.denoiser?.updateQuality(e);
18091
18364
  }
18092
18365
  setOIDNQuality(e) {
18093
- this.denoiser?.updateQuality(e), this._stages.pathTracer?.setCleanAuxNormal?.(!!this.denoiser?.enabled && !!this.denoiser?.expectsCleanAux(e)), this._onPostProcessRefresh?.();
18366
+ this.applyOIDNQuality(e), this._syncGBufferStages(), this._onPostProcessRefresh?.();
18094
18367
  }
18095
18368
  setTileHelperEnabled(e) {
18096
18369
  this._setTileHelper(e);
@@ -18155,7 +18428,7 @@ var dg = {
18155
18428
  let t = Br[e];
18156
18429
  t && (this._stages.asvgf?.updateParameters(t), this._stages.bilateralFilter?.updateParameters(t), this._stages.variance && t.varianceBoost !== void 0 && (this._stages.variance.varianceBoost.value = t.varianceBoost));
18157
18430
  }
18158
- }, mg = class {
18431
+ }, Cg = class {
18159
18432
  constructor() {
18160
18433
  this.layer = "hud", this.visible = !1, this._tileBounds = null, this._imageWidth = 1, this._imageHeight = 1, this.enabled = !0, this._borderColor = "rgba(255, 0, 0, 0.6)", this._borderWidthRatio = 1 / 540, this._borderWidthMin = 1.5, this._borderWidthMax = 4;
18161
18434
  }
@@ -18179,7 +18452,7 @@ var dg = {
18179
18452
  dispose() {
18180
18453
  this.visible = !1;
18181
18454
  }
18182
- }, hg = class {
18455
+ }, wg = class {
18183
18456
  constructor(n, r) {
18184
18457
  this.layer = "scene", this._enabled = !0, this._outlineNode = wn(n, r, {
18185
18458
  selectedObjects: [],
@@ -18210,11 +18483,11 @@ var dg = {
18210
18483
  this._enabled = !1, this._outlineNode?.dispose(), this._material?.dispose(), this._quad = null;
18211
18484
  }
18212
18485
  };
18213
- function gg(e = !1) {
18486
+ function Tg(e = !1) {
18214
18487
  let t = document.createElement("canvas");
18215
18488
  return t.style.cssText = "position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;" + (e ? "display:none;" : ""), t;
18216
18489
  }
18217
- function _g(e, t = Infinity) {
18490
+ function Eg(e, t = Infinity) {
18218
18491
  let n = e?.getBoundingClientRect();
18219
18492
  if (!n || n.width === 0 || n.height === 0) return null;
18220
18493
  let r = Math.min(window.devicePixelRatio || 1, 2), i = Math.round(n.width * r), a = Math.round(n.height * r), o = t / Math.max(i, a);
@@ -18225,9 +18498,9 @@ function _g(e, t = Infinity) {
18225
18498
  }
18226
18499
  //#endregion
18227
18500
  //#region src/managers/helpers/ViewOverlayRenderer.js
18228
- var vg = 4096, yg = class {
18501
+ var Dg = 4096, Og = class {
18229
18502
  constructor() {
18230
- this.canvas = gg(!0), this._visible = !1, this.renderer = null, this._sizeSource = null;
18503
+ this.canvas = Tg(!0), this._visible = !1, this.renderer = null, this._sizeSource = null;
18231
18504
  }
18232
18505
  async init({ device: e, sizeSource: t }) {
18233
18506
  this._sizeSource = t;
@@ -18244,7 +18517,7 @@ var vg = 4096, yg = class {
18244
18517
  }
18245
18518
  syncSize() {
18246
18519
  if (!this.renderer) return;
18247
- let e = _g(this._sizeSource, vg);
18520
+ let e = Eg(this._sizeSource, Dg);
18248
18521
  !e || e.width === this.canvas.width && e.height === this.canvas.height || this.renderer.setSize(e.width, e.height, !1);
18249
18522
  }
18250
18523
  begin() {
@@ -18256,18 +18529,18 @@ var vg = 4096, yg = class {
18256
18529
  dispose() {
18257
18530
  Tr(this.renderer), this.renderer = null, this.canvas.parentElement?.removeChild(this.canvas);
18258
18531
  }
18259
- }, bg = ki("overlay"), xg = (e, t) => e.visible && e.layer === t && e.render, Sg = class {
18532
+ }, kg = ki("overlay"), Ag = (e, t) => e.visible && e.layer === t && e.render, jg = class {
18260
18533
  constructor(e) {
18261
- this.camera = e, this._helpers = /* @__PURE__ */ new Map(), this._hudCanvas = gg(), this._hudCtx = this._hudCanvas.getContext("2d"), this._helperScene = null, this._viewOverlay = null;
18534
+ this.camera = e, this._helpers = /* @__PURE__ */ new Map(), this._hudCanvas = Tg(), this._hudCtx = this._hudCanvas.getContext("2d"), this._helperScene = null, this._viewOverlay = null;
18262
18535
  }
18263
18536
  async initViewRenderer({ device: e, sizeSource: t }) {
18264
18537
  if (!(!e || !t)) try {
18265
- this._viewOverlay = await new yg().init({
18538
+ this._viewOverlay = await new Og().init({
18266
18539
  device: e,
18267
18540
  sizeSource: t
18268
18541
  });
18269
18542
  } catch (e) {
18270
- bg.error("overlay surface unavailable — light gizmos, transform gizmo and outlines are disabled", e), this._viewOverlay = null;
18543
+ kg.error("overlay surface unavailable — light gizmos, transform gizmo and outlines are disabled", e), this._viewOverlay = null;
18271
18544
  }
18272
18545
  }
18273
18546
  setHelperScene(e) {
@@ -18283,23 +18556,23 @@ var vg = 4096, yg = class {
18283
18556
  }
18284
18557
  setupDefaultHelpers({ helperScene: e, meshScene: t, pipeline: n, denoisingManager: r, app: i, renderWidth: a, renderHeight: o }) {
18285
18558
  this.setHelperScene(e);
18286
- let s = new mg();
18559
+ let s = new Cg();
18287
18560
  this.register("tiles", s), s.setRenderSize(a || 1, o || 1), i.addEventListener("resolution_changed", (e) => {
18288
18561
  s.setRenderSize(e.width, e.height);
18289
18562
  }), n.eventBus.on("pipeline:reset", () => s.hide()), this._wireDenoiserTileEvents(s, r);
18290
- let c = new hg(t, this.camera);
18563
+ let c = new wg(t, this.camera);
18291
18564
  this.register("outline", c);
18292
18565
  }
18293
18566
  _wireDenoiserTileEvents(e, t) {
18294
18567
  let n = [t?.denoiser, t?.upscaler];
18295
18568
  for (let t of n) t && (t.addEventListener("tileProgress", (t) => {
18296
- t.tile && (e.setRenderSize(t.imageWidth, t.imageHeight), e.setActiveTile(t.tile), e.show(), this.refreshHUD());
18569
+ t.continuous || t.tile && (e.setRenderSize(t.imageWidth, t.imageHeight), e.setActiveTile(t.tile), e.show(), this.refreshHUD());
18297
18570
  }), t.addEventListener("end", () => {
18298
18571
  e.hide(), this.refreshHUD();
18299
18572
  }));
18300
18573
  }
18301
18574
  register(e, t) {
18302
- this._helpers.has(e) && (bg.warn(`helper "${e}" already registered — replacing.`), this._helpers.get(e).dispose?.()), this._helpers.set(e, t);
18575
+ this._helpers.has(e) && (kg.warn(`helper "${e}" already registered — replacing.`), this._helpers.get(e).dispose?.()), this._helpers.set(e, t);
18303
18576
  }
18304
18577
  unregister(e) {
18305
18578
  let t = this._helpers.get(e);
@@ -18337,16 +18610,16 @@ var vg = 4096, yg = class {
18337
18610
  }
18338
18611
  _renderSceneLayer(e) {
18339
18612
  this._helperScene?.render(e, this.camera);
18340
- for (let t of this._helpers.values()) xg(t, "scene") && t.render(e, this.camera);
18613
+ for (let t of this._helpers.values()) Ag(t, "scene") && t.render(e, this.camera);
18341
18614
  }
18342
18615
  _hasVisibleSceneOverlay() {
18343
18616
  if (this._helperScene?.isDrawing) return !0;
18344
- for (let e of this._helpers.values()) if (xg(e, "scene")) return !0;
18617
+ for (let e of this._helpers.values()) if (Ag(e, "scene")) return !0;
18345
18618
  return !1;
18346
18619
  }
18347
18620
  refreshHUD() {
18348
18621
  let e = this._hudCanvas, t = this._hudCtx, n = !1;
18349
- for (let e of this._helpers.values()) if (xg(e, "hud")) {
18622
+ for (let e of this._helpers.values()) if (Ag(e, "hud")) {
18350
18623
  n = !0;
18351
18624
  break;
18352
18625
  }
@@ -18355,10 +18628,10 @@ var vg = 4096, yg = class {
18355
18628
  return;
18356
18629
  }
18357
18630
  e.style.display !== "" && (e.style.display = "");
18358
- let r = e.clientWidth, i = e.clientHeight, a = r > 0 && i > 0 ? _g(e) : null;
18631
+ let r = e.clientWidth, i = e.clientHeight, a = r > 0 && i > 0 ? Eg(e) : null;
18359
18632
  if (a) {
18360
18633
  (e.width !== a.width || e.height !== a.height) && (e.width = a.width, e.height = a.height), t.clearRect(0, 0, a.width, a.height), t.save(), t.scale(a.width / r, a.height / i);
18361
- for (let e of this._helpers.values()) xg(e, "hud") && e.render(t, r, i);
18634
+ for (let e of this._helpers.values()) Ag(e, "hud") && e.render(t, r, i);
18362
18635
  t.restore(), e.style.display !== "" && (e.style.display = "");
18363
18636
  }
18364
18637
  }
@@ -18366,7 +18639,7 @@ var vg = 4096, yg = class {
18366
18639
  for (let e of this._helpers.values()) e.dispose?.();
18367
18640
  this._helpers.clear(), this._viewOverlay?.dispose(), this._viewOverlay = null, this._hudCanvas.parentElement && this._hudCanvas.parentElement.removeChild(this._hudCanvas);
18368
18641
  }
18369
- }, Cg = class extends dt {
18642
+ }, Mg = class extends dt {
18370
18643
  constructor() {
18371
18644
  super(), this.mixer = null, this.timer = new nn(), this.actions = [], this.isPlaying = !1, this._scene = null, this._mixerRoot = null, this._meshes = null, this._meshTriRanges = null, this._posBuffer = null, this._tempVec = new cn(), this._skinnedCache = null, this._clipsCache = null, this._savedTimeScale = 1, this.onFinished = null, this.wakeCallback = null;
18372
18645
  }
@@ -18466,7 +18739,7 @@ var vg = 4096, yg = class {
18466
18739
  dispose() {
18467
18740
  this.mixer &&= (this.mixer.stopAllAction(), this.mixer.uncacheRoot(this._mixerRoot), null), this.actions = [], this.isPlaying = !1, this.timer.reset(), this._scene = null, this._mixerRoot = null, this._meshes = null, this._meshTriRanges = null, this._posBuffer = null, this._skinnedCache = null, this._clipsCache = null;
18468
18741
  }
18469
- }, wg = new cn(0, 0, -1), Tg = class {
18742
+ }, Ng = new cn(0, 0, -1), Pg = class {
18470
18743
  constructor({ camera: e, canvas: t, orbitControls: n, app: r }) {
18471
18744
  this._app = r, this._orbitControls = n, this._camera = e, this._controls = new Tn(e, t), this._gizmoScene = new Yt(), this._gizmoScene.add(this._controls.getHelper()), this._attached = null, this._isDragging = !1, this._meshes = null, this._meshTriRanges = null, this._posBuffer = null, this._normalBuffer = null, this._skinnedCache = null, this._normalCache = null, this._tempVec = new cn(), this._normalMatrix = new St(), this._refitInFlight = !1, this._baselineComputed = !1, this._tempForward = new cn(), this._lightTargetDistance = null, this._lastLightPosition = null, this._onDraggingChanged = this._onDraggingChanged.bind(this), this._onObjectChange = this._onObjectChange.bind(this), this._controls.addEventListener("dragging-changed", this._onDraggingChanged), this._controls.addEventListener("objectChange", this._onObjectChange);
18472
18745
  }
@@ -18487,7 +18760,7 @@ var vg = 4096, yg = class {
18487
18760
  attach(e) {
18488
18761
  if (this._attached !== e && (this._controls.attach(e), this._attached = e, this._lightTargetDistance = null, this._lastLightPosition = null, e.isLight && e.target)) {
18489
18762
  let t = e.target.position.clone().sub(e.position), n = t.length();
18490
- n > 1e-4 ? (e.quaternion.setFromUnitVectors(wg, t.normalize()), this._lightTargetDistance = n) : this._lightTargetDistance = 1, this._lastLightPosition = e.position.clone();
18763
+ n > 1e-4 ? (e.quaternion.setFromUnitVectors(Ng, t.normalize()), this._lightTargetDistance = n) : this._lightTargetDistance = 1, this._lastLightPosition = e.position.clone();
18491
18764
  }
18492
18765
  }
18493
18766
  detach() {
@@ -18599,7 +18872,7 @@ var vg = 4096, yg = class {
18599
18872
  dispose() {
18600
18873
  this._controls.removeEventListener("dragging-changed", this._onDraggingChanged), this._controls.removeEventListener("objectChange", this._onObjectChange), this.detach(), this._gizmoScene.remove(this._controls.getHelper()), this._controls.dispose(), this._meshes = null, this._meshTriRanges = null, this._posBuffer = null, this._normalBuffer = null, this._skinnedCache = null, this._normalCache = null, this._baselineComputed = !1, this._tempForward = null, this._lightTargetDistance = null, this._lastLightPosition = null, this._app = null, this._orbitControls = null, this._camera = null, this._controls = null, this._gizmoScene = null;
18601
18874
  }
18602
- }, Eg = class {
18875
+ }, Fg = class {
18603
18876
  constructor(e) {
18604
18877
  this.layer = "scene", this._transformManager = e, this._enabled = !0;
18605
18878
  }
@@ -18618,32 +18891,32 @@ var vg = 4096, yg = class {
18618
18891
  dispose() {
18619
18892
  this._enabled = !1;
18620
18893
  }
18621
- }, Dg = /* @__PURE__ */ new WeakMap(), Og = ki("engine");
18622
- function kg(e, t) {
18894
+ }, Ig = /* @__PURE__ */ new WeakMap(), Lg = ki("engine");
18895
+ function Rg(e, t) {
18623
18896
  e.lost.then((e) => {
18624
18897
  t.app && t.app._handleDeviceLost(e);
18625
18898
  });
18626
18899
  }
18627
- var Ag = /swiftshader|llvmpipe|lavapipe|basic render|microsoft basic|warp/i;
18628
- function jg(e) {
18900
+ var zg = /swiftshader|llvmpipe|lavapipe|basic render|microsoft basic|warp/i;
18901
+ function Bg(e) {
18629
18902
  let t = e.info ?? {}, n = `${t.vendor ?? ""} ${t.architecture ?? ""} ${t.device ?? ""} ${t.description ?? ""}`;
18630
18903
  return {
18631
18904
  vendor: t.vendor ?? "",
18632
18905
  architecture: t.architecture ?? "",
18633
18906
  device: t.device ?? "",
18634
18907
  description: t.description ?? "",
18635
- isSoftware: t.isFallbackAdapter === !0 || e.isFallbackAdapter === !0 || Ag.test(n)
18908
+ isSoftware: t.isFallbackAdapter === !0 || e.isFallbackAdapter === !0 || zg.test(n)
18636
18909
  };
18637
18910
  }
18638
- var Mg = class extends dt {
18911
+ var Vg = class extends dt {
18639
18912
  constructor(e, t = {}) {
18640
18913
  super();
18641
18914
  try {
18642
- Dg.get(e)?.dispose();
18915
+ Ig.get(e)?.dispose();
18643
18916
  } catch (e) {
18644
- Og.warn("prior canvas owner dispose failed", e);
18917
+ Lg.warn("prior canvas owner dispose failed", e);
18645
18918
  }
18646
- Dg.set(e, this), this.canvas = e, this._autoResize = t.autoResize !== !1, this._container = t.container || null, this._applySceneMetadataEnabled = t.applySceneMetadata !== !1, this._applyingSceneMetadata = !1, this._profile = Mr(t.profile), this._issues = new ml({
18919
+ Ig.set(e, this), this.canvas = e, this._autoResize = t.autoResize !== !1, this._container = t.container || null, this._applySceneMetadataEnabled = t.applySceneMetadata !== !1, this._applyingSceneMetadata = !1, this._profile = Mr(t.profile), this._issues = new ml({
18647
18920
  strict: t.strict === !0,
18648
18921
  onIssue: (e) => this.dispatchEvent({
18649
18922
  type: mr.ISSUE,
@@ -18653,7 +18926,7 @@ var Mg = class extends dt {
18653
18926
  ...X,
18654
18927
  environmentRotation: this._profile.environmentRotation,
18655
18928
  saturation: this._profile.saturation
18656
- }, { issues: this._issues }), this.renderer = null, this.scene = null, this.meshScene = null, this._sceneHelpers = null, this.assetLoader = null, this._sdf = null, this._animRefitInFlight = !1, this._maxTextureSize = X.maxTextureSize, this.pipeline = null, this._pendingReservedRenderSize = null, this.stages = {}, this.cameraManager = null, this.lightManager = null, this.goboManager = null, this.iesManager = null, this.denoisingManager = null, this.overlayManager = null, this.interactionManager = null, this.transformManager = null, this.animationManager = new Cg(), this.environmentManager = null, this.isInitialized = !1, this.pauseRendering = !1, this._pathTracerEnabled = !0, this._rasterPrecompile = null, this.animationManagerId = null, this.needsReset = !1, this._loadingInProgress = !1, this._needsDisplayRefresh = !1, this._paused = !1, this._emissiveSamplingUserSet = !1, this.completion = new Im(), this._resizeDebounceTimer = null, this._trackedListeners = [], this._disposed = !1, this._deviceLost = !1, this._gpuDevice = null, this._deviceLostHolder = null, this._deterministic = !1, this._dispatchPinned = !1, this._deterministicRestore = null, this.adapterInfo = null;
18929
+ }, { issues: this._issues }), this.renderer = null, this.scene = null, this.meshScene = null, this._sceneHelpers = null, this.assetLoader = null, this._sdf = null, this._animRefitInFlight = !1, this._maxTextureSize = X.maxTextureSize, this.pipeline = null, this._pendingReservedRenderSize = null, this.stages = {}, this.cameraManager = null, this.lightManager = null, this.goboManager = null, this.iesManager = null, this.denoisingManager = null, this.overlayManager = null, this.interactionManager = null, this.transformManager = null, this.animationManager = new Mg(), this.environmentManager = null, this.isInitialized = !1, this.pauseRendering = !1, this._pathTracerEnabled = !0, this._rasterPrecompile = null, this.animationManagerId = null, this.needsReset = !1, this._loadingInProgress = !1, this._needsDisplayRefresh = !1, this._paused = !1, this._emissiveSamplingUserSet = !1, this.completion = new Im(), this._resizeDebounceTimer = null, this._trackedListeners = [], this._disposed = !1, this._deviceLost = !1, this._gpuDevice = null, this._deviceLostHolder = null, this._deterministic = !1, this._dispatchPinned = !1, this._deterministicRestore = null, this.adapterInfo = null;
18657
18930
  }
18658
18931
  _addTrackedListener(e, t, n) {
18659
18932
  e && (e.addEventListener(t, n), this._trackedListeners.push({
@@ -18666,12 +18939,12 @@ var Mg = class extends dt {
18666
18939
  for (let { target: e, type: t, handler: n } of this._trackedListeners) try {
18667
18940
  e.removeEventListener(t, n);
18668
18941
  } catch (e) {
18669
- Og.warn("failed to remove listener", t, e);
18942
+ Lg.warn("failed to remove listener", t, e);
18670
18943
  }
18671
18944
  this._trackedListeners.length = 0;
18672
18945
  }
18673
18946
  async init() {
18674
- return await this._initRenderer(), this._applyPendingReservedRenderSize(), this._initCameraManager(), this._initScenes(), this._initAssetPipeline(), this._initPipeline(), await this._initManagers(), this._wireEvents(), this.stages.pathTracer.setTriangleData(new Float32Array(32), 0), this.stages.pathTracer.setBVHData(new Float32Array(16)), this.stages.pathTracer.materialData.setMaterialData(new Float32Array(16)), this.stages.pathTracer.setupMaterial(), this.isInitialized = !0, Og.debug("WebGPU path tracer app initialized"), this;
18947
+ return await this._initRenderer(), this._applyPendingReservedRenderSize(), this._initCameraManager(), this._initScenes(), this._initAssetPipeline(), this._initPipeline(), await this._initManagers(), this._wireEvents(), this.stages.pathTracer.setTriangleData(new Float32Array(32), 0), this.stages.pathTracer.setBVHData(new Float32Array(16)), this.stages.pathTracer.materialData.setMaterialData(new Float32Array(16)), this.stages.pathTracer.setupMaterial(), this.isInitialized = !0, Lg.debug("WebGPU path tracer app initialized"), this;
18675
18948
  }
18676
18949
  animate() {
18677
18950
  if (!this._deviceLost) {
@@ -18681,7 +18954,7 @@ var Mg = class extends dt {
18681
18954
  }
18682
18955
  if (this.cameraManager.controls && this.cameraManager.controls.update(), this.animationManager?.isPlaying && !this._animRefitInFlight) {
18683
18956
  let e = this.animationManager.update();
18684
- e && (this._animRefitInFlight = !0, this.refitBVH(e).catch((e) => Og.error("animation refit error:", e)).finally(() => {
18957
+ e && (this._animRefitInFlight = !0, this.refitBVH(e).catch((e) => Lg.error("animation refit error:", e)).finally(() => {
18685
18958
  this._animRefitInFlight = !1;
18686
18959
  }));
18687
18960
  }
@@ -18695,7 +18968,7 @@ var Mg = class extends dt {
18695
18968
  this._needsDisplayRefresh && (this._needsDisplayRefresh = !1, this.stages.compositor.render(this.pipeline.context), this._renderHelperOverlay()), this.stopAnimation();
18696
18969
  return;
18697
18970
  }
18698
- this.pipeline.render(), this.stages.pathTracer.isComplete || this.completion.updateTime(), this._ensureVRAMWiring();
18971
+ this.pipeline.render(), this.stages.pathTracer.isComplete || (this.completion.updateTime(), this.denoisingManager?.tickContinuousDenoise(this.stages.pathTracer.frameCount)), this._ensureVRAMWiring();
18699
18972
  let e = this.stages.pathTracer?.vramTracker, t = this.stages.pathTracer?.frameCount ?? 0;
18700
18973
  if (e && (t <= 1 || t % 30 == 0) && e.measure(), br({
18701
18974
  timeElapsed: this.completion.timeElapsed,
@@ -18730,7 +19003,7 @@ var Mg = class extends dt {
18730
19003
  this.animationManagerId &&= (cancelAnimationFrame(this.animationManagerId), null);
18731
19004
  }
18732
19005
  _handleDeviceLost(e) {
18733
- this._deviceLost || (this._deviceLost = !0, Og.error(`WebGPU device lost (${e?.reason || "unknown"}): ${e?.message || ""}`), this.stopAnimation(), this.dispatchEvent({
19006
+ this._deviceLost || (this._deviceLost = !0, Lg.error(`WebGPU device lost (${e?.reason || "unknown"}): ${e?.message || ""}`), this.stopAnimation(), this.dispatchEvent({
18734
19007
  type: mr.DEVICE_LOST,
18735
19008
  reason: e?.reason,
18736
19009
  message: e?.message
@@ -18760,9 +19033,9 @@ var Mg = class extends dt {
18760
19033
  let e = Me().value, t = ee().value;
18761
19034
  e?._listeners?.dispose && (e._listeners.dispose.length = 0), t?._listeners?.dispose && (t._listeners.dispose.length = 0);
18762
19035
  } catch (e) {
18763
- Og.warn("failed to clear TSL texture singleton listeners", e);
19036
+ Lg.warn("failed to clear TSL texture singleton listeners", e);
18764
19037
  }
18765
- this.canvas && Dg.get(this.canvas) === this && Dg.delete(this.canvas), this._gpuDevice &&= (this._gpuDevice.onuncapturederror = null, null), this._deviceLostHolder &&= (this._deviceLostHolder.app = null, null), Tr(this.renderer), this.renderer = null, this.stages = {}, this.isInitialized = !1;
19038
+ this.canvas && Ig.get(this.canvas) === this && Ig.delete(this.canvas), this._gpuDevice &&= (this._gpuDevice.onuncapturederror = null, null), this._deviceLostHolder &&= (this._deviceLostHolder.app = null, null), Tr(this.renderer), this.renderer = null, this.stages = {}, this.isInitialized = !1;
18766
19039
  }
18767
19040
  }
18768
19041
  unloadScene() {
@@ -19108,7 +19381,7 @@ var Mg = class extends dt {
19108
19381
  source: zm.MODE_PRESET
19109
19382
  }), this.stages.pathTracer?.setUniform("renderMode", parseInt(r.renderMode)), this.stages.pathTracer?.updateCompletionThreshold?.();
19110
19383
  let i = this.denoisingManager?.denoiser;
19111
- if (i && (i.abort(), i.enabled = r.enableOIDN, i.updateQuality(r.oidnQuality)), this.denoisingManager?._syncGBufferStages?.(), this.denoisingManager?.upscaler?.abort(), t.canvasWidth && t.canvasHeight && (this.setReservedRenderResolution(Math.max(t.canvasWidth, t.canvasHeight)), this.setCanvasSize(t.canvasWidth, t.canvasHeight)), this.needsReset = !1, this.pauseRendering = !1, n) {
19384
+ if (i && (i.abort(), this.denoisingManager.applyOIDNEnabled(r.enableOIDN), this.denoisingManager.applyOIDNQuality(r.oidnQuality)), this.denoisingManager?._syncGBufferStages?.(), this.denoisingManager?.upscaler?.abort(), t.canvasWidth && t.canvasHeight && (this.setReservedRenderResolution(Math.max(t.canvasWidth, t.canvasHeight)), this.setCanvasSize(t.canvasWidth, t.canvasHeight)), this.needsReset = !1, this.pauseRendering = !1, n) {
19112
19385
  let e = this.stages.pathTracer?.vramTracker;
19113
19386
  e && (e.measure(), e.resetPeak());
19114
19387
  }
@@ -19144,17 +19417,18 @@ var Mg = class extends dt {
19144
19417
  bounceEarlyExit: n._bounceEarlyExitThreshold,
19145
19418
  dynamicDispatch: n._useDynamicDispatch,
19146
19419
  autoFocusMode: this.cameraManager?.autoFocusMode,
19147
- autoExposure: this.stages.autoExposure?.enabled
19420
+ autoExposure: this.stages.autoExposure?.enabled,
19421
+ continuousDenoise: this.denoisingManager?.continuousDenoise
19148
19422
  }, this.settings.setMany({
19149
19423
  useAdaptiveSampling: !1,
19150
19424
  usePixelFreeze: !1,
19151
19425
  interactionModeEnabled: !1,
19152
19426
  renderLimitMode: "frames",
19153
19427
  renderTimeLimit: 0
19154
- }, { silent: !0 }), t ? (n._bounceEarlyExitThreshold = -1, n._useDynamicDispatch = !1) : (n._bounceEarlyExitThreshold = this._deterministicRestore.bounceEarlyExit, n._useDynamicDispatch = this._deterministicRestore.dynamicDispatch), this.cameraManager?.setAutoFocusMode("manual"), this.stages.autoExposure && (this.stages.autoExposure.enabled = !1), n._pinSeedToFrame = !0, this._deterministic = !0, this._dispatchPinned = t;
19428
+ }, { silent: !0 }), t ? (n._bounceEarlyExitThreshold = -1, n._useDynamicDispatch = !1) : (n._bounceEarlyExitThreshold = this._deterministicRestore.bounceEarlyExit, n._useDynamicDispatch = this._deterministicRestore.dynamicDispatch), this.cameraManager?.setAutoFocusMode("manual"), this.stages.autoExposure && (this.stages.autoExposure.enabled = !1), this.denoisingManager?.setContinuousDenoise(!1), n._pinSeedToFrame = !0, this._deterministic = !0, this._dispatchPinned = t;
19155
19429
  else if (this._deterministicRestore) {
19156
19430
  let e = this._deterministicRestore;
19157
- this.settings.setMany(e.settings, { silent: !0 }), n._bounceEarlyExitThreshold = e.bounceEarlyExit, n._useDynamicDispatch = e.dynamicDispatch, e.autoFocusMode !== void 0 && this.cameraManager?.setAutoFocusMode(e.autoFocusMode), this.stages.autoExposure && e.autoExposure !== void 0 && (this.stages.autoExposure.enabled = e.autoExposure), n._pinSeedToFrame = !1, this._deterministicRestore = null, this._deterministic = !1, this._dispatchPinned = !1;
19431
+ this.settings.setMany(e.settings, { silent: !0 }), n._bounceEarlyExitThreshold = e.bounceEarlyExit, n._useDynamicDispatch = e.dynamicDispatch, e.autoFocusMode !== void 0 && this.cameraManager?.setAutoFocusMode(e.autoFocusMode), this.stages.autoExposure && e.autoExposure !== void 0 && (this.stages.autoExposure.enabled = e.autoExposure), e.continuousDenoise !== void 0 && this.denoisingManager?.setContinuousDenoise(e.continuousDenoise), n._pinSeedToFrame = !1, this._deterministicRestore = null, this._deterministic = !1, this._dispatchPinned = !1;
19158
19432
  }
19159
19433
  return this.reset(), this.stopAnimation(), this._deterministic;
19160
19434
  }
@@ -19299,7 +19573,7 @@ var Mg = class extends dt {
19299
19573
  this._pathTracerEnabled = e, e || this.precompileRaster();
19300
19574
  }
19301
19575
  precompileRaster() {
19302
- return !this.renderer || !this.meshScene ? Promise.resolve() : (this._rasterPrecompile ??= this.renderer.compileAsync(this.meshScene, this.cameraManager.camera).catch((e) => Og.warn("raster fallback precompile failed", e)), this._rasterPrecompile);
19576
+ return !this.renderer || !this.meshScene ? Promise.resolve() : (this._rasterPrecompile ??= this.renderer.compileAsync(this.meshScene, this.cameraManager.camera).catch((e) => Lg.warn("raster fallback precompile failed", e)), this._rasterPrecompile);
19303
19577
  }
19304
19578
  get isLoading() {
19305
19579
  return this._loadingInProgress;
@@ -19394,7 +19668,7 @@ var Mg = class extends dt {
19394
19668
  if (_r((e) => this.dispatchEvent(e)), !navigator.gpu) throw Error("WebGPU is not supported in this browser");
19395
19669
  let e = await navigator.gpu.requestAdapter({ powerPreference: "high-performance" });
19396
19670
  if (!e) throw Error("Failed to get WebGPU adapter");
19397
- this.adapterInfo = jg(e), this.adapterInfo.isSoftware && (this._issues.warn(dl.ADAPTER_SOFTWARE, `software GPU adapter "${this.adapterInfo.description || this.adapterInfo.vendor}" — renders are correct but orders of magnitude slower than hardware`, { ...this.adapterInfo }), Og.warn(`software GPU adapter — check app.adapterInfo.isSoftware. ${this.adapterInfo.description}`));
19671
+ this.adapterInfo = Bg(e), this.adapterInfo.isSoftware && (this._issues.warn(dl.ADAPTER_SOFTWARE, `software GPU adapter "${this.adapterInfo.description || this.adapterInfo.vendor}" — renders are correct but orders of magnitude slower than hardware`, { ...this.adapterInfo }), Lg.warn(`software GPU adapter — check app.adapterInfo.isSoftware. ${this.adapterInfo.description}`));
19398
19672
  let t = e.limits;
19399
19673
  if (this.renderer = new u({
19400
19674
  canvas: this.canvas,
@@ -19408,7 +19682,7 @@ var Mg = class extends dt {
19408
19682
  }
19409
19683
  }), await this.renderer.init(), !this.renderer.backend?.isWebGPUBackend) throw Error("WebGPU backend unavailable — three.js fell back to WebGL2, which cannot run the path tracer's compute kernels. Check GPU process flags and driver support.");
19410
19684
  let n = this.renderer.backend?.device;
19411
- n?.lost && (this._gpuDevice = n, this._deviceLostHolder = { app: this }, kg(n, this._deviceLostHolder), n.onuncapturederror = (e) => Og.error("WebGPU uncaptured error:", e.error)), r.setLTC(un.init()), this.renderer.outputColorSpace = a, this.renderer.toneMapping = this._profile.toneMapping, this.renderer.toneMappingExposure = 1, this.renderer.setPixelRatio(1);
19685
+ n?.lost && (this._gpuDevice = n, this._deviceLostHolder = { app: this }, Rg(n, this._deviceLostHolder), n.onuncapturederror = (e) => Lg.error("WebGPU uncaptured error:", e.error)), r.setLTC(un.init()), this.renderer.outputColorSpace = a, this.renderer.toneMapping = this._profile.toneMapping, this.renderer.toneMappingExposure = 1, this.renderer.setPixelRatio(1);
19412
19686
  }
19413
19687
  _initCameraManager() {
19414
19688
  this.cameraManager = new Ph(this.canvas);
@@ -19439,12 +19713,12 @@ var Mg = class extends dt {
19439
19713
  assetLoader: this.assetLoader,
19440
19714
  pathTracer: null,
19441
19715
  floorPlane: this.assetLoader.floorPlane
19442
- }), this.interactionManager.wireAppEvents(this), this.cameraManager.setInteractionManager(this.interactionManager), this.lightManager = new Fh(this.scene, this._sceneHelpers, this.stages.pathTracer, { onReset: () => this.reset() }), this.goboManager = new Ih(this.stages.pathTracer, { onReset: () => this.reset() }), this.iesManager = new qh(this.stages.pathTracer, { onReset: () => this.reset() }), this._setupDenoisingManager(), await this._setupOverlayManager(), this.transformManager = new Tg({
19716
+ }), this.interactionManager.wireAppEvents(this), this.cameraManager.setInteractionManager(this.interactionManager), this.lightManager = new Fh(this.scene, this._sceneHelpers, this.stages.pathTracer, { onReset: () => this.reset() }), this.goboManager = new Ih(this.stages.pathTracer, { onReset: () => this.reset() }), this.iesManager = new qh(this.stages.pathTracer, { onReset: () => this.reset() }), this._setupDenoisingManager(), await this._setupOverlayManager(), this.transformManager = new Pg({
19443
19717
  camera: this.cameraManager.camera,
19444
19718
  canvas: this.canvas,
19445
19719
  orbitControls: this.cameraManager.controls,
19446
19720
  app: this
19447
- }), this.overlayManager.register("transform", new Eg(this.transformManager)), this.interactionManager.setDependencies({
19721
+ }), this.overlayManager.register("transform", new Fg(this.transformManager)), this.interactionManager.setDependencies({
19448
19722
  overlayManager: this.overlayManager,
19449
19723
  transformManager: this.transformManager,
19450
19724
  appDispatch: (e) => this.dispatchEvent(e),
@@ -19525,7 +19799,7 @@ var Mg = class extends dt {
19525
19799
  });
19526
19800
  }
19527
19801
  _setupDenoisingManager() {
19528
- this.denoisingManager = new pg({
19802
+ this.denoisingManager = new Sg({
19529
19803
  renderer: this.renderer,
19530
19804
  mainCanvas: this.canvas,
19531
19805
  scene: this.scene,
@@ -19569,7 +19843,7 @@ var Mg = class extends dt {
19569
19843
  this.scene.updateMatrixWorld(), this.overlayManager?.render();
19570
19844
  }
19571
19845
  async _setupOverlayManager() {
19572
- this.overlayManager = new Sg(this.cameraManager.camera), this.overlayManager.setupDefaultHelpers({
19846
+ this.overlayManager = new jg(this.cameraManager.camera), this.overlayManager.setupDefaultHelpers({
19573
19847
  helperScene: this._sceneHelpers,
19574
19848
  meshScene: this.meshScene,
19575
19849
  pipeline: this.pipeline,
@@ -19603,15 +19877,15 @@ var Mg = class extends dt {
19603
19877
  };
19604
19878
  //#endregion
19605
19879
  //#region src/Headless.js
19606
- async function Ng(e) {
19607
- let t = await Fg(e);
19880
+ async function Hg(e) {
19881
+ let t = await Wg(e);
19608
19882
  try {
19609
- return await Pg(t, e);
19883
+ return await Ug(t, e);
19610
19884
  } finally {
19611
19885
  t.dispose();
19612
19886
  }
19613
19887
  }
19614
- async function Pg(e, { samples: t = 64, colorSpace: n = "srgb", allowEarlyRetire: r = !1, onProgress: i = void 0 } = {}) {
19888
+ async function Ug(e, { samples: t = 64, colorSpace: n = "srgb", allowEarlyRetire: r = !1, onProgress: i = void 0 } = {}) {
19615
19889
  let a = await e.renderFrames(t, {
19616
19890
  onProgress: i,
19617
19891
  allowEarlyRetire: r
@@ -19624,9 +19898,9 @@ async function Pg(e, { samples: t = 64, colorSpace: n = "srgb", allowEarlyRetire
19624
19898
  adapter: e.adapterInfo
19625
19899
  };
19626
19900
  }
19627
- async function Fg({ canvas: e, model: t = null, width: n = 1920, height: r = 1080, strict: i = !0, profile: a = "physical", deterministic: o = !0, settings: s = null } = {}) {
19901
+ async function Wg({ canvas: e, model: t = null, width: n = 1920, height: r = 1080, strict: i = !0, profile: a = "physical", deterministic: o = !0, settings: s = null } = {}) {
19628
19902
  if (!e) throw Error("openHeadless: a canvas is required");
19629
- let c = new Mg(e, {
19903
+ let c = new Vg(e, {
19630
19904
  autoResize: !1,
19631
19905
  strict: i,
19632
19906
  profile: a
@@ -19639,7 +19913,7 @@ async function Fg({ canvas: e, model: t = null, width: n = 1920, height: r = 108
19639
19913
  }
19640
19914
  //#endregion
19641
19915
  //#region src/managers/VideoRenderManager.js
19642
- var Ig = class {
19916
+ var Gg = class {
19643
19917
  constructor(e) {
19644
19918
  this._app = e, this._cancelled = !1, this._rendering = !1;
19645
19919
  }
@@ -19661,7 +19935,7 @@ var Ig = class {
19661
19935
  try {
19662
19936
  for (let e = 0; e < f && !this._cancelled; e++) {
19663
19937
  let n = e * p * r, i = l.animationManager.seekTo(n, t);
19664
- if (i ? await l.refitBVH(i) : l.reset(), l.stopAnimation(), await this._accumulateFrame(l), this._cancelled || (a && l.denoisingManager?.denoiser?.enabled && await this._waitForDenoise(l), this._cancelled)) break;
19938
+ if (i ? await l.refitBVH(i) : l.reset(), l.stopAnimation(), await this._accumulateFrame(l), this._cancelled || (a && l.denoisingManager?.finalDenoise && await this._waitForDenoise(l), this._cancelled)) break;
19665
19939
  let c = l.getCanvas();
19666
19940
  if (c && o) {
19667
19941
  let t = await createImageBitmap(c);
@@ -19721,8 +19995,8 @@ var Ig = class {
19721
19995
  transmissiveBounces: e.settings.get("transmissiveBounces"),
19722
19996
  renderMode: e.stages.pathTracer?.renderMode?.value,
19723
19997
  controlsEnabled: e.cameraManager.controls?.enabled,
19724
- oidnEnabled: e.denoisingManager?.denoiser?.enabled,
19725
- oidnQuality: e.denoisingManager?.denoiser?.quality,
19998
+ oidnEnabled: e.denoisingManager?.finalDenoise,
19999
+ oidnQuality: e.denoisingManager?.oidnQuality,
19726
20000
  wasPlaying: e.animationManager?.isPlaying,
19727
20001
  pauseRendering: e.pauseRendering
19728
20002
  };
@@ -19733,8 +20007,8 @@ var Ig = class {
19733
20007
  maxSamples: e.maxSamples,
19734
20008
  maxBounces: e.maxBounces,
19735
20009
  transmissiveBounces: e.transmissiveBounces
19736
- }, { silent: !0 }), t.stages.pathTracer && e.renderMode !== void 0 && t.stages.pathTracer?.setUniform("renderMode", parseInt(e.renderMode)), t.stages.pathTracer?.updateCompletionThreshold?.(), t.cameraManager.controls && (t.cameraManager.controls.enabled = e.controlsEnabled ?? !0), t.denoisingManager?.denoiser && (t.denoisingManager.denoiser.enabled = e.oidnEnabled ?? !1, e.oidnQuality && t.denoisingManager.denoiser.updateQuality(e.oidnQuality)), t.pauseRendering = e.pauseRendering ?? !1, t.animationManager?.stop(), t.reset(), t.wake();
20010
+ }, { silent: !0 }), t.stages.pathTracer && e.renderMode !== void 0 && t.stages.pathTracer?.setUniform("renderMode", parseInt(e.renderMode)), t.stages.pathTracer?.updateCompletionThreshold?.(), t.cameraManager.controls && (t.cameraManager.controls.enabled = e.controlsEnabled ?? !0), t.denoisingManager?.denoiser && (t.denoisingManager.applyOIDNEnabled(e.oidnEnabled ?? !1), e.oidnQuality && t.denoisingManager.applyOIDNQuality(e.oidnQuality)), t.pauseRendering = e.pauseRendering ?? !1, t.animationManager?.stop(), t.reset(), t.wake();
19737
20011
  }
19738
20012
  };
19739
20013
  //#endregion
19740
- export { Jr as AF_DEFAULTS, Br as ASVGF_QUALITY_PRESETS, qr as AUTO_FOCUS_MODES, Cg as AnimationManager, Xr as BVH_LEAF_MARKERS, Kr as CAMERA_PRESETS, Wr as CAMERA_RANGES, Ph as CameraManager, li as DEFAULT_TEXTURE_MATRIX, pg as DenoisingManager, X as ENGINE_DEFAULTS, mr as EngineEvents, pl as EngineIssueError, Ih as GoboManager, qh as IESManager, di as INTERACTIVE_RENDER_CONFIG, dl as ISSUE_CODES, fl as ISSUE_SEVERITY, Lm as InteractionManager, ml as IssueLog, pi as LOG_LEVELS, Fh as LightManager, Oi as Logger, Lr as MAX_RESERVABLE_RENDER_SIZE, fi as MEMORY_CONSTANTS, Vr as NRD_DEFAULTS, Pr as NRD_HIT_DIST_A, Fr as NRD_HIT_DIST_B, Hr as NRD_PRESET_KEYS, Ur as NRD_QUALITY_PRESETS, Sg as OverlayManager, ui as PRODUCTION_RENDER_CONFIG, Mg as PathTracerApp, Sm as PipelineContext, jr as RENDER_PROFILES, Pm as RenderPipeline, Vm as RenderSettings, fr as RenderStage, zm as SETTING_SOURCE, Gr as SKY_PRESETS, dr as StageExecutionMode, Zr as TEXTURE_CONSTANTS, Z as TRIANGLE_DATA_LAYOUT, Tg as TransformManager, gd as VRAMTracker, Ig as VideoRenderManager, md as bufferBytes, Pg as captureHeadless, km as clearBindingAuditFindings, uu as configureAssets, ki as createLogger, Ul as deriveAlphaMode, jg as describeAdapter, Dh as extractSceneMetadata, Di as fmt, du as getAssetConfig, Om as getBindingAuditFindings, Mr as getRenderProfile, Fg as openHeadless, Eh as parseSceneMetadata, Ng as renderHeadless, Dm as setBindingAudit, hd as textureBytes };
20014
+ export { Jr as AF_DEFAULTS, Br as ASVGF_QUALITY_PRESETS, qr as AUTO_FOCUS_MODES, Mg as AnimationManager, Xr as BVH_LEAF_MARKERS, Kr as CAMERA_PRESETS, Wr as CAMERA_RANGES, Ph as CameraManager, li as DEFAULT_TEXTURE_MATRIX, Sg as DenoisingManager, X as ENGINE_DEFAULTS, mr as EngineEvents, pl as EngineIssueError, Ih as GoboManager, qh as IESManager, di as INTERACTIVE_RENDER_CONFIG, dl as ISSUE_CODES, fl as ISSUE_SEVERITY, Lm as InteractionManager, ml as IssueLog, pi as LOG_LEVELS, Fh as LightManager, Oi as Logger, Lr as MAX_RESERVABLE_RENDER_SIZE, fi as MEMORY_CONSTANTS, Vr as NRD_DEFAULTS, Pr as NRD_HIT_DIST_A, Fr as NRD_HIT_DIST_B, Hr as NRD_PRESET_KEYS, Ur as NRD_QUALITY_PRESETS, jg as OverlayManager, ui as PRODUCTION_RENDER_CONFIG, Vg as PathTracerApp, Sm as PipelineContext, jr as RENDER_PROFILES, Pm as RenderPipeline, Vm as RenderSettings, fr as RenderStage, zm as SETTING_SOURCE, Gr as SKY_PRESETS, dr as StageExecutionMode, Zr as TEXTURE_CONSTANTS, Z as TRIANGLE_DATA_LAYOUT, Pg as TransformManager, gd as VRAMTracker, Gg as VideoRenderManager, md as bufferBytes, Ug as captureHeadless, km as clearBindingAuditFindings, uu as configureAssets, ki as createLogger, Ul as deriveAlphaMode, Bg as describeAdapter, Dh as extractSceneMetadata, Di as fmt, du as getAssetConfig, Om as getBindingAuditFindings, Mr as getRenderProfile, Wg as openHeadless, Eh as parseSceneMetadata, Hg as renderHeadless, Dm as setBindingAudit, hd as textureBytes };