rayzee 11.6.0 → 11.7.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 +13 -14
- package/dist/{ArchiveImporter-iofnC8zB.js → ArchiveImporter-DYcRXeKE.js} +2 -2
- package/dist/{BidirectionalIntegrator-CqAilt2I.js → BidirectionalIntegrator-BvjRpbTP.js} +2 -2
- package/dist/{NeuralRetouch-DFI4pOjO.js → NeuralRetouch-ClaMiKYg.js} +1 -1
- package/dist/{NeuralSuperRes-ChCiiilS.js → NeuralSuperRes-WNEXun9s.js} +1 -1
- package/dist/{PathTracer-BX4sJLx7.js → PathTracer-B9wZPPVL.js} +6 -8
- package/dist/{PhysicalSky-Biv39eTA.js → PhysicalSky-DcjItqKi.js} +1 -1
- package/dist/{RayzeeRenderer-D8XRKU3A.js → RayzeeRenderer-p-NeE6E2.js} +2 -3
- 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 +865 -1591
- package/dist/rayzee.umd.js +87 -134
- package/dist/{sceneCachePolicy-W5PLbzuR.js → sceneCachePolicy-B9w3BnaP.js} +1 -1
- package/package.json +1 -1
- package/src/Passes/OIDNDenoiser.js +9 -11
- package/src/PathTracerApp.js +6 -17
- package/src/Pipeline/BindingAudit.js +2 -3
- package/src/Pipeline/PipelineContext.js +0 -1
- package/src/Pipeline/RenderPipeline.js +1 -2
- package/src/Pipeline/RenderStage.js +1 -1
- package/src/Processor/PackedRayBuffer.js +2 -2
- package/src/Processor/StorageTexturePool.js +1 -1
- package/src/RayzeeRenderer.js +1 -1
- package/src/Stages/DenoiserSettings.js +5 -81
- package/src/Stages/MotionVector.js +21 -215
- package/src/Stages/NormalDepth.js +5 -5
- package/src/Stages/PathTracer.js +1 -1
- package/src/Stages/PathTracerStage.js +4 -17
- package/src/TSL/FinalWriteKernel.js +2 -2
- package/src/TSL/ShadeKernel.js +3 -3
- package/src/index.js +1 -1
- package/src/managers/DenoisingManager.js +78 -187
- package/src/Stages/ASVGF.js +0 -932
- package/src/Stages/BilateralFilter.js +0 -486
- package/src/Stages/EdgeFilter.js +0 -545
- package/src/Stages/Variance.js +0 -443
|
@@ -11,7 +11,7 @@ import { createLogger } from '../utils/Logger.js';
|
|
|
11
11
|
const neuralLog = createLogger( 'neural' );
|
|
12
12
|
import { CAMERA_PROJECTION_IDS } from '../EngineDefaults.js';
|
|
13
13
|
import {
|
|
14
|
-
DENOISER_DEFAULTS,
|
|
14
|
+
DENOISER_DEFAULTS, DENOISER_STRATEGIES, NRD_DEFAULTS, NRD_QUALITY_PRESETS, NRD_PRESET_KEYS,
|
|
15
15
|
} from '../Stages/DenoiserSettings.js';
|
|
16
16
|
|
|
17
17
|
// A refresh slower than this is a slideshow, not a live view, so the cadence swaps to a cheaper
|
|
@@ -85,7 +85,7 @@ const historyFade = ( samples ) => Math.max( 0, 1 - samples / HISTORY_HANDOFF_SA
|
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
87
|
* Orchestrates all denoising, post-processing, and AI upscaling:
|
|
88
|
-
* - Real-time denoiser strategy switching (
|
|
88
|
+
* - Real-time denoiser strategy switching (OIDN / NRD / None)
|
|
89
89
|
* - OIDN (offline denoise on render completion)
|
|
90
90
|
* - AI Upscaler
|
|
91
91
|
* - Auto-exposure coordination
|
|
@@ -118,7 +118,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
118
118
|
this.pipeline = pipeline;
|
|
119
119
|
|
|
120
120
|
// Stage references — only used internally for orchestration
|
|
121
|
-
this._stages = stages; // { pathTracer,
|
|
121
|
+
this._stages = stages; // { pathTracer, normalDepth, motionVector, nrd, autoExposure, compositor }
|
|
122
122
|
|
|
123
123
|
this._getExposure = getExposure;
|
|
124
124
|
this._getSaturation = getSaturation;
|
|
@@ -349,7 +349,9 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
349
349
|
this.dispatchEvent( { type: EngineEvents.DENOISING_START, continuous: !! e.continuous } );
|
|
350
350
|
this._denoiserEndHandler = e => {
|
|
351
351
|
|
|
352
|
-
|
|
352
|
+
// A refresh that lands after the live view stopped wanting one would cover what replaced it.
|
|
353
|
+
const current = ! e.continuous || ( this.continuousDenoise && ! this._cadenceSuspended );
|
|
354
|
+
if ( this.denoiser?.hasOutput && current ) this._publishOutput();
|
|
353
355
|
this.dispatchEvent( { type: EngineEvents.DENOISING_END, continuous: !! e.continuous } );
|
|
354
356
|
|
|
355
357
|
};
|
|
@@ -447,9 +449,8 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
447
449
|
// ── Denoiser Strategy ─────────────────────────────────────────
|
|
448
450
|
|
|
449
451
|
/**
|
|
450
|
-
* Active real-time denoiser, derived from stage state so it can't drift from
|
|
451
|
-
*
|
|
452
|
-
* @returns {'asvgf'|'nrd'|'edgeaware'|'none'}
|
|
452
|
+
* Active real-time denoiser, derived from stage state so it can't drift from setDenoiserStrategy.
|
|
453
|
+
* @returns {'none'|'nrd'|'oidn'}
|
|
453
454
|
*/
|
|
454
455
|
get denoiserStrategy() {
|
|
455
456
|
|
|
@@ -457,105 +458,55 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
457
458
|
// belongs in the same one-of-N choice. Two of these running at once would mean paying for
|
|
458
459
|
// a per-frame denoise whose result the OIDN overlay then covers.
|
|
459
460
|
if ( this.continuousDenoise ) return 'oidn';
|
|
460
|
-
if ( this._stages.asvgf?.enabled ) return 'asvgf';
|
|
461
461
|
if ( this._stages.nrd?.enabled ) return 'nrd';
|
|
462
|
-
if ( this._stages.edgeFilter?.enabled ) return 'edgeaware';
|
|
463
462
|
return 'none';
|
|
464
463
|
|
|
465
464
|
}
|
|
466
465
|
|
|
467
466
|
/**
|
|
468
467
|
* Switches the real-time denoiser strategy.
|
|
469
|
-
* @param {string} strategy -
|
|
470
|
-
* @param {string} [preset] - quality preset
|
|
468
|
+
* @param {string} strategy - one of DENOISER_STRATEGIES; any other name is recorded and runs 'none'
|
|
469
|
+
* @param {string} [preset] - NRD quality preset (NRD_QUALITY_PRESETS)
|
|
471
470
|
*/
|
|
472
471
|
setDenoiserStrategy( strategy, preset ) {
|
|
473
472
|
|
|
474
473
|
const s = this._stages;
|
|
475
474
|
|
|
476
|
-
|
|
477
|
-
if ( s.asvgf ) s.asvgf.enabled = false;
|
|
478
|
-
if ( s.nrd ) s.nrd.enabled = false;
|
|
479
|
-
if ( s.variance ) s.variance.enabled = false;
|
|
480
|
-
if ( s.bilateralFilter ) s.bilateralFilter.enabled = false;
|
|
481
|
-
if ( s.edgeFilter ) s.edgeFilter.setFilteringEnabled( false );
|
|
475
|
+
if ( ! DENOISER_STRATEGIES.includes( strategy ) ) {
|
|
482
476
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
switch ( strategy ) {
|
|
490
|
-
|
|
491
|
-
case 'asvgf':
|
|
492
|
-
s.asvgf.enabled = true;
|
|
493
|
-
if ( s.variance ) s.variance.enabled = true;
|
|
494
|
-
if ( s.bilateralFilter ) s.bilateralFilter.enabled = true;
|
|
495
|
-
s.asvgf.setTemporalEnabled?.( true );
|
|
496
|
-
this._applyASVGFPreset( preset || 'medium' );
|
|
497
|
-
break;
|
|
477
|
+
this._issues?.record(
|
|
478
|
+
ISSUE_CODES.DENOISER_UNAVAILABLE,
|
|
479
|
+
`'${strategy}' is not a live denoiser (${DENOISER_STRATEGIES.join( ', ' )}) — none is used`,
|
|
480
|
+
{ strategy }
|
|
481
|
+
);
|
|
482
|
+
strategy = 'none';
|
|
498
483
|
|
|
499
|
-
|
|
500
|
-
if ( s.nrd ) {
|
|
501
|
-
|
|
502
|
-
s.nrd.enabled = true;
|
|
503
|
-
// Stale history from the last time it ran describes another view.
|
|
504
|
-
s.nrd.resetHistory?.();
|
|
505
|
-
this._applyNRDPreset( preset || 'medium' );
|
|
506
|
-
|
|
507
|
-
}
|
|
484
|
+
}
|
|
508
485
|
|
|
509
|
-
|
|
486
|
+
// NRD reprojects through motion vectors, which mean nothing once every pixel is its own direction.
|
|
487
|
+
if ( strategy === 'nrd' && this._isPanorama() ) {
|
|
510
488
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
// stage's per-pixel variance to drive its luminance edge-stop.
|
|
514
|
-
if ( s.variance ) s.variance.enabled = true;
|
|
515
|
-
if ( s.edgeFilter ) s.edgeFilter.setFilteringEnabled( true );
|
|
516
|
-
break;
|
|
489
|
+
this._issues?.record( ISSUE_CODES.DENOISER_UNAVAILABLE, 'NRD cannot run in a panorama — oidn is used', { strategy } );
|
|
490
|
+
strategy = 'oidn';
|
|
517
491
|
|
|
518
492
|
}
|
|
519
493
|
|
|
520
|
-
this.
|
|
521
|
-
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
/**
|
|
525
|
-
* Enables/disables ASVGF denoising with coordination of related stages.
|
|
526
|
-
* @param {boolean} enabled
|
|
527
|
-
* @param {string} [qualityPreset]
|
|
528
|
-
*/
|
|
529
|
-
setASVGFEnabled( enabled, qualityPreset ) {
|
|
494
|
+
this._clearDenoiserTextures();
|
|
530
495
|
|
|
531
|
-
|
|
532
|
-
if ( s.asvgf ) s.asvgf.enabled = enabled;
|
|
533
|
-
if ( s.variance ) s.variance.enabled = enabled;
|
|
534
|
-
if ( s.bilateralFilter ) s.bilateralFilter.enabled = enabled;
|
|
496
|
+
if ( s.nrd ) s.nrd.enabled = strategy === 'nrd';
|
|
535
497
|
|
|
536
|
-
if ( enabled ) {
|
|
498
|
+
if ( s.nrd?.enabled ) {
|
|
537
499
|
|
|
538
|
-
//
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
this._applyASVGFPreset( qualityPreset || 'medium' );
|
|
500
|
+
// Stale history from the last time it ran describes another view.
|
|
501
|
+
s.nrd.resetHistory?.();
|
|
502
|
+
this._applyNRDPreset( preset || 'medium' );
|
|
542
503
|
|
|
543
504
|
}
|
|
544
505
|
|
|
545
|
-
//
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
this.
|
|
549
|
-
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
/**
|
|
553
|
-
* Applies an ASVGF quality preset.
|
|
554
|
-
* @param {string} presetName - 'low' | 'medium' | 'high'
|
|
555
|
-
*/
|
|
556
|
-
applyASVGFPreset( presetName ) {
|
|
557
|
-
|
|
558
|
-
this._applyASVGFPreset( presetName );
|
|
506
|
+
// Which denoiser owns the live view. Deliberately says nothing about the finished image:
|
|
507
|
+
// wanting OIDN on the viewport is not the same as opting into a final pass. Also re-syncs
|
|
508
|
+
// the G-buffer stages, so NRD must already be set.
|
|
509
|
+
this.setContinuousDenoise( strategy === 'oidn' );
|
|
559
510
|
|
|
560
511
|
}
|
|
561
512
|
|
|
@@ -569,6 +520,13 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
569
520
|
|
|
570
521
|
}
|
|
571
522
|
|
|
523
|
+
/** True while a strategy that reprojects through motion vectors is active. */
|
|
524
|
+
get requiresMotionVectors() {
|
|
525
|
+
|
|
526
|
+
return !! this._stages.nrd?.enabled;
|
|
527
|
+
|
|
528
|
+
}
|
|
529
|
+
|
|
572
530
|
/**
|
|
573
531
|
* Gate the G-buffer stages (NormalDepth, MotionVector) on demand: they only
|
|
574
532
|
* need to run when a real-time denoiser consumes their output. Idling them
|
|
@@ -576,17 +534,10 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
576
534
|
* navigation and frees their textures. Call after any consumer toggle.
|
|
577
535
|
*
|
|
578
536
|
* MotionVector requires NormalDepth (reads pathtracer:normalDepth) and its
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
537
|
+
* consumer (NRD) also reads NormalDepth, so NormalDepth is always enabled
|
|
538
|
+
* whenever MotionVector is. Adaptive sampling and OIDN's own pass do NOT read
|
|
539
|
+
* these signals; only OIDN's motion history keeps NormalDepth alive.
|
|
582
540
|
*/
|
|
583
|
-
/** True while a strategy that reprojects through motion vectors is active. */
|
|
584
|
-
get requiresMotionVectors() {
|
|
585
|
-
|
|
586
|
-
return !! ( this._stages.asvgf?.enabled || this._stages.nrd?.enabled );
|
|
587
|
-
|
|
588
|
-
}
|
|
589
|
-
|
|
590
541
|
_syncGBufferStages() {
|
|
591
542
|
|
|
592
543
|
const s = this._stages;
|
|
@@ -594,8 +545,8 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
594
545
|
const mv = s.motionVector;
|
|
595
546
|
|
|
596
547
|
const motionNeeded = this.requiresMotionVectors;
|
|
597
|
-
// pathtracer:normalDepth consumed by
|
|
598
|
-
const normalNeeded = motionNeeded || this.historyWanted
|
|
548
|
+
// pathtracer:normalDepth consumed by NRD and the OIDN history
|
|
549
|
+
const normalNeeded = motionNeeded || this.historyWanted;
|
|
599
550
|
if ( ! this.historyWanted ) this._releaseHistory();
|
|
600
551
|
|
|
601
552
|
if ( nd ) {
|
|
@@ -612,21 +563,14 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
612
563
|
|
|
613
564
|
// On re-enable, force a camera-history reseed (matricesInitialized survives
|
|
614
565
|
// normal resets) so the first frame reports zero motion, not a spike.
|
|
615
|
-
if ( motionNeeded && ! mv.enabled )
|
|
616
|
-
|
|
617
|
-
mv.matricesInitialized = false;
|
|
618
|
-
mv.isFirstFrame = true;
|
|
619
|
-
mv.frameCount = 0;
|
|
620
|
-
|
|
621
|
-
}
|
|
566
|
+
if ( motionNeeded && ! mv.enabled ) mv.matricesInitialized = false;
|
|
622
567
|
|
|
623
568
|
mv.enabled = motionNeeded;
|
|
624
569
|
|
|
625
570
|
}
|
|
626
571
|
|
|
627
|
-
// PathTracer's aux MRT (normalDepth + albedo) is consumed by
|
|
628
|
-
//
|
|
629
|
-
// MRT read-targets directly). When none are active the wavefront skips those writes entirely.
|
|
572
|
+
// PathTracer's aux MRT (normalDepth + albedo) is consumed by NRD (albedo, hit distance) and by
|
|
573
|
+
// OIDN (reads the MRT read-targets directly). When neither is active the wavefront skips those writes.
|
|
630
574
|
s.pathTracer?.setAuxGBufferEnabled?.( normalNeeded || !! this.denoiser?.enabled );
|
|
631
575
|
|
|
632
576
|
// Clean-aux normal: temporally accumulate the aux normal only for OIDN clean-aux models
|
|
@@ -641,7 +585,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
641
585
|
// disabled (lazily re-created on the next dispatch after re-enable). Every strategy/denoiser
|
|
642
586
|
// toggle funnels through here after the enabled flags above are settled, so this is the one
|
|
643
587
|
// choke point. dispose() is idempotent, so re-running it for an already-released stage is a no-op.
|
|
644
|
-
for ( const stage of [ s.
|
|
588
|
+
for ( const stage of [ s.nrd, nd, mv ] ) {
|
|
645
589
|
|
|
646
590
|
if ( stage && ! stage.enabled ) stage.releaseGPUMemory?.();
|
|
647
591
|
|
|
@@ -849,21 +793,29 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
849
793
|
|
|
850
794
|
this._cadenceSuspended = !! suspended;
|
|
851
795
|
this._historyDirty = true;
|
|
852
|
-
if ( ! this._cadenceSuspended ) return;
|
|
853
796
|
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
797
|
+
if ( this._cadenceSuspended ) {
|
|
798
|
+
|
|
799
|
+
// The accumulation is what a final render shows; a held preview frame would otherwise sit
|
|
800
|
+
// over it until the render finished.
|
|
801
|
+
this.denoiser?.abort();
|
|
802
|
+
this._unpublishOutput();
|
|
803
|
+
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
this._syncGBufferStages();
|
|
858
807
|
|
|
859
808
|
}
|
|
860
809
|
|
|
861
810
|
setContinuousDenoise( enabled ) {
|
|
862
811
|
|
|
812
|
+
// Once nothing else uses OIDN it turns off, and a disabled denoiser can no longer be aborted.
|
|
813
|
+
if ( ! enabled && ! this.finalDenoise ) this.denoiser?.abort();
|
|
863
814
|
this.continuousDenoise = !! enabled;
|
|
864
815
|
this._syncOIDNInUse();
|
|
865
816
|
this._lastCadenceAt = - Infinity;
|
|
866
817
|
this._resetCadence();
|
|
818
|
+
this._syncGBufferStages();
|
|
867
819
|
|
|
868
820
|
}
|
|
869
821
|
|
|
@@ -895,19 +847,24 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
895
847
|
|
|
896
848
|
}
|
|
897
849
|
|
|
898
|
-
// Not at a size proven too slow to denoise while moving
|
|
850
|
+
// Not at a size proven too slow to denoise while moving (the raw render owns the view there), nor
|
|
851
|
+
// through a final render or a panorama, which never reproject it.
|
|
899
852
|
get historyWanted() {
|
|
900
853
|
|
|
901
|
-
return this.temporalHistory && this.continuousDenoise && !! this.denoiser?.enabled && ! this._movingHopeless
|
|
854
|
+
return this.temporalHistory && this.continuousDenoise && !! this.denoiser?.enabled && ! this._movingHopeless
|
|
855
|
+
&& ! this._cadenceSuspended && ! this._isPanorama();
|
|
902
856
|
|
|
903
857
|
}
|
|
904
858
|
|
|
905
859
|
get historyActive() {
|
|
906
860
|
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
861
|
+
return this.historyWanted && !! this._stages.normalDepth?.enabled && ! ( this._stages.pathTracer?.visMode?.value > 0 );
|
|
862
|
+
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
_isPanorama() {
|
|
866
|
+
|
|
867
|
+
return this._stages.pathTracer?.uniforms?.get( 'cameraProjection' )?.value === CAMERA_PROJECTION_IDS.equirectangular;
|
|
911
868
|
|
|
912
869
|
}
|
|
913
870
|
|
|
@@ -1443,7 +1400,9 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1443
1400
|
// What closes the render, if anything. A full pass at the chosen tier when that switch is
|
|
1444
1401
|
// on; otherwise, if OIDN owns the live view, one last cheap refresh — the cadence's last
|
|
1445
1402
|
// tick lands a few samples short, and the picture should match the render that finished.
|
|
1446
|
-
|
|
1403
|
+
// A final render has no live view to match, so with the switch off it stays undenoised.
|
|
1404
|
+
const live = this.continuousDenoise && ! this._cadenceSuspended;
|
|
1405
|
+
const closing = this.finalDenoise ? 'final' : live ? 'refresh' : null;
|
|
1447
1406
|
|
|
1448
1407
|
// Registered only once the closing denoise has been launched, so the next 'end' is
|
|
1449
1408
|
// unambiguously that one — a cadence run's end can look identical otherwise.
|
|
@@ -1686,53 +1645,6 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1686
1645
|
// These methods match the DenoisingAPI surface so call sites need
|
|
1687
1646
|
// zero or minimal changes after facade removal.
|
|
1688
1647
|
|
|
1689
|
-
/** Updates ASVGF stage parameters. */
|
|
1690
|
-
setASVGFParams( params ) {
|
|
1691
|
-
|
|
1692
|
-
this._stages.asvgf?.updateParameters( params );
|
|
1693
|
-
|
|
1694
|
-
}
|
|
1695
|
-
|
|
1696
|
-
/**
|
|
1697
|
-
* Toggle the ASVGF heatmap compute pass. When enabled, the stage writes
|
|
1698
|
-
* the heatmap to its public `heatmapTarget` RenderTarget — the host is
|
|
1699
|
-
* responsible for rendering it.
|
|
1700
|
-
*/
|
|
1701
|
-
toggleASVGFHeatmap( enabled ) {
|
|
1702
|
-
|
|
1703
|
-
this._stages.asvgf?.setHeatmapEnabled?.( enabled );
|
|
1704
|
-
|
|
1705
|
-
}
|
|
1706
|
-
|
|
1707
|
-
/**
|
|
1708
|
-
* Configures ASVGF for a specific render mode (multi-stage coordination).
|
|
1709
|
-
* @param {Object} config - { enabled, temporalAlpha, atrousIterations, ... }
|
|
1710
|
-
*/
|
|
1711
|
-
configureASVGFForMode( config ) {
|
|
1712
|
-
|
|
1713
|
-
if ( ! this._stages.asvgf ) return;
|
|
1714
|
-
|
|
1715
|
-
this._stages.asvgf.enabled = config.enabled;
|
|
1716
|
-
if ( this._stages.variance ) this._stages.variance.enabled = config.enabled;
|
|
1717
|
-
if ( this._stages.bilateralFilter ) this._stages.bilateralFilter.enabled = config.enabled;
|
|
1718
|
-
|
|
1719
|
-
if ( config.enabled ) {
|
|
1720
|
-
|
|
1721
|
-
this._stages.asvgf.updateParameters( config );
|
|
1722
|
-
|
|
1723
|
-
}
|
|
1724
|
-
|
|
1725
|
-
this._syncGBufferStages();
|
|
1726
|
-
|
|
1727
|
-
}
|
|
1728
|
-
|
|
1729
|
-
/** Updates edge-aware filtering parameters. */
|
|
1730
|
-
setEdgeAwareParams( params ) {
|
|
1731
|
-
|
|
1732
|
-
this._stages.edgeFilter?.updateUniforms( params );
|
|
1733
|
-
|
|
1734
|
-
}
|
|
1735
|
-
|
|
1736
1648
|
/** Updates auto-exposure stage parameters. */
|
|
1737
1649
|
setAutoExposureParams( params ) {
|
|
1738
1650
|
|
|
@@ -1850,7 +1762,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1850
1762
|
|
|
1851
1763
|
/**
|
|
1852
1764
|
* Switches strategy with automatic reset (convenience wrapper).
|
|
1853
|
-
* @param {'none'|'
|
|
1765
|
+
* @param {'none'|'nrd'|'oidn'} strategy
|
|
1854
1766
|
* @param {string} [preset]
|
|
1855
1767
|
*/
|
|
1856
1768
|
setStrategy( strategy, preset ) {
|
|
@@ -1919,12 +1831,8 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1919
1831
|
const ctx = this.pipeline?.context;
|
|
1920
1832
|
if ( ! ctx ) return;
|
|
1921
1833
|
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
'variance:output', 'bilateralFiltering:output',
|
|
1925
|
-
'edgeFiltering:output', 'nrd:output', 'oidn:output',
|
|
1926
|
-
];
|
|
1927
|
-
keys.forEach( k => ctx.removeTexture( k ) );
|
|
1834
|
+
ctx.removeTexture( 'nrd:output' );
|
|
1835
|
+
ctx.removeTexture( 'oidn:output' );
|
|
1928
1836
|
|
|
1929
1837
|
}
|
|
1930
1838
|
|
|
@@ -1939,21 +1847,4 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
1939
1847
|
|
|
1940
1848
|
}
|
|
1941
1849
|
|
|
1942
|
-
_applyASVGFPreset( presetName ) {
|
|
1943
|
-
|
|
1944
|
-
const preset = ASVGF_QUALITY_PRESETS[ presetName ];
|
|
1945
|
-
if ( ! preset ) return;
|
|
1946
|
-
// ASVGF consumes temporalAlpha / gradientStrength / maxAccumFrames.
|
|
1947
|
-
// BilateralFilter consumes phi* edge-stopping params and atrousIterations.
|
|
1948
|
-
// Variance consumes varianceBoost. Each stage cherry-picks what it needs.
|
|
1949
|
-
this._stages.asvgf?.updateParameters( preset );
|
|
1950
|
-
this._stages.bilateralFilter?.updateParameters( preset );
|
|
1951
|
-
if ( this._stages.variance && preset.varianceBoost !== undefined ) {
|
|
1952
|
-
|
|
1953
|
-
this._stages.variance.varianceBoost.value = preset.varianceBoost;
|
|
1954
|
-
|
|
1955
|
-
}
|
|
1956
|
-
|
|
1957
|
-
}
|
|
1958
|
-
|
|
1959
1850
|
}
|