rayzee 9.0.0 → 9.1.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/README.md +139 -8
- package/dist/{NeuralRetouch-CYOJ21Wn.js → NeuralRetouch-BRquqfmZ.js} +1 -1
- package/dist/{NeuralSuperRes-CQLCLpcC.js → NeuralSuperRes-CbNvQjCw.js} +3 -2
- package/dist/{ToneMapGPU-BVE852iN.js → ToneMapGPU-DpUZDMbQ.js} +2 -1
- package/dist/rayzee.es.js +10353 -5337
- package/dist/rayzee.umd.js +265 -265
- package/package.json +1 -1
- package/src/AssetConfig.js +4 -0
- package/src/EngineDefaults.js +38 -56
- package/src/EngineEvents.js +3 -0
- package/src/EngineIssues.js +6 -0
- package/src/Headless.js +3 -1
- package/src/Passes/AIUpscaler.js +2 -1
- package/src/Passes/OIDNDenoiser.js +3 -6
- package/src/PathTracerApp.js +290 -19
- package/src/Processor/ArchiveCache.js +120 -0
- package/src/Processor/ArchiveReader.js +179 -32
- package/src/Processor/AssetLoader.js +514 -76
- package/src/Processor/AtmosphereModel.js +465 -0
- package/src/Processor/BVHBuilder.js +4 -1
- package/src/Processor/BVHLeafFold.js +100 -0
- package/src/Processor/BVHRefitter.js +98 -214
- package/src/Processor/ChunkedRecords.js +189 -4
- package/src/Processor/EmissiveTriangleBuilder.js +8 -0
- package/src/Processor/GeometryExtractor.js +238 -40
- package/src/Processor/InstanceTable.js +55 -37
- package/src/Processor/KernelManager.js +4 -1
- package/src/Processor/PBRT/PBRTCurves.js +104 -27
- package/src/Processor/PBRT/PBRTParser.js +132 -22
- package/src/Processor/PBRT/PBRTSceneBuilder.js +192 -49
- package/src/Processor/PBRT/buffers.js +27 -0
- package/src/Processor/PBRT/index.js +55 -15
- package/src/Processor/PackedRayBuffer.js +10 -13
- package/src/Processor/ParallelBVHBuilder.js +36 -15
- package/src/Processor/PhysicalSky.js +308 -0
- package/src/Processor/QueueManager.js +1 -0
- package/src/Processor/SceneProcessor.js +1132 -181
- package/src/Processor/SplitBLAS.js +249 -0
- package/src/Processor/SunPosition.js +41 -0
- package/src/Processor/TextureCreator.js +21 -0
- package/src/Processor/Workers/AIUpscalerWorker.js +79 -52
- package/src/Processor/Workers/BVHWorker.js +17 -13
- package/src/Processor/ZipReader.js +207 -0
- package/src/RenderSettings.js +38 -0
- package/src/SceneState/SceneState.js +367 -0
- package/src/SceneState/portable.js +52 -0
- package/src/Stages/NormalDepth.js +7 -6
- package/src/Stages/PathTracer.js +108 -4
- package/src/Stages/PathTracerStage.js +251 -104
- package/src/Storage/BLASCache.js +190 -0
- package/src/Storage/CDFCache.js +77 -0
- package/src/Storage/DownloadCache.js +266 -0
- package/src/Storage/GeometrySpill.js +217 -0
- package/src/Storage/SceneGraphCodec.js +503 -0
- package/src/Storage/SpillStore.js +112 -0
- package/src/Storage/StorageManager.js +934 -0
- package/src/Storage/StorageOps.js +137 -0
- package/src/Storage/StorageWorker.js +37 -0
- package/src/Storage/events.js +29 -0
- package/src/Storage/identity.js +77 -0
- package/src/Storage/index.js +9 -0
- package/src/Storage/inlineTransport.js +24 -0
- package/src/Storage/locks.js +99 -0
- package/src/Storage/openStorage.js +87 -0
- package/src/Storage/sceneCachePolicy.js +12 -0
- package/src/Storage/shared.js +9 -0
- package/src/Storage/transport.js +62 -0
- package/src/TSL/Atmosphere.js +684 -0
- package/src/TSL/BVHTraversal.js +288 -239
- package/src/TSL/Common.js +11 -2
- package/src/TSL/Displacement.js +6 -6
- package/src/TSL/EmissiveSampling.js +5 -5
- package/src/TSL/EnvironmentCDF.js +176 -0
- package/src/TSL/GenerateKernel.js +3 -3
- package/src/TSL/HitFacet.js +4 -4
- package/src/TSL/LightsDirect.js +8 -8
- package/src/TSL/LightsSampling.js +55 -37
- package/src/TSL/Random.js +1 -0
- package/src/TSL/ShadeKernel.js +75 -19
- package/src/TSL/Sun.js +40 -0
- package/src/TSL/TextureSampling.js +6 -7
- package/src/index.js +18 -0
- package/src/managers/CameraManager.js +169 -1
- package/src/managers/EnvironmentManager.js +263 -33
- package/src/managers/GoboManager.js +19 -8
- package/src/managers/IESManager.js +3 -3
- package/src/managers/LightManager.js +98 -5
- package/src/managers/MaterialDataManager.js +22 -2
- package/src/managers/TransformManager.js +26 -0
- package/src/managers/UniformManager.js +5 -3
- package/src/managers/VideoRenderManager.js +3 -1
- package/src/managers/timeline/CameraTrack.js +22 -0
- package/src/managers/timeline/TimelineManager.js +14 -0
- package/src/version.js +3 -0
- package/src/Processor/ProceduralSky.js +0 -291
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Streaming reader for .tar.gz / .tgz / .tar archives.
|
|
3
3
|
*
|
|
4
|
-
* ZIP is random-access
|
|
4
|
+
* ZIP is random-access (see ZipReader.js), but a gzipped tar is a
|
|
5
5
|
* single compressed stream: the only way to reach the last entry is to decompress
|
|
6
6
|
* everything before it. Holding that in memory is not an option — the pbrt-v4 Moana
|
|
7
7
|
* archive is 5.9 GB compressed and 29 GB unpacked — so entries are decoded one at a
|
|
@@ -97,6 +97,38 @@ function paxPath( bytes ) {
|
|
|
97
97
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
const paddedSize = size => size + ( ( BLOCK - ( size % BLOCK ) ) % BLOCK );
|
|
101
|
+
|
|
102
|
+
const isSpecialType = type => type === 'L' || type === 'x' || type === 'X';
|
|
103
|
+
|
|
104
|
+
function parseHeader( h ) {
|
|
105
|
+
|
|
106
|
+
const prefix = fieldString( h, 345, 155 );
|
|
107
|
+
const raw = fieldString( h, 0, 100 );
|
|
108
|
+
return {
|
|
109
|
+
type: String.fromCharCode( h[ 156 ] || 0x30 ),
|
|
110
|
+
size: fieldNumber( h, 124, 12 ),
|
|
111
|
+
name: prefix ? `${prefix}/${raw}` : raw,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Normalised path of a regular file entry, or null for directories, links and the rest. */
|
|
117
|
+
function regularPath( type, name ) {
|
|
118
|
+
|
|
119
|
+
if ( type === '5' || type === 'g' || type === 'K' || name.endsWith( '/' ) ) return null;
|
|
120
|
+
if ( type !== '0' && type !== ' ' ) return null;
|
|
121
|
+
return normalizeTarPath( name ) || null;
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function isZeroBlock( h ) {
|
|
126
|
+
|
|
127
|
+
for ( let i = 0; i < BLOCK; i ++ ) if ( h[ i ] !== 0 ) return false;
|
|
128
|
+
return true;
|
|
129
|
+
|
|
130
|
+
}
|
|
131
|
+
|
|
100
132
|
/**
|
|
101
133
|
* Pull-free tar parser: chunks are pushed in as they decompress, and entry bodies are
|
|
102
134
|
* copied straight out of them so a skipped entry never allocates.
|
|
@@ -150,8 +182,8 @@ class TarStream {
|
|
|
150
182
|
if ( this._headerLen === BLOCK ) {
|
|
151
183
|
|
|
152
184
|
this._headerLen = 0;
|
|
153
|
-
this._readHeader();
|
|
154
185
|
this._bodyStart = base + i; // body begins right after the header block
|
|
186
|
+
this._readHeader();
|
|
155
187
|
|
|
156
188
|
}
|
|
157
189
|
|
|
@@ -210,21 +242,19 @@ class TarStream {
|
|
|
210
242
|
|
|
211
243
|
}
|
|
212
244
|
|
|
213
|
-
const type
|
|
214
|
-
const
|
|
215
|
-
const prefix = fieldString( h, 345, 155 );
|
|
216
|
-
const raw = fieldString( h, 0, 100 );
|
|
217
|
-
const name = this._pendingName ?? ( prefix ? `${prefix}/${raw}` : raw );
|
|
245
|
+
const { type, size, name: headerName } = parseHeader( h );
|
|
246
|
+
const name = this._pendingName ?? headerName;
|
|
218
247
|
this._pendingName = null;
|
|
219
248
|
|
|
220
249
|
this._size = size;
|
|
221
250
|
this._copied = 0;
|
|
222
|
-
this._remaining =
|
|
251
|
+
this._remaining = paddedSize( size );
|
|
223
252
|
this._dst = null;
|
|
224
253
|
this._special = null;
|
|
254
|
+
this._indexed = false;
|
|
225
255
|
this._state = this._remaining > 0 ? 'body' : 'header';
|
|
226
256
|
|
|
227
|
-
if (
|
|
257
|
+
if ( isSpecialType( type ) ) {
|
|
228
258
|
|
|
229
259
|
this._special = type === 'L' ? 'longname' : 'pax';
|
|
230
260
|
this._dst = new Uint8Array( size );
|
|
@@ -232,30 +262,29 @@ class TarStream {
|
|
|
232
262
|
|
|
233
263
|
}
|
|
234
264
|
|
|
235
|
-
|
|
236
|
-
if ( type !== '0' && type !== ' ' ) return;
|
|
237
|
-
|
|
238
|
-
const path = normalizeTarPath( name );
|
|
265
|
+
const path = regularPath( type, name );
|
|
239
266
|
if ( ! path ) return;
|
|
240
267
|
|
|
241
268
|
this.listing.push( { path, size } );
|
|
269
|
+
this._indexed = this.filter ? this.filter( path, size ) : true;
|
|
242
270
|
|
|
243
|
-
|
|
244
|
-
if ( ! wanted ) return;
|
|
271
|
+
if ( this._indexed && ! ( this.retain && ! this.retain( path, size ) ) ) {
|
|
245
272
|
|
|
246
|
-
|
|
273
|
+
if ( this.retainedBytes + size > this.byteBudget ) {
|
|
247
274
|
|
|
248
|
-
|
|
275
|
+
this.truncated = true;
|
|
249
276
|
|
|
250
|
-
|
|
277
|
+
} else {
|
|
251
278
|
|
|
252
|
-
|
|
253
|
-
|
|
279
|
+
this._dst = new Uint8Array( size );
|
|
280
|
+
this.retainedBytes += size;
|
|
281
|
+
|
|
282
|
+
}
|
|
254
283
|
|
|
255
284
|
}
|
|
256
285
|
|
|
257
|
-
|
|
258
|
-
this.
|
|
286
|
+
// An empty file has no body block, so nothing else would finish it.
|
|
287
|
+
if ( this._remaining === 0 ) this._endBody();
|
|
259
288
|
|
|
260
289
|
}
|
|
261
290
|
|
|
@@ -399,23 +428,132 @@ export async function readTarGz( source, options = {} ) {
|
|
|
399
428
|
|
|
400
429
|
}
|
|
401
430
|
|
|
431
|
+
const WINDOW_BYTES = 1 << 20;
|
|
432
|
+
|
|
402
433
|
/**
|
|
403
|
-
*
|
|
404
|
-
*
|
|
434
|
+
* Lists every regular file of a seekable .tar with its body offset, reading only the headers:
|
|
435
|
+
* each entry's body is skipped by seeking, so a 7 GB archive of large files costs a few
|
|
436
|
+
* thousand small reads instead of a full pass.
|
|
437
|
+
* @param {Blob|File} source
|
|
438
|
+
* @returns {Promise<Array<{path:string, size:number, offset:number}>>}
|
|
439
|
+
*/
|
|
440
|
+
export async function indexTarHeaders( source, { onProgress = null } = {} ) {
|
|
441
|
+
|
|
442
|
+
const size = source.size;
|
|
443
|
+
const listing = [];
|
|
444
|
+
let window = null;
|
|
445
|
+
let windowStart = 0;
|
|
446
|
+
let pendingName = null;
|
|
447
|
+
let pos = 0;
|
|
448
|
+
let nextReport = 0;
|
|
449
|
+
|
|
450
|
+
const bytesAt = async ( at, n ) => {
|
|
451
|
+
|
|
452
|
+
if ( window && at >= windowStart && at + n <= windowStart + window.length ) {
|
|
453
|
+
|
|
454
|
+
return window.subarray( at - windowStart, at - windowStart + n );
|
|
455
|
+
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const end = Math.min( size, at + Math.max( n, WINDOW_BYTES ) );
|
|
459
|
+
window = new Uint8Array( await source.slice( at, end ).arrayBuffer() );
|
|
460
|
+
windowStart = at;
|
|
461
|
+
return window.subarray( 0, n );
|
|
462
|
+
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
while ( pos + BLOCK <= size ) {
|
|
466
|
+
|
|
467
|
+
const h = await bytesAt( pos, BLOCK );
|
|
468
|
+
if ( isZeroBlock( h ) ) break;
|
|
469
|
+
|
|
470
|
+
const { type, size: bodySize, name: headerName } = parseHeader( h );
|
|
471
|
+
const name = pendingName ?? headerName;
|
|
472
|
+
pendingName = null;
|
|
473
|
+
const bodyStart = pos + BLOCK;
|
|
474
|
+
|
|
475
|
+
if ( isSpecialType( type ) ) {
|
|
476
|
+
|
|
477
|
+
const body = await bytesAt( bodyStart, bodySize );
|
|
478
|
+
pendingName = type === 'L' ? fieldString( body, 0, body.length ) : paxPath( body );
|
|
479
|
+
|
|
480
|
+
} else {
|
|
481
|
+
|
|
482
|
+
const path = regularPath( type, name );
|
|
483
|
+
if ( path ) listing.push( { path, size: bodySize, offset: bodyStart } );
|
|
484
|
+
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
pos = bodyStart + paddedSize( bodySize );
|
|
488
|
+
|
|
489
|
+
if ( onProgress && pos >= nextReport ) {
|
|
490
|
+
|
|
491
|
+
nextReport = pos + ( 256 << 20 );
|
|
492
|
+
onProgress( { entries: listing.length, bytes: pos } );
|
|
493
|
+
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return listing;
|
|
499
|
+
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Indexes a tar stream as it goes by — for writing a decompressing archive to disk and knowing
|
|
504
|
+
* where every entry landed without a second pass.
|
|
505
|
+
*/
|
|
506
|
+
export function createTarIndexer() {
|
|
507
|
+
|
|
508
|
+
const tar = new TarStream( { retain: () => false } );
|
|
509
|
+
return {
|
|
510
|
+
push: chunk => tar.push( chunk ),
|
|
511
|
+
finish: () => {
|
|
512
|
+
|
|
513
|
+
tar.end();
|
|
514
|
+
return tar.listing.filter( e => e.offset !== undefined );
|
|
515
|
+
|
|
516
|
+
},
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* A seekable view over an uncompressed .tar: entries are indexed and read back on demand from
|
|
523
|
+
* the source, so the archive is never resident.
|
|
405
524
|
*
|
|
406
|
-
* Only for `.tar` over a Blob/File — a gzip stream cannot be seeked
|
|
407
|
-
* whole by fflate.
|
|
525
|
+
* Only for `.tar` over a Blob/File — a gzip stream cannot be seeked.
|
|
408
526
|
*
|
|
409
527
|
* @param {Blob|File} source
|
|
410
528
|
* @param {object} [options] - `filter` and `retain` as in readTar
|
|
411
|
-
* @
|
|
529
|
+
* @param {{listing: Array}} [options.index] - a saved index (`result.index`): skips the walk
|
|
530
|
+
* @param {boolean} [options.headersOnly] - index by seeking between headers; nothing is retained
|
|
531
|
+
* @returns {Promise<{entries, listing, read: (path:string)=>Promise<Uint8Array|null>, truncated,
|
|
532
|
+
* index: ?{v:number, listing:Array}}>}
|
|
412
533
|
*/
|
|
413
534
|
export async function openTar( source, options = {} ) {
|
|
414
535
|
|
|
415
|
-
const
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
536
|
+
const { index = null, headersOnly = false, onProgress = null, ...streamOptions } = options;
|
|
537
|
+
|
|
538
|
+
let entries, listing, retainedBytes, truncated, full = null;
|
|
539
|
+
|
|
540
|
+
if ( index || headersOnly ) {
|
|
541
|
+
|
|
542
|
+
full = index?.listing ?? await indexTarHeaders( source, { onProgress } );
|
|
543
|
+
const { filter } = streamOptions;
|
|
544
|
+
listing = full.map( e => ( ! filter || filter( e.path, e.size ) ? { ...e } : { path: e.path, size: e.size } ) );
|
|
545
|
+
entries = Object.create( null );
|
|
546
|
+
retainedBytes = 0;
|
|
547
|
+
truncated = false;
|
|
548
|
+
|
|
549
|
+
} else {
|
|
550
|
+
|
|
551
|
+
const tar = new TarStream( { ...streamOptions } );
|
|
552
|
+
await forEachSlice( source, slice => tar.push( slice ) );
|
|
553
|
+
tar.end();
|
|
554
|
+
( { entries, listing, retainedBytes, truncated } = tar.result() );
|
|
555
|
+
|
|
556
|
+
}
|
|
419
557
|
|
|
420
558
|
const byPath = new Map();
|
|
421
559
|
for ( const e of listing ) if ( e.offset !== undefined ) byPath.set( e.path, e );
|
|
@@ -429,7 +567,16 @@ export async function openTar( source, options = {} ) {
|
|
|
429
567
|
|
|
430
568
|
};
|
|
431
569
|
|
|
432
|
-
|
|
570
|
+
const readHead = async ( path, bytes ) => {
|
|
571
|
+
|
|
572
|
+
if ( entries[ path ] ) return entries[ path ].subarray( 0, bytes );
|
|
573
|
+
const e = byPath.get( path );
|
|
574
|
+
if ( ! e ) return null;
|
|
575
|
+
return new Uint8Array( await source.slice( e.offset, e.offset + Math.min( e.size, bytes ) ).arrayBuffer() );
|
|
576
|
+
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
return { entries, listing, read, readHead, retainedBytes, truncated, indexed: byPath.size, index: full ? { v: 1, listing: full } : null };
|
|
433
580
|
|
|
434
581
|
}
|
|
435
582
|
|