66
77#include "nbl/builtin/hlsl/limits.hlsl"
88#include "nbl/builtin/hlsl/bxdf/ndf/microfacet_to_light_transform.hlsl"
9+ #include "nbl/builtin/hlsl/bxdf/ndf.hlsl"
910
1011namespace nbl
1112{
@@ -16,6 +17,37 @@ namespace bxdf
1617namespace ndf
1718{
1819
20+ namespace beckmann_concepts
21+ {
22+ #define NBL_CONCEPT_NAME DG1Query
23+ #define NBL_CONCEPT_TPLT_PRM_KINDS (typename)
24+ #define NBL_CONCEPT_TPLT_PRM_NAMES (T)
25+ #define NBL_CONCEPT_PARAM_0 (query, T)
26+ NBL_CONCEPT_BEGIN (1 )
27+ #define query NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0
28+ NBL_CONCEPT_END (
29+ ((NBL_CONCEPT_REQ_TYPE)(T::scalar_type))
30+ ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((query.getNdf ()), ::nbl::hlsl::is_same_v, typename T::scalar_type))
31+ ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((query.getLambdaV ()), ::nbl::hlsl::is_same_v, typename T::scalar_type))
32+ );
33+ #undef query
34+ #include <nbl/builtin/hlsl/concepts/__end.hlsl>
35+
36+ #define NBL_CONCEPT_NAME G2overG1Query
37+ #define NBL_CONCEPT_TPLT_PRM_KINDS (typename)
38+ #define NBL_CONCEPT_TPLT_PRM_NAMES (T)
39+ #define NBL_CONCEPT_PARAM_0 (query, T)
40+ NBL_CONCEPT_BEGIN (1 )
41+ #define query NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0
42+ NBL_CONCEPT_END (
43+ ((NBL_CONCEPT_REQ_TYPE)(T::scalar_type))
44+ ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((query.getLambdaL ()), ::nbl::hlsl::is_same_v, typename T::scalar_type))
45+ ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((query.getLambdaV ()), ::nbl::hlsl::is_same_v, typename T::scalar_type))
46+ );
47+ #undef query
48+ #include <nbl/builtin/hlsl/concepts/__end.hlsl>
49+ }
50+
1951namespace impl
2052{
2153
@@ -43,18 +75,6 @@ struct SBeckmannG2overG1Query
4375 scalar_type lambda_V;
4476};
4577
46- template<typename T>
47- struct SBeckmannQuantQuery
48- {
49- using scalar_type = T;
50-
51- scalar_type getVdotHLdotH () NBL_CONST_MEMBER_FUNC { return VdotHLdotH; }
52- scalar_type getVdotH_etaLdotH () NBL_CONST_MEMBER_FUNC { return VdotH_etaLdotH; }
53-
54- scalar_type VdotHLdotH;
55- scalar_type VdotH_etaLdotH;
56- };
57-
5878template<typename T, bool IsAnisotropic=false NBL_STRUCT_CONSTRAINABLE>
5979struct BeckmannCommon;
6080
@@ -63,8 +83,6 @@ NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar<T>)
6383struct BeckmannCommon<T,false NBL_PARTIAL_REQ_BOT (concepts::FloatingPointScalar<T>) >
6484{
6585 using scalar_type = T;
66- using dg1_query_type = SBeckmannDG1Query<scalar_type>;
67- using g2g1_query_type = SBeckmannG2overG1Query<scalar_type>;
6886
6987 template<class MicrofacetCache NBL_FUNC_REQUIRES (ReadableIsotropicMicrofacetCache<MicrofacetCache>)
7088 scalar_type D (NBL_CONST_REF_ARG (MicrofacetCache) cache)
@@ -75,22 +93,12 @@ struct BeckmannCommon<T,false NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<
7593 return numbers::inv_pi<scalar_type> * nom / denom;
7694 }
7795
78- scalar_type DG1 (NBL_CONST_REF_ARG (dg1_query_type) query)
96+ template<class Query NBL_FUNC_REQUIRES (beckmann_concepts::DG1Query<Query>)
97+ static scalar_type DG1 (NBL_CONST_REF_ARG (Query) query)
7998 {
8099 return query.getNdf () / (scalar_type (1.0 ) + query.getLambdaV ());
81100 }
82101
83- //conversion between alpha and Phong exponent, Walter et.al.
84- static scalar_type phong_exp_to_alpha2 (scalar_type _n)
85- {
86- return 2.0 / (_n + 2.0 );
87- }
88- //+INF for a2==0.0
89- static scalar_type alpha2_to_phong_exp (scalar_type a2)
90- {
91- return 2.0 / a2 - 2.0 ;
92- }
93-
94102 scalar_type C2 (scalar_type NdotX2)
95103 {
96104 return NdotX2 / (a2 * (scalar_type (1.0 ) - NdotX2));
@@ -109,13 +117,14 @@ struct BeckmannCommon<T,false NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<
109117 return Lambda (C2 (NdotX2));
110118 }
111119
112- scalar_type correlated (NBL_CONST_REF_ARG (g2g1_query_type) query)
120+ template<class Query NBL_FUNC_REQUIRES (beckmann_concepts::G2overG1Query<Query>)
121+ static scalar_type correlated (NBL_CONST_REF_ARG (Query) query)
113122 {
114123 return scalar_type (1.0 ) / (scalar_type (1.0 ) + query.getLambdaV () + query.getLambdaL ());
115124 }
116125
117- template<class MicrofacetCache NBL_FUNC_REQUIRES (ReadableIsotropicMicrofacetCache<MicrofacetCache>)
118- scalar_type G2_over_G1 (NBL_CONST_REF_ARG (g2g1_query_type ) query, NBL_CONST_REF_ARG (MicrofacetCache) cache)
126+ template<class Query, class MicrofacetCache NBL_FUNC_REQUIRES (beckmann_concepts::G2overG1Query<Query> && ReadableIsotropicMicrofacetCache<MicrofacetCache>)
127+ static scalar_type G2_over_G1 (NBL_CONST_REF_ARG (Query ) query, NBL_CONST_REF_ARG (MicrofacetCache) cache)
119128 {
120129 scalar_type onePlusLambda_V = scalar_type (1.0 ) + query.getLambdaV ();
121130 scalar_type lambda_L = query.getLambdaL ();
@@ -131,8 +140,6 @@ NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar<T>)
131140struct BeckmannCommon<T,true NBL_PARTIAL_REQ_BOT (concepts::FloatingPointScalar<T>) >
132141{
133142 using scalar_type = T;
134- using dg1_query_type = SBeckmannDG1Query<scalar_type>;
135- using g2g1_query_type = SBeckmannG2overG1Query<scalar_type>;
136143
137144 template<class MicrofacetCache NBL_FUNC_REQUIRES (AnisotropicMicrofacetCache<MicrofacetCache>)
138145 scalar_type D (NBL_CONST_REF_ARG (MicrofacetCache) cache)
@@ -143,24 +150,14 @@ struct BeckmannCommon<T,true NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<T
143150 return numbers::inv_pi<scalar_type> * nom / denom;
144151 }
145152
146- scalar_type DG1 (NBL_CONST_REF_ARG (dg1_query_type) query)
153+ template<class Query NBL_FUNC_REQUIRES (beckmann_concepts::DG1Query<Query>)
154+ static scalar_type DG1 (NBL_CONST_REF_ARG (Query) query)
147155 {
148156 BeckmannCommon<T,false > beckmann;
149157 scalar_type dg = beckmann.DG1 (query);
150158 return dg;
151159 }
152160
153- //conversion between alpha and Phong exponent, Walter et.al.
154- static scalar_type phong_exp_to_alpha2 (scalar_type _n)
155- {
156- return 2.0 / (_n + 2.0 );
157- }
158- //+INF for a2==0.0
159- static scalar_type alpha2_to_phong_exp (scalar_type a2)
160- {
161- return 2.0 / a2 - 2.0 ;
162- }
163-
164161 scalar_type C2 (scalar_type TdotX2, scalar_type BdotX2, scalar_type NdotX2)
165162 {
166163 return NdotX2 / (TdotX2 * ax2 + BdotX2 * ay2);
@@ -179,13 +176,14 @@ struct BeckmannCommon<T,true NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<T
179176 return Lambda (C2 (TdotX2, BdotX2, NdotX2));
180177 }
181178
182- scalar_type correlated (NBL_CONST_REF_ARG (g2g1_query_type) query)
179+ template<class Query NBL_FUNC_REQUIRES (beckmann_concepts::G2overG1Query<Query>)
180+ static scalar_type correlated (NBL_CONST_REF_ARG (Query) query)
183181 {
184182 return scalar_type (1.0 ) / (scalar_type (1.0 ) + query.getLambdaV () + query.getLambdaL ());
185183 }
186184
187- template<class MicrofacetCache NBL_FUNC_REQUIRES (AnisotropicMicrofacetCache<MicrofacetCache>)
188- scalar_type G2_over_G1 (NBL_CONST_REF_ARG (g2g1_query_type ) query, NBL_CONST_REF_ARG (MicrofacetCache) cache)
185+ template<class Query, class MicrofacetCache NBL_FUNC_REQUIRES (beckmann_concepts::G2overG1Query<Query> && AnisotropicMicrofacetCache<MicrofacetCache>)
186+ static scalar_type G2_over_G1 (NBL_CONST_REF_ARG (Query ) query, NBL_CONST_REF_ARG (MicrofacetCache) cache)
189187 {
190188 scalar_type onePlusLambda_V = scalar_type (1.0 ) + query.getLambdaV ();
191189 scalar_type lambda_L = query.getLambdaL ();
@@ -285,9 +283,9 @@ struct Beckmann
285283 using vector2_type = vector <T, 2 >;
286284 using vector3_type = vector <T, 3 >;
287285
288- using dg1_query_type = typename base_type::dg1_query_type ;
289- using g2g1_query_type = typename base_type::g2g1_query_type ;
290- using quant_query_type = impl::SBeckmannQuantQuery <scalar_type>;
286+ using dg1_query_type = impl::SBeckmannDG1Query<scalar_type> ;
287+ using g2g1_query_type = impl::SBeckmannG2overG1Query<scalar_type> ;
288+ using quant_query_type = impl::NDFQuantQuery <scalar_type>;
291289
292290 NBL_CONSTEXPR_STATIC_INLINE bool IsBSDF = reflect_refract != MTT_REFLECT;
293291 template<class Interaction>
@@ -363,31 +361,46 @@ struct Beckmann
363361 template<class LS, class Interaction, typename C=bool_constant<!IsBSDF> NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction>)
364362 enable_if_t<C::value && !IsBSDF, quant_type> DG1 (NBL_CONST_REF_ARG (dg1_query_type) query, NBL_CONST_REF_ARG (quant_query_type) quant_query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
365363 {
366- scalar_type dg1 = __base. DG1 (query);
364+ scalar_type dg1 = base_type::template DG1<dg1_query_type> (query);
367365 return createDualMeasureQuantity<T>(dg1, interaction.getNdotV (BxDFClampMode::BCM_MAX), _sample.getNdotL (BxDFClampMode::BCM_MAX));
368366 }
369367 template<class LS, class Interaction, typename C=bool_constant<IsBSDF> NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction>)
370368 enable_if_t<C::value && IsBSDF, quant_type> DG1 (NBL_CONST_REF_ARG (dg1_query_type) query, NBL_CONST_REF_ARG (quant_query_type) quant_query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
371369 {
372- scalar_type dg1 = __base. DG1 (query);
370+ scalar_type dg1 = base_type::template DG1<dg1_query_type> (query);
373371 return createDualMeasureQuantity<T, reflect_refract>(dg1, interaction.getNdotV (BxDFClampMode::BCM_ABS), _sample.getNdotL (BxDFClampMode::BCM_ABS), quant_query.getVdotHLdotH (), quant_query.getVdotH_etaLdotH ());
374372 }
375373
376374 template<class LS, class Interaction NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction>)
377375 scalar_type correlated (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction)
378376 {
379- return __base. correlated (query);
377+ return base_type::template correlated<g2g1_query_type> (query);
380378 }
381379
382380 template<class LS, class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES (LightSample<LS> && RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
383381 scalar_type G2_over_G1 (NBL_CONST_REF_ARG (g2g1_query_type) query, NBL_CONST_REF_ARG (LS) _sample, NBL_CONST_REF_ARG (Interaction) interaction, NBL_CONST_REF_ARG (MicrofacetCache) cache)
384382 {
385- return __base. template G2_over_G1<MicrofacetCache>(query, cache);
383+ return base_type:: template G2_over_G1<g2g1_query_type, MicrofacetCache>(query, cache);
386384 }
387385
388386 base_type __base;
389387};
390388
389+ template<typename T>
390+ struct PhongExponent
391+ {
392+ //conversion between alpha and Phong exponent, Walter et.al.
393+ static T ToAlpha2 (T _n)
394+ {
395+ return T (2.0 ) / (_n + T (2.0 ));
396+ }
397+ //+INF for a2==0.0
398+ static T FromAlpha2 (T a2)
399+ {
400+ return T (2.0 ) / a2 - T (2.0 );
401+ }
402+ };
403+
391404}
392405}
393406}
0 commit comments