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.
- package/README.md +252 -44
- package/dist/ActiveColor-YvuQq44O.js +13 -0
- package/dist/ArchiveImporter-BRQvLggb.js +4300 -0
- package/dist/AssetConfig-DSEntE65.js +30 -0
- package/dist/BidirectionalIntegrator-9lZQxFVH.js +934 -0
- package/dist/BufferLayout-D_IBo2ci.js +150 -0
- package/dist/ColorManagement-oeEk7oSu.js +1488 -0
- package/dist/EngineEvents-Ci8dVWCP.js +73 -0
- package/dist/EngineIssues-CIZnXHsF.js +72 -0
- package/dist/FileFormats-sPGJeCRc.js +102 -0
- package/dist/Logger-dDDGj9Av.js +97 -0
- package/dist/{NeuralRetouch-CYgkQY8Z.js → NeuralRetouch-BCXylThH.js} +8 -6
- package/dist/{NeuralSuperRes-PkgDLQcD.js → NeuralSuperRes-sZAeS142.js} +55 -120
- package/dist/PathTracer-CQPW06Mm.js +29971 -0
- package/dist/PhysicalSky-BvqCw_dy.js +1219 -0
- package/dist/RayzeeRenderer-COpwotpU.js +3551 -0
- package/dist/SolarLimb-CPaeZVwz.js +721 -0
- package/dist/ToneMapGPU-CjU3osDd.js +177 -0
- package/dist/ViewTransforms-CYN7bq2w.js +255 -0
- package/dist/WorkingMatrix-C6y233hT.js +27 -0
- package/dist/ZipReader-gDSWr0I5.js +98 -0
- package/dist/addons/archives.es.js +3 -0
- package/dist/addons/bidirectional.es.js +2 -0
- package/dist/addons/color.es.js +3 -0
- package/dist/addons/formats.es.js +2 -0
- package/dist/addons/physical-sky.es.js +2 -0
- package/dist/addons/storage.es.js +3 -0
- package/dist/archiveFormats-BZw7TiDp.js +75 -0
- package/dist/identity-DrQsGT2o.js +39 -0
- package/dist/openStorage-DwcBRUj7.js +820 -0
- package/dist/rayzee-core.es.js +12 -0
- package/dist/rayzee.es.js +2551 -44024
- package/dist/rayzee.umd.js +528 -487
- package/dist/sceneCachePolicy-BSSsKY98.js +443 -0
- package/dist/shared-BGBcSxBQ.js +17 -0
- package/package.json +23 -2
- package/src/Color/ActiveColor.js +34 -0
- package/src/Color/BasicColor.js +147 -0
- package/src/Color/ColorManagement.js +7 -31
- package/src/Color/ViewTransforms.js +5 -1
- package/src/EngineDefaults.js +62 -1029
- package/src/EngineEvents.js +2 -0
- package/src/EngineIssues.js +2 -0
- package/src/Headless.js +6 -5
- package/src/Passes/AIUpscaler.js +58 -141
- package/src/Passes/OIDNDenoiser.js +92 -65
- package/src/Passes/OIDNTemporalHistory.js +1 -1
- package/src/PathTracerApp.js +620 -4026
- package/src/Pipeline/PipelineContext.js +0 -4
- package/src/Platform.js +36 -0
- package/src/Processor/ArchiveCache.js +1 -1
- package/src/Processor/ArchiveImporter.js +1259 -0
- package/src/Processor/AssetLoader.js +327 -1763
- package/src/Processor/AtmosphereModel.js +1 -2
- package/src/Processor/BVHBuilder.js +14 -126
- package/src/Processor/BVHLeafFold.js +4 -6
- package/src/Processor/BVHRefitter.js +67 -46
- package/src/Processor/BufferLayout.js +291 -0
- package/src/Processor/EmissiveTriangleBuilder.js +1 -1
- package/src/Processor/EnvironmentExactTable.js +187 -0
- package/src/Processor/EquirectHDRInfo.js +30 -223
- package/src/Processor/FileFormats.js +116 -0
- package/src/Processor/GLTFDecoders.js +85 -0
- package/src/Processor/GLTFDiffuseTransmission.js +63 -0
- package/src/Processor/GeometryExtractor.js +15 -5
- package/src/Processor/HostMemory.js +7 -1
- package/src/Processor/IESParser.js +47 -35
- package/src/Processor/InstanceTable.js +1 -1
- package/src/Processor/KernelManager.js +35 -2
- package/src/Processor/MaterialPacking.js +10 -8
- package/src/Processor/PBRT/PBRTMaterials.js +129 -41
- package/src/Processor/PBRT/PBRTParser.js +30 -17
- package/src/Processor/PBRT/PBRTSceneBuilder.js +548 -37
- package/src/Processor/PBRT/PBRTTextureBake.js +154 -0
- package/src/Processor/PBRT/PFM.js +59 -0
- package/src/Processor/PackedRayBuffer.js +116 -9
- package/src/Processor/ParallelBVHBuilder.js +3 -6
- package/src/Processor/PhysicalSky.js +5 -4
- package/src/Processor/PlatformImageLoader.js +50 -6
- package/src/Processor/QueueManager.js +39 -5
- package/src/Processor/ReinsertionOptimizer.js +2 -2
- package/src/Processor/SceneProcessor.js +53 -62
- package/src/Processor/ShaderBuilder.js +6 -16
- package/src/Processor/SimpleSky.js +1 -62
- package/src/Processor/SolarLimb.js +3 -0
- package/src/Processor/SplitBLAS.js +1 -1
- package/src/Processor/StorageTexturePool.js +22 -1
- package/src/Processor/TLASBuilder.js +1 -3
- package/src/Processor/TextureBuckets.js +237 -0
- package/src/Processor/TextureCreator.js +181 -8
- package/src/Processor/ToneMapGPU.js +64 -15
- package/src/Processor/Workers/BVHRefitWorker.js +5 -2
- package/src/Processor/Workers/BVHSubtreeWorker.js +1 -34
- package/src/Processor/Workers/BVHWorker.js +5 -18
- package/src/Processor/Workers/CDFWorker.js +6 -183
- package/src/Processor/Workers/TexturesWorker.js +103 -18
- package/src/Processor/archiveFormats.js +7 -0
- package/src/Processor/utils.js +2 -1
- package/src/RayzeeRenderer.js +3899 -0
- package/src/RenderSettings.js +68 -62
- package/src/Stages/ASVGF.js +13 -14
- package/src/Stages/AutoExposure.js +17 -17
- package/src/Stages/BilateralFilter.js +2 -1
- package/src/Stages/Compositor.js +8 -23
- package/src/Stages/DenoiserSettings.js +182 -0
- package/src/Stages/EdgeFilter.js +2 -1
- package/src/Stages/MotionVector.js +1 -1
- package/src/Stages/NRD.js +11 -5
- package/src/Stages/NormalDepth.js +12 -8
- package/src/Stages/PathTracer.js +338 -43
- package/src/Stages/PathTracerStage.js +69 -66
- package/src/Stages/Variance.js +1 -1
- package/src/Storage/BLASCache.js +1 -1
- package/src/Storage/CDFCache.js +18 -17
- package/src/Storage/DownloadCache.js +1 -1
- package/src/Storage/SceneGraphCodec.js +46 -3
- package/src/Storage/SpillStore.js +1 -1
- package/src/Storage/StorageManager.js +45 -9
- package/src/Storage/areas.js +4 -0
- package/src/TSL/BVHTraversal.js +50 -25
- package/src/TSL/Bidirectional.js +204 -0
- package/src/TSL/BidirectionalLamps.js +132 -0
- package/src/TSL/Clearcoat.js +15 -6
- package/src/TSL/Common.js +20 -15
- package/src/TSL/ConnectKernel.js +147 -0
- package/src/TSL/Debugger.js +1 -1
- package/src/TSL/Displacement.js +4 -3
- package/src/TSL/EmissiveSampling.js +65 -18
- package/src/TSL/Environment.js +77 -106
- package/src/TSL/EnvironmentCDF.js +85 -39
- package/src/TSL/ExtendKernel.js +8 -3
- package/src/TSL/FinalWriteKernel.js +4 -4
- package/src/TSL/GenerateKernel.js +18 -4
- package/src/TSL/HitFacet.js +35 -5
- package/src/TSL/LightBVHSampling.js +40 -9
- package/src/TSL/LightGenerateKernel.js +293 -0
- package/src/TSL/LightGuide.js +198 -0
- package/src/TSL/LightSplatKernel.js +165 -0
- package/src/TSL/LightVisibility.js +111 -0
- package/src/TSL/LightsCore.js +13 -38
- package/src/TSL/LightsDirect.js +28 -29
- package/src/TSL/LightsIndirect.js +3 -1
- package/src/TSL/LightsSampling.js +239 -51
- package/src/TSL/MaterialEvaluation.js +113 -31
- package/src/TSL/MaterialProperties.js +44 -17
- package/src/TSL/MaterialTransmission.js +52 -47
- package/src/TSL/MergeKernel.js +218 -0
- package/src/TSL/PathTracerCore.js +65 -29
- package/src/TSL/Random.js +5 -1
- package/src/TSL/SceneResources.js +51 -0
- package/src/TSL/ShadeKernel.js +964 -101
- package/src/TSL/Struct.js +10 -0
- package/src/TSL/Sun.js +1 -1
- package/src/TSL/TextureSampling.js +66 -61
- package/src/addons/archives.js +14 -0
- package/src/addons/bidirectional.js +13 -0
- package/src/addons/color.js +32 -0
- package/src/addons/formats.js +16 -0
- package/src/addons/physicalSky.js +14 -0
- package/src/addons/storage.js +19 -0
- package/src/core.js +31 -0
- package/src/index.js +13 -23
- package/src/integrators/BidirectionalIntegrator.js +833 -0
- package/src/managers/AnimationManager.js +88 -6
- package/src/managers/CameraManager.js +103 -46
- package/src/managers/DenoisingManager.js +14 -10
- package/src/managers/EnvironmentManager.js +125 -103
- package/src/managers/GoboManager.js +9 -0
- package/src/managers/MaterialDataManager.js +48 -37
- package/src/managers/UniformManager.js +32 -10
- package/dist/ToneMapGPU-B6XIe3DU.js +0 -544
- package/dist/rolldown-runtime-CAFD8bLK.js +0 -11
- package/src/Processor/TreeletOptimizer.js +0 -574
|
@@ -311,8 +311,7 @@ function transmittanceSpectrum( coefficients, depth ) {
|
|
|
311
311
|
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
-
|
|
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)
|
|
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
|
-
|
|
11
|
-
|
|
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,
|
|
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 (
|
|
412
|
+
if ( splitStats ) {
|
|
463
413
|
|
|
464
|
-
this.splitStats =
|
|
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:
|
|
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
|
-
|
|
1489
|
+
assertBVHIndexFits( nodes.length, 'BLAS node count' );
|
|
1602
1490
|
const data = new Float32Array( nodes.length * FLOATS_PER_NODE );
|
|
1603
|
-
const idx =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
1645
|
+
assertBVHIndexFits( totalNodes, 'assembled BLAS node count' );
|
|
1758
1646
|
const finalData = new Float32Array( totalNodes * FLOATS_PER_NODE );
|
|
1759
|
-
const finalIdx =
|
|
1647
|
+
const finalIdx = bvhIndexView( finalData );
|
|
1760
1648
|
|
|
1761
1649
|
// Copy top-level data
|
|
1762
1650
|
finalData.set( topFlatData );
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const TRIANGLE_LEAF =
|
|
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 (
|
|
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
|
-
|
|
97
|
-
|
|
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
|