@@ -284,27 +284,42 @@ struct GGX
284284 return dmq;
285285 }
286286
287- template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction>)
288- scalar_type correlated_wo_numerator (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
287+ template<class LS, class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache >)
288+ scalar_type correlated_wo_numerator (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction, NBL_CONST_REF_ARG (MicrofacetCache) cache )
289289 {
290+ scalar_type NdotV = interaction.getNdotV (_clamp);
291+ scalar_type NdotL = _sample.getNdotL (_clamp);
292+ scalar_type devsh_v = query.getDevshV ();
293+ scalar_type devsh_l = query.getDevshL ();
290294 // without numerator, numerator is 2 * NdotV * NdotL, we factor out 4 * NdotV * NdotL, hence 0.5
291- scalar_type Vterm = _sample.getNdotL (_clamp) * query.getDevshV ();
292- scalar_type Lterm = interaction.getNdotV (_clamp) * query.getDevshL ();
293- return scalar_type (0.5 ) / (Vterm + Lterm);
295+ if (cache.isTransmission ())
296+ {
297+ if (NdotV < 1e-7 || NdotL < 1e-7 )
298+ return 0.0 ;
299+ scalar_type onePlusLambda_V = scalar_type (0.5 ) * (devsh_v / NdotV + scalar_type (1.0 ));
300+ scalar_type onePlusLambda_L = scalar_type (0.5 ) * (devsh_l / NdotL + scalar_type (1.0 ));
301+ return bxdf::beta_wo_check<scalar_type>(onePlusLambda_L, onePlusLambda_V);
302+ }
303+ else
304+ {
305+ scalar_type Vterm = NdotL * devsh_v;
306+ scalar_type Lterm = NdotV * devsh_l;
307+ return scalar_type (0.5 ) / (Vterm + Lterm);
308+ }
294309 }
295310
296- template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction>)
297- scalar_type correlated (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
311+ template<class LS, class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache >)
312+ scalar_type correlated (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction, NBL_CONST_REF_ARG (MicrofacetCache) cache )
298313 {
299- return scalar_type (4.0 ) * interaction.getNdotV (_clamp) * _sample.getNdotL (_clamp) * correlated_wo_numerator<LS, Interaction>(query, _sample, interaction);
314+ return scalar_type (4.0 ) * interaction.getNdotV (_clamp) * _sample.getNdotL (_clamp) * correlated_wo_numerator<LS, Interaction, MicrofacetCache >(query, _sample, interaction, cache );
300315 }
301316
302317 template<class LS, class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
303318 quant_type Dcorrelated (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (quant_query_type) quant_query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction, NBL_CONST_REF_ARG (MicrofacetCache) cache)
304319 {
305320 scalar_type dg = __ndf_base.template D<MicrofacetCache>(cache);
306321 if (dg < bit_cast<scalar_type>(numeric_limits<scalar_type>::infinity))
307- dg *= correlated_wo_numerator<LS, Interaction>(query, _sample, interaction);
322+ dg *= correlated_wo_numerator<LS, Interaction, MicrofacetCache >(query, _sample, interaction, cache );
308323 else
309324 dg = scalar_type (0.0 );
310325
0 commit comments