@@ -68,6 +68,29 @@ struct quant_query_helper<N, F, false>
68
68
}
69
69
};
70
70
71
+ template<class F, bool IsBSDF>
72
+ struct check_TIR_helper;
73
+
74
+ template<class F>
75
+ struct check_TIR_helper<F, false >
76
+ {
77
+ template<class MicrofacetCache>
78
+ static bool __call (NBL_CONST_REF_ARG (F) fresnel, NBL_CONST_REF_ARG (MicrofacetCache) cache)
79
+ {
80
+ return true ;
81
+ }
82
+ };
83
+
84
+ template<class F>
85
+ struct check_TIR_helper<F, true >
86
+ {
87
+ template<class MicrofacetCache>
88
+ static bool __call (NBL_CONST_REF_ARG (F) fresnel, NBL_CONST_REF_ARG (MicrofacetCache) cache)
89
+ {
90
+ return ComputeMicrofacetNormal<typename F::scalar_type>::isValidMicrofacet (cache.isTransmission (), cache.getVdotL (), cache.getAbsNdotH (), fresnel.orientedEta);
91
+ }
92
+ };
93
+
71
94
template<class F, typename Spectral, bool IsAnisotropic>
72
95
struct CookTorranceParams;
73
96
@@ -129,7 +152,8 @@ struct SCookTorrance
129
152
template<class Interaction, class MicrofacetCache>
130
153
spectral_type __eval (NBL_CONST_REF_ARG (sample_type) _sample, NBL_CONST_REF_ARG (Interaction) interaction, NBL_CONST_REF_ARG (MicrofacetCache) cache)
131
154
{
132
- if (IsBSDF || (_sample.getNdotL () > numeric_limits<scalar_type>::min && interaction.getNdotV () > numeric_limits<scalar_type>::min ))
155
+ const bool notTIR = impl::check_TIR_helper<fresnel_type, IsBSDF>::template __call<MicrofacetCache>(fresnel, cache);
156
+ if ((IsBSDF && notTIR) || (!IsBSDF && _sample.getNdotL () > numeric_limits<scalar_type>::min && interaction.getNdotV () > numeric_limits<scalar_type>::min ))
133
157
{
134
158
using quant_query_type = typename ndf_type::quant_query_type;
135
159
using g2g1_query_type = typename ndf_type::g2g1_query_type;
@@ -283,14 +307,17 @@ struct SCookTorrance
283
307
scalar_type _pdf = __pdf<Interaction, MicrofacetCache>(_sample, interaction, cache);
284
308
285
309
spectral_type quo = hlsl::promote<spectral_type>(0.0 );
286
-
287
- using g2g1_query_type = typename N::g2g1_query_type;
288
- g2g1_query_type gq = ndf.template createG2G1Query<sample_type, Interaction>(_sample, interaction);
289
- scalar_type G2_over_G1 = ndf.template G2_over_G1<sample_type, Interaction, MicrofacetCache>(gq, _sample, interaction, cache);
290
- NBL_IF_CONSTEXPR (IsBSDF)
291
- quo = hlsl::promote<spectral_type>(G2_over_G1);
292
- else
293
- quo = fresnel (cache.getVdotH ()) * G2_over_G1;
310
+ const bool notTIR = impl::check_TIR_helper<fresnel_type, IsBSDF>::template __call<MicrofacetCache>(fresnel, cache);
311
+ if (notTIR)
312
+ {
313
+ using g2g1_query_type = typename N::g2g1_query_type;
314
+ g2g1_query_type gq = ndf.template createG2G1Query<sample_type, Interaction>(_sample, interaction);
315
+ scalar_type G2_over_G1 = ndf.template G2_over_G1<sample_type, Interaction, MicrofacetCache>(gq, _sample, interaction, cache);
316
+ NBL_IF_CONSTEXPR (IsBSDF)
317
+ quo = hlsl::promote<spectral_type>(G2_over_G1);
318
+ else
319
+ quo = fresnel (cache.getVdotH ()) * G2_over_G1;
320
+ }
294
321
295
322
// set pdf=0 when quo=0 because we don't want to give high weight to sampling strategy that yields 0 contribution
296
323
_pdf = hlsl::mix (_pdf, scalar_type (0.0 ), hlsl::all (quo < hlsl::promote<spectral_type>(numeric_limits<scalar_type>::min )));
0 commit comments