@@ -25,10 +25,10 @@ struct SGGXDG1Query
2525 using scalar_type = T;
2626
2727 scalar_type getNdf () NBL_CONST_MEMBER_FUNC { return ndf; }
28- scalar_type getG1 () NBL_CONST_MEMBER_FUNC { return G1 ; }
28+ scalar_type getG1over2NdotV () NBL_CONST_MEMBER_FUNC { return G1_over_2NdotV ; }
2929
3030 scalar_type ndf;
31- scalar_type G1 ;
31+ scalar_type G1_over_2NdotV ;
3232};
3333
3434template<typename T>
@@ -78,7 +78,7 @@ struct GGXCommon<T,false NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<T>) >
7878
7979 scalar_type DG1 (NBL_CONST_REF_ARG (dg1_query_type) query)
8080 {
81- return query.getNdf () * query.getG1 ();
81+ return scalar_type ( 0.5 ) * query.getNdf () * query.getG1over2NdotV ();
8282 }
8383
8484 scalar_type devsh_part (scalar_type NdotX2)
@@ -166,6 +166,8 @@ struct GGXCommon<T,true NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<T>) >
166166 return numbers::inv_pi<scalar_type> / (a2 * denom * denom);
167167 }
168168
169+ // TODO: potential idea for making GGX spin using covariance matrix of sorts: https://www.desmos.com/3d/weq2ginq9o
170+
169171 // burley
170172 scalar_type D (scalar_type a2, scalar_type TdotH, scalar_type BdotH, scalar_type NdotH, scalar_type anisotropy)
171173 {
@@ -314,7 +316,7 @@ struct GGX<T,false,MTT_REFLECT NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar
314316 dg1_query_type dg1_query;
315317 dg1_query.ndf = __base.template D<MicrofacetCache>(cache);
316318 scalar_type clampedNdotV = interaction.getNdotV ();
317- dg1_query.G1 = scalar_type ( 2.0 ) * clampedNdotV * __base.G1_wo_numerator (clampedNdotV, interaction.getNdotV2 ());
319+ dg1_query.G1_over_2NdotV = __base.G1_wo_numerator (clampedNdotV, interaction.getNdotV2 ());
318320 return dg1_query;
319321 }
320322 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Isotropic<Interaction>)
@@ -336,20 +338,26 @@ struct GGX<T,false,MTT_REFLECT NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar
336338 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)
337339 {
338340 scalar_type d = __base.template D<MicrofacetCache>(cache);
339- return createDualMeasureQuantity<T>(d, interaction.getNdotV (BxDFClampMode::BCM_MAX), _sample.getNdotL (BxDFClampMode::BCM_MAX));
341+ quant_type dmq;
342+ dmq.microfacetMeasure = d;
343+ dmq.projectedLightMeasure = d * _sample.getNdotL (BxDFClampMode::BCM_MAX);
344+ return dmq;
340345 }
341346
342347 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Isotropic<Interaction>)
343348 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)
344349 {
345350 scalar_type dg1 = __base.DG1 (query);
346- return createDualMeasureQuantity<T>(dg1, interaction.getNdotV (BxDFClampMode::BCM_MAX), _sample.getNdotL (BxDFClampMode::BCM_MAX));
351+ quant_type dmq;
352+ dmq.microfacetMeasure = dg1;
353+ dmq.projectedLightMeasure = dg1;// TODO: figure this out * _sample.getNdotL(BxDFClampMode::BCM_MAX);
354+ return dmq;
347355 }
348356
349357 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Isotropic<Interaction>)
350358 scalar_type correlated (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
351359 {
352- return __base.template correlated <LS, Interaction>(query, _sample, interaction);
360+ return __base.template correlated_wo_numerator <LS, Interaction>(query, _sample, interaction);
353361 }
354362
355363 template<class LS, class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Isotropic<Interaction> && ReadableIsotropicMicrofacetCache<MicrofacetCache>)
@@ -387,7 +395,7 @@ struct GGX<T,true,MTT_REFLECT NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<
387395 dg1_query_type dg1_query;
388396 dg1_query.ndf = __base.template D<MicrofacetCache>(cache);
389397 scalar_type clampedNdotV = interaction.getNdotV ();
390- dg1_query.G1 = scalar_type ( 2.0 ) * clampedNdotV * __base.G1_wo_numerator (clampedNdotV, interaction.getTdotV2 (), interaction.getBdotV2 (), interaction.getNdotV2 ());
398+ dg1_query.G1_over_2NdotV = __base.G1_wo_numerator (clampedNdotV, interaction.getTdotV2 (), interaction.getBdotV2 (), interaction.getNdotV2 ());
391399 return dg1_query;
392400 }
393401 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Anisotropic <Interaction>)
@@ -409,20 +417,26 @@ struct GGX<T,true,MTT_REFLECT NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<
409417 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)
410418 {
411419 scalar_type d = __base.template D<MicrofacetCache>(cache);
412- return createDualMeasureQuantity<T>(d, interaction.getNdotV (BxDFClampMode::BCM_MAX), _sample.getNdotL (BxDFClampMode::BCM_MAX));
420+ quant_type dmq;
421+ dmq.microfacetMeasure = d;
422+ dmq.projectedLightMeasure = d * _sample.getNdotL (BxDFClampMode::BCM_MAX);
423+ return dmq;
413424 }
414425
415426 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Anisotropic <Interaction>)
416427 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)
417428 {
418429 scalar_type dg1 = __base.DG1 (query);
419- return createDualMeasureQuantity<T>(dg1, interaction.getNdotV (BxDFClampMode::BCM_MAX), _sample.getNdotL (BxDFClampMode::BCM_MAX));
430+ quant_type dmq;
431+ dmq.microfacetMeasure = dg1;
432+ dmq.projectedLightMeasure = dg1;// TODO: figure this out * _sample.getNdotL(BxDFClampMode::BCM_MAX);
433+ return dmq;
420434 }
421435
422436 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Anisotropic <Interaction>)
423437 scalar_type correlated (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
424438 {
425- return __base.template correlated <LS, Interaction>(query, _sample, interaction);
439+ return __base.template correlated_wo_numerator <LS, Interaction>(query, _sample, interaction);
426440 }
427441
428442 template<class LS, class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Anisotropic <Interaction> && AnisotropicMicrofacetCache<MicrofacetCache>)
@@ -463,7 +477,7 @@ struct GGX<T,false,reflect_refract NBL_PARTIAL_REQ_BOT(concepts::FloatingPointSc
463477 dg1_query_type dg1_query;
464478 dg1_query.ndf = __base.template D<MicrofacetCache>(cache);
465479 scalar_type clampedNdotV = interaction.getNdotV (BxDFClampMode::BCM_ABS);
466- dg1_query.G1 = scalar_type ( 2.0 ) * clampedNdotV * __base.G1_wo_numerator (clampedNdotV, interaction.getNdotV2 ());
480+ dg1_query.G1_over_2NdotV = __base.G1_wo_numerator (clampedNdotV, interaction.getNdotV2 ());
467481 return dg1_query;
468482 }
469483 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Isotropic<Interaction>)
@@ -485,20 +499,40 @@ struct GGX<T,false,reflect_refract NBL_PARTIAL_REQ_BOT(concepts::FloatingPointSc
485499 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)
486500 {
487501 scalar_type d = __base.template D<MicrofacetCache>(cache);
488- return createDualMeasureQuantity<T, reflect_refract>(d, interaction.getNdotV (BxDFClampMode::BCM_ABS), _sample.getNdotL (BxDFClampMode::BCM_ABS), quant_query.getVdotHLdotH (), quant_query.getVdotH_etaLdotH ());
502+ quant_type dmq;
503+ dmq.microfacetMeasure = d; // note: microfacetMeasure/2NdotV
504+
505+ const scalar_type VdotHLdotH = quant_query.getVdotHLdotH ();
506+ const scalar_type VdotH_etaLdotH = quant_query.getVdotH_etaLdotH ();
507+ const bool transmitted = reflect_refract==MTT_REFRACT || (reflect_refract!=MTT_REFLECT && VdotHLdotH < scalar_type (0.0 ));
508+ scalar_type NdotL_over_denominator = _sample.getNdotL (BxDFClampMode::BCM_ABS);
509+ if (transmitted)
510+ NdotL_over_denominator *= -scalar_type (4.0 ) * VdotHLdotH / (VdotH_etaLdotH * VdotH_etaLdotH);
511+ dmq.projectedLightMeasure = d * NdotL_over_denominator;
512+ return dmq;
489513 }
490514
491515 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Isotropic<Interaction>)
492516 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)
493517 {
494518 scalar_type dg1 = __base.DG1 (query);
495- return createDualMeasureQuantity<T, reflect_refract>(dg1, interaction.getNdotV (BxDFClampMode::BCM_ABS), _sample.getNdotL (BxDFClampMode::BCM_ABS), quant_query.getVdotHLdotH (), quant_query.getVdotH_etaLdotH ());
519+ quant_type dmq;
520+ dmq.microfacetMeasure = dg1; // note: microfacetMeasure/2NdotV
521+
522+ const scalar_type VdotHLdotH = quant_query.getVdotHLdotH ();
523+ const scalar_type VdotH_etaLdotH = quant_query.getVdotH_etaLdotH ();
524+ const bool transmitted = reflect_refract==MTT_REFRACT || (reflect_refract!=MTT_REFLECT && VdotHLdotH < scalar_type (0.0 ));
525+ scalar_type NdotL_over_denominator = _sample.getNdotL (BxDFClampMode::BCM_ABS);
526+ if (transmitted)
527+ NdotL_over_denominator *= -scalar_type (4.0 ) * VdotHLdotH / (VdotH_etaLdotH * VdotH_etaLdotH);
528+ dmq.projectedLightMeasure = dg1;// TODO: figure this out * NdotL_over_denominator;
529+ return dmq;
496530 }
497531
498532 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Isotropic<Interaction>)
499533 scalar_type correlated (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
500534 {
501- return __base.template correlated <LS, Interaction>(query, _sample, interaction);
535+ return __base.template correlated_wo_numerator <LS, Interaction>(query, _sample, interaction);
502536 }
503537
504538 template<class LS, class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Isotropic<Interaction> && ReadableIsotropicMicrofacetCache<MicrofacetCache>)
@@ -538,7 +572,7 @@ struct GGX<T,true,reflect_refract NBL_PARTIAL_REQ_BOT(concepts::FloatingPointSca
538572 dg1_query_type dg1_query;
539573 dg1_query.ndf = __base.template D<MicrofacetCache>(cache);
540574 scalar_type clampedNdotV = interaction.getNdotV (BxDFClampMode::BCM_ABS);
541- dg1_query.G1 = scalar_type ( 2.0 ) * clampedNdotV * __base.G1_wo_numerator (clampedNdotV, interaction.getTdotV2 (), interaction.getBdotV2 (), interaction.getNdotV2 ());
575+ dg1_query.G1_over_2NdotV = __base.G1_wo_numerator (clampedNdotV, interaction.getTdotV2 (), interaction.getBdotV2 (), interaction.getNdotV2 ());
542576 return dg1_query;
543577 }
544578 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Anisotropic <Interaction>)
@@ -560,20 +594,40 @@ struct GGX<T,true,reflect_refract NBL_PARTIAL_REQ_BOT(concepts::FloatingPointSca
560594 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)
561595 {
562596 scalar_type d = __base.template D<MicrofacetCache>(cache);
563- return createDualMeasureQuantity<T, reflect_refract>(d, interaction.getNdotV (BxDFClampMode::BCM_ABS), _sample.getNdotL (BxDFClampMode::BCM_ABS), quant_query.getVdotHLdotH (), quant_query.getVdotH_etaLdotH ());
597+ quant_type dmq;
598+ dmq.microfacetMeasure = d; // note: microfacetMeasure/2NdotV
599+
600+ const scalar_type VdotHLdotH = quant_query.getVdotHLdotH ();
601+ const scalar_type VdotH_etaLdotH = quant_query.getVdotH_etaLdotH ();
602+ const bool transmitted = reflect_refract==MTT_REFRACT || (reflect_refract!=MTT_REFLECT && VdotHLdotH < scalar_type (0.0 ));
603+ scalar_type NdotL_over_denominator = _sample.getNdotL (BxDFClampMode::BCM_ABS);
604+ if (transmitted)
605+ NdotL_over_denominator *= -scalar_type (4.0 ) * VdotHLdotH / (VdotH_etaLdotH * VdotH_etaLdotH);
606+ dmq.projectedLightMeasure = d * NdotL_over_denominator;
607+ return dmq;
564608 }
565609
566610 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Anisotropic <Interaction>)
567611 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)
568612 {
569613 scalar_type dg1 = __base.DG1 (query);
570- return createDualMeasureQuantity<T, reflect_refract>(dg1, interaction.getNdotV (BxDFClampMode::BCM_ABS), _sample.getNdotL (BxDFClampMode::BCM_ABS), quant_query.getVdotHLdotH (), quant_query.getVdotH_etaLdotH ());
614+ quant_type dmq;
615+ dmq.microfacetMeasure = dg1; // note: microfacetMeasure/2NdotV
616+
617+ const scalar_type VdotHLdotH = quant_query.getVdotHLdotH ();
618+ const scalar_type VdotH_etaLdotH = quant_query.getVdotH_etaLdotH ();
619+ const bool transmitted = reflect_refract==MTT_REFRACT || (reflect_refract!=MTT_REFLECT && VdotHLdotH < scalar_type (0.0 ));
620+ scalar_type NdotL_over_denominator = _sample.getNdotL (BxDFClampMode::BCM_ABS);
621+ if (transmitted)
622+ NdotL_over_denominator *= -scalar_type (4.0 ) * VdotHLdotH / (VdotH_etaLdotH * VdotH_etaLdotH);
623+ dmq.projectedLightMeasure = dg1;// TODO: figure this out * NdotL_over_denominator;
624+ return dmq;
571625 }
572626
573627 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Anisotropic <Interaction>)
574628 scalar_type correlated (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
575629 {
576- return __base.template correlated <LS, Interaction>(query, _sample, interaction);
630+ return __base.template correlated_wo_numerator <LS, Interaction>(query, _sample, interaction);
577631 }
578632
579633 template<class LS, class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES (LightSample<LS> && surface_interactions::Anisotropic <Interaction> && AnisotropicMicrofacetCache<MicrofacetCache>)
0 commit comments