rayzee 7.19.0 → 7.19.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rayzee",
3
- "version": "7.19.0",
3
+ "version": "7.19.1",
4
4
  "type": "module",
5
5
  "description": "Real-time WebGPU path tracing engine built on Three.js",
6
6
  "main": "dist/rayzee.umd.js",
@@ -1215,10 +1215,12 @@ export class PathTracerApp extends EventDispatcher {
1215
1215
  *
1216
1216
  * MUST be called before the pipeline/stages are constructed (they pre-allocate at this value and cannot
1217
1217
  * resize). Calling it after init only takes effect on the next full pipeline (re)build.
1218
- * @param {number} requestedPx desired reserved size (longest edge)
1218
+ * @param {number} requestedPx desired reserved size (longest edge)
1219
+ * @param {Object} [opts]
1220
+ * @param {boolean} [opts.allowLower=false] permit lowering, paying a rebuild, to reclaim VRAM
1219
1221
  * @returns {number} the applied reserved size
1220
1222
  */
1221
- setReservedRenderResolution( requestedPx ) {
1223
+ setReservedRenderResolution( requestedPx, { allowLower = false } = {} ) {
1222
1224
 
1223
1225
  const limits = this.renderer?.backend?.device?.limits;
1224
1226
  const maxBinding = limits?.maxStorageBufferBindingSize || ( 128 * 1024 * 1024 );
@@ -1227,7 +1229,11 @@ export class PathTracerApp extends EventDispatcher {
1227
1229
  const deviceSafeMax = ( deviceMemGB >= 8 && maxBinding >= 1024 * 1024 * 1024 )
1228
1230
  ? MAX_RESERVABLE_RENDER_SIZE : 2048;
1229
1231
  const prev = MAX_STORAGE_TEXTURE_SIZE;
1230
- const applied = setReservedRenderSize( Math.min( requestedPx, deviceSafeMax ) );
1232
+
1233
+ // Monotonic up: UI-driven callers request whatever the current view needs, so honouring decreases made
1234
+ // the reserve oscillate on every preview↔render switch and paid a full kernel rebuild each time.
1235
+ const target = allowLower ? requestedPx : Math.max( requestedPx, prev );
1236
+ const applied = setReservedRenderSize( Math.min( target, deviceSafeMax ) );
1231
1237
 
1232
1238
  // If the pipeline is already built and the reserved size changed, re-init the reserved GPU storage in
1233
1239
  // place: each stage recreates its pre-allocated StorageTextures at the new size + rebuilds its compute
@@ -1240,6 +1246,17 @@ export class PathTracerApp extends EventDispatcher {
1240
1246
  this.pauseRendering = true;
1241
1247
  try {
1242
1248
 
1249
+ // Lowering below the live backing store makes copyToReadTargets read past the end of the
1250
+ // (now smaller) write textures — a GPUValidationError. Shrink the backing store first.
1251
+ // renderer.setSize, not setCanvasSize/onResize: those also rewrite camera.aspect.
1252
+ const backing = this.renderer.domElement;
1253
+ if ( backing.width > applied || backing.height > applied ) {
1254
+
1255
+ this.renderer.setSize(
1256
+ Math.min( backing.width, applied ), Math.min( backing.height, applied ), false );
1257
+
1258
+ }
1259
+
1243
1260
  for ( const stage of Object.values( this.stages ) ) stage?.reallocateReservedStorage?.();
1244
1261
 
1245
1262
  } finally {
@@ -1257,6 +1274,16 @@ export class PathTracerApp extends EventDispatcher {
1257
1274
 
1258
1275
  }
1259
1276
 
1277
+ /**
1278
+ * The current reserved (pre-allocated) square render size in px.
1279
+ * @returns {number}
1280
+ */
1281
+ getReservedRenderResolution() {
1282
+
1283
+ return MAX_STORAGE_TEXTURE_SIZE;
1284
+
1285
+ }
1286
+
1260
1287
  /**
1261
1288
  * Guard against render resolutions the compute pipeline can't support.
1262
1289
  * Per-resolution StorageTextures are pre-allocated at MAX_STORAGE_TEXTURE_SIZE
@@ -1344,28 +1371,27 @@ export class PathTracerApp extends EventDispatcher {
1344
1371
 
1345
1372
  this.cameraManager.controls.enabled = ! isProduction;
1346
1373
 
1347
- // Batch uniform updates via settings
1374
+ // Anything with a SETTING_ROUTES entry must go through settings, not setUniform: set() early-returns on
1375
+ // `prev === value`, so a uniform written behind the map leaves it stale and the next set() silently no-ops.
1348
1376
  this.settings.setMany( {
1349
1377
  maxSamples: config.maxSamples,
1350
1378
  maxBounces: config.bounces,
1351
1379
  transmissiveBounces: config.transmissiveBounces,
1352
1380
  maxSubsurfaceSteps: config.maxSubsurfaceSteps,
1381
+ enableAlphaShadows: config.enableAlphaShadows ?? false,
1382
+ // Tier-1 convergence early-stop
1383
+ useAdaptiveSampling: config.useAdaptiveSampling ?? false,
1384
+ noiseThreshold: config.noiseThreshold ?? DEFAULT_STATE.noiseThreshold,
1385
+ adaptiveStopFraction: config.adaptiveStopFraction ?? DEFAULT_STATE.adaptiveStopFraction,
1386
+ adaptiveMinSamples: config.adaptiveMinSamples ?? DEFAULT_STATE.adaptiveMinSamples,
1387
+ // Tier-2 per-pixel freeze
1388
+ usePixelFreeze: config.usePixelFreeze ?? false,
1389
+ pixelFreezeThreshold: config.pixelFreezeThreshold ?? DEFAULT_STATE.pixelFreezeThreshold,
1390
+ pixelFreezeStability: config.pixelFreezeStability ?? DEFAULT_STATE.pixelFreezeStability,
1353
1391
  }, { silent: true } );
1354
1392
 
1393
+ // renderMode has no SETTING_ROUTES entry
1355
1394
  this.stages.pathTracer?.setUniform( 'renderMode', parseInt( config.renderMode ) );
1356
- this.stages.pathTracer?.setUniform( 'enableAlphaShadows', config.enableAlphaShadows ?? false );
1357
-
1358
- // Tier-1 convergence early-stop (live uniforms, no kernel rebuild). Threshold/min-samples fall back to
1359
- // engine defaults when a config doesn't override them.
1360
- this.stages.pathTracer?.setUniform( 'useAdaptiveSampling', config.useAdaptiveSampling ?? false );
1361
- this.stages.pathTracer?.setUniform( 'noiseThreshold', config.noiseThreshold ?? DEFAULT_STATE.noiseThreshold );
1362
- this.stages.pathTracer?.setUniform( 'adaptiveStopFraction', config.adaptiveStopFraction ?? DEFAULT_STATE.adaptiveStopFraction );
1363
- this.stages.pathTracer?.setUniform( 'adaptiveMinSamples', config.adaptiveMinSamples ?? DEFAULT_STATE.adaptiveMinSamples );
1364
-
1365
- // Tier-2 per-pixel freeze (per-mode; falls back off when a config doesn't set it).
1366
- this.stages.pathTracer?.setUniform( 'usePixelFreeze', config.usePixelFreeze ?? false );
1367
- this.stages.pathTracer?.setUniform( 'pixelFreezeThreshold', config.pixelFreezeThreshold ?? DEFAULT_STATE.pixelFreezeThreshold );
1368
- this.stages.pathTracer?.setUniform( 'pixelFreezeStability', config.pixelFreezeStability ?? DEFAULT_STATE.pixelFreezeStability );
1369
1395
 
1370
1396
  this.stages.pathTracer?.updateCompletionThreshold?.();
1371
1397
 
@@ -769,8 +769,11 @@ export class PathTracer extends PathTracerStage {
769
769
 
770
770
  if ( ! this._packedBuffers || ! ( this.materialData?.materialCount > 0 ) ) return;
771
771
 
772
- const w = this.storageTextures.renderWidth || 1;
773
- const h = this.storageTextures.renderHeight || 1;
772
+ // Clamp into the (possibly just-lowered) reserve: create() sizes the write StorageTextures at
773
+ // MAX_STORAGE_TEXTURE_SIZE but the readTarget at what's passed here, and the tracked render size still
774
+ // holds the pre-change value — unclamped, copyToReadTargets reads past the write textures.
775
+ const w = Math.min( this.storageTextures.renderWidth || 1, MAX_STORAGE_TEXTURE_SIZE );
776
+ const h = Math.min( this.storageTextures.renderHeight || 1, MAX_STORAGE_TEXTURE_SIZE );
774
777
 
775
778
  // Recreate the MRT pool at the new reserved size (create() reallocates the write StorageTextures at the
776
779
  // live MAX_STORAGE_TEXTURE_SIZE; the read RenderTarget follows the current render size).
@@ -382,6 +382,10 @@ export class OverlayManager {
382
382
 
383
383
  }
384
384
 
385
+ // Un-park BEFORE measuring: a display:none canvas reports clientWidth 0, which returns early below and
386
+ // skips the un-park at the end — so once parked the HUD could never come back.
387
+ if ( canvas.style.display !== '' ) canvas.style.display = '';
388
+
385
389
  // Helpers draw in CSS-pixel coordinates of the unscaled layout box; the
386
390
  // backing store is sized off the on-screen box, so nothing is drawn below
387
391
  // view resolution.