rayzee 11.3.0 → 11.4.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 +33 -5
- package/dist/{ArchiveImporter-D735xX-4.js → ArchiveImporter-Cgyx5AF7.js} +2 -2
- package/dist/{BidirectionalIntegrator-M89c0AlP.js → BidirectionalIntegrator-BKF-cwH2.js} +2 -2
- package/dist/{NeuralRetouch-DiBH63kz.js → NeuralRetouch-C3Q2XqbF.js} +4 -3
- package/dist/{NeuralSuperRes-CZNQP13W.js → NeuralSuperRes-DV5TtURP.js} +11 -5
- package/dist/{PathTracer-BXCCVrPK.js → PathTracer-D3MvEaZK.js} +19 -12
- package/dist/{PhysicalSky-DqmaS0lb.js → PhysicalSky-CY4jiz6a.js} +1 -1
- package/dist/{RayzeeRenderer-DUSMFhmc.js → RayzeeRenderer-D23m6NqG.js} +313 -281
- package/dist/{ToneMapGPU-BOjpul7A.js → ToneMapGPU-CTDBvmmS.js} +31 -22
- package/dist/addons/archives.es.js +1 -1
- package/dist/addons/bidirectional.es.js +1 -1
- package/dist/addons/physical-sky.es.js +1 -1
- package/dist/rayzee-core.es.js +3 -3
- package/dist/rayzee.es.js +1343 -858
- package/dist/rayzee.umd.js +124 -113
- package/dist/{sceneCachePolicy-BAib5fCp.js → sceneCachePolicy-AKOEu2lf.js} +1 -1
- package/package.json +1 -1
- package/src/EngineDefaults.js +2 -2
- package/src/Passes/AIUpscaler.js +2 -0
- package/src/PathTracerApp.js +122 -16
- package/src/Pipeline/CompletionTracker.js +7 -3
- package/src/Processor/ToneMapCPU.js +16 -4
- package/src/Processor/ToneMapGPU.js +30 -14
- package/src/RayzeeRenderer.js +54 -7
- package/src/RenderSettings.js +4 -2
- package/src/Stages/AutoExposure.js +484 -494
- package/src/Stages/Compositor.js +27 -6
- package/src/Stages/LocalExposure.js +546 -0
- package/src/Stages/PathTracer.js +6 -4
- package/src/Stages/PathTracerStage.js +9 -7
- package/src/index.js +1 -0
- package/src/managers/DenoisingManager.js +11 -15
- package/src/managers/VideoRenderManager.js +30 -4
- package/src/neural/NeuralRetouch.js +1 -0
- package/src/neural/NeuralSuperRes.js +6 -1
|
@@ -104,9 +104,10 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
104
104
|
* @param {import('../Pipeline/RenderPipeline.js').RenderPipeline} params.pipeline
|
|
105
105
|
* @param {Function} params.getExposure - () => current exposure value
|
|
106
106
|
* @param {Function} params.getSaturation - () => current saturation value
|
|
107
|
+
* @param {Function} [params.getDisplayGain] - () => the shown picture's per-pixel gain (PackedToneMapper `gain`)
|
|
107
108
|
* @param {import('../EngineIssues.js').IssueLog} [params.issues]
|
|
108
109
|
*/
|
|
109
|
-
constructor( { renderer, mainCanvas, stages, pipeline, getExposure, getSaturation, issues = null } ) {
|
|
110
|
+
constructor( { renderer, mainCanvas, stages, pipeline, getExposure, getSaturation, getDisplayGain = null, issues = null } ) {
|
|
110
111
|
|
|
111
112
|
super();
|
|
112
113
|
|
|
@@ -121,6 +122,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
121
122
|
|
|
122
123
|
this._getExposure = getExposure;
|
|
123
124
|
this._getSaturation = getSaturation;
|
|
125
|
+
this._getDisplayGain = getDisplayGain;
|
|
124
126
|
|
|
125
127
|
this.denoiser = null;
|
|
126
128
|
this.upscaler = null;
|
|
@@ -409,6 +411,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
409
411
|
getExposure: () => this._getEffectiveExposure(),
|
|
410
412
|
getToneMapping: () => this._getToneMapping(),
|
|
411
413
|
getSaturation: () => this._getSaturation(),
|
|
414
|
+
getDisplayGain: () => this._getDisplayGain?.() ?? null,
|
|
412
415
|
} );
|
|
413
416
|
|
|
414
417
|
this.upscaler.enabled = DENOISER_DEFAULTS.enableUpscaler || false;
|
|
@@ -546,21 +549,11 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
546
549
|
|
|
547
550
|
/**
|
|
548
551
|
* @param {boolean} enabled
|
|
549
|
-
* @param {number} manualExposure -
|
|
552
|
+
* @param {number} manualExposure - the compensation while on, the exposure again once off
|
|
550
553
|
*/
|
|
551
554
|
setAutoExposureEnabled( enabled, manualExposure ) {
|
|
552
555
|
|
|
553
|
-
|
|
554
|
-
if ( ! s.autoExposure ) return;
|
|
555
|
-
|
|
556
|
-
s.autoExposure.enabled = enabled;
|
|
557
|
-
|
|
558
|
-
// AutoExposure overwrites renderer.toneMappingExposure each frame; restore manual on disable.
|
|
559
|
-
if ( ! enabled && this.renderer ) {
|
|
560
|
-
|
|
561
|
-
this.renderer.toneMappingExposure = manualExposure;
|
|
562
|
-
|
|
563
|
-
}
|
|
556
|
+
this._stages.autoExposure?.setEnabled( enabled, manualExposure );
|
|
564
557
|
|
|
565
558
|
}
|
|
566
559
|
|
|
@@ -1246,6 +1239,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1246
1239
|
exposure: this._getEffectiveExposure(),
|
|
1247
1240
|
toneMapping: this._getToneMapping(),
|
|
1248
1241
|
saturation: this._getSaturation?.() ?? 1,
|
|
1242
|
+
gain: this._getDisplayGain?.() ?? null,
|
|
1249
1243
|
};
|
|
1250
1244
|
|
|
1251
1245
|
// Scene-referred throughout. Exposure reaches the detail pass through its own `paper_white`
|
|
@@ -1561,6 +1555,9 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1561
1555
|
this._onReset = null;
|
|
1562
1556
|
this._onPostProcessRefresh = null;
|
|
1563
1557
|
this._onDisplayRefresh = null;
|
|
1558
|
+
this._getExposure = null;
|
|
1559
|
+
this._getSaturation = null;
|
|
1560
|
+
this._getDisplayGain = null;
|
|
1564
1561
|
this._issues = null;
|
|
1565
1562
|
|
|
1566
1563
|
if ( this.upscalerCanvas?.parentNode ) {
|
|
@@ -1764,13 +1761,12 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1764
1761
|
// ── Convenience (match DenoisingAPI names with reset) ────────
|
|
1765
1762
|
|
|
1766
1763
|
/**
|
|
1767
|
-
* Enables or disables auto-exposure
|
|
1764
|
+
* Enables or disables auto-exposure. A finished render is metered as it stands, not restarted.
|
|
1768
1765
|
* @param {boolean} enabled
|
|
1769
1766
|
*/
|
|
1770
1767
|
setAutoExposure( enabled ) {
|
|
1771
1768
|
|
|
1772
1769
|
this.setAutoExposureEnabled( enabled, this._getExposure() );
|
|
1773
|
-
this._onReset?.();
|
|
1774
1770
|
|
|
1775
1771
|
}
|
|
1776
1772
|
|
|
@@ -87,8 +87,13 @@ export class VideoRenderManager {
|
|
|
87
87
|
// Configure for high-quality offline rendering
|
|
88
88
|
app.configureForMode( 'production' );
|
|
89
89
|
|
|
90
|
-
//
|
|
91
|
-
app.
|
|
90
|
+
// Auto exposure adapts in video time, once a frame, not to each pass's wall clock.
|
|
91
|
+
const autoExposure = app.stages.autoExposure?.enabled ? app.stages.autoExposure : null;
|
|
92
|
+
if ( autoExposure ) autoExposure.instant = false;
|
|
93
|
+
|
|
94
|
+
// Override samples per frame. 'frames': this loop never checks the deadline, so a 'timeOnly'
|
|
95
|
+
// ceiling of Infinity would never finish a frame.
|
|
96
|
+
app.settings.setMany( { maxSamples: samplesPerFrame, renderLimitMode: 'frames' }, { silent: true, reset: false } );
|
|
92
97
|
app.stages.pathTracer?.updateCompletionThreshold?.();
|
|
93
98
|
|
|
94
99
|
// Disable camera controls during render
|
|
@@ -131,11 +136,23 @@ export class VideoRenderManager {
|
|
|
131
136
|
// kill it immediately so it doesn't race with our manual render loop
|
|
132
137
|
app.stopAnimation();
|
|
133
138
|
|
|
139
|
+
// Before accumulating: the stage meters as it goes, and a reading of this frame's view filed under the last
|
|
140
|
+
// one read as a scene change, moving the room the whole way each frame.
|
|
141
|
+
if ( autoExposure ) app._noteExposureView();
|
|
142
|
+
|
|
134
143
|
// 3. Accumulate samples until convergence
|
|
135
144
|
await this._accumulateFrame( app );
|
|
136
145
|
|
|
137
146
|
if ( this._cancelled ) break;
|
|
138
147
|
|
|
148
|
+
if ( autoExposure ) {
|
|
149
|
+
|
|
150
|
+
await autoExposure.meter( app.pipeline.context );
|
|
151
|
+
autoExposure.advance( i === Math.max( 0, startFrame ) ? Infinity : frameDuration );
|
|
152
|
+
app._presentDisplay();
|
|
153
|
+
|
|
154
|
+
}
|
|
155
|
+
|
|
139
156
|
// 4. Denoise if enabled
|
|
140
157
|
if ( enableOIDN && app.denoisingManager?.finalDenoise ) {
|
|
141
158
|
|
|
@@ -298,17 +315,19 @@ export class VideoRenderManager {
|
|
|
298
315
|
|
|
299
316
|
const app = this._app;
|
|
300
317
|
const effective = app.settings.getEffective();
|
|
301
|
-
const keys = Object.keys( modePresetSettings( PRODUCTION_RENDER_CONFIG ) );
|
|
318
|
+
const keys = [ ...Object.keys( modePresetSettings( PRODUCTION_RENDER_CONFIG ) ), 'renderLimitMode' ];
|
|
302
319
|
if ( view ) keys.push( 'focusDistance' );
|
|
303
320
|
|
|
304
321
|
return {
|
|
305
322
|
view: view ? app.cameraManager.captureView() : null,
|
|
306
|
-
// Everything configureForMode( 'production' )
|
|
323
|
+
// Everything configureForMode( 'production' ) and the export overwrite, with who set it.
|
|
307
324
|
settings: keys.map( key => [ key, effective[ key ] ] ),
|
|
308
325
|
renderMode: app.stages.pathTracer?.renderMode?.value,
|
|
309
326
|
controlsEnabled: app.cameraManager.controls?.enabled,
|
|
310
327
|
oidnEnabled: app.denoisingManager?.finalDenoise,
|
|
311
328
|
oidnQuality: app.denoisingManager?.oidnQuality,
|
|
329
|
+
instantExposure: app.stages.autoExposure?.instant,
|
|
330
|
+
holdExposureSamples: app.stages.autoExposure?.holdSamples,
|
|
312
331
|
wasPlaying: app.animationManager?.isPlaying,
|
|
313
332
|
pauseRendering: app.pauseRendering,
|
|
314
333
|
};
|
|
@@ -347,6 +366,13 @@ export class VideoRenderManager {
|
|
|
347
366
|
}
|
|
348
367
|
|
|
349
368
|
app.pauseRendering = state.pauseRendering ?? false;
|
|
369
|
+
if ( app.stages.autoExposure ) {
|
|
370
|
+
|
|
371
|
+
app.stages.autoExposure.instant = state.instantExposure ?? false;
|
|
372
|
+
// configureForMode( 'production' ) set it, and nothing switches the mode back: left on, it froze the exposure while orbiting.
|
|
373
|
+
app.stages.autoExposure.holdSamples = state.holdExposureSamples ?? 0;
|
|
374
|
+
|
|
375
|
+
}
|
|
350
376
|
|
|
351
377
|
if ( state.view ) app.cameraManager.applyPose( state.view );
|
|
352
378
|
|
|
@@ -373,6 +373,7 @@ export class NeuralSuperRes {
|
|
|
373
373
|
exposure: tone.exposure ?? 1,
|
|
374
374
|
toneMapping: tone.toneMapping ?? 0,
|
|
375
375
|
saturation: tone.saturation ?? 1,
|
|
376
|
+
gain: tone.gain,
|
|
376
377
|
// The network emits its picture vertically flipped.
|
|
377
378
|
flipY: true,
|
|
378
379
|
} );
|
|
@@ -482,6 +483,7 @@ export async function renderUpscaled( app, {
|
|
|
482
483
|
width: pathTracer?.width,
|
|
483
484
|
height: pathTracer?.height,
|
|
484
485
|
maxSamples: app.settings?.get?.( 'maxSamples' ),
|
|
486
|
+
renderLimitMode: app.settings?.get?.( 'renderLimitMode' ),
|
|
485
487
|
finalDenoise: app.denoisingManager?.finalDenoise,
|
|
486
488
|
paused: app.pauseRendering,
|
|
487
489
|
};
|
|
@@ -512,7 +514,8 @@ export async function renderUpscaled( app, {
|
|
|
512
514
|
await new Promise( r => setTimeout( r, 300 ) );
|
|
513
515
|
|
|
514
516
|
app.denoisingManager.applyOIDNEnabled( true );
|
|
515
|
-
|
|
517
|
+
// 'frames': under 'timeOnly' the deadline, not `samples`, would end the render.
|
|
518
|
+
app.settings.setMany( { maxSamples: samples, renderLimitMode: 'frames' }, { reset: false } );
|
|
516
519
|
const done = waitForDenoise( app, samples, timeoutMs );
|
|
517
520
|
app.reset();
|
|
518
521
|
await done;
|
|
@@ -529,6 +532,7 @@ export async function renderUpscaled( app, {
|
|
|
529
532
|
exposure: app.renderer.toneMappingExposure,
|
|
530
533
|
toneMapping: app.renderer.toneMapping,
|
|
531
534
|
saturation: app.settings.get( 'saturation' ) ?? 1,
|
|
535
|
+
gain: app._displayGain?.() ?? null,
|
|
532
536
|
};
|
|
533
537
|
|
|
534
538
|
const { rgba8, width, height, ms, toneMs } = await sr.upscaleToRGBA8( source, tone );
|
|
@@ -550,6 +554,7 @@ export async function renderUpscaled( app, {
|
|
|
550
554
|
|
|
551
555
|
if ( restore.width && restore.height ) app.setCanvasSize( restore.width, restore.height );
|
|
552
556
|
if ( restore.maxSamples !== undefined ) app.settings?.set?.( 'maxSamples', restore.maxSamples );
|
|
557
|
+
if ( restore.renderLimitMode !== undefined ) app.settings?.set?.( 'renderLimitMode', restore.renderLimitMode, { reset: false } );
|
|
553
558
|
if ( restore.finalDenoise !== undefined ) app.denoisingManager?.applyOIDNEnabled( restore.finalDenoise );
|
|
554
559
|
app.pauseRendering = restore.paused;
|
|
555
560
|
|