rayzee 7.16.0 → 7.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +1 -1
  2. package/dist/assets/BVHSubtreeWorker-D7KMbrQ-.js +2 -0
  3. package/dist/assets/BVHSubtreeWorker-D7KMbrQ-.js.map +1 -0
  4. package/dist/assets/BVHWorker-DOaGn6uN.js +2 -0
  5. package/dist/assets/BVHWorker-DOaGn6uN.js.map +1 -0
  6. package/dist/rayzee.es.js +2817 -2537
  7. package/dist/rayzee.es.js.map +1 -1
  8. package/dist/rayzee.umd.js +55 -55
  9. package/dist/rayzee.umd.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/EngineDefaults.js +27 -11
  12. package/src/Passes/OIDNDenoiser.js +17 -14
  13. package/src/PathTracerApp.js +86 -13
  14. package/src/Processor/BVHBuilder.js +11 -7
  15. package/src/Processor/BuildTimer.js +20 -6
  16. package/src/Processor/EmissiveTriangleBuilder.js +11 -7
  17. package/src/Processor/GeometryExtractor.js +11 -5
  18. package/src/Processor/KernelManager.js +48 -1
  19. package/src/Processor/PackedRayBuffer.js +69 -35
  20. package/src/Processor/ParallelBVHBuilder.js +9 -6
  21. package/src/Processor/QueueManager.js +6 -8
  22. package/src/Processor/SceneProcessor.js +47 -21
  23. package/src/Processor/ShaderBuilder.js +4 -1
  24. package/src/Processor/StorageTexturePool.js +4 -1
  25. package/src/Processor/Workers/BVHWorker.js +12 -6
  26. package/src/RenderSettings.js +1 -1
  27. package/src/Stages/ASVGF.js +38 -0
  28. package/src/Stages/BilateralFilter.js +23 -0
  29. package/src/Stages/EdgeFilter.js +18 -0
  30. package/src/Stages/MotionVector.js +23 -0
  31. package/src/Stages/NormalDepth.js +22 -0
  32. package/src/Stages/PathTracer.js +324 -169
  33. package/src/Stages/PathTracerStage.js +17 -14
  34. package/src/Stages/Variance.js +23 -0
  35. package/src/TSL/FinalWriteKernel.js +30 -18
  36. package/src/TSL/GenerateKernel.js +28 -17
  37. package/src/TSL/ShadeKernel.js +186 -87
  38. package/src/TSL/TextureSampling.js +12 -2
  39. package/src/index.js +3 -0
  40. package/src/managers/EnvironmentManager.js +12 -8
  41. package/src/managers/MaterialDataManager.js +12 -9
  42. package/src/managers/UniformManager.js +1 -1
  43. package/src/utils/Logger.js +291 -0
  44. package/dist/assets/BVHSubtreeWorker-sNzvxn66.js +0 -2
  45. package/dist/assets/BVHSubtreeWorker-sNzvxn66.js.map +0 -1
  46. package/dist/assets/BVHWorker-CiVdFrwe.js +0 -2
  47. package/dist/assets/BVHWorker-CiVdFrwe.js.map +0 -1
@@ -1,4 +1,7 @@
1
1
  import { BVHBuilder } from '../BVHBuilder.js';
2
+ import { createLogger, fmt, applyWorkerLogLevel } from '../../utils/Logger.js';
3
+
4
+ const log = createLogger( 'bvh' );
2
5
 
3
6
  const FPT = 32; // FLOATS_PER_TRIANGLE
4
7
 
@@ -9,6 +12,9 @@ self.onmessage = function ( e ) {
9
12
  const data = e.data;
10
13
  const type = data.type;
11
14
 
15
+ // Workers get their own globals, so the main thread forwards its level per message.
16
+ applyWorkerLogLevel( data.logLevel );
17
+
12
18
  if ( type === 'buildPhase1' ) {
13
19
 
14
20
  handlePhase1( data );
@@ -100,7 +106,7 @@ function handlePhase1( data ) {
100
106
  const flattenTime = performance.now() - flattenStart;
101
107
 
102
108
  const totalTime = performance.now() - startTime;
103
- console.log( `[BVHWorker] Phase 1: ${Math.round( totalTime )}ms (init: ${Math.round( builder.splitStats.initTime )}ms, morton: ${Math.round( builder.splitStats.mortonSortTime )}ms, SAH: ${Math.round( builder.splitStats.sahBuildTime )}ms, flatten: ${Math.round( flattenTime )}ms), ${builder.frontierTasks.length} frontier tasks` );
109
+ log.debug( `phase 1 ${fmt.ms( totalTime )} (init ${fmt.ms( builder.splitStats.initTime )} · morton ${fmt.ms( builder.splitStats.mortonSortTime )} · SAH ${fmt.ms( builder.splitStats.sahBuildTime )} · flatten ${fmt.ms( flattenTime )}) · ${builder.frontierTasks.length} frontier tasks` );
104
110
 
105
111
  self.postMessage( {
106
112
  type: 'phase1Result',
@@ -113,7 +119,7 @@ function handlePhase1( data ) {
113
119
 
114
120
  } catch ( error ) {
115
121
 
116
- console.error( '[BVHWorker] Phase 1 error:', error );
122
+ log.error( 'phase 1 failed:', error );
117
123
  self.postMessage( { type: 'error', error: error.message } );
118
124
 
119
125
  }
@@ -162,7 +168,7 @@ function handleAssemble( data ) {
162
168
  }
163
169
 
164
170
  const totalTime = performance.now() - startTime;
165
- console.log( `[BVHWorker] Phase 3 (assemble + reorder): ${Math.round( totalTime )}ms (${( bvhData.byteLength / 1024 / 1024 ).toFixed( 1 )}MB BVH)` );
171
+ log.debug( `phase 3 assemble + reorder ${fmt.ms( totalTime )} (${fmt.mb( bvhData.byteLength )} BVH)` );
166
172
 
167
173
  self.postMessage( {
168
174
  type: 'assembleResult',
@@ -173,7 +179,7 @@ function handleAssemble( data ) {
173
179
 
174
180
  } catch ( error ) {
175
181
 
176
- console.error( '[BVHWorker] Assembly error:', error );
182
+ log.error( 'assembly failed:', error );
177
183
  self.postMessage( { type: 'error', error: error.message } );
178
184
 
179
185
  }
@@ -225,7 +231,7 @@ function handleFullBuild( data ) {
225
231
  const flattenStart = performance.now();
226
232
  const bvhData = builder.flattenBVH( bvhRoot );
227
233
  const flattenTime = performance.now() - flattenStart;
228
- console.log( `[BVHWorker] Flatten BVH: ${Math.round( flattenTime )}ms (${( bvhData.byteLength / 1024 / 1024 ).toFixed( 1 )}MB)` );
234
+ log.debug( `flatten ${fmt.ms( flattenTime )} (${fmt.mb( bvhData.byteLength )})` );
229
235
 
230
236
  const originalToBvh = builder.originalToBvhMap || null;
231
237
 
@@ -261,7 +267,7 @@ function handleFullBuild( data ) {
261
267
 
262
268
  } catch ( error ) {
263
269
 
264
- console.error( '[BVHWorker] Error:', error );
270
+ log.error( 'build failed:', error );
265
271
  self.postMessage( { error: error.message } );
266
272
 
267
273
  }
@@ -18,6 +18,7 @@ const SETTING_ROUTES = {
18
18
  maxBounces: { uniform: 'maxBounces', reset: true },
19
19
  transmissiveBounces: { uniform: 'transmissiveBounces', reset: true },
20
20
  maxSubsurfaceSteps: { uniform: 'maxSubsurfaceSteps', reset: true },
21
+ maxTransparentBounces: { uniform: 'maxTransparentBounces', reset: true },
21
22
  environmentIntensity: { uniform: 'environmentIntensity', reset: true },
22
23
  backgroundIntensity: { uniform: 'backgroundIntensity', reset: true },
23
24
  backgroundBlurriness: { uniform: 'backgroundBlurriness', reset: true },
@@ -43,7 +44,6 @@ const SETTING_ROUTES = {
43
44
  // Adaptive sampling — whole-frame early-stop (useAdaptiveSampling) + per-pixel freeze (usePixelFreeze)
44
45
  useAdaptiveSampling: { uniform: 'useAdaptiveSampling', reset: true },
45
46
  noiseThreshold: { uniform: 'noiseThreshold', reset: true },
46
- darkNoiseFloor: { uniform: 'darkNoiseFloor', reset: true },
47
47
  adaptiveMinSamples: { uniform: 'adaptiveMinSamples', reset: true },
48
48
  adaptiveStopFraction: { uniform: 'adaptiveStopFraction', reset: true },
49
49
  usePixelFreeze: { uniform: 'usePixelFreeze', reset: true },
@@ -796,6 +796,44 @@ export class ASVGF extends RenderStage {
796
796
 
797
797
  }
798
798
 
799
+ // Reserved-storage change (e.g. 4K toggle): recreate the MAX-preallocated StorageTextures at the new live
800
+ // reserved size + rebuild all compute nodes in place. Same stage object, so refs/wiring stay valid. Fresh
801
+ // build ⇒ the first-render warmup re-runs (no aliasing — the nodes are new, matching initial construction).
802
+ reallocateReservedStorage() {
803
+
804
+ this._gradientNode?.dispose();
805
+ this._temporalNodeA?.dispose();
806
+ this._temporalNodeB?.dispose();
807
+ this._heatmapComputeNode?.dispose();
808
+ this._temporalTexA?.dispose();
809
+ this._temporalTexB?.dispose();
810
+ this._outputModulatedTex?.dispose();
811
+ this._gradientStorageTex?.dispose();
812
+ this._heatmapStorageTex?.dispose();
813
+
814
+ const mk = ( type, filter ) => {
815
+
816
+ const t = new StorageTexture( MAX_STORAGE_TEXTURE_SIZE, MAX_STORAGE_TEXTURE_SIZE );
817
+ t.type = type; t.format = RGBAFormat; t.minFilter = filter; t.magFilter = filter;
818
+ return t;
819
+
820
+ };
821
+
822
+ this._temporalTexA = mk( FloatType, LinearFilter );
823
+ this._temporalTexB = mk( FloatType, LinearFilter );
824
+ this._outputModulatedTex = mk( FloatType, LinearFilter );
825
+ this._gradientStorageTex = mk( HalfFloatType, LinearFilter );
826
+ this._heatmapStorageTex = mk( FloatType, NearestFilter );
827
+
828
+ this._buildGradientCompute();
829
+ this._buildTemporalCompute();
830
+ this._buildHeatmapCompute();
831
+ this._compiled = false;
832
+ this.currentMoments = 0;
833
+ this._needsWarmReset = true;
834
+
835
+ }
836
+
799
837
  setSize( width, height ) {
800
838
 
801
839
  // StorageTextures stay at max alloc — see resize crash fix (three.js #33061).
@@ -385,6 +385,29 @@ export class BilateralFilter extends RenderStage {
385
385
 
386
386
  }
387
387
 
388
+ // Reserved-storage change (e.g. 4K toggle): recreate the MAX-preallocated StorageTextures at the new live
389
+ // reserved size + rebuild the compute nodes in place. Same stage object, so refs/wiring stay valid.
390
+ reallocateReservedStorage() {
391
+
392
+ this._computeNodeA?.dispose();
393
+ this._computeNodeB?.dispose();
394
+ this._storageTexA?.dispose();
395
+ this._storageTexB?.dispose();
396
+ const mk = () => {
397
+
398
+ const t = new StorageTexture( MAX_STORAGE_TEXTURE_SIZE, MAX_STORAGE_TEXTURE_SIZE );
399
+ t.type = HalfFloatType; t.format = RGBAFormat; t.minFilter = LinearFilter; t.magFilter = LinearFilter;
400
+ return t;
401
+
402
+ };
403
+
404
+ this._storageTexA = mk();
405
+ this._storageTexB = mk();
406
+ this._buildCompute();
407
+ this._compiled = false;
408
+
409
+ }
410
+
388
411
  dispose() {
389
412
 
390
413
  this._computeNodeA?.dispose();
@@ -454,6 +454,24 @@ export class EdgeFilter extends RenderStage {
454
454
 
455
455
  }
456
456
 
457
+ // Reserved-storage change (e.g. 4K toggle): recreate the MAX-preallocated StorageTextures at the new live
458
+ // reserved size + rebuild the compute nodes in place. Same stage object, so refs/wiring stay valid.
459
+ reallocateReservedStorage() {
460
+
461
+ this._computeDemod?.dispose();
462
+ this._computeAtrousA?.dispose();
463
+ this._computeAtrousB?.dispose();
464
+ this._demodTex?.dispose();
465
+ this._storageTexA?.dispose();
466
+ this._storageTexB?.dispose();
467
+ this._demodTex = this._makeStorageTex();
468
+ this._storageTexA = this._makeStorageTex();
469
+ this._storageTexB = this._makeStorageTex();
470
+ this._buildCompute();
471
+ this._compiled = false;
472
+
473
+ }
474
+
457
475
  dispose() {
458
476
 
459
477
  this._computeDemod?.dispose();
@@ -556,6 +556,29 @@ export class MotionVector extends RenderStage {
556
556
 
557
557
  }
558
558
 
559
+ // Reserved-storage change (e.g. 4K toggle): recreate the MAX-preallocated StorageTextures at the new live
560
+ // reserved size + rebuild the compute nodes in place. Same stage object, so refs/wiring stay valid.
561
+ reallocateReservedStorage() {
562
+
563
+ this._screenSpaceComputeNode?.dispose();
564
+ this._worldSpaceComputeNode?.dispose();
565
+ this._screenSpaceStorageTex?.dispose();
566
+ this._worldSpaceStorageTex?.dispose();
567
+ const mk = () => {
568
+
569
+ const t = new StorageTexture( MAX_STORAGE_TEXTURE_SIZE, MAX_STORAGE_TEXTURE_SIZE );
570
+ t.type = HalfFloatType; t.format = RGBAFormat; t.minFilter = NearestFilter; t.magFilter = NearestFilter;
571
+ return t;
572
+
573
+ };
574
+
575
+ this._screenSpaceStorageTex = mk();
576
+ this._worldSpaceStorageTex = mk();
577
+ this._buildScreenSpaceCompute();
578
+ this._buildWorldSpaceCompute();
579
+
580
+ }
581
+
559
582
  dispose() {
560
583
 
561
584
  this._screenSpaceComputeNode?.dispose();
@@ -405,6 +405,28 @@ export class NormalDepth extends RenderStage {
405
405
 
406
406
  }
407
407
 
408
+ // Reserved-storage change (e.g. 4K toggle): recreate the MAX-preallocated StorageTextures at the new live
409
+ // reserved size. The compute node rebuilds lazily on the next execute (guarded by _computeBuilt).
410
+ reallocateReservedStorage() {
411
+
412
+ this._computeNode?.dispose();
413
+ this._computeNode = null;
414
+ this._outputStorageTex?.dispose();
415
+ this._shadingStorageTex?.dispose();
416
+ const mk = () => {
417
+
418
+ const t = new StorageTexture( MAX_STORAGE_TEXTURE_SIZE, MAX_STORAGE_TEXTURE_SIZE );
419
+ t.type = HalfFloatType; t.format = RGBAFormat; t.minFilter = NearestFilter; t.magFilter = NearestFilter;
420
+ return t;
421
+
422
+ };
423
+
424
+ this._outputStorageTex = mk();
425
+ this._shadingStorageTex = mk();
426
+ this._computeBuilt = false;
427
+
428
+ }
429
+
408
430
  dispose() {
409
431
 
410
432
  this._computeNode?.dispose();