rayzee 6.2.0 → 6.4.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.
@@ -206,28 +206,24 @@ export const generateSampledDirection = Fn( ( [
206
206
  const cumulativeDiffuse = weights.diffuse.toVar();
207
207
  const cumulativeSpecular = cumulativeDiffuse.add( weights.specular ).toVar();
208
208
  const cumulativeSheen = cumulativeSpecular.add( weights.sheen ).toVar();
209
- const cumulativeClearcoat = cumulativeSheen.add( weights.clearcoat ).toVar();
209
+ const cumulativeClearcoat = cumulativeSheen.add( weights.clearcoat );
210
210
 
211
- const sampled = tslBool( false ).toVar();
211
+ // Hoisted out of the lobe chain: used by both Specular and Clearcoat branches
212
+ const NoV = clamp( dot( N, V ), 0.001, 1.0 ).toVar();
212
213
 
213
- // Diffuse sampling
214
- If( rand.lessThan( cumulativeDiffuse ).and( sampled.not() ), () => {
214
+ // Chained If/ElseIf so emitted WGSL becomes a single mutually-exclusive branch
215
+ // (replaces five separate If blocks gated on a `sampled` flag divergence hotspot)
216
+ If( rand.lessThan( cumulativeDiffuse ), () => {
215
217
 
216
218
  resultDirection.assign( ImportanceSampleCosine( { N, xi: directionSample } ) );
217
219
  const NoL = clamp( dot( N, resultDirection ), 0.0, 1.0 );
218
220
  resultPdf.assign( NoL.mul( PI_INV ) );
219
221
  resultValue.assign( evaluateMaterialResponse( V, resultDirection, N, material ) );
220
- sampled.assign( tslBool( true ) );
221
-
222
- } );
223
-
224
- const NoV = clamp( dot( N, V ), 0.001, 1.0 ).toVar();
225
222
 
226
- // Specular sampling
227
- If( rand.lessThan( cumulativeSpecular ).and( sampled.not() ), () => {
223
+ } ).ElseIf( rand.lessThan( cumulativeSpecular ), () => {
228
224
 
229
225
  const TBN = constructTBN( { N } );
230
- const localV = TBN.transpose().mul( V ).toVar();
226
+ const localV = TBN.transpose().mul( V );
231
227
 
232
228
  // VNDF sampling
233
229
  const localH = sampleGGXVNDF( { V: localV, roughness: material.roughness, Xi: xi } );
@@ -238,12 +234,8 @@ export const generateSampledDirection = Fn( ( [
238
234
  resultDirection.assign( reflect( V.negate(), H ) );
239
235
  resultPdf.assign( calculateVNDFPDF( NoH, NoV, material.roughness ) );
240
236
  resultValue.assign( evaluateMaterialResponse( V, resultDirection, N, material ) );
241
- sampled.assign( tslBool( true ) );
242
237
 
243
- } );
244
-
245
- // Sheen sampling
246
- If( rand.lessThan( cumulativeSheen ).and( sampled.not() ), () => {
238
+ } ).ElseIf( rand.lessThan( cumulativeSheen ), () => {
247
239
 
248
240
  H.assign( ImportanceSampleGGX( { N, roughness: material.sheenRoughness, Xi: xi } ) );
249
241
  const NoH = clamp( dot( N, H ), 0.001, 1.0 );
@@ -267,12 +259,7 @@ export const generateSampledDirection = Fn( ( [
267
259
 
268
260
  } );
269
261
 
270
- sampled.assign( tslBool( true ) );
271
-
272
- } );
273
-
274
- // Clearcoat sampling
275
- If( rand.lessThan( cumulativeClearcoat ).and( sampled.not() ), () => {
262
+ } ).ElseIf( rand.lessThan( cumulativeClearcoat ), () => {
276
263
 
277
264
  const clearcoatRoughness = clamp( material.clearcoatRoughness, MIN_CLEARCOAT_ROUGHNESS, MAX_ROUGHNESS );
278
265
  H.assign( ImportanceSampleGGX( { N, roughness: clearcoatRoughness, Xi: xi } ) );
@@ -281,14 +268,11 @@ export const generateSampledDirection = Fn( ( [
281
268
  resultPdf.assign( calculateVNDFPDF( NoH, NoV, clearcoatRoughness ) );
282
269
  resultPdf.assign( max( resultPdf, MIN_PDF ) );
283
270
  resultValue.assign( evaluateMaterialResponse( V, resultDirection, N, material ) );
284
- sampled.assign( tslBool( true ) );
285
-
286
- } );
287
271
 
288
- // Transmission sampling (fallback)
289
- If( sampled.not(), () => {
272
+ } ).Else( () => {
290
273
 
291
- const entering = dot( V, N ).greaterThan( 0.0 ).toVar();
274
+ // Transmission sampling (fallback)
275
+ const entering = dot( V, N ).greaterThan( 0.0 );
292
276
  // pathWavelength=0 — only direction/PDF are consumed here, throughput goes via handleTransmission
293
277
  const mtResult = MicrofacetTransmissionResult.wrap( sampleMicrofacetTransmission(
294
278
  V, N, material.ior, material.roughness, entering, material.dispersion, xi, rngState, float( 0.0 ),
@@ -934,6 +918,18 @@ export const Trace = Fn( ( [
934
918
  const randomSample = getRandomSample( pixelCoord, rayIndex, bounceIndex, rngState, int( - 1 ), resolution, frame ).toVar();
935
919
 
936
920
  const V = rayDirection.negate().toVar();
921
+
922
+ // Two-sided shading: flip the shading normal into the viewer's hemisphere.
923
+ // This is the opaque reflection path (transmissive rays already Continue'd),
924
+ // so it never disturbs dielectric entering/exiting. No-op when N already
925
+ // faces V; rescues meshes with inward-facing normals (common in imported
926
+ // scenes, e.g. pbrt PLY assets) that would otherwise shade black.
927
+ If( dot( N, V ).lessThan( 0.0 ), () => {
928
+
929
+ N.assign( N.negate() );
930
+
931
+ } );
932
+
937
933
  material.sheenRoughness.assign( clamp( material.sheenRoughness, MIN_ROUGHNESS, MAX_ROUGHNESS ) );
938
934
 
939
935
  // Sync material classification cache up front — the materialCache, BRDF
@@ -100,9 +100,9 @@ export const computeUVCache = Fn( ( [ baseUV, material ] ) => {
100
100
  const roughnessUV = vec2( 0.0 ).toVar();
101
101
  const emissiveUV = vec2( 0.0 ).toVar();
102
102
  const bumpUV = vec2( 0.0 ).toVar();
103
- const normalBumpSameUV = normalBumpSame.or( allSameUV ).toVar();
104
- const metalRoughSameUV = metalRoughSame.or( allSameUV ).toVar();
105
- const albedoEmissiveSameUV = albedoEmissiveSame.or( allSameUV ).toVar();
103
+ const normalBumpSameUV = normalBumpSame.or( allSameUV );
104
+ const metalRoughSameUV = metalRoughSame.or( allSameUV );
105
+ const albedoEmissiveSameUV = albedoEmissiveSame.or( allSameUV );
106
106
 
107
107
  If( allSameUV, () => {
108
108
 
@@ -729,7 +729,7 @@ export class DenoisingManager extends EventDispatcher {
729
729
  if ( ! ctx ) return;
730
730
 
731
731
  const keys = [
732
- 'asvgf:output', 'asvgf:temporalColor', 'asvgf:variance',
732
+ 'asvgf:output', 'asvgf:demodulated', 'asvgf:gradient',
733
733
  'variance:output', 'bilateralFiltering:output',
734
734
  'edgeFiltering:output', 'ssrc:output',
735
735
  ];
@@ -740,7 +740,17 @@ export class DenoisingManager extends EventDispatcher {
740
740
  _applyASVGFPreset( presetName ) {
741
741
 
742
742
  const preset = ASVGF_QUALITY_PRESETS[ presetName ];
743
- if ( preset ) this._stages.asvgf?.updateParameters( preset );
743
+ if ( ! preset ) return;
744
+ // ASVGF consumes temporalAlpha / gradientStrength / maxAccumFrames.
745
+ // BilateralFilter consumes phi* edge-stopping params and atrousIterations.
746
+ // Variance consumes varianceBoost. Each stage cherry-picks what it needs.
747
+ this._stages.asvgf?.updateParameters( preset );
748
+ this._stages.bilateralFilter?.updateParameters( preset );
749
+ if ( this._stages.variance && preset.varianceBoost !== undefined ) {
750
+
751
+ this._stages.variance.varianceBoost.value = preset.varianceBoost;
752
+
753
+ }
744
754
 
745
755
  }
746
756