rayzee 10.0.0 → 11.1.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 +252 -44
- package/dist/ActiveColor-YvuQq44O.js +13 -0
- package/dist/ArchiveImporter-Hn35o6Z5.js +5145 -0
- package/dist/AssetConfig-DSEntE65.js +30 -0
- package/dist/BidirectionalIntegrator-CBw8hkeu.js +946 -0
- package/dist/BufferLayout-D_IBo2ci.js +150 -0
- package/dist/ColorManagement-oeEk7oSu.js +1488 -0
- package/dist/EngineEvents-Ci8dVWCP.js +73 -0
- package/dist/EngineIssues-CIZnXHsF.js +72 -0
- package/dist/FileFormats-sPGJeCRc.js +102 -0
- package/dist/Logger-dDDGj9Av.js +97 -0
- package/dist/{NeuralRetouch-CYgkQY8Z.js → NeuralRetouch-BzNpiVHZ.js} +8 -6
- package/dist/{NeuralSuperRes-PkgDLQcD.js → NeuralSuperRes-Bk7bHg2B.js} +55 -120
- package/dist/PathTracer-72XufKAr.js +29976 -0
- package/dist/PhysicalSky-BgjdV88k.js +1219 -0
- package/dist/RayzeeRenderer-1QRO97eq.js +3551 -0
- package/dist/SolarLimb-CPaeZVwz.js +721 -0
- package/dist/ToneMapGPU-CjU3osDd.js +177 -0
- package/dist/ViewTransforms-CYN7bq2w.js +255 -0
- package/dist/WorkingMatrix-C6y233hT.js +27 -0
- package/dist/ZipReader-gDSWr0I5.js +98 -0
- package/dist/addons/archives.es.js +3 -0
- package/dist/addons/bidirectional.es.js +2 -0
- package/dist/addons/color.es.js +3 -0
- package/dist/addons/formats.es.js +2 -0
- package/dist/addons/physical-sky.es.js +2 -0
- package/dist/addons/storage.es.js +3 -0
- package/dist/archiveFormats-tnAoUL1j.js +94 -0
- package/dist/identity-DrQsGT2o.js +39 -0
- package/dist/openStorage-DwcBRUj7.js +820 -0
- package/dist/rayzee-core.es.js +12 -0
- package/dist/rayzee.es.js +2551 -44024
- package/dist/rayzee.umd.js +528 -487
- package/dist/sceneCachePolicy-C67jbci-.js +443 -0
- package/dist/shared-BGBcSxBQ.js +17 -0
- package/package.json +23 -2
- package/src/Color/ActiveColor.js +34 -0
- package/src/Color/BasicColor.js +147 -0
- package/src/Color/ColorManagement.js +7 -31
- package/src/Color/ViewTransforms.js +5 -1
- package/src/EngineDefaults.js +62 -1029
- package/src/EngineEvents.js +2 -0
- package/src/EngineIssues.js +2 -0
- package/src/Headless.js +6 -5
- package/src/Passes/AIUpscaler.js +58 -141
- package/src/Passes/OIDNDenoiser.js +92 -65
- package/src/Passes/OIDNTemporalHistory.js +1 -1
- package/src/PathTracerApp.js +620 -4026
- package/src/Pipeline/PipelineContext.js +0 -4
- package/src/Platform.js +36 -0
- package/src/Processor/ArchiveCache.js +20 -7
- package/src/Processor/ArchiveImporter.js +1265 -0
- package/src/Processor/ArchiveReader.js +22 -4
- package/src/Processor/AssetLoader.js +327 -1763
- package/src/Processor/AtmosphereModel.js +1 -2
- package/src/Processor/BVHBuilder.js +14 -126
- package/src/Processor/BVHLeafFold.js +4 -6
- package/src/Processor/BVHRefitter.js +67 -46
- package/src/Processor/BufferLayout.js +291 -0
- package/src/Processor/EmissiveTriangleBuilder.js +1 -1
- package/src/Processor/EnvironmentExactTable.js +187 -0
- package/src/Processor/EquirectHDRInfo.js +30 -223
- package/src/Processor/FileFormats.js +116 -0
- package/src/Processor/GLTFDecoders.js +85 -0
- package/src/Processor/GLTFDiffuseTransmission.js +63 -0
- package/src/Processor/GeometryExtractor.js +15 -5
- package/src/Processor/HostMemory.js +7 -1
- package/src/Processor/IESParser.js +47 -35
- package/src/Processor/InstanceTable.js +1 -1
- package/src/Processor/KernelManager.js +35 -2
- package/src/Processor/MaterialPacking.js +10 -8
- package/src/Processor/PBRT/PBRTMaterials.js +254 -42
- package/src/Processor/PBRT/PBRTParser.js +49 -19
- package/src/Processor/PBRT/PBRTScattering.js +93 -0
- package/src/Processor/PBRT/PBRTSceneBuilder.js +1050 -75
- package/src/Processor/PBRT/PBRTTextureBake.js +179 -0
- package/src/Processor/PBRT/PFM.js +59 -0
- package/src/Processor/PackedRayBuffer.js +116 -9
- package/src/Processor/ParallelBVHBuilder.js +3 -6
- package/src/Processor/PhysicalSky.js +5 -4
- package/src/Processor/PlatformImageLoader.js +50 -6
- package/src/Processor/QueueManager.js +39 -5
- package/src/Processor/ReinsertionOptimizer.js +2 -2
- package/src/Processor/SceneMetadata.js +30 -5
- package/src/Processor/SceneProcessor.js +53 -62
- package/src/Processor/ShaderBuilder.js +6 -16
- package/src/Processor/SimpleSky.js +1 -62
- package/src/Processor/SolarLimb.js +3 -0
- package/src/Processor/SplitBLAS.js +1 -1
- package/src/Processor/StorageTexturePool.js +22 -1
- package/src/Processor/TLASBuilder.js +1 -3
- package/src/Processor/TextureBuckets.js +237 -0
- package/src/Processor/TextureCreator.js +181 -8
- package/src/Processor/ToneMapGPU.js +64 -15
- package/src/Processor/Workers/BVHRefitWorker.js +5 -2
- package/src/Processor/Workers/BVHSubtreeWorker.js +1 -34
- package/src/Processor/Workers/BVHWorker.js +5 -18
- package/src/Processor/Workers/CDFWorker.js +6 -183
- package/src/Processor/Workers/TexturesWorker.js +103 -18
- package/src/Processor/archiveFormats.js +7 -0
- package/src/Processor/utils.js +2 -1
- package/src/RayzeeRenderer.js +3900 -0
- package/src/RenderSettings.js +68 -62
- package/src/Stages/ASVGF.js +13 -14
- package/src/Stages/AutoExposure.js +17 -17
- package/src/Stages/BilateralFilter.js +2 -1
- package/src/Stages/Compositor.js +8 -23
- package/src/Stages/DenoiserSettings.js +182 -0
- package/src/Stages/EdgeFilter.js +2 -1
- package/src/Stages/MotionVector.js +1 -1
- package/src/Stages/NRD.js +11 -5
- package/src/Stages/NormalDepth.js +12 -8
- package/src/Stages/PathTracer.js +336 -43
- package/src/Stages/PathTracerStage.js +69 -66
- package/src/Stages/Variance.js +1 -1
- package/src/Storage/BLASCache.js +1 -1
- package/src/Storage/CDFCache.js +18 -17
- package/src/Storage/DownloadCache.js +1 -1
- package/src/Storage/SceneGraphCodec.js +46 -3
- package/src/Storage/SpillStore.js +1 -1
- package/src/Storage/StorageManager.js +45 -9
- package/src/Storage/areas.js +4 -0
- package/src/TSL/BVHTraversal.js +50 -25
- package/src/TSL/Bidirectional.js +208 -0
- package/src/TSL/BidirectionalLamps.js +132 -0
- package/src/TSL/Clearcoat.js +15 -6
- package/src/TSL/Common.js +20 -15
- package/src/TSL/ConnectKernel.js +167 -0
- package/src/TSL/Debugger.js +1 -1
- package/src/TSL/Displacement.js +4 -3
- package/src/TSL/EmissiveSampling.js +65 -18
- package/src/TSL/Environment.js +77 -106
- package/src/TSL/EnvironmentCDF.js +85 -39
- package/src/TSL/ExtendKernel.js +8 -3
- package/src/TSL/FinalWriteKernel.js +4 -4
- package/src/TSL/GenerateKernel.js +18 -4
- package/src/TSL/HitFacet.js +35 -5
- package/src/TSL/LightBVHSampling.js +40 -9
- package/src/TSL/LightGenerateKernel.js +293 -0
- package/src/TSL/LightGuide.js +198 -0
- package/src/TSL/LightSplatKernel.js +180 -0
- package/src/TSL/LightVisibility.js +111 -0
- package/src/TSL/LightsCore.js +13 -38
- package/src/TSL/LightsDirect.js +28 -29
- package/src/TSL/LightsIndirect.js +3 -1
- package/src/TSL/LightsSampling.js +239 -51
- package/src/TSL/MaterialEvaluation.js +113 -31
- package/src/TSL/MaterialProperties.js +44 -17
- package/src/TSL/MaterialTransmission.js +52 -47
- package/src/TSL/MergeKernel.js +224 -0
- package/src/TSL/PathTracerCore.js +65 -29
- package/src/TSL/Random.js +5 -1
- package/src/TSL/SceneResources.js +51 -0
- package/src/TSL/ShadeKernel.js +985 -101
- package/src/TSL/Struct.js +10 -0
- package/src/TSL/Sun.js +1 -1
- package/src/TSL/TextureSampling.js +66 -61
- package/src/addons/archives.js +14 -0
- package/src/addons/bidirectional.js +13 -0
- package/src/addons/color.js +32 -0
- package/src/addons/formats.js +16 -0
- package/src/addons/physicalSky.js +14 -0
- package/src/addons/storage.js +19 -0
- package/src/core.js +31 -0
- package/src/index.js +13 -23
- package/src/integrators/BidirectionalIntegrator.js +838 -0
- package/src/managers/AnimationManager.js +88 -6
- package/src/managers/CameraManager.js +103 -46
- package/src/managers/DenoisingManager.js +14 -10
- package/src/managers/EnvironmentManager.js +125 -103
- package/src/managers/GoboManager.js +9 -0
- package/src/managers/MaterialDataManager.js +48 -37
- package/src/managers/UniformManager.js +32 -10
- package/dist/ToneMapGPU-B6XIe3DU.js +0 -544
- package/dist/rolldown-runtime-CAFD8bLK.js +0 -11
- package/src/Processor/TreeletOptimizer.js +0 -574
package/src/RenderSettings.js
CHANGED
|
@@ -5,13 +5,14 @@ import { ISSUE_CODES } from './EngineIssues.js';
|
|
|
5
5
|
import { toPortable, fromPortable } from './SceneState/portable.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* The renderer core's settings: maps each key to its target.
|
|
9
9
|
*
|
|
10
10
|
* - `uniform` → forwarded to PathTracer.setUniform(uniform, value)
|
|
11
11
|
* - `handler` → calls a named handler method for multi-stage settings
|
|
12
|
-
* -
|
|
12
|
+
* - neither → stored only; whoever needs it reads it
|
|
13
13
|
* - `reset` → whether to reset accumulation after the change (default true)
|
|
14
|
-
*
|
|
14
|
+
*
|
|
15
|
+
* Other layers add their own keys with {@link RenderSettings#define}.
|
|
15
16
|
*/
|
|
16
17
|
const SETTING_ROUTES = {
|
|
17
18
|
|
|
@@ -68,7 +69,6 @@ const SETTING_ROUTES = {
|
|
|
68
69
|
panoramaLonRange: { handler: 'handlePanoramaLonRange', reset: true },
|
|
69
70
|
panoramaLatRange: { handler: 'handlePanoramaLatRange', reset: true },
|
|
70
71
|
interactionModeEnabled: { handler: 'handleInteractionModeEnabled', reset: false },
|
|
71
|
-
interactionRenderScale: { handler: 'handleInteractionRenderScale', reset: false },
|
|
72
72
|
maxSamples: { handler: 'handleMaxSamples', reset: false },
|
|
73
73
|
transparentBackground: { handler: 'handleTransparentBackground' },
|
|
74
74
|
backgroundColor: { handler: 'handleBackgroundColor', reset: true },
|
|
@@ -77,14 +77,17 @@ const SETTING_ROUTES = {
|
|
|
77
77
|
renderLimitMode: { handler: 'handleRenderLimitMode' },
|
|
78
78
|
renderTimeLimit: { handler: 'handleRenderTimeLimit', reset: false },
|
|
79
79
|
renderMode: { handler: 'handleRenderMode' },
|
|
80
|
+
integrator: { handler: 'handleIntegrator', reset: true },
|
|
81
|
+
shadowRays: { handler: 'handleShadowRays', reset: true },
|
|
80
82
|
environmentRotation: { handler: 'handleEnvironmentRotation' },
|
|
83
|
+
// Read when the kernels next build.
|
|
84
|
+
wavefrontSortMaterials: { handler: 'handleWavefrontSortMaterials', reset: false },
|
|
85
|
+
// No target: read when a model loads (setMaxTextureSize() also reprocesses the scene now).
|
|
86
|
+
maxTextureSize: { reset: false },
|
|
87
|
+
areaLightIntensityScale: { reset: false },
|
|
81
88
|
|
|
82
89
|
};
|
|
83
90
|
|
|
84
|
-
/**
|
|
85
|
-
* Default keys to extract from ENGINE_DEFAULTS for initializing the values map.
|
|
86
|
-
* Maps ENGINE_DEFAULTS key → RenderSettings key when they differ.
|
|
87
|
-
*/
|
|
88
91
|
/** Provenance tags for getEffective(). Add-only — hosts branch on them. */
|
|
89
92
|
export const SETTING_SOURCE = Object.freeze( {
|
|
90
93
|
DEFAULT: 'default',
|
|
@@ -93,11 +96,6 @@ export const SETTING_SOURCE = Object.freeze( {
|
|
|
93
96
|
MODE_PRESET: 'mode-preset',
|
|
94
97
|
} );
|
|
95
98
|
|
|
96
|
-
const DEFAULTS_KEY_MAP = {
|
|
97
|
-
bounces: 'maxBounces',
|
|
98
|
-
debugMode: 'visMode',
|
|
99
|
-
};
|
|
100
|
-
|
|
101
99
|
/**
|
|
102
100
|
* Single source of truth for all render parameters.
|
|
103
101
|
*
|
|
@@ -122,6 +120,12 @@ export class RenderSettings extends EventDispatcher {
|
|
|
122
120
|
|
|
123
121
|
this._issues = issues;
|
|
124
122
|
|
|
123
|
+
/** Default values, kept for keys another layer defines later */
|
|
124
|
+
this._defaults = defaults;
|
|
125
|
+
|
|
126
|
+
/** @type {Map<string, Object>} - the core's routes and those other layers define */
|
|
127
|
+
this._routes = new Map( Object.entries( SETTING_ROUTES ) );
|
|
128
|
+
|
|
125
129
|
/** @type {Map<string, *>} */
|
|
126
130
|
this._values = new Map();
|
|
127
131
|
|
|
@@ -137,39 +141,57 @@ export class RenderSettings extends EventDispatcher {
|
|
|
137
141
|
/** @type {Object<string, Function>} - Named handlers for multi-stage settings */
|
|
138
142
|
this._handlers = {};
|
|
139
143
|
|
|
140
|
-
/** @type {Object<string, Object>} - Named delegate managers */
|
|
141
|
-
this._delegates = {};
|
|
142
|
-
|
|
143
144
|
// Initialize values from ENGINE_DEFAULTS
|
|
144
145
|
this._initDefaults( defaults );
|
|
145
146
|
|
|
146
147
|
}
|
|
147
148
|
|
|
148
149
|
/**
|
|
149
|
-
* Wires
|
|
150
|
+
* Wires the core's settings to their targets. Called by the renderer during init().
|
|
150
151
|
*
|
|
151
152
|
* @param {Object} params
|
|
152
|
-
* @param {Object} params.stages - Pipeline stages { pathTracer, compositor
|
|
153
|
+
* @param {Object} params.stages - Pipeline stages { pathTracer, compositor }
|
|
153
154
|
* @param {Function} params.resetCallback - Called to reset accumulation
|
|
154
155
|
* @param {Function} [params.reconcileCompletion] - Called when completion limits change
|
|
155
|
-
* @param {
|
|
156
|
-
* @param {Function} [params.onInteractionRenderScale] - Applies a new moving-camera render scale
|
|
156
|
+
* @param {Function} [params.applyExposure] - Shows a new `exposure`
|
|
157
157
|
* @param {Function} [params.onCameraProjection] - The camera's side of a `cameraProjection` change
|
|
158
158
|
*/
|
|
159
159
|
bind( params ) {
|
|
160
160
|
|
|
161
161
|
this._pathTracer = params.stages.pathTracer;
|
|
162
162
|
this._resetCallback = params.resetCallback;
|
|
163
|
-
this._delegates = {};
|
|
164
163
|
this._handlers = this._buildHandlers( params );
|
|
165
164
|
|
|
166
165
|
}
|
|
167
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Adds a setting of another layer — the viewer's, or an add-on's — with the same provenance, events, session
|
|
169
|
+
* saving and reset as the core's. The layer brings its own default.
|
|
170
|
+
* @param {string} key
|
|
171
|
+
* @param {Object} route
|
|
172
|
+
* @param {*} [route.default] - the value until someone sets one; else the one this store was built with
|
|
173
|
+
* @param {function(*, *): void} route.apply - called with ( value, prev ) on every change, and by applyAll()
|
|
174
|
+
* @param {boolean} [route.reset=true] - reset accumulation after a change
|
|
175
|
+
*/
|
|
176
|
+
define( key, { default: initial, apply, reset = true } ) {
|
|
177
|
+
|
|
178
|
+
if ( this._routes.has( key ) ) throw new Error( `setting "${key}" is already defined` );
|
|
179
|
+
this._routes.set( key, { apply, reset } );
|
|
180
|
+
const value = initial !== undefined ? initial : this._defaults[ key ];
|
|
181
|
+
if ( ! this._values.has( key ) && value !== undefined ) {
|
|
182
|
+
|
|
183
|
+
this._values.set( key, value );
|
|
184
|
+
this._sources.set( key, SETTING_SOURCE.DEFAULT );
|
|
185
|
+
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
}
|
|
189
|
+
|
|
168
190
|
/**
|
|
169
191
|
* Builds handler functions for multi-stage settings that can't
|
|
170
192
|
* be routed with a simple uniform forward.
|
|
171
193
|
*/
|
|
172
|
-
_buildHandlers( { stages,
|
|
194
|
+
_buildHandlers( { stages, resetCallback, reconcileCompletion, applyExposure, onCameraProjection } ) {
|
|
173
195
|
|
|
174
196
|
// UniformManager copies into the existing node, so one scratch vector serves every write.
|
|
175
197
|
const panoScratch = new Vector2();
|
|
@@ -187,13 +209,6 @@ export class RenderSettings extends EventDispatcher {
|
|
|
187
209
|
stages.pathTracer?.setUniform( 'cameraProjection', CAMERA_PROJECTION_IDS[ value ] ?? CAMERA_PROJECTION_IDS.perspective );
|
|
188
210
|
onCameraProjection?.( value );
|
|
189
211
|
|
|
190
|
-
if ( value !== 'equirectangular' ) return;
|
|
191
|
-
|
|
192
|
-
// MotionVector unprojects through projectionMatrixInverse, which is meaningless once
|
|
193
|
-
// every pixel is its own direction. Fall back to the spatial-only denoiser rather
|
|
194
|
-
// than leaving no strategy.
|
|
195
|
-
if ( denoisingManager?.requiresMotionVectors ) denoisingManager.setDenoiserStrategy( 'edgeaware' );
|
|
196
|
-
|
|
197
212
|
},
|
|
198
213
|
|
|
199
214
|
handleDofMode: ( value ) => stages.pathTracer?.setUniform( 'dofMode', value === 'look' ? 1 : 0 ),
|
|
@@ -220,13 +235,7 @@ export class RenderSettings extends EventDispatcher {
|
|
|
220
235
|
|
|
221
236
|
handleExposure: ( value ) => {
|
|
222
237
|
|
|
223
|
-
|
|
224
|
-
// so this has no effect when renderer.toneMapping === NoToneMapping.
|
|
225
|
-
if ( ! stages.autoExposure?.enabled && renderer ) {
|
|
226
|
-
|
|
227
|
-
renderer.toneMappingExposure = value;
|
|
228
|
-
|
|
229
|
-
}
|
|
238
|
+
applyExposure?.( value );
|
|
230
239
|
|
|
231
240
|
},
|
|
232
241
|
|
|
@@ -274,21 +283,33 @@ export class RenderSettings extends EventDispatcher {
|
|
|
274
283
|
|
|
275
284
|
},
|
|
276
285
|
|
|
286
|
+
handleIntegrator: ( value ) => {
|
|
287
|
+
|
|
288
|
+
stages.pathTracer?.setIntegrator?.( value );
|
|
289
|
+
|
|
290
|
+
},
|
|
291
|
+
|
|
292
|
+
handleShadowRays: ( value ) => {
|
|
293
|
+
|
|
294
|
+
stages.pathTracer?.setShadowRays?.( value );
|
|
295
|
+
|
|
296
|
+
},
|
|
297
|
+
|
|
277
298
|
handleEnvironmentRotation: ( value ) => {
|
|
278
299
|
|
|
279
300
|
stages.pathTracer?.environment.setEnvironmentRotation( value );
|
|
280
301
|
|
|
281
302
|
},
|
|
282
303
|
|
|
283
|
-
|
|
304
|
+
handleWavefrontSortMaterials: ( value ) => {
|
|
284
305
|
|
|
285
|
-
stages.pathTracer
|
|
306
|
+
if ( stages.pathTracer ) stages.pathTracer.sortMaterials = value;
|
|
286
307
|
|
|
287
308
|
},
|
|
288
309
|
|
|
289
|
-
|
|
310
|
+
handleInteractionModeEnabled: ( value ) => {
|
|
290
311
|
|
|
291
|
-
|
|
312
|
+
stages.pathTracer?.setInteractionModeEnabled( value );
|
|
292
313
|
|
|
293
314
|
},
|
|
294
315
|
|
|
@@ -365,7 +386,7 @@ export class RenderSettings extends EventDispatcher {
|
|
|
365
386
|
this._values.set( key, value );
|
|
366
387
|
this._sources.set( key, source );
|
|
367
388
|
|
|
368
|
-
const route =
|
|
389
|
+
const route = this._routes.get( key );
|
|
369
390
|
if ( ! route ) {
|
|
370
391
|
|
|
371
392
|
this._reportUnknownKey( key );
|
|
@@ -410,7 +431,7 @@ export class RenderSettings extends EventDispatcher {
|
|
|
410
431
|
out[ key ] = {
|
|
411
432
|
value,
|
|
412
433
|
source: this._sources.get( key ) ?? SETTING_SOURCE.DEFAULT,
|
|
413
|
-
routed:
|
|
434
|
+
routed: this._routes.has( key ),
|
|
414
435
|
};
|
|
415
436
|
|
|
416
437
|
}
|
|
@@ -431,7 +452,7 @@ export class RenderSettings extends EventDispatcher {
|
|
|
431
452
|
const out = {};
|
|
432
453
|
for ( const [ key, value ] of this._values ) {
|
|
433
454
|
|
|
434
|
-
if ( this._sources.get( key ) !== SETTING_SOURCE.HOST || !
|
|
455
|
+
if ( this._sources.get( key ) !== SETTING_SOURCE.HOST || ! this._routes.has( key ) ) continue;
|
|
435
456
|
const portable = toPortable( value );
|
|
436
457
|
if ( portable !== undefined ) out[ key ] = portable;
|
|
437
458
|
|
|
@@ -452,7 +473,7 @@ export class RenderSettings extends EventDispatcher {
|
|
|
452
473
|
const unknown = [];
|
|
453
474
|
for ( const [ key, value ] of Object.entries( values ?? {} ) ) {
|
|
454
475
|
|
|
455
|
-
if (
|
|
476
|
+
if ( this._routes.has( key ) ) known[ key ] = fromPortable( value );
|
|
456
477
|
else unknown.push( key );
|
|
457
478
|
|
|
458
479
|
}
|
|
@@ -470,7 +491,7 @@ export class RenderSettings extends EventDispatcher {
|
|
|
470
491
|
|
|
471
492
|
for ( const [ key, value ] of this._values ) {
|
|
472
493
|
|
|
473
|
-
const route =
|
|
494
|
+
const route = this._routes.get( key );
|
|
474
495
|
if ( ! route ) continue;
|
|
475
496
|
|
|
476
497
|
// prev is undefined on initial apply — handlers should not rely on it
|
|
@@ -487,15 +508,14 @@ export class RenderSettings extends EventDispatcher {
|
|
|
487
508
|
if ( route.uniform ) {
|
|
488
509
|
|
|
489
510
|
this._pathTracer?.setUniform( route.uniform, value );
|
|
490
|
-
if ( route.after ) this._pathTracer?.[ route.after ]?.();
|
|
491
511
|
|
|
492
512
|
} else if ( route.handler ) {
|
|
493
513
|
|
|
494
514
|
this._handlers[ route.handler ]?.( value, prev );
|
|
495
515
|
|
|
496
|
-
} else
|
|
516
|
+
} else {
|
|
497
517
|
|
|
498
|
-
|
|
518
|
+
route.apply?.( value, prev );
|
|
499
519
|
|
|
500
520
|
}
|
|
501
521
|
|
|
@@ -503,11 +523,9 @@ export class RenderSettings extends EventDispatcher {
|
|
|
503
523
|
|
|
504
524
|
/**
|
|
505
525
|
* Populates the values map from ENGINE_DEFAULTS.
|
|
506
|
-
* Handles key renames via DEFAULTS_KEY_MAP.
|
|
507
526
|
*/
|
|
508
527
|
_initDefaults( defaults ) {
|
|
509
528
|
|
|
510
|
-
// Keys that exist in both SETTING_ROUTES and ENGINE_DEFAULTS (direct match)
|
|
511
529
|
for ( const key of Object.keys( SETTING_ROUTES ) ) {
|
|
512
530
|
|
|
513
531
|
if ( key in defaults ) {
|
|
@@ -519,18 +537,6 @@ export class RenderSettings extends EventDispatcher {
|
|
|
519
537
|
|
|
520
538
|
}
|
|
521
539
|
|
|
522
|
-
// Keys where ENGINE_DEFAULTS uses a different name
|
|
523
|
-
for ( const [ defaultsKey, settingsKey ] of Object.entries( DEFAULTS_KEY_MAP ) ) {
|
|
524
|
-
|
|
525
|
-
if ( defaultsKey in defaults ) {
|
|
526
|
-
|
|
527
|
-
this._values.set( settingsKey, defaults[ defaultsKey ] );
|
|
528
|
-
this._sources.set( settingsKey, SETTING_SOURCE.DEFAULT );
|
|
529
|
-
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
}
|
|
533
|
-
|
|
534
540
|
}
|
|
535
541
|
|
|
536
542
|
}
|
package/src/Stages/ASVGF.js
CHANGED
|
@@ -5,7 +5,8 @@ import { RenderTarget, TextureNode, StorageTexture } from 'three/webgpu';
|
|
|
5
5
|
import { HalfFloatType, FloatType, RGBAFormat, NearestFilter, LinearFilter, Box2, Vector2 } from 'three';
|
|
6
6
|
import { RenderStage, StageExecutionMode } from '../Pipeline/RenderStage.js';
|
|
7
7
|
import { luminance } from '../TSL/Common.js';
|
|
8
|
-
import {
|
|
8
|
+
import { MAX_STORAGE_TEXTURE_SIZE } from '../Processor/StorageTexturePool.js';
|
|
9
|
+
import { ALBEDO_EPS, ASVGF_QUALITY_PRESETS } from './DenoiserSettings.js';
|
|
9
10
|
|
|
10
11
|
// Replace NaN/±Inf with a bounded value so one firefly can't permanently poison the
|
|
11
12
|
// temporal EMA (mix() propagates NaN forever). Per-channel: NaN (x!=x) → 0, ±Inf → [0,1e7].
|
|
@@ -39,20 +40,20 @@ export class ASVGF extends RenderStage {
|
|
|
39
40
|
|
|
40
41
|
this.renderer = renderer;
|
|
41
42
|
|
|
42
|
-
this.temporalAlpha = uniform( options.temporalAlpha ??
|
|
43
|
-
// > 0 is required for firefly rejection, not just anti-lag — see
|
|
44
|
-
this.gradientStrength = uniform( options.gradientStrength ??
|
|
43
|
+
this.temporalAlpha = uniform( options.temporalAlpha ?? ASVGF_QUALITY_PRESETS.medium.temporalAlpha );
|
|
44
|
+
// > 0 is required for firefly rejection, not just anti-lag — see DENOISER_DEFAULTS.
|
|
45
|
+
this.gradientStrength = uniform( options.gradientStrength ?? ASVGF_QUALITY_PRESETS.medium.gradientStrength );
|
|
45
46
|
// σ multiplier for the per-pixel noise floor (NRD luminanceSigmaScale ≈ 2).
|
|
46
|
-
this.gradientSigmaScale = uniform( options.gradientSigmaScale ??
|
|
47
|
+
this.gradientSigmaScale = uniform( options.gradientSigmaScale ?? ASVGF_QUALITY_PRESETS.medium.gradientSigmaScale );
|
|
47
48
|
// Secondary relative floor on the normalised gradient (0 = rely on σ alone).
|
|
48
|
-
this.gradientNoiseFloor = uniform( options.gradientNoiseFloor ??
|
|
49
|
-
this.maxAccumFrames = uniform( options.maxAccumFrames ??
|
|
49
|
+
this.gradientNoiseFloor = uniform( options.gradientNoiseFloor ?? ASVGF_QUALITY_PRESETS.medium.gradientNoiseFloor );
|
|
50
|
+
this.maxAccumFrames = uniform( options.maxAccumFrames ?? ASVGF_QUALITY_PRESETS.medium.maxAccumFrames );
|
|
50
51
|
|
|
51
52
|
this.resW = uniform( options.width || 1 );
|
|
52
53
|
this.resH = uniform( options.height || 1 );
|
|
53
54
|
|
|
54
55
|
this.temporalEnabledU = uniform( 1.0 );
|
|
55
|
-
// 1.0 for one frame after
|
|
56
|
+
// 1.0 for one frame after pipeline:historyReset → forces a fresh sample so stale pre-reset
|
|
56
57
|
// (wrong-scene) history isn't blended in (mirrors Variance's _needsWarmReset).
|
|
57
58
|
this.forceResetU = uniform( 0.0 );
|
|
58
59
|
|
|
@@ -398,7 +399,7 @@ export class ASVGF extends RenderStage {
|
|
|
398
399
|
const demodResult = vec4( currentLighting, 1.0 ).toVar();
|
|
399
400
|
const modulatedResult = vec4( currentColor, currentAlpha ).toVar();
|
|
400
401
|
|
|
401
|
-
// forceResetU skips the blend for one frame after
|
|
402
|
+
// forceResetU skips the blend for one frame after pipeline:historyReset → re-anchors
|
|
402
403
|
// history to the current (post-reset) scene instead of the stale ping-pong.
|
|
403
404
|
If( temporalEnabledU.greaterThan( 0.5 ).and( forceResetU.lessThan( 0.5 ) ), () => {
|
|
404
405
|
|
|
@@ -647,9 +648,7 @@ export class ASVGF extends RenderStage {
|
|
|
647
648
|
|
|
648
649
|
setupEventListeners() {
|
|
649
650
|
|
|
650
|
-
this.on( '
|
|
651
|
-
|
|
652
|
-
this.on( 'asvgf:updateParameters', ( data ) => this.updateParameters( data ) );
|
|
651
|
+
this.on( 'pipeline:historyReset', () => this.resetTemporalData() );
|
|
653
652
|
|
|
654
653
|
}
|
|
655
654
|
|
|
@@ -720,7 +719,7 @@ export class ASVGF extends RenderStage {
|
|
|
720
719
|
|
|
721
720
|
}
|
|
722
721
|
|
|
723
|
-
// One-shot fresh re-anchor after
|
|
722
|
+
// One-shot fresh re-anchor after pipeline:historyReset, threaded through the SINGLE
|
|
724
723
|
// writeNode dispatch (a dual-node warmup would alias the read target — see setSize).
|
|
725
724
|
this.forceResetU.value = this._needsWarmReset ? 1.0 : 0.0;
|
|
726
725
|
this.renderer.compute( writeNode );
|
|
@@ -865,7 +864,7 @@ export class ASVGF extends RenderStage {
|
|
|
865
864
|
|
|
866
865
|
reset() {
|
|
867
866
|
|
|
868
|
-
// No-op: motion vectors handle camera moves; explicit
|
|
867
|
+
// No-op: motion vectors handle camera moves; explicit pipeline:historyReset
|
|
869
868
|
// clears history on scene/mode change.
|
|
870
869
|
|
|
871
870
|
}
|
|
@@ -7,6 +7,15 @@ import { RenderStage, StageExecutionMode } from '../Pipeline/RenderStage.js';
|
|
|
7
7
|
import { luminance } from '../TSL/Common.js';
|
|
8
8
|
|
|
9
9
|
// ── Histogram constants ────────────────────────────────────
|
|
10
|
+
export const AUTO_EXPOSURE_DEFAULTS = {
|
|
11
|
+
autoExposure: false,
|
|
12
|
+
autoExposureKeyValue: 0.18,
|
|
13
|
+
autoExposureMinExposure: 0.1,
|
|
14
|
+
autoExposureMaxExposure: 20.0,
|
|
15
|
+
autoExposureAdaptSpeedBright: 3.0,
|
|
16
|
+
autoExposureAdaptSpeedDark: 0.5,
|
|
17
|
+
};
|
|
18
|
+
|
|
10
19
|
const NUM_BINS = 256;
|
|
11
20
|
const MIN_LOG_LUM = - 8.0; // ln(~0.00034) — very dark
|
|
12
21
|
const MAX_LOG_LUM = 6.0; // ln(~403) — bright specular
|
|
@@ -80,9 +89,8 @@ const adaptExposure = /*@__PURE__*/ wgslFn( `
|
|
|
80
89
|
* Execution: ALWAYS
|
|
81
90
|
*
|
|
82
91
|
* Events listened:
|
|
83
|
-
* pipeline:reset — reset
|
|
84
|
-
*
|
|
85
|
-
* autoexposure:updateParameters — update key value, speeds, bounds, percentiles
|
|
92
|
+
* pipeline:reset — soft reset (keeps the exposure, discards an in-flight readback)
|
|
93
|
+
* pipeline:lightingChanged — a new model or environment: start the exposure history over
|
|
86
94
|
*
|
|
87
95
|
* Textures published: (none — publishes state, not textures)
|
|
88
96
|
* Textures read: edgeFiltering:output > asvgf:output > pathtracer:color
|
|
@@ -104,11 +112,11 @@ export class AutoExposure extends RenderStage {
|
|
|
104
112
|
|
|
105
113
|
// ── Adaptation uniforms ──────────────────────────
|
|
106
114
|
|
|
107
|
-
this.keyValueU = uniform( options.keyValue ??
|
|
108
|
-
this.minExposureU = uniform( options.minExposure ??
|
|
109
|
-
this.maxExposureU = uniform( options.maxExposure ??
|
|
110
|
-
this.adaptSpeedBrightU = uniform( options.adaptSpeedBright ??
|
|
111
|
-
this.adaptSpeedDarkU = uniform( options.adaptSpeedDark ??
|
|
115
|
+
this.keyValueU = uniform( options.keyValue ?? AUTO_EXPOSURE_DEFAULTS.autoExposureKeyValue );
|
|
116
|
+
this.minExposureU = uniform( options.minExposure ?? AUTO_EXPOSURE_DEFAULTS.autoExposureMinExposure );
|
|
117
|
+
this.maxExposureU = uniform( options.maxExposure ?? AUTO_EXPOSURE_DEFAULTS.autoExposureMaxExposure );
|
|
118
|
+
this.adaptSpeedBrightU = uniform( options.adaptSpeedBright ?? AUTO_EXPOSURE_DEFAULTS.autoExposureAdaptSpeedBright );
|
|
119
|
+
this.adaptSpeedDarkU = uniform( options.adaptSpeedDark ?? AUTO_EXPOSURE_DEFAULTS.autoExposureAdaptSpeedDark );
|
|
112
120
|
this.epsilonU = uniform( options.epsilon ?? 0.0001 );
|
|
113
121
|
this.deltaTimeU = uniform( 1.0 / 60.0 );
|
|
114
122
|
this.isFirstFrameU = uniform( 1.0 ); // 1.0 = true
|
|
@@ -471,15 +479,7 @@ export class AutoExposure extends RenderStage {
|
|
|
471
479
|
setupEventListeners() {
|
|
472
480
|
|
|
473
481
|
this.on( 'pipeline:reset', () => this.reset() );
|
|
474
|
-
this.on( '
|
|
475
|
-
|
|
476
|
-
this.on( 'autoexposure:toggle', ( enabled ) => {
|
|
477
|
-
|
|
478
|
-
this.enabled = enabled;
|
|
479
|
-
|
|
480
|
-
} );
|
|
481
|
-
|
|
482
|
-
this.on( 'autoexposure:updateParameters', ( data ) => data && this.updateParameters( data ) );
|
|
482
|
+
this.on( 'pipeline:lightingChanged', () => this.resetHistory() );
|
|
483
483
|
|
|
484
484
|
}
|
|
485
485
|
|
|
@@ -4,7 +4,8 @@ import { RenderTarget, TextureNode, StorageTexture } from 'three/webgpu';
|
|
|
4
4
|
import { HalfFloatType, RGBAFormat, LinearFilter, Box2, Vector2 } from 'three';
|
|
5
5
|
import { RenderStage, StageExecutionMode } from '../Pipeline/RenderStage.js';
|
|
6
6
|
import { luminance } from '../TSL/Common.js';
|
|
7
|
-
import {
|
|
7
|
+
import { MAX_STORAGE_TEXTURE_SIZE } from '../Processor/StorageTexturePool.js';
|
|
8
|
+
import { ALBEDO_EPS } from './DenoiserSettings.js';
|
|
8
9
|
|
|
9
10
|
// SVGF bilateral edge-stopping weight. All three φ params are relative
|
|
10
11
|
// tolerances (unitless fractions) so the filter is scale-invariant across
|
package/src/Stages/Compositor.js
CHANGED
|
@@ -4,15 +4,6 @@ import { NoBlending, NoToneMapping } from 'three';
|
|
|
4
4
|
import { RenderStage, StageExecutionMode } from '../Pipeline/RenderStage.js';
|
|
5
5
|
import { REC709_LUMINANCE_COEFFICIENTS } from '../TSL/Common.js';
|
|
6
6
|
|
|
7
|
-
// In priority order: the first one published wins.
|
|
8
|
-
const LIGHT_SOURCES = [
|
|
9
|
-
'oidn:output',
|
|
10
|
-
'edgeFiltering:output',
|
|
11
|
-
'bilateralFiltering:output',
|
|
12
|
-
'asvgf:output',
|
|
13
|
-
'nrd:output',
|
|
14
|
-
'pathtracer:color',
|
|
15
|
-
];
|
|
16
7
|
|
|
17
8
|
/**
|
|
18
9
|
* Compositor — Terminal pipeline stage.
|
|
@@ -36,6 +27,10 @@ export class Compositor extends RenderStage {
|
|
|
36
27
|
|
|
37
28
|
this.renderer = renderer;
|
|
38
29
|
|
|
30
|
+
// In priority order: the first one published wins. Whoever builds the pipeline names the
|
|
31
|
+
// processed pictures; the accumulation is the fallback that is always there.
|
|
32
|
+
this._lightSources = [ ...( options.displaySources ?? [] ), 'pathtracer:color' ];
|
|
33
|
+
|
|
39
34
|
// 1.0 = neutral; >1 boosts to compensate for ACES/AgX desaturation.
|
|
40
35
|
this.saturation = uniform( options.saturation ?? 1.0 );
|
|
41
36
|
|
|
@@ -71,18 +66,8 @@ export class Compositor extends RenderStage {
|
|
|
71
66
|
}
|
|
72
67
|
|
|
73
68
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*/
|
|
77
|
-
_resolveSourceTexture( context ) {
|
|
78
|
-
|
|
79
|
-
return context.getTexture( 'bloom:output' ) || this.resolveLightTexture( context );
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* The newest scene-referred image the pipeline holds — denoised when a denoiser has run — without
|
|
85
|
-
* bloom, which is a look added on top rather than light in the scene.
|
|
69
|
+
* The picture to show: the first published of the display sources, else `pathtracer:color` — the newest
|
|
70
|
+
* scene-referred image the pipeline holds, denoised when a denoiser has run.
|
|
86
71
|
*/
|
|
87
72
|
resolveLightTexture( context ) {
|
|
88
73
|
|
|
@@ -93,7 +78,7 @@ export class Compositor extends RenderStage {
|
|
|
93
78
|
/** {@link resolveLightTexture} plus the context key it came from. */
|
|
94
79
|
resolveLightSource( context ) {
|
|
95
80
|
|
|
96
|
-
for ( const key of
|
|
81
|
+
for ( const key of this._lightSources ) {
|
|
97
82
|
|
|
98
83
|
const texture = context.getTexture( key );
|
|
99
84
|
if ( texture ) return { key, texture };
|
|
@@ -215,7 +200,7 @@ export class Compositor extends RenderStage {
|
|
|
215
200
|
|
|
216
201
|
}
|
|
217
202
|
|
|
218
|
-
const sourceTexture = this.
|
|
203
|
+
const sourceTexture = this.resolveLightTexture( context );
|
|
219
204
|
if ( ! sourceTexture ) return;
|
|
220
205
|
|
|
221
206
|
this._sourceTexNode.value = sourceTexture;
|