Skip to content

Commit 6272281

Browse files
committed
reduced duplicate code in beckmann, ggx ndfs
1 parent 97e5ce3 commit 6272281

File tree

4 files changed

+100
-250
lines changed

4 files changed

+100
-250
lines changed

include/nbl/builtin/hlsl/bxdf/ndf.hlsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ template<class MicrofacetCache>\
7272
NBL_CONSTEXPR_STATIC_INLINE bool RequiredMicrofacetCache = IsAnisotropic ? AnisotropicMicrofacetCache<MicrofacetCache> : ReadableIsotropicMicrofacetCache<MicrofacetCache>;\
7373

7474
// help avoid preprocessor splitting template declarations by comma
75-
#define SINGLE_ARG(...) __VA_ARGS__
75+
#define NDF_SINGLE_ARG(...) __VA_ARGS__
7676

7777
#define NDF_TYPE_ALIASES(N,BASE,DG1_QUERY,G2_QUERY,QUANT_QUERY) using this_t = N;\
7878
using scalar_type = T;\

include/nbl/builtin/hlsl/bxdf/ndf/beckmann.hlsl

Lines changed: 27 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -110,45 +110,12 @@ struct BeckmannCommon<T,false NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<
110110
return numbers::inv_pi<scalar_type> * nom / denom;
111111
}
112112

113-
template<class Query NBL_FUNC_REQUIRES(beckmann_concepts::DG1Query<Query>)
114-
static scalar_type DG1(NBL_CONST_REF_ARG(Query) query)
115-
{
116-
return query.getNdf() / (scalar_type(1.0) + query.getLambdaV());
117-
}
118-
119113
scalar_type C2(scalar_type NdotX2)
120114
{
121115
assert(NdotX2 >= scalar_type(0.0));
122116
return NdotX2 / (a2 * (scalar_type(1.0) - NdotX2));
123117
}
124118

125-
static scalar_type Lambda(scalar_type c2)
126-
{
127-
scalar_type c = sqrt<scalar_type>(c2);
128-
scalar_type nom = scalar_type(1.0) - scalar_type(1.259) * c + scalar_type(0.396) * c2;
129-
scalar_type denom = scalar_type(2.181) * c2 + scalar_type(3.535) * c;
130-
return hlsl::mix<scalar_type>(scalar_type(0.0), nom / denom, c < scalar_type(1.6));
131-
}
132-
133-
scalar_type LambdaC2(scalar_type NdotX2)
134-
{
135-
return Lambda(C2(NdotX2));
136-
}
137-
138-
template<class Query NBL_FUNC_REQUIRES(beckmann_concepts::G2overG1Query<Query>)
139-
static scalar_type correlated(NBL_CONST_REF_ARG(Query) query)
140-
{
141-
return scalar_type(1.0) / (scalar_type(1.0) + query.getLambdaV() + query.getLambdaL());
142-
}
143-
144-
template<class Query, class MicrofacetCache NBL_FUNC_REQUIRES(beckmann_concepts::G2overG1Query<Query> && ReadableIsotropicMicrofacetCache<MicrofacetCache>)
145-
static scalar_type G2_over_G1(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(MicrofacetCache) cache)
146-
{
147-
scalar_type onePlusLambda_V = scalar_type(1.0) + query.getLambdaV();
148-
scalar_type lambda_L = query.getLambdaL();
149-
return onePlusLambda_V * hlsl::mix(scalar_type(1.0)/(onePlusLambda_V + lambda_L), bxdf::beta<scalar_type>(onePlusLambda_V, scalar_type(1.0) + lambda_L), cache.isTransmission());
150-
}
151-
152119
scalar_type a2;
153120
};
154121

@@ -169,46 +136,11 @@ struct BeckmannCommon<T,true NBL_PARTIAL_REQ_BOT(concepts::FloatingPointScalar<T
169136
return numbers::inv_pi<scalar_type> * nom / denom;
170137
}
171138

172-
template<class Query NBL_FUNC_REQUIRES(beckmann_concepts::DG1Query<Query>)
173-
static scalar_type DG1(NBL_CONST_REF_ARG(Query) query)
174-
{
175-
BeckmannCommon<T,false> beckmann;
176-
scalar_type dg = beckmann.DG1(query);
177-
return dg;
178-
}
179-
180139
scalar_type C2(scalar_type TdotX2, scalar_type BdotX2, scalar_type NdotX2)
181140
{
182141
return NdotX2 / (TdotX2 * ax2 + BdotX2 * ay2);
183142
}
184143

185-
static scalar_type Lambda(scalar_type c2)
186-
{
187-
scalar_type c = sqrt<scalar_type>(c2);
188-
scalar_type nom = scalar_type(1.0) - scalar_type(1.259) * c + scalar_type(0.396) * c2;
189-
scalar_type denom = scalar_type(2.181) * c2 + scalar_type(3.535) * c;
190-
return hlsl::mix<scalar_type>(scalar_type(0.0), nom / denom, c < scalar_type(1.6));
191-
}
192-
193-
scalar_type LambdaC2(scalar_type TdotX2, scalar_type BdotX2, scalar_type NdotX2)
194-
{
195-
return Lambda(C2(TdotX2, BdotX2, NdotX2));
196-
}
197-
198-
template<class Query NBL_FUNC_REQUIRES(beckmann_concepts::G2overG1Query<Query>)
199-
static scalar_type correlated(NBL_CONST_REF_ARG(Query) query)
200-
{
201-
return scalar_type(1.0) / (scalar_type(1.0) + query.getLambdaV() + query.getLambdaL());
202-
}
203-
204-
template<class Query, class MicrofacetCache NBL_FUNC_REQUIRES(beckmann_concepts::G2overG1Query<Query> && AnisotropicMicrofacetCache<MicrofacetCache>)
205-
static scalar_type G2_over_G1(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(MicrofacetCache) cache)
206-
{
207-
scalar_type onePlusLambda_V = scalar_type(1.0) + query.getLambdaV();
208-
scalar_type lambda_L = query.getLambdaL();
209-
return onePlusLambda_V * hlsl::mix(scalar_type(1.0)/(onePlusLambda_V + lambda_L), bxdf::beta<scalar_type>(onePlusLambda_V, scalar_type(1.0) + lambda_L), cache.isTransmission());
210-
}
211-
212144
scalar_type ax2;
213145
scalar_type ay2;
214146
scalar_type a2;
@@ -299,7 +231,7 @@ template<typename T, bool _IsAnisotropic, MicrofacetTransformTypes reflect_refra
299231
struct Beckmann
300232
{
301233
NDF_CONSTEXPR_DECLS(_IsAnisotropic,reflect_refract);
302-
NDF_TYPE_ALIASES(SINGLE_ARG(Beckmann<T,IsAnisotropic,SupportedPaths>), SINGLE_ARG(impl::BeckmannCommon<T,IsAnisotropic>), impl::SBeckmannDG1Query<scalar_type>, impl::SBeckmannG2overG1Query<scalar_type>, DualMeasureQuantQuery<scalar_type>);
234+
NDF_TYPE_ALIASES(NDF_SINGLE_ARG(Beckmann<T,IsAnisotropic,SupportedPaths>), NDF_SINGLE_ARG(impl::BeckmannCommon<T,IsAnisotropic>), impl::SBeckmannDG1Query<scalar_type>, impl::SBeckmannG2overG1Query<scalar_type>, DualMeasureQuantQuery<scalar_type>);
303235

304236
template<typename C=bool_constant<!IsAnisotropic> >
305237
static enable_if_t<C::value && !IsAnisotropic, this_t> create(scalar_type A)
@@ -322,11 +254,19 @@ struct Beckmann
322254
return retval;
323255
}
324256

257+
static scalar_type Lambda(scalar_type c2)
258+
{
259+
scalar_type c = sqrt<scalar_type>(c2);
260+
scalar_type nom = scalar_type(1.0) - scalar_type(1.259) * c + scalar_type(0.396) * c2;
261+
scalar_type denom = scalar_type(2.181) * c2 + scalar_type(3.535) * c;
262+
return hlsl::mix<scalar_type>(scalar_type(0.0), nom / denom, c < scalar_type(1.6));
263+
}
264+
325265
template<class MicrofacetCache NBL_FUNC_REQUIRES(RequiredMicrofacetCache<MicrofacetCache>)
326266
quant_query_type createQuantQuery(NBL_CONST_REF_ARG(MicrofacetCache) cache, scalar_type orientedEta)
327267
{
328268
quant_query_type quant_query; // only has members for refraction
329-
if (SupportsTransmission)
269+
NBL_IF_CONSTEXPR(SupportsTransmission)
330270
{
331271
quant_query.VdotHLdotH = cache.getVdotHLdotH();
332272
quant_query.VdotH_etaLdotH = cache.getVdotH() + orientedEta * cache.getLdotH();
@@ -338,31 +278,31 @@ struct Beckmann
338278
{
339279
dg1_query_type dg1_query;
340280
dg1_query.ndf = __ndf_base.template D<MicrofacetCache>(cache);
341-
dg1_query.lambda_V = __ndf_base.LambdaC2(interaction.getNdotV2());
281+
dg1_query.lambda_V = Lambda(__ndf_base.C2(interaction.getNdotV2()));
342282
return dg1_query;
343283
}
344284
template<class LS, class Interaction, typename C=bool_constant<!IsAnisotropic> NBL_FUNC_REQUIRES(LightSample<LS> && RequiredInteraction<Interaction>)
345285
enable_if_t<C::value && !IsAnisotropic, g2g1_query_type> createG2G1Query(NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction)
346286
{
347287
g2g1_query_type g2_query;
348-
g2_query.lambda_L = __ndf_base.LambdaC2(_sample.getNdotL2());
349-
g2_query.lambda_V = __ndf_base.LambdaC2(interaction.getNdotV2());
288+
g2_query.lambda_L = Lambda(__ndf_base.C2(_sample.getNdotL2()));
289+
g2_query.lambda_V = Lambda(__ndf_base.C2(interaction.getNdotV2()));
350290
return g2_query;
351291
}
352292
template<class Interaction, class MicrofacetCache, typename C=bool_constant<IsAnisotropic> NBL_FUNC_REQUIRES(RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
353293
enable_if_t<C::value && IsAnisotropic, dg1_query_type> createDG1Query(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache)
354294
{
355295
dg1_query_type dg1_query;
356296
dg1_query.ndf = __ndf_base.template D<MicrofacetCache>(cache);
357-
dg1_query.lambda_V = __ndf_base.LambdaC2(interaction.getTdotV2(), interaction.getBdotV2(), interaction.getNdotV2());
297+
dg1_query.lambda_V = Lambda(__ndf_base.C2(interaction.getTdotV2(), interaction.getBdotV2(), interaction.getNdotV2()));
358298
return dg1_query;
359299
}
360300
template<class LS, class Interaction, typename C=bool_constant<IsAnisotropic> NBL_FUNC_REQUIRES(LightSample<LS> && RequiredInteraction<Interaction>)
361301
enable_if_t<C::value && IsAnisotropic, g2g1_query_type> createG2G1Query(NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction)
362302
{
363303
g2g1_query_type g2_query;
364-
g2_query.lambda_L = __ndf_base.LambdaC2(_sample.getTdotL2(), _sample.getBdotL2(), _sample.getNdotL2());
365-
g2_query.lambda_V = __ndf_base.LambdaC2(interaction.getTdotV2(), interaction.getBdotV2(), interaction.getNdotV2());
304+
g2_query.lambda_L = Lambda(__ndf_base.C2(_sample.getTdotL2(), _sample.getBdotL2(), _sample.getNdotL2()));
305+
g2_query.lambda_V = Lambda(__ndf_base.C2(interaction.getTdotV2(), interaction.getBdotV2(), interaction.getNdotV2()));
366306
return g2_query;
367307
}
368308

@@ -371,42 +311,32 @@ struct Beckmann
371311
return __generate_base.__call(localV, u);
372312
}
373313

374-
template<class LS, class Interaction, class MicrofacetCache, typename C=bool_constant<!SupportsTransmission> NBL_FUNC_REQUIRES(LightSample<LS> && RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
375-
enable_if_t<C::value && !SupportsTransmission, quant_type> D(NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache)
376-
{
377-
scalar_type d = __ndf_base.template D<MicrofacetCache>(cache);
378-
return createDualMeasureQuantity<T>(d, interaction.getNdotV(BxDFClampMode::BCM_MAX), _sample.getNdotL(BxDFClampMode::BCM_MAX));
379-
}
380-
template<class LS, class Interaction, class MicrofacetCache, typename C=bool_constant<SupportsTransmission> NBL_FUNC_REQUIRES(LightSample<LS> && RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
381-
enable_if_t<C::value && SupportsTransmission, quant_type> D(NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache)
314+
template<class LS, class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES(LightSample<LS> && RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
315+
quant_type D(NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache)
382316
{
383317
scalar_type d = __ndf_base.template D<MicrofacetCache>(cache);
384-
return createDualMeasureQuantity<T, reflect_refract>(d, interaction.getNdotV(BxDFClampMode::BCM_ABS), _sample.getNdotL(BxDFClampMode::BCM_ABS), quant_query.getVdotHLdotH(), quant_query.getVdotH_etaLdotH());
318+
return createDualMeasureQuantity<T, reflect_refract, quant_query_type>(d, interaction.getNdotV(BxDFClampMode::BCM_ABS), _sample.getNdotL(BxDFClampMode::BCM_ABS), quant_query);
385319
}
386320

387-
template<class LS, class Interaction, typename C=bool_constant<!SupportsTransmission> NBL_FUNC_REQUIRES(LightSample<LS> && RequiredInteraction<Interaction>)
388-
enable_if_t<C::value && !SupportsTransmission, 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)
389-
{
390-
scalar_type dg1 = base_type::template DG1<dg1_query_type>(query);
391-
return createDualMeasureQuantity<T>(dg1, interaction.getNdotV(BxDFClampMode::BCM_MAX), _sample.getNdotL(BxDFClampMode::BCM_MAX));
392-
}
393-
template<class LS, class Interaction, typename C=bool_constant<SupportsTransmission> NBL_FUNC_REQUIRES(LightSample<LS> && RequiredInteraction<Interaction>)
394-
enable_if_t<C::value && SupportsTransmission, 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)
321+
template<class LS, class Interaction NBL_FUNC_REQUIRES(LightSample<LS> && RequiredInteraction<Interaction>)
322+
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)
395323
{
396-
scalar_type dg1 = base_type::template DG1<dg1_query_type>(query);
397-
return createDualMeasureQuantity<T, reflect_refract>(dg1, interaction.getNdotV(BxDFClampMode::BCM_ABS), _sample.getNdotL(BxDFClampMode::BCM_ABS), quant_query.getVdotHLdotH(), quant_query.getVdotH_etaLdotH());
324+
scalar_type dg1 = query.getNdf() / (scalar_type(1.0) + query.getLambdaV());
325+
return createDualMeasureQuantity<T, reflect_refract, quant_query_type>(dg1, interaction.getNdotV(BxDFClampMode::BCM_ABS), _sample.getNdotL(BxDFClampMode::BCM_ABS), quant_query);
398326
}
399327

400328
template<class LS, class Interaction NBL_FUNC_REQUIRES(LightSample<LS> && RequiredInteraction<Interaction>)
401329
scalar_type correlated(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction)
402330
{
403-
return base_type::template correlated<g2g1_query_type>(query);
331+
return scalar_type(1.0) / (scalar_type(1.0) + query.getLambdaV() + query.getLambdaL());
404332
}
405333

406334
template<class LS, class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES(LightSample<LS> && RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
407335
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)
408336
{
409-
return base_type::template G2_over_G1<g2g1_query_type, MicrofacetCache>(query, cache);
337+
scalar_type onePlusLambda_V = scalar_type(1.0) + query.getLambdaV();
338+
scalar_type lambda_L = query.getLambdaL();
339+
return onePlusLambda_V * hlsl::mix(scalar_type(1.0)/(onePlusLambda_V + lambda_L), bxdf::beta<scalar_type>(onePlusLambda_V, scalar_type(1.0) + lambda_L), cache.isTransmission());
410340
}
411341

412342
base_type __ndf_base;

0 commit comments

Comments
 (0)