1111#include <nbl/builtin/hlsl/concepts/vector .hlsl>
1212#include <nbl/builtin/hlsl/concepts/matrix .hlsl>
1313#include <nbl/builtin/hlsl/cpp_compat/promote.hlsl>
14+ #include <nbl/builtin/hlsl/numbers.hlsl>
1415
1516namespace nbl
1617{
@@ -61,6 +62,22 @@ template<typename T NBL_STRUCT_CONSTRAINABLE>
6162struct frac_helper;
6263template<typename T, typename U NBL_STRUCT_CONSTRAINABLE>
6364struct 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;
6481
6582#ifdef __HLSL_VERSION // HLSL only specializations
6683
@@ -91,6 +108,10 @@ AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER(frac_helper, fract, T)
91108AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (inverse_helper, matrixInverse, T)
92109AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER (all_helper, any, T)
93110AUTO_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)
94115
95116#define BITCOUNT_HELPER_RETRUN_TYPE conditional_t<is_vector_v<T>, vector <int32_t, vector_traits<T>::Dimension>, int32_t>
96117AUTO_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)
115136AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (min_helper, fMin, T)
116137AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC (min_helper, uMin, T)
117138AUTO_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+
118142#undef AUTO_SPECIALIZE_TRIVIAL_CASE_HELPER_2_ARG_FUNC
119143
120144template<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
205229 using return_t = conditional_t<is_vector_v<T>, vector <typename vector_traits<T>::scalar_type, vector_traits<T>::Dimension>, T>;
206230 static inline return_t __call (const T x, const T y, const U a)
207231 {
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);
209273 }
210274};
211275
@@ -388,6 +452,117 @@ struct mix_helper<T, U>
388452 }
389453};
390454
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+
391566#endif // C++ only specializations
392567
393568// C++ and HLSL specializations
@@ -535,20 +710,6 @@ struct mul_helper<LhsT, RhsT NBL_PARTIAL_REQ_BOT(concepts::Matrix<LhsT> && conce
535710 }
536711};
537712
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-
552713#define AUTO_SPECIALIZE_HELPER_FOR_VECTOR (HELPER_NAME, REQUIREMENT, RETURN_TYPE)\
553714template<typename T>\
554715NBL_PARTIAL_REQ_TOP (REQUIREMENT)\
@@ -573,6 +734,9 @@ struct HELPER_NAME<T NBL_PARTIAL_REQ_BOT(REQUIREMENT) >\
573734AUTO_SPECIALIZE_HELPER_FOR_VECTOR (rsqrt_helper, concepts::FloatingPointVectorial<T> && VECTOR_SPECIALIZATION_CONCEPT, T)
574735AUTO_SPECIALIZE_HELPER_FOR_VECTOR (bitReverse_helper, VECTOR_SPECIALIZATION_CONCEPT, T)
575736AUTO_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)
576740#define INT32_VECTOR_TYPE vector <int32_t, hlsl::vector_traits<T>::Dimension>
577741AUTO_SPECIALIZE_HELPER_FOR_VECTOR (bitCount_helper, VECTOR_SPECIALIZATION_CONCEPT, INT32_VECTOR_TYPE)
578742AUTO_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
616780 }
617781};
618782
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+
619821}
620822}
621823}
0 commit comments