@@ -216,22 +216,27 @@ NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar<T>)
216
216
struct lgamma_helper<T NBL_PARTIAL_REQ_BOT (concepts::FloatingPointScalar<T>) >
217
217
{
218
218
// implementation from Numerical Recipes in C, 2nd ed.
219
- static T __call (T val)
220
- {
221
- T x, y;
222
- y = x = val;
223
- T tmp = x + T (5.5 );
224
- tmp -= (x + T (0.5 )) * log_helper<T>::__call (tmp);
225
-
226
- T ser = T (1.000000000190015 );
219
+ static T __call (T val)
220
+ {
221
+ const T thresholds[3 ] = { 7e4, 1e19, 1e19 };
222
+ if (val > thresholds[findLSB (uint32_t (sizeof (T)))])
223
+ return bit_cast<T>(numeric_limits<T>::infinity);
224
+
225
+ T x, y;
226
+ y = x = val;
227
+ T tmp = x + T (5.5 );
228
+ tmp -= (x + T (0.5 )) * log_helper<T>::__call (tmp);
229
+
230
+ T ser = T (1.000000000190015 );
227
231
ser += T (76.18009172947146 ) / ++y;
228
232
ser += T (-86.50532032941677 ) / ++y;
229
233
ser += T (24.01409824083091 ) / ++y;
230
234
ser += T (-1.231739572450155 ) / ++y;
231
235
ser += T (0. 1208650973866179e-2 ) / ++y;
232
- ser += T (-0. 5395239384953e-5 ) / ++y;
233
- return -tmp + log_helper<T>::__call (T (2.5066282746310005 ) * ser / x);
234
- }
236
+ if (sizeof (T)>2 )
237
+ ser += T (-0. 5395239384953e-5 ) / ++y;
238
+ return -tmp + log_helper<T>::__call (T (2.5066282746310005 ) * ser / x);
239
+ }
235
240
};
236
241
237
242
// beta function
@@ -242,6 +247,12 @@ struct beta_helper<T NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<T>) >
242
247
// implementation from Numerical Recipes in C, 2nd ed.
243
248
static T __call (T v1, T v2)
244
249
{
250
+ // specialized for Cook Torrance BTDFs
251
+ assert (v1 >= 1.0 && v2 >= 1.0 );
252
+
253
+ if (v1+v2 > 1e6)
254
+ return T (0.0 );
255
+
245
256
return exp2_helper<T>::__call (l2gamma_helper<T>::__call (v1) + l2gamma_helper<T>::__call (v2) - l2gamma_helper<T>::__call (v1+v2));
246
257
}
247
258
};
@@ -576,12 +587,16 @@ NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar<T>)
576
587
struct l2gamma_helper<T NBL_PARTIAL_REQ_BOT (concepts::FloatingPointScalar<T>) >
577
588
{
578
589
// modified Stirling's approximation for log2 up to 3rd polynomial
579
- static T __call (T x)
580
- {
581
- const T l2x = log2_helper<T>::__call (x);
590
+ static T __call (T x)
591
+ {
592
+ const T thresholds[3 ] = {5e4, 1e19, 1e19};
593
+ if (x > thresholds[findLSB (uint32_t (sizeof (T)))])
594
+ return bit_cast<T>(numeric_limits<T>::infinity);
595
+
596
+ const T l2x = log2_helper<T>::__call (x);
582
597
const T one_over_ln2 = T (1.44269504088896 );
583
598
return (x - T (0.5 )) * l2x - one_over_ln2 * x + T (1.32574806473616 ) + one_over_ln2 / (T (12.0 ) * x) + one_over_ln2 / (T (360.0 ) * x * x * x);
584
- }
599
+ }
585
600
};
586
601
587
602
#ifdef __HLSL_VERSION
0 commit comments