rayzee 10.0.0 → 11.0.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 (173) hide show
  1. package/README.md +252 -44
  2. package/dist/ActiveColor-YvuQq44O.js +13 -0
  3. package/dist/ArchiveImporter-BRQvLggb.js +4300 -0
  4. package/dist/AssetConfig-DSEntE65.js +30 -0
  5. package/dist/BidirectionalIntegrator-9lZQxFVH.js +934 -0
  6. package/dist/BufferLayout-D_IBo2ci.js +150 -0
  7. package/dist/ColorManagement-oeEk7oSu.js +1488 -0
  8. package/dist/EngineEvents-Ci8dVWCP.js +73 -0
  9. package/dist/EngineIssues-CIZnXHsF.js +72 -0
  10. package/dist/FileFormats-sPGJeCRc.js +102 -0
  11. package/dist/Logger-dDDGj9Av.js +97 -0
  12. package/dist/{NeuralRetouch-CYgkQY8Z.js → NeuralRetouch-BCXylThH.js} +8 -6
  13. package/dist/{NeuralSuperRes-PkgDLQcD.js → NeuralSuperRes-sZAeS142.js} +55 -120
  14. package/dist/PathTracer-CQPW06Mm.js +29971 -0
  15. package/dist/PhysicalSky-BvqCw_dy.js +1219 -0
  16. package/dist/RayzeeRenderer-COpwotpU.js +3551 -0
  17. package/dist/SolarLimb-CPaeZVwz.js +721 -0
  18. package/dist/ToneMapGPU-CjU3osDd.js +177 -0
  19. package/dist/ViewTransforms-CYN7bq2w.js +255 -0
  20. package/dist/WorkingMatrix-C6y233hT.js +27 -0
  21. package/dist/ZipReader-gDSWr0I5.js +98 -0
  22. package/dist/addons/archives.es.js +3 -0
  23. package/dist/addons/bidirectional.es.js +2 -0
  24. package/dist/addons/color.es.js +3 -0
  25. package/dist/addons/formats.es.js +2 -0
  26. package/dist/addons/physical-sky.es.js +2 -0
  27. package/dist/addons/storage.es.js +3 -0
  28. package/dist/archiveFormats-BZw7TiDp.js +75 -0
  29. package/dist/identity-DrQsGT2o.js +39 -0
  30. package/dist/openStorage-DwcBRUj7.js +820 -0
  31. package/dist/rayzee-core.es.js +12 -0
  32. package/dist/rayzee.es.js +2551 -44024
  33. package/dist/rayzee.umd.js +528 -487
  34. package/dist/sceneCachePolicy-BSSsKY98.js +443 -0
  35. package/dist/shared-BGBcSxBQ.js +17 -0
  36. package/package.json +23 -2
  37. package/src/Color/ActiveColor.js +34 -0
  38. package/src/Color/BasicColor.js +147 -0
  39. package/src/Color/ColorManagement.js +7 -31
  40. package/src/Color/ViewTransforms.js +5 -1
  41. package/src/EngineDefaults.js +62 -1029
  42. package/src/EngineEvents.js +2 -0
  43. package/src/EngineIssues.js +2 -0
  44. package/src/Headless.js +6 -5
  45. package/src/Passes/AIUpscaler.js +58 -141
  46. package/src/Passes/OIDNDenoiser.js +92 -65
  47. package/src/Passes/OIDNTemporalHistory.js +1 -1
  48. package/src/PathTracerApp.js +620 -4026
  49. package/src/Pipeline/PipelineContext.js +0 -4
  50. package/src/Platform.js +36 -0
  51. package/src/Processor/ArchiveCache.js +1 -1
  52. package/src/Processor/ArchiveImporter.js +1259 -0
  53. package/src/Processor/AssetLoader.js +327 -1763
  54. package/src/Processor/AtmosphereModel.js +1 -2
  55. package/src/Processor/BVHBuilder.js +14 -126
  56. package/src/Processor/BVHLeafFold.js +4 -6
  57. package/src/Processor/BVHRefitter.js +67 -46
  58. package/src/Processor/BufferLayout.js +291 -0
  59. package/src/Processor/EmissiveTriangleBuilder.js +1 -1
  60. package/src/Processor/EnvironmentExactTable.js +187 -0
  61. package/src/Processor/EquirectHDRInfo.js +30 -223
  62. package/src/Processor/FileFormats.js +116 -0
  63. package/src/Processor/GLTFDecoders.js +85 -0
  64. package/src/Processor/GLTFDiffuseTransmission.js +63 -0
  65. package/src/Processor/GeometryExtractor.js +15 -5
  66. package/src/Processor/HostMemory.js +7 -1
  67. package/src/Processor/IESParser.js +47 -35
  68. package/src/Processor/InstanceTable.js +1 -1
  69. package/src/Processor/KernelManager.js +35 -2
  70. package/src/Processor/MaterialPacking.js +10 -8
  71. package/src/Processor/PBRT/PBRTMaterials.js +129 -41
  72. package/src/Processor/PBRT/PBRTParser.js +30 -17
  73. package/src/Processor/PBRT/PBRTSceneBuilder.js +548 -37
  74. package/src/Processor/PBRT/PBRTTextureBake.js +154 -0
  75. package/src/Processor/PBRT/PFM.js +59 -0
  76. package/src/Processor/PackedRayBuffer.js +116 -9
  77. package/src/Processor/ParallelBVHBuilder.js +3 -6
  78. package/src/Processor/PhysicalSky.js +5 -4
  79. package/src/Processor/PlatformImageLoader.js +50 -6
  80. package/src/Processor/QueueManager.js +39 -5
  81. package/src/Processor/ReinsertionOptimizer.js +2 -2
  82. package/src/Processor/SceneProcessor.js +53 -62
  83. package/src/Processor/ShaderBuilder.js +6 -16
  84. package/src/Processor/SimpleSky.js +1 -62
  85. package/src/Processor/SolarLimb.js +3 -0
  86. package/src/Processor/SplitBLAS.js +1 -1
  87. package/src/Processor/StorageTexturePool.js +22 -1
  88. package/src/Processor/TLASBuilder.js +1 -3
  89. package/src/Processor/TextureBuckets.js +237 -0
  90. package/src/Processor/TextureCreator.js +181 -8
  91. package/src/Processor/ToneMapGPU.js +64 -15
  92. package/src/Processor/Workers/BVHRefitWorker.js +5 -2
  93. package/src/Processor/Workers/BVHSubtreeWorker.js +1 -34
  94. package/src/Processor/Workers/BVHWorker.js +5 -18
  95. package/src/Processor/Workers/CDFWorker.js +6 -183
  96. package/src/Processor/Workers/TexturesWorker.js +103 -18
  97. package/src/Processor/archiveFormats.js +7 -0
  98. package/src/Processor/utils.js +2 -1
  99. package/src/RayzeeRenderer.js +3899 -0
  100. package/src/RenderSettings.js +68 -62
  101. package/src/Stages/ASVGF.js +13 -14
  102. package/src/Stages/AutoExposure.js +17 -17
  103. package/src/Stages/BilateralFilter.js +2 -1
  104. package/src/Stages/Compositor.js +8 -23
  105. package/src/Stages/DenoiserSettings.js +182 -0
  106. package/src/Stages/EdgeFilter.js +2 -1
  107. package/src/Stages/MotionVector.js +1 -1
  108. package/src/Stages/NRD.js +11 -5
  109. package/src/Stages/NormalDepth.js +12 -8
  110. package/src/Stages/PathTracer.js +338 -43
  111. package/src/Stages/PathTracerStage.js +69 -66
  112. package/src/Stages/Variance.js +1 -1
  113. package/src/Storage/BLASCache.js +1 -1
  114. package/src/Storage/CDFCache.js +18 -17
  115. package/src/Storage/DownloadCache.js +1 -1
  116. package/src/Storage/SceneGraphCodec.js +46 -3
  117. package/src/Storage/SpillStore.js +1 -1
  118. package/src/Storage/StorageManager.js +45 -9
  119. package/src/Storage/areas.js +4 -0
  120. package/src/TSL/BVHTraversal.js +50 -25
  121. package/src/TSL/Bidirectional.js +204 -0
  122. package/src/TSL/BidirectionalLamps.js +132 -0
  123. package/src/TSL/Clearcoat.js +15 -6
  124. package/src/TSL/Common.js +20 -15
  125. package/src/TSL/ConnectKernel.js +147 -0
  126. package/src/TSL/Debugger.js +1 -1
  127. package/src/TSL/Displacement.js +4 -3
  128. package/src/TSL/EmissiveSampling.js +65 -18
  129. package/src/TSL/Environment.js +77 -106
  130. package/src/TSL/EnvironmentCDF.js +85 -39
  131. package/src/TSL/ExtendKernel.js +8 -3
  132. package/src/TSL/FinalWriteKernel.js +4 -4
  133. package/src/TSL/GenerateKernel.js +18 -4
  134. package/src/TSL/HitFacet.js +35 -5
  135. package/src/TSL/LightBVHSampling.js +40 -9
  136. package/src/TSL/LightGenerateKernel.js +293 -0
  137. package/src/TSL/LightGuide.js +198 -0
  138. package/src/TSL/LightSplatKernel.js +165 -0
  139. package/src/TSL/LightVisibility.js +111 -0
  140. package/src/TSL/LightsCore.js +13 -38
  141. package/src/TSL/LightsDirect.js +28 -29
  142. package/src/TSL/LightsIndirect.js +3 -1
  143. package/src/TSL/LightsSampling.js +239 -51
  144. package/src/TSL/MaterialEvaluation.js +113 -31
  145. package/src/TSL/MaterialProperties.js +44 -17
  146. package/src/TSL/MaterialTransmission.js +52 -47
  147. package/src/TSL/MergeKernel.js +218 -0
  148. package/src/TSL/PathTracerCore.js +65 -29
  149. package/src/TSL/Random.js +5 -1
  150. package/src/TSL/SceneResources.js +51 -0
  151. package/src/TSL/ShadeKernel.js +964 -101
  152. package/src/TSL/Struct.js +10 -0
  153. package/src/TSL/Sun.js +1 -1
  154. package/src/TSL/TextureSampling.js +66 -61
  155. package/src/addons/archives.js +14 -0
  156. package/src/addons/bidirectional.js +13 -0
  157. package/src/addons/color.js +32 -0
  158. package/src/addons/formats.js +16 -0
  159. package/src/addons/physicalSky.js +14 -0
  160. package/src/addons/storage.js +19 -0
  161. package/src/core.js +31 -0
  162. package/src/index.js +13 -23
  163. package/src/integrators/BidirectionalIntegrator.js +833 -0
  164. package/src/managers/AnimationManager.js +88 -6
  165. package/src/managers/CameraManager.js +103 -46
  166. package/src/managers/DenoisingManager.js +14 -10
  167. package/src/managers/EnvironmentManager.js +125 -103
  168. package/src/managers/GoboManager.js +9 -0
  169. package/src/managers/MaterialDataManager.js +48 -37
  170. package/src/managers/UniformManager.js +32 -10
  171. package/dist/ToneMapGPU-B6XIe3DU.js +0 -544
  172. package/dist/rolldown-runtime-CAFD8bLK.js +0 -11
  173. package/src/Processor/TreeletOptimizer.js +0 -574
@@ -311,8 +311,7 @@ function transmittanceSpectrum( coefficients, depth ) {
311
311
 
312
312
  }
313
313
 
314
- // Hestroffer & Magnan 1998: I(µ)/I(1) = µ^α, α = −0.023 + 0.292 / λ[µm], at each primary's centroid.
315
- export const LIMB_DARKENING_EXPONENT = [ 610, 550, 465 ].map( l => - 0.023 + 0.292 / ( l / 1000 ) );
314
+ export { LIMB_DARKENING_EXPONENT } from './SolarLimb.js';
316
315
 
317
316
  /** Solid angle of a cone of the given half-angle, without the cancellation `2π(1 − cos)` suffers. */
318
317
  export function coneSolidAngle( halfAngle ) {
@@ -1,26 +1,14 @@
1
- import { TreeletOptimizer } from './TreeletOptimizer.js';
2
1
  import { ReinsertionOptimizer } from './ReinsertionOptimizer.js';
3
- // Logger is worker-safe (globalThis only, storage access guarded), unlike Constants.js below.
2
+ // Logger is worker-safe (globalThis only, storage access guarded).
4
3
  import { createLogger, fmt } from '../utils/Logger.js';
5
4
  import { foldLeaves } from './BVHLeafFold.js';
6
5
  import { hasWorkers } from '../Platform.js';
6
+ import { BVH_LEAF_MARKERS, bvhIndexView, assertBVHIndexFits, TRIANGLE_DATA_LAYOUT } from './BufferLayout.js';
7
7
 
8
8
  const log = createLogger( 'bvh' );
9
9
 
10
- // Inline copies of EngineDefaults.BVH_LEAF_MARKERS / bvhIndexView — this module also runs inside
11
- // a worker, where importing Constants is not safe. Keep in step with EngineDefaults.js.
12
- // Index fields are u32 BIT PATTERNS, never float values: as floats they round past 2^24.
13
- const TRIANGLE_LEAF = 0x40000000;
14
- const FRONTIER_LEAF = 0x40000002;
15
- const indexView = f32 => new Uint32Array( f32.buffer, f32.byteOffset, f32.length );
16
- const BVH_MAX_INDEX = 0x40000000;
17
-
18
- function assertFits( count, what ) {
19
-
20
- if ( count >= BVH_MAX_INDEX ) throw new RangeError( `${what} is ${count}, at or past the BVH index limit of ${BVH_MAX_INDEX}` );
21
- return count;
22
-
23
- }
10
+ const TRIANGLE_LEAF = BVH_LEAF_MARKERS.TRIANGLE_LEAF;
11
+ const FRONTIER_LEAF = BVH_LEAF_MARKERS.FRONTIER;
24
12
 
25
13
  // Injected, not imported: this module also runs inside the worker, and `?worker&inline`
26
14
  // would embed a second copy of BVHWorker's source there.
@@ -32,16 +20,6 @@ export function setBVHWorkerFactory( factory ) {
32
20
 
33
21
  }
34
22
 
35
- // Inline copy of TRIANGLE_DATA_LAYOUT (mirrors Constants.js).
36
- // Cannot import Constants.js because BVHBuilder runs inside BVHWorker
37
- // where `window` (used elsewhere in Constants.js) is not defined.
38
- const TRIANGLE_DATA_LAYOUT = {
39
- FLOATS_PER_TRIANGLE: 20,
40
- POSITION_A_OFFSET: 0,
41
- POSITION_B_OFFSET: 4,
42
- POSITION_C_OFFSET: 8
43
- };
44
-
45
23
  const FPT = TRIANGLE_DATA_LAYOUT.FLOATS_PER_TRIANGLE;
46
24
 
47
25
  // The record buffer is uint; positions are f32 in it. Views share the memory, no copy.
@@ -104,23 +82,11 @@ export class BVHBuilder {
104
82
  totalSplitAttempts: 0,
105
83
  mortonSortTime: 0,
106
84
  totalBuildTime: 0,
107
- treeletOptimizationTime: 0,
108
- treeletsProcessed: 0,
109
- treeletsImproved: 0,
110
- averageSAHImprovement: 0,
111
85
  reinsertionOptimizationTime: 0,
112
86
  reinsertionsApplied: 0,
113
87
  reinsertionIterations: 0
114
88
  };
115
89
 
116
- // Off: repairs LBVH trees, so on this binned-SAH build it buys 0.005% tree SAH for 72%
117
- // of build time.
118
- this.enableTreeletOptimization = false;
119
- this.treeletSize = 5;
120
- this.treeletOptimizationPasses = 1;
121
- this.treeletMinImprovement = 0.02;
122
- this.treeletComplexityThreshold = 50000;
123
-
124
90
  // Reinsertion optimization configuration
125
91
  this.enableReinsertionOptimization = true;
126
92
  this.reinsertionBatchSizeRatio = 0.02;
@@ -201,22 +167,6 @@ export class BVHBuilder {
201
167
 
202
168
  }
203
169
 
204
- setTreeletConfig( config ) {
205
-
206
- if ( config.enabled !== undefined ) this.enableTreeletOptimization = config.enabled;
207
- if ( config.size !== undefined ) this.treeletSize = Math.max( 3, Math.min( 12, config.size ) );
208
- if ( config.passes !== undefined ) this.treeletOptimizationPasses = Math.max( 1, Math.min( 3, config.passes ) );
209
- if ( config.minImprovement !== undefined ) this.treeletMinImprovement = Math.max( 0.001, config.minImprovement );
210
- if ( config.complexityThreshold !== undefined ) this.treeletComplexityThreshold = config.complexityThreshold;
211
-
212
- }
213
-
214
- disableTreeletOptimization() {
215
-
216
- this.enableTreeletOptimization = false;
217
-
218
- }
219
-
220
170
  setReinsertionConfig( config ) {
221
171
 
222
172
  if ( config.enabled !== undefined ) this.enableReinsertionOptimization = config.enabled;
@@ -442,7 +392,7 @@ export class BVHBuilder {
442
392
 
443
393
  worker.onmessage = ( e ) => {
444
394
 
445
- const { bvhData, triangles: transferredTriangles, originalToBvh, error, progress, treeletStats } = e.data;
395
+ const { bvhData, triangles: transferredTriangles, originalToBvh, error, progress, splitStats } = e.data;
446
396
 
447
397
  if ( error ) {
448
398
 
@@ -459,9 +409,9 @@ export class BVHBuilder {
459
409
 
460
410
  }
461
411
 
462
- if ( treeletStats ) {
412
+ if ( splitStats ) {
463
413
 
464
- this.splitStats = treeletStats;
414
+ this.splitStats = splitStats;
465
415
 
466
416
  }
467
417
 
@@ -493,12 +443,6 @@ export class BVHBuilder {
493
443
  depth,
494
444
  reportProgress: !! progressCallback,
495
445
  sharedReorderBuffer,
496
- treeletOptimization: {
497
- enabled: this.enableTreeletOptimization,
498
- size: this.treeletSize,
499
- passes: this.treeletOptimizationPasses,
500
- minImprovement: this.treeletMinImprovement
501
- },
502
446
  reinsertionOptimization: {
503
447
  enabled: this.enableReinsertionOptimization,
504
448
  batchSizeRatio: this.reinsertionBatchSizeRatio,
@@ -571,10 +515,6 @@ export class BVHBuilder {
571
515
  totalSplitAttempts: 0,
572
516
  mortonSortTime: 0,
573
517
  totalBuildTime: 0,
574
- treeletOptimizationTime: 0,
575
- treeletsProcessed: 0,
576
- treeletsImproved: 0,
577
- averageSAHImprovement: 0,
578
518
  reinsertionOptimizationTime: 0,
579
519
  reinsertionsApplied: 0,
580
520
  reinsertionIterations: 0,
@@ -608,58 +548,7 @@ export class BVHBuilder {
608
548
  const root = this.buildNodeRecursive( 0, n, depth, progressCallback );
609
549
  this.splitStats.sahBuildTime = performance.now() - sahStart;
610
550
 
611
- // Phase 4: Treelet optimization
612
- if ( this.enableTreeletOptimization && this.totalTriangles > 1000 ) {
613
-
614
- const isLargeScene = this.totalTriangles > this.treeletComplexityThreshold;
615
- const adaptiveTreeletSize = isLargeScene ? 3 : this.treeletSize;
616
-
617
- const optimizer = new TreeletOptimizer( this.traversalCost, this.intersectionCost );
618
- optimizer.setTreeletSize( adaptiveTreeletSize );
619
- optimizer.setMinImprovement( this.treeletMinImprovement );
620
-
621
- const optimizationStartTime = performance.now();
622
-
623
- for ( let pass = 0; pass < this.treeletOptimizationPasses; pass ++ ) {
624
-
625
- const passCallback = progressCallback ? ( status ) => {
626
-
627
- progressCallback( `Treelet optimization pass ${pass + 1}/${this.treeletOptimizationPasses}: ${status}` );
628
-
629
- } : null;
630
-
631
- try {
632
-
633
- optimizer.optimizeBVH( root, passCallback );
634
-
635
- } catch ( error ) {
636
-
637
- log.error( `treelet optimizer failed in pass ${pass + 1}:`, error );
638
- break;
639
-
640
- }
641
-
642
- // optimizeBVH resets stats internally, so afterStats reflects this pass only
643
- const afterStats = optimizer.getStatistics();
644
- const passTime = performance.now() - optimizationStartTime;
645
- if ( ( afterStats.treeletsImproved === 0 && pass > 0 ) || passTime > 15000 ) {
646
-
647
- break;
648
-
649
- }
650
-
651
- }
652
-
653
- const treeletTime = performance.now() - optimizationStartTime;
654
- this.splitStats.treeletOptimizationTime = treeletTime;
655
- const treeletStats = optimizer.getStatistics();
656
- this.splitStats.treeletsProcessed = treeletStats.treeletsProcessed;
657
- this.splitStats.treeletsImproved = treeletStats.treeletsImproved;
658
- this.splitStats.averageSAHImprovement = treeletStats.averageSAHImprovement;
659
-
660
- }
661
-
662
- // Phase 4b: Reinsertion optimization (Meister & Bittner)
551
+ // Phase 4: Reinsertion optimization (Meister & Bittner)
663
552
  if ( this.enableReinsertionOptimization && this.totalTriangles > 1000 ) {
664
553
 
665
554
  const reinsertionOptimizer = new ReinsertionOptimizer( this.traversalCost, this.intersectionCost );
@@ -728,7 +617,6 @@ export class BVHBuilder {
728
617
  log.debug(
729
618
  `${fmt.n( n )} tris → ${fmt.n( this.totalNodes )} nodes in ${fmt.ms( total )}` +
730
619
  ` | SAH ${s.sahSplits} objMed ${s.objectMedianSplits} spatMed ${s.spatialMedianSplits} failed ${s.failedSplits}` +
731
- ( s.treeletsProcessed ? ` | treelets ${s.treeletsImproved}/${s.treeletsProcessed} improved` : '' ) +
732
620
  ( s.reinsertionsApplied ? ` | reinsertions ${s.reinsertionsApplied}` : '' )
733
621
  );
734
622
 
@@ -1598,9 +1486,9 @@ export class BVHBuilder {
1598
1486
  // Inner: [leftMin.xyz, leftChild] [leftMax.xyz, rightChild] [rightMin.xyz, 0] [rightMax.xyz, 0]
1599
1487
  // Leaf: [triOffset, triCount, 0, -1] [0,0,0,0] [0,0,0,0] [0,0,0,0]
1600
1488
  const FLOATS_PER_NODE = 16;
1601
- assertFits( nodes.length, 'BLAS node count' );
1489
+ assertBVHIndexFits( nodes.length, 'BLAS node count' );
1602
1490
  const data = new Float32Array( nodes.length * FLOATS_PER_NODE );
1603
- const idx = indexView( data );
1491
+ const idx = bvhIndexView( data );
1604
1492
 
1605
1493
  for ( let i = 0; i < nodes.length; i ++ ) {
1606
1494
 
@@ -1672,10 +1560,10 @@ export class BVHBuilder {
1672
1560
  }
1673
1561
 
1674
1562
  // Second pass: write flat data
1675
- assertFits( nodes.length, 'BLAS node count' );
1563
+ assertBVHIndexFits( nodes.length, 'BLAS node count' );
1676
1564
  const data = new Float32Array( nodes.length * FLOATS_PER_NODE );
1677
1565
  const frontierMap = [];
1678
- const idx = indexView( data );
1566
+ const idx = bvhIndexView( data );
1679
1567
 
1680
1568
  for ( let i = 0; i < nodes.length; i ++ ) {
1681
1569
 
@@ -1754,9 +1642,9 @@ export class BVHBuilder {
1754
1642
  }
1755
1643
 
1756
1644
  // Allocate final array
1757
- assertFits( totalNodes, 'assembled BLAS node count' );
1645
+ assertBVHIndexFits( totalNodes, 'assembled BLAS node count' );
1758
1646
  const finalData = new Float32Array( totalNodes * FLOATS_PER_NODE );
1759
- const finalIdx = indexView( finalData );
1647
+ const finalIdx = bvhIndexView( finalData );
1760
1648
 
1761
1649
  // Copy top-level data
1762
1650
  finalData.set( topFlatData );
@@ -1,12 +1,10 @@
1
- // Inline copies of EngineDefaults' BVH_LEAF_MARKERS.TRIANGLE_LEAF, BVH_MAX_INDEX and
2
- // BVH_FOLDED_LEAF_MAX: this runs in the BVH workers, which cannot import it. Keep in step.
3
- const TRIANGLE_LEAF = 0x40000000;
4
- const BVH_MAX_INDEX = 0x40000000;
5
- const BVH_FOLDED_LEAF_MAX = 15;
1
+ import { BVH_LEAF_MARKERS, BVH_MAX_INDEX, BVH_FOLDED_LEAF_MAX } from './BufferLayout.js';
2
+
3
+ const TRIANGLE_LEAF = BVH_LEAF_MARKERS.TRIANGLE_LEAF;
6
4
  const FLOATS_PER_NODE = 16;
7
5
  const FOLDED = 0x80000000;
8
6
 
9
- /** A folded leaf as its parent stores it (EngineDefaults: BVH_FOLDED_LEAF_MAX). */
7
+ /** A folded leaf as its parent stores it (see BVH_FOLDED_LEAF_MAX). */
10
8
  export const foldedRef = ( first, count ) => ( ~ ( ( first << 4 ) | count ) ) >>> 0;
11
9
  export const isFoldedRef = ref => ref >= FOLDED;
12
10
  export const foldedFirst = ref => ( ( ~ ref ) >>> 0 ) >>> 4;
@@ -10,18 +10,7 @@
10
10
  */
11
11
 
12
12
  import { isFoldedRef, foldedFirst, foldedCount } from './BVHLeafFold.js';
13
-
14
- // Inline copy of layout constants (source of truth: EngineDefaults.js).
15
- // Cannot import because this runs inside Web Workers where window is not defined.
16
- const TRIANGLE_DATA_LAYOUT = {
17
- FLOATS_PER_TRIANGLE: 20,
18
- POSITION_A_OFFSET: 0,
19
- POSITION_B_OFFSET: 4,
20
- POSITION_C_OFFSET: 8,
21
- NORMAL_A_PACKED_OFFSET: 3,
22
- NORMAL_B_PACKED_OFFSET: 7,
23
- NORMAL_C_PACKED_OFFSET: 11,
24
- };
13
+ import { TRIANGLE_DATA_LAYOUT, packNormalOct, BVH_LEAF_MARKERS } from './BufferLayout.js';
25
14
 
26
15
  const FPT = TRIANGLE_DATA_LAYOUT.FLOATS_PER_TRIANGLE;
27
16
 
@@ -62,41 +51,9 @@ const triAccess = ( triangleData ) => {
62
51
 
63
52
  };
64
53
 
65
- // Octahedral snorm16 pair, matching packNormalOct in EngineDefaults (not importable here).
66
- function packNormalOct( x, y, z ) {
67
-
68
- const len = Math.sqrt( x * x + y * y + z * z );
69
- if ( len > 0 ) {
70
-
71
- x /= len; y /= len; z /= len;
72
-
73
- } else {
74
-
75
- x = 0; y = 0; z = 1;
76
-
77
- }
78
-
79
- const sum = Math.abs( x ) + Math.abs( y ) + Math.abs( z );
80
- let u = x / sum, v = y / sum;
81
- if ( z < 0 ) {
82
-
83
- const au = u, av = v;
84
- u = ( 1 - Math.abs( av ) ) * ( au >= 0 ? 1 : - 1 );
85
- v = ( 1 - Math.abs( au ) ) * ( av >= 0 ? 1 : - 1 );
86
-
87
- }
88
-
89
- const qu = Math.round( Math.min( 1, Math.max( - 1, u ) ) * 32767 ) & 0xffff;
90
- const qv = Math.round( Math.min( 1, Math.max( - 1, v ) ) * 32767 ) & 0xffff;
91
- return ( ( qv << 16 ) | qu ) >>> 0;
92
-
93
- }
94
-
95
54
  const FLOATS_PER_NODE = 16; // 4 vec4s per BVH node
96
- // Inline copies of EngineDefaults.BVH_LEAF_MARKERS — this module also runs inside a worker.
97
- // Index fields are u32 BIT PATTERNS (exact past 2^24), read through `indexView`.
98
- const LEAF_MARKER = 0x40000000;
99
- const BLAS_POINTER_MARKER = 0x40000001;
55
+ const LEAF_MARKER = BVH_LEAF_MARKERS.TRIANGLE_LEAF;
56
+ const BLAS_POINTER_MARKER = BVH_LEAF_MARKERS.BLAS_POINTER_LEAF;
100
57
 
101
58
  // Relative to the matrix's own magnitude, never an absolute floor — see transformBoundsToWorld.
102
59
  const SINGULAR_REL_EPS = 1e-12;
@@ -194,6 +151,29 @@ function triangleBounds( acc, first, count, out, off ) {
194
151
 
195
152
  const folded = new Float32Array( 12 );
196
153
 
154
+ /** A node's own box from what it stores — its two child boxes, or a leaf's triangles — into out[ 0 .. 6 ). */
155
+ function storedBounds( nodes, n, acc, out ) {
156
+
157
+ const f = nodeF( nodes, n );
158
+ const idx = nodeIdx( nodes, n );
159
+ const o = nodeBase( nodes, n );
160
+
161
+ if ( idx[ o + 3 ] === LEAF_MARKER ) {
162
+
163
+ triangleBounds( acc, idx[ o ], idx[ o + 1 ], out, 0 );
164
+ return;
165
+
166
+ }
167
+
168
+ for ( let a = 0; a < 3; a ++ ) {
169
+
170
+ out[ a ] = Math.min( f[ o + a ], f[ o + 8 + a ] );
171
+ out[ 3 + a ] = Math.max( f[ o + 4 + a ], f[ o + 12 + a ] );
172
+
173
+ }
174
+
175
+ }
176
+
197
177
  /**
198
178
  * One node of a bottom-up refit: its own bounds into `bounds[ ( i - base ) * 6 ]`, and an inner
199
179
  * node's two child boxes rewritten from theirs. A leaf folded into its parent takes its box from
@@ -264,6 +244,8 @@ export class BVHRefitter {
264
244
  // Resized only when nodeCount changes (i.e., new scene loaded).
265
245
  this._bounds = null;
266
246
  this._boundsNodeCount = 0;
247
+ this._tlasBounds = null;
248
+ this._rootBox = null;
267
249
 
268
250
  }
269
251
 
@@ -355,6 +337,45 @@ export class BVHRefitter {
355
337
 
356
338
  }
357
339
 
340
+ /**
341
+ * Refit the given BLAS node ranges, then the TLAS from every BLAS root's stored box. The same
342
+ * nodes as refit() when every other BLAS is as the last refit left it.
343
+ *
344
+ * @param {Float32Array} bvhData - Combined BVH array (TLAS + all BLASes)
345
+ * @param {Uint32Array} triangleData - Global triangle records
346
+ * @param {ArrayLike<number>} blasRanges - flat [ startNode, nodeCount, ... ]
347
+ * @param {number} tlasNodeCount - the TLAS occupies nodes [0, tlasNodeCount)
348
+ */
349
+ refitPartial( bvhData, triangleData, blasRanges, tlasNodeCount ) {
350
+
351
+ for ( let r = 0; r < blasRanges.length; r += 2 ) this.refitRange( bvhData, triangleData, blasRanges[ r ], blasRanges[ r + 1 ] );
352
+
353
+ const acc = triAccess( triangleData );
354
+ const nodes = nodeAccess( bvhData );
355
+ if ( ! this._tlasBounds || this._tlasBounds.length < tlasNodeCount * 6 ) this._tlasBounds = new Float32Array( tlasNodeCount * 6 );
356
+ const bounds = this._tlasBounds;
357
+ const rootBox = this._rootBox ||= new Float32Array( 6 );
358
+
359
+ for ( let i = tlasNodeCount - 1; i >= 0; i -- ) {
360
+
361
+ const idx = nodeIdx( nodes, i );
362
+ const o = nodeBase( nodes, i );
363
+
364
+ if ( idx[ o + 3 ] === BLAS_POINTER_MARKER ) {
365
+
366
+ storedBounds( nodes, idx[ o ], acc, rootBox );
367
+ transformBoundsToWorld( nodeF( nodes, i ), o, rootBox, 0, bounds, i * 6 );
368
+
369
+ } else {
370
+
371
+ refitNode( nodes, i, acc, bounds, 0 );
372
+
373
+ }
374
+
375
+ }
376
+
377
+ }
378
+
358
379
  /**
359
380
  * Bottom-up refit of all BVH node AABBs.
360
381
  * Reverse pre-order iteration gives valid bottom-up order (children have higher