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
package/package.json
CHANGED
|
@@ -55,8 +55,8 @@ const MODEL_CONFIG = {
|
|
|
55
55
|
DEFAULT_OPTIONS: {
|
|
56
56
|
enableOIDN: true,
|
|
57
57
|
oidnQuality: 'fast',
|
|
58
|
-
// A cap on the frame, not a tile size: a frame
|
|
59
|
-
//
|
|
58
|
+
// A cap on the frame, not a tile size: a frame no larger in area than this square is one
|
|
59
|
+
// tile, with no overlap. The area bounds the network's activation memory.
|
|
60
60
|
tileSize: 1024
|
|
61
61
|
}
|
|
62
62
|
};
|
|
@@ -382,16 +382,14 @@ export class OIDNDenoiser extends EventDispatcher {
|
|
|
382
382
|
*/
|
|
383
383
|
_resolveTileSize() {
|
|
384
384
|
|
|
385
|
-
|
|
386
|
-
if ( ! longest ) return this.maxTileSize;
|
|
385
|
+
if ( ! this._renderWidth || ! this._renderHeight ) return this.maxTileSize;
|
|
387
386
|
|
|
388
|
-
//
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
}
|
|
387
|
+
// One tile for any frame no larger in area than the square the cap allows: oidn-web's memory
|
|
388
|
+
// follows the tile's area, not its longest side, so a wide frame needs no split. The cap is on
|
|
389
|
+
// the frame, so the border never splits a frame that fits.
|
|
390
|
+
const input = oidnInputSize( this._renderWidth, this._renderHeight );
|
|
391
|
+
const largest = oidnInputSize( this.maxTileSize, this.maxTileSize );
|
|
392
|
+
if ( input.width * input.height <= largest.width * largest.height ) return Math.max( input.width, input.height );
|
|
395
393
|
|
|
396
394
|
return Math.max( OIDN_TILE_ALIGNMENT, Math.floor( this.maxTileSize / OIDN_TILE_ALIGNMENT ) * OIDN_TILE_ALIGNMENT );
|
|
397
395
|
|
package/src/PathTracerApp.js
CHANGED
|
@@ -2,11 +2,7 @@ import { Box3, Vector3 } from 'three';
|
|
|
2
2
|
import { RayzeeRenderer, describeAdapter, RENDER_CHECKPOINT_VERSION } from './RayzeeRenderer.js';
|
|
3
3
|
import { NormalDepth } from './Stages/NormalDepth.js';
|
|
4
4
|
import { MotionVector } from './Stages/MotionVector.js';
|
|
5
|
-
import { ASVGF } from './Stages/ASVGF.js';
|
|
6
5
|
import { NRD } from './Stages/NRD.js';
|
|
7
|
-
import { Variance } from './Stages/Variance.js';
|
|
8
|
-
import { BilateralFilter } from './Stages/BilateralFilter.js';
|
|
9
|
-
import { EdgeFilter } from './Stages/EdgeFilter.js';
|
|
10
6
|
import { AutoExposure, AUTO_EXPOSURE_DEFAULTS } from './Stages/AutoExposure.js';
|
|
11
7
|
import { LocalExposure, LOCAL_EXPOSURE_DEFAULTS } from './Stages/LocalExposure.js';
|
|
12
8
|
import { PRODUCTION_RENDER_CONFIG, INTERACTIVE_RENDER_CONFIG, modePresetSettings } from './EngineDefaults.js';
|
|
@@ -151,17 +147,12 @@ export class PathTracerApp extends RayzeeRenderer {
|
|
|
151
147
|
const { renderer, stages } = this;
|
|
152
148
|
stages.normalDepth = new NormalDepth( renderer, { pathTracer: stages.pathTracer } );
|
|
153
149
|
stages.motionVector = new MotionVector( renderer, this.camera, { pathTracer: stages.pathTracer } );
|
|
154
|
-
stages.asvgf = new ASVGF( renderer, { enabled: false } );
|
|
155
150
|
stages.nrd = new NRD( renderer, { enabled: false, pathTracer: stages.pathTracer } );
|
|
156
|
-
stages.variance = new Variance( renderer, { enabled: false } );
|
|
157
|
-
stages.bilateralFilter = new BilateralFilter( renderer, { enabled: false } );
|
|
158
|
-
stages.edgeFilter = new EdgeFilter( renderer, { enabled: false } );
|
|
159
151
|
stages.autoExposure = new AutoExposure( renderer, { enabled: AUTO_EXPOSURE_DEFAULTS.autoExposure } );
|
|
160
152
|
stages.localExposure = new LocalExposure( renderer, { enabled: LOCAL_EXPOSURE_DEFAULTS.localExposure } );
|
|
161
153
|
|
|
162
154
|
return [
|
|
163
|
-
stages.normalDepth, stages.motionVector, stages.nrd, stages.
|
|
164
|
-
stages.variance, stages.bilateralFilter, stages.edgeFilter, stages.autoExposure, stages.localExposure,
|
|
155
|
+
stages.normalDepth, stages.motionVector, stages.nrd, stages.autoExposure, stages.localExposure,
|
|
165
156
|
];
|
|
166
157
|
|
|
167
158
|
}
|
|
@@ -318,7 +309,7 @@ export class PathTracerApp extends RayzeeRenderer {
|
|
|
318
309
|
|
|
319
310
|
_displaySources() {
|
|
320
311
|
|
|
321
|
-
return [ 'oidn:output', '
|
|
312
|
+
return [ 'oidn:output', 'nrd:output' ];
|
|
322
313
|
|
|
323
314
|
}
|
|
324
315
|
|
|
@@ -338,8 +329,10 @@ export class PathTracerApp extends RayzeeRenderer {
|
|
|
338
329
|
|
|
339
330
|
this.cameraManager.applyProjection( value );
|
|
340
331
|
// MotionVector unprojects through projectionMatrixInverse, which is meaningless once every pixel is its
|
|
341
|
-
// own direction:
|
|
342
|
-
if ( value === 'equirectangular' && this.denoisingManager?.requiresMotionVectors ) this.denoisingManager.setDenoiserStrategy( '
|
|
332
|
+
// own direction: hand the view to OIDN, which needs none, rather than leaving no denoiser.
|
|
333
|
+
if ( value === 'equirectangular' && this.denoisingManager?.requiresMotionVectors ) this.denoisingManager.setDenoiserStrategy( 'oidn' );
|
|
334
|
+
// OIDN's motion history is off in a panorama and back on outside one.
|
|
335
|
+
else this.denoisingManager?._syncGBufferStages?.();
|
|
343
336
|
|
|
344
337
|
},
|
|
345
338
|
};
|
|
@@ -1106,11 +1099,7 @@ export class PathTracerApp extends RayzeeRenderer {
|
|
|
1106
1099
|
pathTracer: this.stages.pathTracer,
|
|
1107
1100
|
normalDepth: this.stages.normalDepth,
|
|
1108
1101
|
motionVector: this.stages.motionVector,
|
|
1109
|
-
asvgf: this.stages.asvgf,
|
|
1110
1102
|
nrd: this.stages.nrd,
|
|
1111
|
-
variance: this.stages.variance,
|
|
1112
|
-
bilateralFilter: this.stages.bilateralFilter,
|
|
1113
|
-
edgeFilter: this.stages.edgeFilter,
|
|
1114
1103
|
autoExposure: this.stages.autoExposure,
|
|
1115
1104
|
compositor: this.stages.compositor,
|
|
1116
1105
|
},
|
|
@@ -3,13 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Two TextureNodes still holding the default EmptyTexture when a stage's kernel is first
|
|
5
5
|
* compiled can share one GPU binding, which then resolves to whichever is assigned last.
|
|
6
|
-
* Nothing throws — the aliased node reads a real texture, just not its own.
|
|
7
|
-
* shipped this way, reading ASVGF's history counter as its variance.
|
|
6
|
+
* Nothing throws — the aliased node reads a real texture, just not its own.
|
|
8
7
|
*
|
|
9
8
|
* Rule enforced: every TextureNode a kernel reads must hold its real texture before that
|
|
10
9
|
* kernel is first dispatched. StorageTexture-typed nodes are exempt — `textureLoad` codegen
|
|
11
10
|
* only emits the required `level` parameter while the node still holds EmptyTexture, so those
|
|
12
|
-
* are deliberately bound after compile
|
|
11
|
+
* are deliberately bound after compile.
|
|
13
12
|
*
|
|
14
13
|
* Off by default; the bench harness turns it on.
|
|
15
14
|
*/
|
|
@@ -23,8 +23,7 @@ import { ISSUE_CODES } from '../EngineIssues.js';
|
|
|
23
23
|
*
|
|
24
24
|
* // Add stages in execution order
|
|
25
25
|
* pipeline.addStage(new PathTracer(...));
|
|
26
|
-
* pipeline.addStage(new
|
|
27
|
-
* pipeline.addStage(new EdgeFilter(...));
|
|
26
|
+
* pipeline.addStage(new NRD(...));
|
|
28
27
|
*
|
|
29
28
|
* // Render all stages
|
|
30
29
|
* pipeline.render(writeBuffer);
|
|
@@ -12,7 +12,7 @@ export const StageExecutionMode = {
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* PER_CYCLE - Execute only when tile rendering cycle completes
|
|
15
|
-
* Use for: Post-processing, denoisers, filters (
|
|
15
|
+
* Use for: Post-processing, denoisers, filters (NRD, OIDN)
|
|
16
16
|
*
|
|
17
17
|
* Complete cycle means:
|
|
18
18
|
* - Progressive mode (renderMode=0): Every frame
|
|
@@ -424,7 +424,7 @@ export const writeMediumStack = ( buf, id, stackDepth, transTraversals, ior1, io
|
|
|
424
424
|
), ior1, ior2, ior3 ) );
|
|
425
425
|
|
|
426
426
|
// Region 7: Beer-Lambert sigmaA (.xyz) of the active medium + DDFA feature-throughput (.w).
|
|
427
|
-
// .xyz absorption is gated on stackDepth>0; .w carries the OIDN/
|
|
427
|
+
// .xyz absorption is gated on stackDepth>0; .w carries the OIDN/NRD see-through aux tint (see below).
|
|
428
428
|
// Both writers RMW-preserve the other half so sigmaA (live in glass) and featTP never clobber each other.
|
|
429
429
|
export const readMediumSigmaA = ( buf, id ) => buf.element( soa( id, RAY.MEDIUM_SIGMA_A ) ).xyz;
|
|
430
430
|
|
|
@@ -436,7 +436,7 @@ export const writeMediumSigmaA = ( buf, id, sigmaA ) => {
|
|
|
436
436
|
};
|
|
437
437
|
|
|
438
438
|
// DDFA (Deferred Denoising-Feature Aux) feature-throughput: a clean per-ray tint carried through smooth
|
|
439
|
-
// glass/mirror, committed into the OIDN/
|
|
439
|
+
// glass/mirror, committed into the OIDN/NRD albedo guide at the first diffuse-enough surface. Rides the
|
|
440
440
|
// otherwise-dead MEDIUM_SIGMA_A.w, packed 10/10/10 into 30 bits (top 2 bits zero ⇒ the float bit-pattern is
|
|
441
441
|
// always finite — never NaN/Inf). LDR [0,1] per channel; final albedo re-quantizes to unorm16 anyway.
|
|
442
442
|
const pack30 = ( tp ) => {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - 1 MRT RenderTarget (3 attachments) used as the readable copy
|
|
8
8
|
* - After each compute dispatch, copyTextureToTexture() transfers data
|
|
9
9
|
* from StorageTextures → RenderTarget textures
|
|
10
|
-
* - Downstream stages (
|
|
10
|
+
* - Downstream stages (NRD, display, OIDN) read from the RenderTarget
|
|
11
11
|
* - Previous-frame reads in the path tracer sample from RenderTarget textures
|
|
12
12
|
* via texture() (not storageTexture().toReadOnly())
|
|
13
13
|
*/
|
package/src/RayzeeRenderer.js
CHANGED
|
@@ -2730,7 +2730,7 @@ export class RayzeeRenderer extends EventDispatcher {
|
|
|
2730
2730
|
* accumulation
|
|
2731
2731
|
* @returns {Promise<{data: Float32Array|Uint8ClampedArray, width: number, height: number, colorSpace: string,
|
|
2732
2732
|
* source: string, toneMappedOn?: 'gpu'|'cpu'}>} `source` is what was read: `'accumulation'`, or the
|
|
2733
|
-
* denoiser that published it (`'oidn'`, `'
|
|
2733
|
+
* denoiser that published it (`'oidn'`, `'nrd'`).
|
|
2734
2734
|
* `toneMappedOn` is set for `'srgb'` only.
|
|
2735
2735
|
*/
|
|
2736
2736
|
async renderToBuffer( { colorSpace = 'srgb', preserveAlpha = false, source = 'accumulation' } = {} ) {
|
|
@@ -4,57 +4,12 @@
|
|
|
4
4
|
export const GBUFFER_MISS_DEPTH = 65504.0;
|
|
5
5
|
export const GBUFFER_MISS_THRESHOLD = 6e4;
|
|
6
6
|
|
|
7
|
-
// Albedo demodulation safety floor.
|
|
8
|
-
//
|
|
9
|
-
// only round-trip exactly when both sides agree.
|
|
7
|
+
// Albedo demodulation safety floor. Demod (`color / safeAlbedo`) and remod (`lighting * safeAlbedo`)
|
|
8
|
+
// only round-trip exactly when both sides use the same value.
|
|
10
9
|
export const ALBEDO_EPS = 0.01;
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// permissive. The adaptive temporal gradient (gradientStrength > 0) is always
|
|
15
|
-
// on: it measures real change in units of noise σ (gradientSigmaScale), so a
|
|
16
|
-
// static scene reads ~0 (no convergence penalty) and only moving lights / anim
|
|
17
|
-
// / disocclusion drop history. See ASVGF._buildGradientCompute.
|
|
18
|
-
low: {
|
|
19
|
-
temporalAlpha: 0.1,
|
|
20
|
-
gradientStrength: 0.8,
|
|
21
|
-
gradientSigmaScale: 2.5,
|
|
22
|
-
gradientNoiseFloor: 0.05,
|
|
23
|
-
atrousIterations: 3,
|
|
24
|
-
phiColor: 1.0,
|
|
25
|
-
phiNormal: 64.0,
|
|
26
|
-
phiDepth: 0.1,
|
|
27
|
-
phiLuminance: 6.0,
|
|
28
|
-
maxAccumFrames: 16,
|
|
29
|
-
varianceBoost: 0.5
|
|
30
|
-
},
|
|
31
|
-
medium: {
|
|
32
|
-
temporalAlpha: 0.03,
|
|
33
|
-
gradientStrength: 1.0,
|
|
34
|
-
gradientSigmaScale: 2.5,
|
|
35
|
-
gradientNoiseFloor: 0.05,
|
|
36
|
-
atrousIterations: 4,
|
|
37
|
-
phiColor: 0.5,
|
|
38
|
-
phiNormal: 128.0,
|
|
39
|
-
phiDepth: 0.05,
|
|
40
|
-
phiLuminance: 4.0,
|
|
41
|
-
maxAccumFrames: 64,
|
|
42
|
-
varianceBoost: 1.0
|
|
43
|
-
},
|
|
44
|
-
high: {
|
|
45
|
-
temporalAlpha: 0.0,
|
|
46
|
-
gradientStrength: 1.0,
|
|
47
|
-
gradientSigmaScale: 2.5,
|
|
48
|
-
gradientNoiseFloor: 0.05,
|
|
49
|
-
atrousIterations: 6,
|
|
50
|
-
phiColor: 0.3,
|
|
51
|
-
phiNormal: 256.0,
|
|
52
|
-
phiDepth: 0.02,
|
|
53
|
-
phiLuminance: 2.0,
|
|
54
|
-
maxAccumFrames: 128,
|
|
55
|
-
varianceBoost: 1.5
|
|
56
|
-
}
|
|
57
|
-
};
|
|
11
|
+
// The live view's denoisers, for setDenoiserStrategy.
|
|
12
|
+
export const DENOISER_STRATEGIES = Object.freeze( [ 'none', 'nrd', 'oidn' ] );
|
|
58
13
|
|
|
59
14
|
// normHitDist = hitDist / (A + B·viewZ). A constant, not a uniform: the Shade write and the NRD
|
|
60
15
|
// decode must agree, and the normalization is a pure round trip.
|
|
@@ -122,21 +77,9 @@ export const NRD_QUALITY_PRESETS = {
|
|
|
122
77
|
},
|
|
123
78
|
};
|
|
124
79
|
|
|
125
|
-
const ASVGF_MEDIUM = ASVGF_QUALITY_PRESETS.medium;
|
|
126
|
-
|
|
127
80
|
// What the live denoisers, the final OIDN pass and the AI upscaler start with; a host's own state seeds from these.
|
|
128
81
|
export const DENOISER_DEFAULTS = {
|
|
129
|
-
denoiserStrategy: 'none', // the live view's denoiser
|
|
130
|
-
|
|
131
|
-
// EdgeAware denoiser (spatial-only SVGF à-trous). filterStrength: final blend
|
|
132
|
-
// (0 = raw, 1 = filtered). edgeAtrousIterations: à-trous passes (step 1,2,4,8,16).
|
|
133
|
-
// edgePhiLuminance: variance-scaled luminance edge-stop. edgePhiNormal: normal cone
|
|
134
|
-
// exponent. edgePhiDepth: RELATIVE depth tolerance (fraction of ray distance).
|
|
135
|
-
filterStrength: 1.0,
|
|
136
|
-
edgeAtrousIterations: 5,
|
|
137
|
-
edgePhiLuminance: 4.0,
|
|
138
|
-
edgePhiNormal: 64.0,
|
|
139
|
-
edgePhiDepth: 0.1,
|
|
82
|
+
denoiserStrategy: 'none', // the live view's denoiser, one of DENOISER_STRATEGIES
|
|
140
83
|
|
|
141
84
|
enableOIDN: false,
|
|
142
85
|
oidnQuality: 'fast',
|
|
@@ -157,25 +100,6 @@ export const DENOISER_DEFAULTS = {
|
|
|
157
100
|
upscalerQuality: 'fast',
|
|
158
101
|
upscalerHdr: true,
|
|
159
102
|
|
|
160
|
-
// ASVGF runs its quality preset whenever it is switched on, so its values are that preset's.
|
|
161
|
-
enableASVGF: false,
|
|
162
|
-
asvgfQualityPreset: 'medium',
|
|
163
|
-
asvgfTemporalAlpha: ASVGF_MEDIUM.temporalAlpha,
|
|
164
|
-
asvgfAtrousIterations: ASVGF_MEDIUM.atrousIterations,
|
|
165
|
-
asvgfPhiColor: ASVGF_MEDIUM.phiColor,
|
|
166
|
-
asvgfPhiNormal: ASVGF_MEDIUM.phiNormal,
|
|
167
|
-
asvgfPhiDepth: ASVGF_MEDIUM.phiDepth,
|
|
168
|
-
asvgfPhiLuminance: ASVGF_MEDIUM.phiLuminance,
|
|
169
|
-
asvgfVarianceBoost: ASVGF_MEDIUM.varianceBoost,
|
|
170
|
-
asvgfMaxAccumFrames: ASVGF_MEDIUM.maxAccumFrames,
|
|
171
|
-
// Must be > 0: the gradient also rejects fireflies before the EMA smears them across
|
|
172
|
-
// ~1/alpha frames. At 0 the denoiser measures ~3x worse than no denoiser at 1 spp.
|
|
173
|
-
asvgfGradientStrength: ASVGF_MEDIUM.gradientStrength,
|
|
174
|
-
asvgfGradientSigmaScale: ASVGF_MEDIUM.gradientSigmaScale,
|
|
175
|
-
asvgfGradientNoiseFloor: ASVGF_MEDIUM.gradientNoiseFloor,
|
|
176
|
-
asvgfDebugMode: 0,
|
|
177
|
-
showAsvgfHeatmap: false,
|
|
178
|
-
|
|
179
103
|
// NRD (ReBLUR port) real-time denoiser — see NRD_DEFAULTS / NRD_QUALITY_PRESETS.
|
|
180
104
|
nrdQualityPreset: 'medium',
|
|
181
105
|
nrdDebugMode: 0,
|