rayzee 5.10.2 → 5.11.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 +4 -1
- package/dist/rayzee.es.js +69 -43
- package/dist/rayzee.es.js.map +1 -1
- package/dist/rayzee.umd.js +2 -2
- package/dist/rayzee.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/PathTracerApp.js +9 -2
- package/src/Processor/TextureCreator.js +42 -15
- package/src/managers/OverlayManager.js +14 -2
package/package.json
CHANGED
package/src/PathTracerApp.js
CHANGED
|
@@ -65,7 +65,10 @@ export class PathTracerApp extends EventDispatcher {
|
|
|
65
65
|
* @param {Object} [options] - Engine options
|
|
66
66
|
* @param {boolean} [options.autoResize=true] - Automatically listen for window resize events
|
|
67
67
|
* @param {boolean} [options.showStats=true] - Show the performance stats panel
|
|
68
|
-
* @param {HTMLElement} [options.
|
|
68
|
+
* @param {HTMLElement} [options.container] - Single DOM parent the engine mounts all auxiliary
|
|
69
|
+
* elements into (HUD overlay, denoiser canvas, stats). Defaults to `canvas.parentNode`.
|
|
70
|
+
* @param {HTMLElement} [options.statsContainer] - Override mount target for the stats panel only.
|
|
71
|
+
* Defaults to `options.container`.
|
|
69
72
|
*/
|
|
70
73
|
constructor( canvas, options = {} ) {
|
|
71
74
|
|
|
@@ -86,6 +89,7 @@ export class PathTracerApp extends EventDispatcher {
|
|
|
86
89
|
this.canvas = canvas;
|
|
87
90
|
this._autoResize = options.autoResize !== false;
|
|
88
91
|
this._showStats = options.showStats !== false;
|
|
92
|
+
this._container = options.container || null;
|
|
89
93
|
this._statsContainer = options.statsContainer || null;
|
|
90
94
|
|
|
91
95
|
// ── Settings (single source of truth for all render parameters) ──
|
|
@@ -1550,7 +1554,7 @@ export class PathTracerApp extends EventDispatcher {
|
|
|
1550
1554
|
|
|
1551
1555
|
_initStats() {
|
|
1552
1556
|
|
|
1553
|
-
const container = this._statsContainer || this.canvas.parentElement || document.body;
|
|
1557
|
+
const container = this._statsContainer || this._container || this.canvas.parentElement || document.body;
|
|
1554
1558
|
this._stats = createStats( this.renderer, container );
|
|
1555
1559
|
|
|
1556
1560
|
}
|
|
@@ -1592,6 +1596,9 @@ export class PathTracerApp extends EventDispatcher {
|
|
|
1592
1596
|
renderHeight: this.denoisingManager?._lastRenderHeight || this.canvas.clientHeight || 1,
|
|
1593
1597
|
} );
|
|
1594
1598
|
|
|
1599
|
+
this._container = this._container || this.canvas.parentNode || null;
|
|
1600
|
+
this.overlayManager.mount( this._container );
|
|
1601
|
+
|
|
1595
1602
|
}
|
|
1596
1603
|
|
|
1597
1604
|
|
|
@@ -351,7 +351,8 @@ class TextureCache {
|
|
|
351
351
|
const width = texture.image.width || 0;
|
|
352
352
|
const height = texture.image.height || 0;
|
|
353
353
|
const src = texture.image.src || texture.uuid || '';
|
|
354
|
-
|
|
354
|
+
const flipFlag = texture.flipY === false ? 'n' : 'f';
|
|
355
|
+
hash += `${width}x${height}_${src.slice( - 8 )}_${flipFlag}_`;
|
|
355
356
|
|
|
356
357
|
}
|
|
357
358
|
|
|
@@ -681,12 +682,16 @@ export class TextureCreator {
|
|
|
681
682
|
|
|
682
683
|
if ( ! texture?.image ) continue;
|
|
683
684
|
|
|
685
|
+
const flipY = texture.flipY !== false;
|
|
686
|
+
|
|
684
687
|
try {
|
|
685
688
|
|
|
686
689
|
// Option 1: Direct ImageBitmap transfer (when supported)
|
|
687
690
|
if ( typeof createImageBitmap !== 'undefined' && texture.image instanceof HTMLImageElement ) {
|
|
688
691
|
|
|
689
|
-
const bitmap = await createImageBitmap( texture.image
|
|
692
|
+
const bitmap = await createImageBitmap( texture.image, {
|
|
693
|
+
imageOrientation: flipY ? 'flipY' : 'none',
|
|
694
|
+
} );
|
|
690
695
|
texturesData.push( {
|
|
691
696
|
bitmap: bitmap,
|
|
692
697
|
width: texture.image.width,
|
|
@@ -696,16 +701,22 @@ export class TextureCreator {
|
|
|
696
701
|
|
|
697
702
|
} else { // Option 2: Efficient canvas-based transfer
|
|
698
703
|
|
|
699
|
-
const
|
|
704
|
+
const w = texture.image.width;
|
|
705
|
+
const h = texture.image.height;
|
|
706
|
+
const bitmap = await createImageBitmap( texture.image, {
|
|
707
|
+
imageOrientation: flipY ? 'flipY' : 'none',
|
|
708
|
+
} );
|
|
709
|
+
const pair = this.canvasPool.getCanvasWithContext( w, h );
|
|
700
710
|
|
|
701
|
-
pair.context.drawImage(
|
|
702
|
-
|
|
711
|
+
pair.context.drawImage( bitmap, 0, 0 );
|
|
712
|
+
bitmap.close();
|
|
713
|
+
const imageData = pair.context.getImageData( 0, 0, w, h );
|
|
703
714
|
|
|
704
715
|
// Transfer the underlying ArrayBuffer directly
|
|
705
716
|
texturesData.push( {
|
|
706
717
|
data: imageData.data.buffer, // Direct buffer transfer
|
|
707
|
-
width:
|
|
708
|
-
height:
|
|
718
|
+
width: w,
|
|
719
|
+
height: h,
|
|
709
720
|
isImageData: true
|
|
710
721
|
} );
|
|
711
722
|
|
|
@@ -759,11 +770,13 @@ export class TextureCreator {
|
|
|
759
770
|
for ( let i = batchStart; i < batchEnd; i ++ ) {
|
|
760
771
|
|
|
761
772
|
const texture = validTextures[ i ];
|
|
773
|
+
const flipY = texture.flipY !== false;
|
|
762
774
|
|
|
763
775
|
const bitmapPromise = createImageBitmap( texture.image, {
|
|
764
776
|
resizeWidth: maxWidth,
|
|
765
777
|
resizeHeight: maxHeight,
|
|
766
|
-
resizeQuality: 'high'
|
|
778
|
+
resizeQuality: 'high',
|
|
779
|
+
imageOrientation: flipY ? 'flipY' : 'none',
|
|
767
780
|
} );
|
|
768
781
|
|
|
769
782
|
batchPromises.push(
|
|
@@ -815,9 +828,16 @@ export class TextureCreator {
|
|
|
815
828
|
for ( let i = 0; i < validTextures.length; i ++ ) {
|
|
816
829
|
|
|
817
830
|
const texture = validTextures[ i ];
|
|
831
|
+
const bitmap = await createImageBitmap( texture.image, {
|
|
832
|
+
resizeWidth: maxWidth,
|
|
833
|
+
resizeHeight: maxHeight,
|
|
834
|
+
resizeQuality: 'high',
|
|
835
|
+
imageOrientation: texture.flipY !== false ? 'flipY' : 'none',
|
|
836
|
+
} );
|
|
818
837
|
|
|
819
838
|
pair.context.clearRect( 0, 0, maxWidth, maxHeight );
|
|
820
|
-
pair.context.drawImage(
|
|
839
|
+
pair.context.drawImage( bitmap, 0, 0 );
|
|
840
|
+
bitmap.close();
|
|
821
841
|
|
|
822
842
|
const imageData = pair.context.getImageData( 0, 0, maxWidth, maxHeight );
|
|
823
843
|
const offset = maxWidth * maxHeight * 4 * i;
|
|
@@ -853,9 +873,16 @@ export class TextureCreator {
|
|
|
853
873
|
for ( let i = 0; i < validTextures.length; i ++ ) {
|
|
854
874
|
|
|
855
875
|
const texture = validTextures[ i ];
|
|
876
|
+
const bitmap = await createImageBitmap( texture.image, {
|
|
877
|
+
resizeWidth: maxWidth,
|
|
878
|
+
resizeHeight: maxHeight,
|
|
879
|
+
resizeQuality: 'high',
|
|
880
|
+
imageOrientation: texture.flipY !== false ? 'flipY' : 'none',
|
|
881
|
+
} );
|
|
856
882
|
|
|
857
883
|
pair.context.clearRect( 0, 0, maxWidth, maxHeight );
|
|
858
|
-
pair.context.drawImage(
|
|
884
|
+
pair.context.drawImage( bitmap, 0, 0 );
|
|
885
|
+
bitmap.close();
|
|
859
886
|
|
|
860
887
|
const imageData = pair.context.getImageData( 0, 0, maxWidth, maxHeight );
|
|
861
888
|
const offset = maxWidth * maxHeight * 4 * i;
|
|
@@ -1301,7 +1328,7 @@ export class TextureCreator {
|
|
|
1301
1328
|
const mip = tex.mipmaps[ 0 ];
|
|
1302
1329
|
const idx = normalized.length;
|
|
1303
1330
|
normalized.push( null ); // placeholder — filled after Promise.all
|
|
1304
|
-
bitmapJobs.push( { index: idx, promise: _rawPixelsToBitmap( mip.data, mip.width, mip.height ) } );
|
|
1331
|
+
bitmapJobs.push( { index: idx, flipY: tex.flipY, promise: _rawPixelsToBitmap( mip.data, mip.width, mip.height ) } );
|
|
1305
1332
|
continue;
|
|
1306
1333
|
|
|
1307
1334
|
}
|
|
@@ -1323,7 +1350,7 @@ export class TextureCreator {
|
|
|
1323
1350
|
|
|
1324
1351
|
const idx = normalized.length;
|
|
1325
1352
|
normalized.push( null );
|
|
1326
|
-
bitmapJobs.push( { index: idx, promise: _rawPixelsToBitmap( tex.image.data, tex.image.width, tex.image.height ) } );
|
|
1353
|
+
bitmapJobs.push( { index: idx, flipY: tex.flipY, promise: _rawPixelsToBitmap( tex.image.data, tex.image.width, tex.image.height ) } );
|
|
1327
1354
|
continue;
|
|
1328
1355
|
|
|
1329
1356
|
}
|
|
@@ -1339,14 +1366,14 @@ export class TextureCreator {
|
|
|
1339
1366
|
|
|
1340
1367
|
for ( let i = 0; i < bitmapJobs.length; i ++ ) {
|
|
1341
1368
|
|
|
1342
|
-
const { index } = bitmapJobs[ i ];
|
|
1369
|
+
const { index, flipY } = bitmapJobs[ i ];
|
|
1343
1370
|
const result = results[ i ];
|
|
1344
1371
|
|
|
1345
1372
|
if ( result.status === 'fulfilled' ) {
|
|
1346
1373
|
|
|
1347
1374
|
const bitmap = result.value;
|
|
1348
1375
|
bitmapsToClose.push( bitmap );
|
|
1349
|
-
normalized[ index ] = { image: bitmap };
|
|
1376
|
+
normalized[ index ] = { image: bitmap, flipY };
|
|
1350
1377
|
|
|
1351
1378
|
} else {
|
|
1352
1379
|
|
|
@@ -1367,7 +1394,7 @@ export class TextureCreator {
|
|
|
1367
1394
|
const placeholder = new Uint8ClampedArray( [ 255, 255, 255, 255 ] );
|
|
1368
1395
|
const bitmap = await createImageBitmap( new ImageData( placeholder, 1, 1 ) );
|
|
1369
1396
|
bitmapsToClose.push( bitmap );
|
|
1370
|
-
normalized[ i ] = { image: bitmap };
|
|
1397
|
+
normalized[ i ] = { image: bitmap, flipY: false };
|
|
1371
1398
|
|
|
1372
1399
|
}
|
|
1373
1400
|
|
|
@@ -57,8 +57,8 @@ export class OverlayManager {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
|
-
* Returns the HUD canvas element.
|
|
61
|
-
*
|
|
60
|
+
* Returns the HUD canvas element. Normally mounted automatically by
|
|
61
|
+
* {@link PathTracerApp}; exposed for advanced clients that mount it manually.
|
|
62
62
|
* @returns {HTMLCanvasElement}
|
|
63
63
|
*/
|
|
64
64
|
getHUDCanvas() {
|
|
@@ -67,6 +67,18 @@ export class OverlayManager {
|
|
|
67
67
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Mounts the HUD canvas into the given container. Idempotent — safe to call
|
|
72
|
+
* multiple times; re-mounts only when the parent differs.
|
|
73
|
+
* @param {HTMLElement} container
|
|
74
|
+
*/
|
|
75
|
+
mount( container ) {
|
|
76
|
+
|
|
77
|
+
if ( ! container || this._hudCanvas.parentElement === container ) return;
|
|
78
|
+
container.appendChild( this._hudCanvas );
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
70
82
|
// ═══════════════════════════════════════════════════════════════
|
|
71
83
|
// Default helpers setup
|
|
72
84
|
// ═══════════════════════════════════════════════════════════════
|