@@ -260,29 +260,55 @@ struct GGX
260260 quant_type D (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)
261261 {
262262 scalar_type d = __ndf_base.template D<MicrofacetCache>(cache);
263+ return createDualMeasureQuantity<T, reflect_refract, quant_query_type>(d, interaction.getNdotV (BxDFClampMode::BCM_ABS), _sample.getNdotL (BxDFClampMode::BCM_ABS), quant_query);
264+ }
265+
266+ template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction>)
267+ quant_type DG1 (NBL_CONST_REF_ARG (dg1_query_type) query, NBL_CONST_REF_ARG (quant_query_type) quant_query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
268+ {
269+ scalar_type dg1_over_2NdotV = query.getNdfwoNumerator () * query.getG1over2NdotV ();
263270 quant_type dmq;
264- dmq.microfacetMeasure = d ;
271+ dmq.microfacetMeasure = scalar_type ( 2.0 ) * interaction. getNdotV (_clamp) * dg1_over_2NdotV ;
265272
266273 NBL_IF_CONSTEXPR (SupportsTransmission)
267274 {
268275 const scalar_type VdotHLdotH = quant_query.getVdotHLdotH ();
269276 const bool transmitted = reflect_refract==MTT_REFRACT || (reflect_refract!=MTT_REFLECT && VdotHLdotH < scalar_type (0.0 ));
270- scalar_type NdotL_over_denominator = _sample. getNdotL (BxDFClampMode::BCM_ABS) ;
277+ dmq.projectedLightMeasure = hlsl:: mix ( scalar_type ( 0.5 ), scalar_type ( 2.0 ),transmitted) * dg1_over_2NdotV ;
271278 if (transmitted)
272- NdotL_over_denominator *= scalar_type (4.0 ) * VdotHLdotH * quant_query.getNeg_rcp2_VdotH_etaLdotH ();
273- dmq.projectedLightMeasure = d * NdotL_over_denominator;
279+ dmq.projectedLightMeasure *= VdotHLdotH * quant_query.getNeg_rcp2_VdotH_etaLdotH ();
274280 }
275281 else
276- dmq.projectedLightMeasure = d * _sample. getNdotL (BxDFClampMode::BCM_ABS) ;
282+ dmq.projectedLightMeasure = scalar_type ( 0.5 ) * dg1_over_2NdotV ;
277283 return dmq;
278284 }
279285
280286 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction>)
281- quant_type DG1 (NBL_CONST_REF_ARG (dg1_query_type) query, NBL_CONST_REF_ARG (quant_query_type) quant_query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
287+ 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)
288+ {
289+ // without numerator, numerator is 2 * NdotV * NdotL, we factor out 4 * NdotV * NdotL, hence 0.5
290+ scalar_type Vterm = _sample.getNdotL (_clamp) * query.getDevshV ();
291+ scalar_type Lterm = interaction.getNdotV (_clamp) * query.getDevshL ();
292+ return scalar_type (0.5 ) / (Vterm + Lterm);
293+ }
294+
295+ template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction>)
296+ scalar_type correlated (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
297+ {
298+ return scalar_type (4.0 ) * interaction.getNdotV (_clamp) * _sample.getNdotL (_clamp) * correlated_wo_numerator<LS, Interaction>(query, _sample, interaction);
299+ }
300+
301+ template<class LS, class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
302+ 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)
282303 {
283- scalar_type dg1 = scalar_type (0.5 ) * query.getNdfwoNumerator () * query.getG1over2NdotV ();
304+ scalar_type dg = __ndf_base.template D<MicrofacetCache>(cache);
305+ if (dg < bit_cast<scalar_type>(numeric_limits<scalar_type>::infinity))
306+ dg *= correlated_wo_numerator<LS, Interaction>(query, _sample, interaction);
307+ else
308+ dg = scalar_type (0.0 );
309+
284310 quant_type dmq;
285- dmq.microfacetMeasure = dg1; // note: microfacetMeasure/4NdotV
311+ dmq.microfacetMeasure = dg;
286312
287313 NBL_IF_CONSTEXPR (SupportsTransmission)
288314 {
@@ -291,22 +317,13 @@ struct GGX
291317 scalar_type NdotL_over_denominator = _sample.getNdotL (BxDFClampMode::BCM_ABS);
292318 if (transmitted)
293319 NdotL_over_denominator *= scalar_type (4.0 ) * VdotHLdotH * quant_query.getNeg_rcp2_VdotH_etaLdotH ();
294- dmq.projectedLightMeasure = dg1; // TODO: figure this out * NdotL_over_denominator;
320+ dmq.projectedLightMeasure = dg * NdotL_over_denominator;
295321 }
296322 else
297- dmq.projectedLightMeasure = dg1; // TODO: figure this out * _sample.getNdotL(BxDFClampMode::BCM_ABS);
323+ dmq.projectedLightMeasure = dg * _sample.getNdotL (BxDFClampMode::BCM_ABS);
298324 return dmq;
299325 }
300326
301- template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction>)
302- scalar_type correlated (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
303- {
304- // without numerator, numerator is 2 * NdotV * NdotL, we factor out 4 * NdotV * NdotL, hence 0.5
305- scalar_type Vterm = _sample.getNdotL (_clamp) * query.getDevshV ();
306- scalar_type Lterm = interaction.getNdotV (_clamp) * query.getDevshL ();
307- return scalar_type (0.5 ) / (Vterm + Lterm);
308- }
309-
310327 template<class LS, class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
311328 scalar_type G2_over_G1 (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)
312329 {
0 commit comments