rayzee 7.22.4 → 7.22.6
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/dist/rayzee.es.js +328 -328
- package/dist/rayzee.umd.js +24 -24
- package/package.json +1 -1
- package/src/Stages/EdgeFilter.js +22 -9
- package/src/TSL/PathTracerCore.js +5 -1
package/package.json
CHANGED
package/src/Stages/EdgeFilter.js
CHANGED
|
@@ -18,6 +18,9 @@ const MISS_THRESHOLD = 6e4;
|
|
|
18
18
|
const sanitize1 = ( x ) => select( x.equal( x ), x, float( 0.0 ) ).clamp( 0.0, 1e7 );
|
|
19
19
|
const sanitizeRGB = ( c ) => vec3( sanitize1( c.x ), sanitize1( c.y ), sanitize1( c.z ) );
|
|
20
20
|
|
|
21
|
+
// Frames before the temporal EMA variance is trusted on its own (Schied 2017 §4.2).
|
|
22
|
+
const VARIANCE_HISTORY_MIN = 4;
|
|
23
|
+
|
|
21
24
|
// 5×5 à-trous kernel weights (B3-spline / Gaussian approx, Σ = 1.0).
|
|
22
25
|
const ATROUS_KERNEL = [
|
|
23
26
|
1.0 / 256.0, 4.0 / 256.0, 6.0 / 256.0, 4.0 / 256.0, 1.0 / 256.0,
|
|
@@ -66,7 +69,9 @@ export class EdgeFilter extends RenderStage {
|
|
|
66
69
|
// phiNormal: normal cone exponent (bigger = tighter, preserves more edges).
|
|
67
70
|
// phiDepth: RELATIVE depth tolerance (fraction of ray distance, scale-invariant).
|
|
68
71
|
this.filterStrength = uniform( options.filterStrength ?? 1.0 );
|
|
69
|
-
|
|
72
|
+
// 1.0, not the old 4.0, which was tuned against the non-converging variance seed below
|
|
73
|
+
// and now over-blurs enough to lose to no denoising at all from ~16spp up.
|
|
74
|
+
this.phiLuminance = uniform( options.phiLuminance ?? 1.0 );
|
|
70
75
|
this.phiNormal = uniform( options.phiNormal ?? 64.0 );
|
|
71
76
|
this.phiDepth = uniform( options.phiDepth ?? 0.1 );
|
|
72
77
|
this.iterations = options.atrousIterations ?? options.edgeAtrousIterations ?? 5;
|
|
@@ -75,6 +80,7 @@ export class EdgeFilter extends RenderStage {
|
|
|
75
80
|
this.isLastIterationU = uniform( 0, 'int' );
|
|
76
81
|
// 1 on pass 0 → seed variance from variance:output; later passes read the carried value.
|
|
77
82
|
this.isFirstIterationU = uniform( 1, 'int' );
|
|
83
|
+
this.varianceHistoryU = uniform( 0, 'int' );
|
|
78
84
|
this.resW = uniform( options.width || 1 );
|
|
79
85
|
this.resH = uniform( options.height || 1 );
|
|
80
86
|
|
|
@@ -205,6 +211,7 @@ export class EdgeFilter extends RenderStage {
|
|
|
205
211
|
const stepSize = this.stepSizeU;
|
|
206
212
|
const isLastIterationU = this.isLastIterationU;
|
|
207
213
|
const isFirstIterationU = this.isFirstIterationU;
|
|
214
|
+
const varianceHistoryU = this.varianceHistoryU;
|
|
208
215
|
const resW = this.resW;
|
|
209
216
|
const resH = this.resH;
|
|
210
217
|
|
|
@@ -233,19 +240,23 @@ export class EdgeFilter extends RenderStage {
|
|
|
233
240
|
const demodAlbedo = select( centerIsHitBool, max( centerAlbedo, vec3( ALBEDO_EPS ) ), vec3( 1.0 ) );
|
|
234
241
|
const centerAlbedoLum = max( luminance( demodAlbedo ), float( ALBEDO_EPS ) );
|
|
235
242
|
|
|
236
|
-
// Variance-guided luminance σ (SVGF). .z = temporal, .w = spatial variance
|
|
237
|
-
//
|
|
238
|
-
//
|
|
239
|
-
//
|
|
243
|
+
// Variance-guided luminance σ (SVGF). .z = temporal, .w = spatial variance.
|
|
244
|
+
// Temporal only, once the EMA is warm: .w is the 3×3 contrast of the
|
|
245
|
+
// *accumulated* image, so it plateaus at scene detail instead of decaying with
|
|
246
|
+
// sample count. max()-ing it in pinned sigma_l wide forever, which left the
|
|
247
|
+
// geometric gates — binary reads off the jitter-free G-buffer — to snap every
|
|
248
|
+
// antialiased silhouette pixel to one side, destroying sub-pixel AA.
|
|
240
249
|
//
|
|
241
|
-
//
|
|
242
|
-
//
|
|
243
|
-
// the
|
|
250
|
+
// Dividing by albedoLum rescales the modulated-space variance into demodulated
|
|
251
|
+
// space (std ∝ 1/albedo). Filtered alongside colour and carried between passes
|
|
252
|
+
// as √variance in the ping-pong's spare alpha, so sigma_l tightens as the signal
|
|
253
|
+
// smooths. Stored as the root because converged variance is a half-float subnormal.
|
|
244
254
|
const isFirst = isFirstIterationU.equal( int( 1 ) );
|
|
255
|
+
const historyShort = varianceHistoryU.lessThan( int( VARIANCE_HISTORY_MIN ) );
|
|
245
256
|
const seedVariance = ( at ) => {
|
|
246
257
|
|
|
247
258
|
const v = textureLoad( varTex, at );
|
|
248
|
-
return max( v.z, v.w );
|
|
259
|
+
return select( historyShort, max( v.z, v.w ), v.z );
|
|
249
260
|
|
|
250
261
|
};
|
|
251
262
|
|
|
@@ -383,6 +394,8 @@ export class EdgeFilter extends RenderStage {
|
|
|
383
394
|
|
|
384
395
|
}
|
|
385
396
|
|
|
397
|
+
this.varianceHistoryU.value = context.getState( 'accumulatedFrames' ) ?? 0;
|
|
398
|
+
|
|
386
399
|
this._colorTexNode.value = colorTex;
|
|
387
400
|
this._ndTexNode.value = ndTex;
|
|
388
401
|
this._snTexNode.value = snTex;
|
|
@@ -356,7 +356,11 @@ export const handleRussianRoulette = Fn( ( [
|
|
|
356
356
|
rrProb.mulAssign( depthFactor );
|
|
357
357
|
|
|
358
358
|
const minProb = select( mc.isEmissive, float( 0.04 ), float( 0.02 ) );
|
|
359
|
-
|
|
359
|
+
// Upper clamp is load-bearing, not cosmetic: pathContribution scales with throughput,
|
|
360
|
+
// which prior RR compensation inflates well past 1, so rrProb could exceed 1. The path
|
|
361
|
+
// then always survives while throughput is still divided by rrProb — a plain energy
|
|
362
|
+
// sink that compounds with depth (albedo-1 concave furnace read 0.955 instead of 1.0).
|
|
363
|
+
rrProb.assign( clamp( rrProb, minProb, 1.0 ) );
|
|
360
364
|
|
|
361
365
|
const rrSample = getRandomSample1D( pixelCoord, int( 0 ), dimBase.add( int( 3 ) ), rngState, resolution, frame );
|
|
362
366
|
result.assign( select( rrSample.lessThan( rrProb ), rrProb, float( 0.0 ) ) );
|