rayzee 11.3.0 → 11.5.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-29Nl1567.js} +2 -2
- package/dist/{BidirectionalIntegrator-M89c0AlP.js → BidirectionalIntegrator-CJay8tXK.js} +2 -2
- package/dist/{NeuralRetouch-DiBH63kz.js → NeuralRetouch-KqGVPV7u.js} +4 -3
- package/dist/{NeuralSuperRes-CZNQP13W.js → NeuralSuperRes-BHxhYzlD.js} +11 -5
- package/dist/{PathTracer-BXCCVrPK.js → PathTracer-Cldt0mXi.js} +19 -12
- package/dist/{PhysicalSky-DqmaS0lb.js → PhysicalSky-CUWrTcmT.js} +1 -1
- package/dist/{RayzeeRenderer-DUSMFhmc.js → RayzeeRenderer-Dd-Dit0v.js} +313 -281
- package/dist/{ToneMapGPU-BOjpul7A.js → ToneMapGPU-sAs8wdgI.js} +44 -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 +1428 -902
- package/dist/rayzee.umd.js +124 -113
- package/dist/{sceneCachePolicy-BAib5fCp.js → sceneCachePolicy--ta6moJu.js} +1 -1
- package/package.json +1 -1
- package/src/EngineDefaults.js +2 -2
- package/src/Passes/AIUpscaler.js +17 -12
- 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 +49 -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 +569 -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 +93 -34
- package/src/managers/VideoRenderManager.js +30 -4
- package/src/neural/NeuralRetouch.js +1 -0
- package/src/neural/NeuralSuperRes.js +6 -1
package/src/index.js
CHANGED
|
@@ -68,6 +68,7 @@ export {
|
|
|
68
68
|
} from './Stages/DenoiserSettings.js';
|
|
69
69
|
export { SKY_DEFAULTS, DEFAULT_SUN_PATH } from './managers/EnvironmentManager.js';
|
|
70
70
|
export { AUTO_EXPOSURE_DEFAULTS } from './Stages/AutoExposure.js';
|
|
71
|
+
export { LOCAL_EXPOSURE_DEFAULTS } from './Stages/LocalExposure.js';
|
|
71
72
|
export { AUTO_FOCUS_DEFAULTS } from './managers/CameraManager.js';
|
|
72
73
|
export { TRIANGLE_DATA_LAYOUT, BVH_LEAF_MARKERS } from './Processor/BufferLayout.js';
|
|
73
74
|
export { sunPosition, timeForSunElevation, dayOfYearForMonth } from './Processor/SunPosition.js';
|
|
@@ -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;
|
|
@@ -135,6 +137,11 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
135
137
|
this._retouch = null;
|
|
136
138
|
this._superResModule = null;
|
|
137
139
|
this._neuralPostBusy = false;
|
|
140
|
+
// The finished render's post passes: its guard, the run in flight, a queued rerun, and a cancel.
|
|
141
|
+
this._postIsStillComplete = null;
|
|
142
|
+
this._postRun = null;
|
|
143
|
+
this._postRedo = null;
|
|
144
|
+
this._postCancelled = false;
|
|
138
145
|
|
|
139
146
|
// The tier the finished image uses. The loaded tier is not always this one: while the
|
|
140
147
|
// image is still accumulating we run a cheaper model (see previewQuality).
|
|
@@ -409,6 +416,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
409
416
|
getExposure: () => this._getEffectiveExposure(),
|
|
410
417
|
getToneMapping: () => this._getToneMapping(),
|
|
411
418
|
getSaturation: () => this._getSaturation(),
|
|
419
|
+
getDisplayGain: () => this._getDisplayGain?.() ?? null,
|
|
412
420
|
} );
|
|
413
421
|
|
|
414
422
|
this.upscaler.enabled = DENOISER_DEFAULTS.enableUpscaler || false;
|
|
@@ -546,21 +554,11 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
546
554
|
|
|
547
555
|
/**
|
|
548
556
|
* @param {boolean} enabled
|
|
549
|
-
* @param {number} manualExposure -
|
|
557
|
+
* @param {number} manualExposure - the compensation while on, the exposure again once off
|
|
550
558
|
*/
|
|
551
559
|
setAutoExposureEnabled( enabled, manualExposure ) {
|
|
552
560
|
|
|
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
|
-
}
|
|
561
|
+
this._stages.autoExposure?.setEnabled( enabled, manualExposure );
|
|
564
562
|
|
|
565
563
|
}
|
|
566
564
|
|
|
@@ -1155,6 +1153,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1155
1153
|
/** Turns the neural-rendering (detail) pass on or off, and sets its appearance controls. */
|
|
1156
1154
|
setNeuralRendering( enabled, settings = null ) {
|
|
1157
1155
|
|
|
1156
|
+
const changed = this.neuralRendering !== !! enabled;
|
|
1158
1157
|
this.neuralRendering = !! enabled;
|
|
1159
1158
|
if ( settings ) this.neuralRenderingSettings = { ...this.neuralRenderingSettings, ...settings };
|
|
1160
1159
|
if ( ! this.neuralRendering ) {
|
|
@@ -1164,6 +1163,8 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1164
1163
|
|
|
1165
1164
|
}
|
|
1166
1165
|
|
|
1166
|
+
if ( changed ) this._redoPostPasses();
|
|
1167
|
+
|
|
1167
1168
|
}
|
|
1168
1169
|
|
|
1169
1170
|
_releaseNeuralRetouch() {
|
|
@@ -1174,14 +1175,8 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1174
1175
|
}
|
|
1175
1176
|
|
|
1176
1177
|
/**
|
|
1177
|
-
* The
|
|
1178
|
-
*
|
|
1179
|
-
*
|
|
1180
|
-
* Order is forced by the models. Super resolution hands back light that can be fed onward; the
|
|
1181
|
-
* detail pass writes an `rgba8unorm` texture with no `COPY_SRC`, so nothing can read its result
|
|
1182
|
-
* and it has to be last — and it presents in its own display space rather than the engine's tone
|
|
1183
|
-
* curve. Which shape super resolution returns therefore depends on what follows it: packed
|
|
1184
|
-
* halves when the detail pass is next, display bytes when it is the end of the chain.
|
|
1178
|
+
* The post-chain over the picture the closing denoise just produced: the detail pass at render size,
|
|
1179
|
+
* then the chosen upscaler (neural super resolution or the ONNX one), either or both.
|
|
1185
1180
|
*
|
|
1186
1181
|
* Deliberately fire-and-forget: the render is already finished and a failure must not break it.
|
|
1187
1182
|
*/
|
|
@@ -1189,6 +1184,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1189
1184
|
|
|
1190
1185
|
const wantSR = this.upscaler?.enabled && this.upscalerBackend === 'neural';
|
|
1191
1186
|
const wantNR = this.neuralRendering;
|
|
1187
|
+
const wantESRGAN = this.upscaler?.enabled && ! wantSR;
|
|
1192
1188
|
if ( ! wantSR && ! wantNR ) return;
|
|
1193
1189
|
|
|
1194
1190
|
// A second completion can land while the first pass is still in flight — the models are
|
|
@@ -1237,7 +1233,12 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1237
1233
|
|
|
1238
1234
|
}
|
|
1239
1235
|
|
|
1240
|
-
if ( ! wantSR && ! runNR )
|
|
1236
|
+
if ( ! wantSR && ! runNR ) {
|
|
1237
|
+
|
|
1238
|
+
if ( wantESRGAN && ! this._postCancelled ) await this.upscaler.start();
|
|
1239
|
+
return;
|
|
1240
|
+
|
|
1241
|
+
}
|
|
1241
1242
|
|
|
1242
1243
|
// Must be the effective value, not the settings one: AutoExposure overwrites
|
|
1243
1244
|
// `renderer.toneMappingExposure` every frame and never touches settings, so reading
|
|
@@ -1246,6 +1247,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1246
1247
|
exposure: this._getEffectiveExposure(),
|
|
1247
1248
|
toneMapping: this._getToneMapping(),
|
|
1248
1249
|
saturation: this._getSaturation?.() ?? 1,
|
|
1250
|
+
gain: this._getDisplayGain?.() ?? null,
|
|
1249
1251
|
};
|
|
1250
1252
|
|
|
1251
1253
|
// Scene-referred throughout. Exposure reaches the detail pass through its own `paper_white`
|
|
@@ -1297,6 +1299,15 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1297
1299
|
|
|
1298
1300
|
}
|
|
1299
1301
|
|
|
1302
|
+
if ( this._postRedo || this._postCancelled ) return;
|
|
1303
|
+
|
|
1304
|
+
if ( wantESRGAN ) {
|
|
1305
|
+
|
|
1306
|
+
await this.upscaler.start( new ImageData( image.rgba8, image.width, image.height ) );
|
|
1307
|
+
return;
|
|
1308
|
+
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1300
1311
|
sr.presentRGBA8( this.upscalerCanvas, image.rgba8, image.width, image.height );
|
|
1301
1312
|
|
|
1302
1313
|
if ( ! isStillComplete() ) {
|
|
@@ -1366,10 +1377,61 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1366
1377
|
|
|
1367
1378
|
}
|
|
1368
1379
|
|
|
1380
|
+
/** The neural chain or the ONNX upscaler over the finished render, as the switches ask. */
|
|
1381
|
+
_runPostPasses( isStillComplete ) {
|
|
1382
|
+
|
|
1383
|
+
this._postIsStillComplete = isStillComplete;
|
|
1384
|
+
this._postCancelled = false;
|
|
1385
|
+
|
|
1386
|
+
// The neural chain owns the overlay canvas when it runs, and hands its result to the ONNX upscaler.
|
|
1387
|
+
if ( this.neuralRendering || ( this.upscaler?.enabled && this.upscalerBackend === 'neural' ) ) {
|
|
1388
|
+
|
|
1389
|
+
this._postRun = this._runNeuralPost( isStillComplete );
|
|
1390
|
+
|
|
1391
|
+
} else {
|
|
1392
|
+
|
|
1393
|
+
this._postRun = this.upscaler?.enabled ? this.upscaler.start() : null;
|
|
1394
|
+
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
/** Runs the post passes again on a finished render whose switches changed, once the run in flight ends. */
|
|
1400
|
+
_redoPostPasses() {
|
|
1401
|
+
|
|
1402
|
+
const isStillComplete = this._postIsStillComplete;
|
|
1403
|
+
// No chain yet: the closing denoise is still running and the chain reads the switches when it starts.
|
|
1404
|
+
if ( ! isStillComplete?.() || this._postRedo ) return;
|
|
1405
|
+
|
|
1406
|
+
this.upscaler?.abort();
|
|
1407
|
+
this._postCancelled = false;
|
|
1408
|
+
this._postRedo = Promise.resolve( this._postRun ).catch( () => {} ).then( () => {
|
|
1409
|
+
|
|
1410
|
+
this._postRedo = null;
|
|
1411
|
+
if ( this._postCancelled || this._postIsStillComplete !== isStillComplete || ! isStillComplete() ) return;
|
|
1412
|
+
this._restoreRenderDisplay();
|
|
1413
|
+
this._runPostPasses( isStillComplete );
|
|
1414
|
+
|
|
1415
|
+
} );
|
|
1416
|
+
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
/** Stops the post passes on the finished render, which stays on screen as rendered. The switches stay as they are. */
|
|
1420
|
+
cancelPostPasses() {
|
|
1421
|
+
|
|
1422
|
+
this._postCancelled = true;
|
|
1423
|
+
this.upscaler?.abort();
|
|
1424
|
+
this._restoreRenderDisplay();
|
|
1425
|
+
// A retouch in flight cannot be stopped, only discarded, and ends later.
|
|
1426
|
+
this.dispatchEvent( { type: EngineEvents.UPSCALING_END } );
|
|
1427
|
+
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1369
1430
|
onRenderComplete( { isStillComplete } ) {
|
|
1370
1431
|
|
|
1371
1432
|
// Remove any stale completion-chain listener from a previous render cycle
|
|
1372
1433
|
this._cleanupCompletionListener();
|
|
1434
|
+
this._postIsStillComplete = null;
|
|
1373
1435
|
|
|
1374
1436
|
// What closes the render, if anything. A full pass at the chosen tier when that switch is
|
|
1375
1437
|
// on; otherwise, if OIDN owns the live view, one last cheap refresh — the cadence's last
|
|
@@ -1389,16 +1451,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1389
1451
|
// denoise. Ordered after `_denoiserEndHandler`, which publishes the picture.
|
|
1390
1452
|
if ( closing ) this._onDisplayRefresh?.();
|
|
1391
1453
|
|
|
1392
|
-
|
|
1393
|
-
// exclusive. The neural chain also runs on its own when only its detail pass is on.
|
|
1394
|
-
if ( this.neuralRendering || ( this.upscaler?.enabled && this.upscalerBackend === 'neural' ) ) {
|
|
1395
|
-
|
|
1396
|
-
this._runNeuralPost( isStillComplete );
|
|
1397
|
-
return;
|
|
1398
|
-
|
|
1399
|
-
}
|
|
1400
|
-
|
|
1401
|
-
if ( this.upscaler?.enabled ) this.upscaler.start();
|
|
1454
|
+
this._runPostPasses( isStillComplete );
|
|
1402
1455
|
|
|
1403
1456
|
};
|
|
1404
1457
|
|
|
@@ -1473,6 +1526,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1473
1526
|
|
|
1474
1527
|
// Remove stale completion-chain listener before aborting
|
|
1475
1528
|
this._cleanupCompletionListener();
|
|
1529
|
+
this._postIsStillComplete = null;
|
|
1476
1530
|
|
|
1477
1531
|
// The 2D canvas is the upscaler's alone: a reset means its enlarged result no longer
|
|
1478
1532
|
// describes anything, so the render canvas comes back.
|
|
@@ -1515,6 +1569,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1515
1569
|
|
|
1516
1570
|
// Remove pending completion-chain listener
|
|
1517
1571
|
this._cleanupCompletionListener();
|
|
1572
|
+
this._postIsStillComplete = null;
|
|
1518
1573
|
// Owns a second GPUDevice plus 3 MB of weights, so it must not outlive the manager.
|
|
1519
1574
|
this._releaseNeuralUpscaler();
|
|
1520
1575
|
this._releaseNeuralRetouch();
|
|
@@ -1561,6 +1616,9 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1561
1616
|
this._onReset = null;
|
|
1562
1617
|
this._onPostProcessRefresh = null;
|
|
1563
1618
|
this._onDisplayRefresh = null;
|
|
1619
|
+
this._getExposure = null;
|
|
1620
|
+
this._getSaturation = null;
|
|
1621
|
+
this._getDisplayGain = null;
|
|
1564
1622
|
this._issues = null;
|
|
1565
1623
|
|
|
1566
1624
|
if ( this.upscalerCanvas?.parentNode ) {
|
|
@@ -1740,10 +1798,12 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1740
1798
|
/** Enables or disables the AI upscaler. */
|
|
1741
1799
|
setUpscalerEnabled( enabled ) {
|
|
1742
1800
|
|
|
1801
|
+
const changed = !! this.upscaler && this.upscaler.enabled !== !! enabled;
|
|
1743
1802
|
if ( this.upscaler ) this.upscaler.enabled = enabled;
|
|
1744
1803
|
else if ( enabled ) this._recordNoOverlayCanvas( 'upscaler' );
|
|
1745
1804
|
// The enlarged picture describes a setting that is no longer on.
|
|
1746
1805
|
if ( ! enabled ) this._restoreRenderDisplay();
|
|
1806
|
+
if ( changed ) this._redoPostPasses();
|
|
1747
1807
|
|
|
1748
1808
|
}
|
|
1749
1809
|
|
|
@@ -1764,13 +1824,12 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1764
1824
|
// ── Convenience (match DenoisingAPI names with reset) ────────
|
|
1765
1825
|
|
|
1766
1826
|
/**
|
|
1767
|
-
* Enables or disables auto-exposure
|
|
1827
|
+
* Enables or disables auto-exposure. A finished render is metered as it stands, not restarted.
|
|
1768
1828
|
* @param {boolean} enabled
|
|
1769
1829
|
*/
|
|
1770
1830
|
setAutoExposure( enabled ) {
|
|
1771
1831
|
|
|
1772
1832
|
this.setAutoExposureEnabled( enabled, this._getExposure() );
|
|
1773
|
-
this._onReset?.();
|
|
1774
1833
|
|
|
1775
1834
|
}
|
|
1776
1835
|
|
|
@@ -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
|
|