@@ -128,10 +128,10 @@ struct SCookTorrance
128128 return cache.isValid (orientedEta);
129129 }
130130
131- bool dotIsUnity (const vector3_type a, const vector3_type b)
131+ bool dotIsUnity (const vector3_type a, const vector3_type b, const scalar_type value )
132132 {
133133 const scalar_type ab = hlsl::dot (a, b);
134- return hlsl::max (ab, scalar_type ( 1.0 ) / ab) <= scalar_type (1.0 + 1e-3 );
134+ return hlsl::max (ab, value / ab) <= scalar_type (value + 1e-3 );
135135 }
136136
137137 // bxdf stuff
@@ -197,11 +197,11 @@ struct SCookTorrance
197197 ray_dir_info_type V = interaction.getV ();
198198 const matrix3x3_type fromTangent = interaction.getFromTangentSpace ();
199199 // tangent frame orthonormality
200- assert (dotIsUnity (fromTangent[0 ],fromTangent[1 ]));
201- assert (dotIsUnity (fromTangent[1 ],fromTangent[2 ]));
202- assert (dotIsUnity (fromTangent[2 ],fromTangent[0 ]));
200+ assert (dotIsUnity (fromTangent[0 ],fromTangent[1 ], 0.0 ));
201+ assert (dotIsUnity (fromTangent[1 ],fromTangent[2 ], 0.0 ));
202+ assert (dotIsUnity (fromTangent[2 ],fromTangent[0 ], 0.0 ));
203203 // NDF sampling produced a unit length direction
204- assert (dotIsUnity (localH,localH));
204+ assert (dotIsUnity (localH,localH, 1.0 ));
205205 const vector3_type H = hlsl::mul (interaction.getFromTangentSpace (), localH);
206206 Refract<scalar_type> r = Refract<scalar_type>::create (V.getDirection (), H);
207207
@@ -238,7 +238,17 @@ struct SCookTorrance
238238 const vector3_type localV = interaction.getTangentSpaceV ();
239239 const vector3_type localH = ndf.generateH (localV, u);
240240 const scalar_type VdotH = hlsl::dot (localV, localH);
241- assert (VdotH >= scalar_type (0.0 )); // VNDF sampling guarantees VdotH has same sign as NdotV (should be positive for BRDF)
241+ NBL_IF_CONSTEXPR (!ndf_type::GuaranteedVNDF) // VNDF sampling guarantees VdotH has same sign as NdotV (should be positive for BRDF)
242+ {
243+ // allow for rejection sampling, theoretically NdotV=0 or VdotH=0 is valid, but leads to 0 value contribution anyway
244+ if (VdotH <= scalar_type (0.0 ))
245+ return sample_type::createInvalid ();
246+ assert (!hlsl::isnan (NdotV*VdotH));
247+ }
248+ else
249+ {
250+ assert (VdotH >= scalar_type (0.0 ));
251+ }
242252
243253 fresnel::OrientedEtaRcps<monochrome_type> dummy;
244254 bool valid;
@@ -263,7 +273,7 @@ struct SCookTorrance
263273 NBL_IF_CONSTEXPR (!ndf_type::GuaranteedVNDF)
264274 {
265275 // allow for rejection sampling, theoretically NdotV=0 or VdotH=0 is valid, but leads to 0 value contribution anyway
266- if ((IsBSDF ? ( NdotV*VdotH) : VdotH) <= scalar_type (0.0 ))
276+ if (NdotV*VdotH <= scalar_type (0.0 ))
267277 return sample_type::createInvalid ();
268278 assert (!hlsl::isnan (NdotV*VdotH));
269279 }
@@ -283,7 +293,7 @@ struct SCookTorrance
283293 sample_type s = __generate_common (interaction, localH, NdotV, VdotH, transmitted, rcpEta, cache, valid);
284294 if (valid)
285295 {
286- assert (cache.isValid (fresnel::OrientedEtas<vector_type >::create (scalar_type (1.0 ), hlsl::promote<vector_type >(_f.getRefractionOrientedEta ()))));
296+ assert (cache.isValid (fresnel::OrientedEtas<monochrome_type >::create (scalar_type (1.0 ), hlsl::promote<monochrome_type >(_f.getRefractionOrientedEta ()))));
287297 const vector3_type T = interaction.getT ();
288298 const vector3_type B = interaction.getB ();
289299 const vector3_type H = hlsl::mul (interaction.getFromTangentSpace (), localH);
0 commit comments