@@ -121,27 +121,6 @@ struct getOrientedFresnel<F, true NBL_PARTIAL_REQ_BOT(fresnel::TwoSidedFresnel<F
121121 return fresnel.getReorientedFresnel (NdotV);
122122 }
123123};
124-
125- template<class N, class LS, class Interaction, class MicrofacetCache>
126- struct overwrite_DG
127- {
128- using scalar_type = typename N::scalar_type;
129- using quant_type = typename N::quant_type;
130- using quant_query_type = typename N::quant_query_type;
131- using g2g1_query_type = typename N::g2g1_query_type;
132- NBL_CONSTEXPR_STATIC_INLINE bool HasOverwrite = ndf::NDF_CanOverwriteDG<N>;
133-
134- template<typename C=bool_constant<!HasOverwrite> >
135- static enable_if_t<C::value && !HasOverwrite, void > __call (NBL_REF_ARG (scalar_type) DG, N ndf, 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)
136- {
137- }
138- template<typename C=bool_constant<HasOverwrite> >
139- static enable_if_t<C::value && HasOverwrite, void > __call (NBL_REF_ARG (scalar_type) DG, N ndf, 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)
140- {
141- quant_type dg = ndf.template Dcorrelated<LS, Interaction, MicrofacetCache>(query, quant_query, _sample, interaction, cache);
142- DG = dg.projectedLightMeasure;
143- }
144- };
145124}
146125
147126// N (NDF), F (fresnel)
@@ -159,6 +138,23 @@ struct SCookTorrance
159138 NBL_CONSTEXPR_STATIC_INLINE bool IsBSDF = ndf_type::SupportedPaths != ndf::MTT_REFLECT;
160139 NBL_HLSL_BXDF_ANISOTROPIC_COND_DECLS (IsAnisotropic);
161140
141+ template<class Interaction=conditional_t<IsAnisotropic,anisotropic_interaction_type,isotropic_interaction_type>,
142+ class MicrofacetCache=conditional_t<IsAnisotropic,anisocache_type,isocache_type>
143+ NBL_FUNC_REQUIRES (!ndf::NDF_CanOverwriteDG<ndf_type> && RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
144+ static void overwriteDG (NBL_REF_ARG (scalar_type) DG, ndf_type ndf, NBL_CONST_REF_ARG (typename ndf_type::g2g1_query_type) query, NBL_CONST_REF_ARG (typename ndf_type::quant_query_type) quant_query,
145+ NBL_CONST_REF_ARG (sample_type) _sample, NBL_CONST_REF_ARG (Interaction) interaction, NBL_CONST_REF_ARG (MicrofacetCache) cache, NBL_REF_ARG (bool ) isInfinity)
146+ {
147+ }
148+ template<class Interaction=conditional_t<IsAnisotropic,anisotropic_interaction_type,isotropic_interaction_type>,
149+ class MicrofacetCache=conditional_t<IsAnisotropic,anisocache_type,isocache_type>
150+ NBL_FUNC_REQUIRES (ndf::NDF_CanOverwriteDG<ndf_type> && RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
151+ static void overwriteDG (NBL_REF_ARG (scalar_type) DG, ndf_type ndf, NBL_CONST_REF_ARG (typename ndf_type::g2g1_query_type) query, NBL_CONST_REF_ARG (typename ndf_type::quant_query_type) quant_query,
152+ NBL_CONST_REF_ARG (sample_type) _sample, NBL_CONST_REF_ARG (Interaction) interaction, NBL_CONST_REF_ARG (MicrofacetCache) cache, NBL_REF_ARG (bool ) isInfinity)
153+ {
154+ quant_type dg = ndf.template Dcorrelated<sample_type, Interaction, MicrofacetCache>(query, quant_query, _sample, interaction, cache, isInfinity);
155+ DG = dg.projectedLightMeasure;
156+ }
157+
162158 template<class Interaction=conditional_t<IsAnisotropic,anisotropic_interaction_type,isotropic_interaction_type>,
163159 class MicrofacetCache=conditional_t<IsAnisotropic,anisocache_type,isocache_type>
164160 NBL_FUNC_REQUIRES (RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
@@ -174,14 +170,16 @@ struct SCookTorrance
174170 using g2g1_query_type = typename ndf_type::g2g1_query_type;
175171 g2g1_query_type gq = ndf.template createG2G1Query<sample_type, Interaction>(_sample, interaction);
176172
177- quant_type D = ndf.template D<sample_type, Interaction, MicrofacetCache>(qq, _sample, interaction, cache);
173+ bool isInfinity;
174+ quant_type D = ndf.template D<sample_type, Interaction, MicrofacetCache>(qq, _sample, interaction, cache, isInfinity);
178175 scalar_type DG = D.projectedLightMeasure;
179- if (D.microfacetMeasure < bit_cast<scalar_type>(numeric_limits<scalar_type>::infinity) )
176+ if (!isInfinity )
180177 DG *= ndf.template correlated<sample_type, Interaction, MicrofacetCache>(gq, _sample, interaction, cache);
181- else
182- return hlsl::promote<spectral_type>(0.0 );
183178
184- impl::overwrite_DG<ndf_type, sample_type, Interaction, MicrofacetCache>::__call (DG, ndf, gq, qq, _sample, interaction, cache);
179+ overwriteDG<Interaction, MicrofacetCache>(DG, ndf, gq, qq, _sample, interaction, cache, isInfinity);
180+
181+ if (isInfinity)
182+ return hlsl::promote<spectral_type>(0.0 );
185183
186184 scalar_type clampedVdotH = cache.getVdotH ();
187185 NBL_IF_CONSTEXPR (IsBSDF)
@@ -320,7 +318,7 @@ struct SCookTorrance
320318 }
321319
322320 template<class Interaction, class MicrofacetCache>
323- scalar_type __pdf (NBL_CONST_REF_ARG (sample_type) _sample, NBL_CONST_REF_ARG (Interaction) interaction, NBL_CONST_REF_ARG (MicrofacetCache) cache)
321+ scalar_type __pdf (NBL_CONST_REF_ARG (sample_type) _sample, NBL_CONST_REF_ARG (Interaction) interaction, NBL_CONST_REF_ARG (MicrofacetCache) cache, NBL_REF_ARG ( bool ) isInfinity )
324322 {
325323 using quant_query_type = typename ndf_type::quant_query_type;
326324 using dg1_query_type = typename ndf_type::dg1_query_type;
@@ -329,7 +327,7 @@ struct SCookTorrance
329327
330328 fresnel_type _f = impl::getOrientedFresnel<fresnel_type, IsBSDF>::__call (fresnel, interaction.getNdotV ());
331329 quant_query_type qq = impl::quant_query_helper<ndf_type, fresnel_type, IsBSDF>::template __call<Interaction, MicrofacetCache>(ndf, _f, interaction, cache);
332- quant_type DG1 = ndf.template DG1<sample_type, Interaction>(dq, qq, _sample, interaction);
330+ quant_type DG1 = ndf.template DG1<sample_type, Interaction>(dq, qq, _sample, interaction, isInfinity );
333331
334332 NBL_IF_CONSTEXPR (IsBSDF)
335333 {
@@ -350,8 +348,9 @@ struct SCookTorrance
350348 if (!impl::checkValid<fresnel_type, IsBSDF>::template __call<sample_type, Interaction, MicrofacetCache>(_f, _sample, interaction, cache))
351349 return scalar_type (0.0 );
352350
353- scalar_type _pdf = __pdf<Interaction, MicrofacetCache>(_sample, interaction, cache);
354- return hlsl::mix (scalar_type (0.0 ), _pdf, _pdf < bit_cast<scalar_type>(numeric_limits<scalar_type>::infinity));
351+ bool isInfinity;
352+ scalar_type _pdf = __pdf<Interaction, MicrofacetCache>(_sample, interaction, cache, isInfinity);
353+ return hlsl::mix (_pdf, scalar_type (0.0 ), isInfinity);
355354 }
356355
357356 template<class Interaction=conditional_t<IsAnisotropic,anisotropic_interaction_type,isotropic_interaction_type>,
@@ -362,14 +361,15 @@ struct SCookTorrance
362361 if (!_sample.isValid ())
363362 return quotient_pdf_type::create (scalar_type (0.0 ), scalar_type (0.0 )); // set pdf=0 when quo=0 because we don't want to give high weight to sampling strategy that yields 0 contribution
364363
365- scalar_type _pdf = __pdf<Interaction, MicrofacetCache>(_sample, interaction, cache);
364+ bool isInfinity;
365+ scalar_type _pdf = __pdf<Interaction, MicrofacetCache>(_sample, interaction, cache, isInfinity);
366366 fresnel_type _f = impl::getOrientedFresnel<fresnel_type, IsBSDF>::__call (fresnel, interaction.getNdotV ());
367367
368368 const bool valid = impl::checkValid<fresnel_type, IsBSDF>::template __call<sample_type, Interaction, MicrofacetCache>(_f, _sample, interaction, cache);
369369 assert (valid); // expect the generated sample to always be valid, different checks for brdf and btdf
370370
371371 scalar_type G2_over_G1 = scalar_type (1.0 );
372- if (_pdf < bit_cast<scalar_type>(numeric_limits<scalar_type>::infinity) )
372+ if (!isInfinity )
373373 {
374374 using g2g1_query_type = typename N::g2g1_query_type;
375375 g2g1_query_type gq = ndf.template createG2G1Query<sample_type, Interaction>(_sample, interaction);
0 commit comments