11
11
#include <nbl/builtin/hlsl/concepts/vector .hlsl>
12
12
#include <nbl/builtin/hlsl/concepts/matrix .hlsl>
13
13
#include <nbl/builtin/hlsl/cpp_compat/promote.hlsl>
14
+ #include <nbl/builtin/hlsl/numbers.hlsl>
14
15
15
16
namespace nbl
16
17
{
@@ -61,6 +62,22 @@ template<typename T NBL_STRUCT_CONSTRAINABLE>
61
62
struct frac_helper;
62
63
template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
63
64
struct mix_helper;
65
+ template<typename T NBL_STRUCT_CONSTRAINABLE>
66
+ struct sign_helper;
67
+ template<typename T NBL_STRUCT_CONSTRAINABLE>
68
+ struct radians_helper;
69
+ template<typename T NBL_STRUCT_CONSTRAINABLE>
70
+ struct degrees_helper;
71
+ template<typename T NBL_STRUCT_CONSTRAINABLE>
72
+ struct step_helper;
73
+ template<typename T NBL_STRUCT_CONSTRAINABLE>
74
+ struct smoothStep_helper;
75
+ template<typename T NBL_STRUCT_CONSTRAINABLE>
76
+ struct faceForward_helper;
77
+ template<typename T NBL_STRUCT_CONSTRAINABLE>
78
+ struct reflect_helper;
79
+ template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
80
+ struct refract_helper;
64
81
65
82
#ifdef __HLSL_VERSION // HLSL only specializations
66
83
@@ -91,6 +108,10 @@ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(frac_helper, fract, T)
91
108
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (inverse_helper, matrixInverse, T)
92
109
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (all_helper, any, T)
93
110
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (any_helper, any, T)
111
+ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (sign_helper, fSign, T)
112
+ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (sign_helper, sSign, T)
113
+ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (radians_helper, radians, T)
114
+ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (degrees_helper, degrees, T)
94
115
95
116
#define BITCOUNT_HELPER_RETRUN_TYPE conditional_t<is_vector_v<T>, vector <int32_t, vector_traits<T>::Dimension>, int32_t>
96
117
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (bitCount_helper, bitCount, BITCOUNT_HELPER_RETRUN_TYPE)
@@ -115,6 +136,9 @@ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC(max_helper, sMax, T)
115
136
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (min_helper, fMin, T)
116
137
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (min_helper, uMin, T)
117
138
AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (min_helper, sMin, T)
139
+ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (step_helper, step, T)
140
+ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (reflect_helper, reflect, T)
141
+
118
142
#undef AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC
119
143
120
144
template<typename T> NBL_PARTIAL_REQ_TOP (always_true<decltype (spirv::fClamp<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>)
@@ -205,7 +229,47 @@ struct mix_helper<T, U NBL_PARTIAL_REQ_BOT(always_true<decltype(spirv::fMix<T>(e
205
229
using return_t = conditional_t<is_vector_v<T>, vector <typename vector_traits<T>::scalar_type, vector_traits<T>::Dimension>, T>;
206
230
static inline return_t __call (const T x, const T y, const U a)
207
231
{
208
- return spirv::fMix<T>(x, y, a);
232
+ T aAsT = a;
233
+ return spirv::fMix<T>(x, y, aAsT);
234
+ }
235
+ };
236
+
237
+ template<typename T> NBL_PARTIAL_REQ_TOP (always_true<decltype (spirv::smoothStep<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>)
238
+ struct smoothStep_helper<T NBL_PARTIAL_REQ_BOT (always_true<decltype (spirv::smoothStep<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>) >
239
+ {
240
+ using return_t = T;
241
+ static inline return_t __call (const T edge0, const T edge1, const T x)
242
+ {
243
+ return spirv::smoothStep<T>(edge0, edge1, x);
244
+ }
245
+ };
246
+
247
+ template<typename T> NBL_PARTIAL_REQ_TOP (always_true<decltype (spirv::faceForward<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>)
248
+ struct faceForward_helper<T NBL_PARTIAL_REQ_BOT (always_true<decltype (spirv::faceForward<T>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<T>()))>) >
249
+ {
250
+ using return_t = T;
251
+ static inline return_t __call (const T N, const T I, const T Nref)
252
+ {
253
+ return spirv::faceForward<T>(N, I, Nref);
254
+ }
255
+ };
256
+
257
+ template<typename SquareMatrix> NBL_PARTIAL_REQ_TOP (matrix_traits<SquareMatrix>::Square)
258
+ struct determinant_helper<SquareMatrix NBL_PARTIAL_REQ_BOT (matrix_traits<SquareMatrix>::Square) >
259
+ {
260
+ static typename matrix_traits<SquareMatrix>::scalar_type __call (NBL_CONST_REF_ARG (SquareMatrix) mat)
261
+ {
262
+ return spirv::determinant (mat);
263
+ }
264
+ };
265
+
266
+ template<typename T, typename U> NBL_PARTIAL_REQ_TOP (always_true<decltype (spirv::refract<T, U>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<U>()))>)
267
+ struct refract_helper<T, U NBL_PARTIAL_REQ_BOT (always_true<decltype (spirv::refract<T, U>(experimental::declval<T>(), experimental::declval<T>(), experimental::declval<U>()))>) >
268
+ {
269
+ using return_t = T;
270
+ static inline return_t __call (const T I, const T N, const U eta)
271
+ {
272
+ return spirv::refract<T>(I, N, eta);
209
273
}
210
274
};
211
275
@@ -388,6 +452,117 @@ struct mix_helper<T, U>
388
452
}
389
453
};
390
454
455
+ template<typename T>
456
+ requires concepts::FloatingPointScalar<T> || concepts::IntegralScalar<T>
457
+ struct sign_helper<T>
458
+ {
459
+ using return_t = T;
460
+ static inline return_t __call (const T val)
461
+ {
462
+ if (val < 0 )
463
+ return -1 ;
464
+ if (val > 0 )
465
+ return 1 ;
466
+
467
+ return 0 ;
468
+ }
469
+ };
470
+
471
+ template<typename T>
472
+ requires concepts::FloatingPointScalar<T>
473
+ struct radians_helper<T>
474
+ {
475
+ using return_t = T;
476
+ static inline return_t __call (const T degrees)
477
+ {
478
+ return degrees * (numbers::pi<T> / static_cast<T>(180.0 ));
479
+ }
480
+ };
481
+
482
+ template<typename T>
483
+ requires concepts::FloatingPointScalar<T>
484
+ struct degrees_helper<T>
485
+ {
486
+ using return_t = T;
487
+ static inline return_t __call (const T radians)
488
+ {
489
+ return radians * (static_cast<T>(180.0 ) / numbers::pi<T>);
490
+ }
491
+ };
492
+
493
+ template<typename T>
494
+ requires concepts::FloatingPointScalar<T>
495
+ struct step_helper<T>
496
+ {
497
+ using return_t = T;
498
+ static inline return_t __call (const T edge, const T x)
499
+ {
500
+ return x < edge ? 0.0 : 1.0 ;
501
+ }
502
+ };
503
+
504
+ template<typename T>
505
+ requires concepts::FloatingPointScalar<T>
506
+ struct smoothStep_helper<T>
507
+ {
508
+ using return_t = T;
509
+ static inline return_t __call (const T edge0, const T edge1, const T x)
510
+ {
511
+ T t = clamp_helper<T>::__call ((x - edge0) / (edge1 - edge0), 0 , 1 );
512
+ return t * t * (3 - 2 * t);
513
+ }
514
+ };
515
+
516
+ template<typename SquareMatrix>
517
+ NBL_PARTIAL_REQ_TOP (matrix_traits<SquareMatrix>::Square)
518
+ struct determinant_helper<SquareMatrix NBL_PARTIAL_REQ_BOT (matrix_traits<SquareMatrix>::Square) >
519
+ {
520
+ static typename matrix_traits<SquareMatrix>::scalar_type __call (NBL_CONST_REF_ARG (SquareMatrix) mat)
521
+ {
522
+ return glm::determinant (reinterpret_cast<typename SquareMatrix::Base const &>(mat));
523
+ }
524
+ };
525
+
526
+ template<typename T>
527
+ requires concepts::FloatingPointVectorial<T>
528
+ struct faceForward_helper<T>
529
+ {
530
+ using return_t = T;
531
+ static inline return_t __call (const T N, const T I, const T Nref)
532
+ {
533
+ if (dot_helper<T>::__call (Nref, I) < 0.0 )
534
+ return N;
535
+ else
536
+ return -N;
537
+ }
538
+ };
539
+
540
+ template<typename T>
541
+ requires concepts::FloatingPointVector<T>
542
+ struct reflect_helper<T>
543
+ {
544
+ using return_t = T;
545
+ static inline return_t __call (const T I, const T N)
546
+ {
547
+ return I - T (2.0 * dot_helper<T>::__call (N, I)) * N;
548
+ }
549
+ };
550
+
551
+ template<typename T, typename U>
552
+ requires concepts::FloatingPointVector<T> && concepts::FloatingPointScalar<U>
553
+ struct refract_helper<T, U>
554
+ {
555
+ using return_t = T;
556
+ static inline return_t __call (const T I, const T N, const U eta)
557
+ {
558
+ U k = 1.0 - eta * eta * (1.0 - dot_helper<T>::__call (N, I) * dot_helper<T>::__call (N, I));
559
+ if (k < 0.0 )
560
+ return T (0.0 );
561
+
562
+ return eta * I - (eta * dot_helper<T>::__call (N, I) + std::sqrt (k)) * N;
563
+ }
564
+ };
565
+
391
566
#endif // C++ only specializations
392
567
393
568
// C++ and HLSL specializations
@@ -535,20 +710,6 @@ struct mul_helper<LhsT, RhsT NBL_PARTIAL_REQ_BOT(concepts::Matrix<LhsT> && conce
535
710
}
536
711
};
537
712
538
- template<typename SquareMatrix>
539
- NBL_PARTIAL_REQ_TOP (matrix_traits<SquareMatrix>::Square)
540
- struct determinant_helper<SquareMatrix NBL_PARTIAL_REQ_BOT (matrix_traits<SquareMatrix>::Square) >
541
- {
542
- static typename matrix_traits<SquareMatrix>::scalar_type __call (NBL_CONST_REF_ARG (SquareMatrix) mat)
543
- {
544
- #ifdef __HLSL_VERSION
545
- return spirv::determinant (mat);
546
- #else
547
- return glm::determinant (reinterpret_cast<typename SquareMatrix::Base const &>(mat));
548
- #endif
549
- }
550
- };
551
-
552
713
#define AUTO_SPECIALIZE_HELPER_FOR_VECTOR (HELPER_NAME, REQUIREMENT, RETURN_TYPE)\
553
714
template<typename T>\
554
715
NBL_PARTIAL_REQ_TOP (REQUIREMENT)\
@@ -573,6 +734,9 @@ struct HELPER_NAME<T NBL_PARTIAL_REQ_BOT(REQUIREMENT) >\
573
734
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (rsqrt_helper, concepts::FloatingPointVectorial<T> && VECTOR_SPECIALIZATION_CONCEPT, T)
574
735
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (bitReverse_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
575
736
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (frac_helper, VECTOR_SPECIALIZATION_CONCEPT,T)
737
+ AUTO_SPECIALIZE_HELPER_FOR_VECTOR (sign_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
738
+ AUTO_SPECIALIZE_HELPER_FOR_VECTOR (degrees_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
739
+ AUTO_SPECIALIZE_HELPER_FOR_VECTOR (radians_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
576
740
#define INT32_VECTOR_TYPE vector <int32_t, hlsl::vector_traits<T>::Dimension>
577
741
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (bitCount_helper, VECTOR_SPECIALIZATION_CONCEPT, INT32_VECTOR_TYPE)
578
742
AUTO_SPECIALIZE_HELPER_FOR_VECTOR (find_msb_helper, VECTOR_SPECIALIZATION_CONCEPT, INT32_VECTOR_TYPE)
@@ -616,6 +780,44 @@ struct any_helper<BooleanVector NBL_PARTIAL_REQ_BOT(concepts::Vectorial<BooleanV
616
780
}
617
781
};
618
782
783
+ template<typename T>
784
+ NBL_PARTIAL_REQ_TOP (VECTOR_SPECIALIZATION_CONCEPT)
785
+ struct step_helper<T NBL_PARTIAL_REQ_BOT (VECTOR_SPECIALIZATION_CONCEPT) >
786
+ {
787
+ using return_t = T;
788
+ static return_t __call (NBL_CONST_REF_ARG (T) edge, NBL_CONST_REF_ARG (T) x)
789
+ {
790
+ using traits = hlsl::vector_traits<T>;
791
+ array_get<T, typename traits::scalar_type> getter;
792
+ array_set<return_t, typename traits::scalar_type> setter;
793
+
794
+ return_t output;
795
+ for (uint32_t i = 0 ; i < traits::Dimension; ++i)
796
+ setter (output, i, step_helper<typename traits::scalar_type>::__call (getter (edge, i), getter (x, i)));
797
+
798
+ return output;
799
+ }
800
+ };
801
+
802
+ template<typename T>
803
+ NBL_PARTIAL_REQ_TOP (VECTOR_SPECIALIZATION_CONCEPT)
804
+ struct smoothStep_helper<T NBL_PARTIAL_REQ_BOT (VECTOR_SPECIALIZATION_CONCEPT) >
805
+ {
806
+ using return_t = T;
807
+ static return_t __call (NBL_CONST_REF_ARG (T) edge0, NBL_CONST_REF_ARG (T) edge1, NBL_CONST_REF_ARG (T) x)
808
+ {
809
+ using traits = hlsl::vector_traits<T>;
810
+ array_get<T, typename traits::scalar_type> getter;
811
+ array_set<return_t, typename traits::scalar_type> setter;
812
+
813
+ return_t output;
814
+ for (uint32_t i = 0 ; i < traits::Dimension; ++i)
815
+ setter (output, i, smoothStep_helper<typename traits::scalar_type>::__call (getter (edge0, i), getter (edge1, i), getter (x, i)));
816
+
817
+ return output;
818
+ }
819
+ };
820
+
619
821
}
620
822
}
621
823
}
0 commit comments