Skip to content

Commit 906d437

Browse files
committed
moved lambertian and oren nayar logic into a base class
1 parent 75ef607 commit 906d437

File tree

7 files changed

+241
-144
lines changed

7 files changed

+241
-144
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright (C) 2018-2025 - DevSH Graphics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
#ifndef _NBL_BUILTIN_HLSL_BXDF_BASE_LAMBERTIAN_INCLUDED_
5+
#define _NBL_BUILTIN_HLSL_BXDF_BASE_LAMBERTIAN_INCLUDED_
6+
7+
#include "nbl/builtin/hlsl/bxdf/common.hlsl"
8+
#include "nbl/builtin/hlsl/bxdf/config.hlsl"
9+
#include "nbl/builtin/hlsl/sampling/cos_weighted_spheres.hlsl"
10+
11+
namespace nbl
12+
{
13+
namespace hlsl
14+
{
15+
namespace bxdf
16+
{
17+
namespace base
18+
{
19+
20+
template<class Config, bool IsBSDF NBL_PRIMARY_REQUIRES(config_concepts::BasicConfiguration<Config>)
21+
struct SLambertianBase
22+
{
23+
using this_t = SLambertianBase<Config, IsBSDF>;
24+
BXDF_CONFIG_TYPE_ALIASES(Config);
25+
26+
NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value<IsBSDF, BxDFClampMode, BxDFClampMode::BCM_ABS, BxDFClampMode::BCM_MAX>::value;
27+
28+
spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction)
29+
{
30+
return hlsl::promote<spectral_type>(_sample.getNdotL(_clamp) * numbers::inv_pi<scalar_type> * hlsl::mix(1.0, 0.5, IsBSDF));
31+
}
32+
33+
sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u)
34+
{
35+
// static_assert(!IsBSDF);
36+
ray_dir_info_type L;
37+
L.direction = sampling::ProjectedHemisphere<scalar_type>::generate(u);
38+
return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace());
39+
}
40+
41+
sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u)
42+
{
43+
// static_assert(IsBSDF);
44+
ray_dir_info_type L;
45+
L.direction = sampling::ProjectedSphere<scalar_type>::generate(u);
46+
return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace());
47+
}
48+
49+
scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample)
50+
{
51+
if (IsBSDF)
52+
return sampling::ProjectedSphere<scalar_type>::pdf(_sample.getNdotL(_clamp));
53+
else
54+
return sampling::ProjectedHemisphere<scalar_type>::pdf(_sample.getNdotL(_clamp));
55+
}
56+
57+
quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction)
58+
{
59+
sampling::quotient_and_pdf<monochrome_type, scalar_type> qp;
60+
if (IsBSDF)
61+
qp = sampling::ProjectedSphere<scalar_type>::template quotient_and_pdf(_sample.getNdotL(_clamp));
62+
else
63+
qp = sampling::ProjectedHemisphere<scalar_type>::template quotient_and_pdf(_sample.getNdotL(_clamp));
64+
return quotient_pdf_type::create(qp.quotient[0], qp.pdf);
65+
}
66+
};
67+
68+
}
69+
}
70+
}
71+
}
72+
73+
#endif
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Copyright (C) 2018-2025 - DevSH Graphics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
#ifndef _NBL_BUILTIN_HLSL_BXDF_BASE_OREN_NAYAR_INCLUDED_
5+
#define _NBL_BUILTIN_HLSL_BXDF_BASE_OREN_NAYAR_INCLUDED_
6+
7+
#include "nbl/builtin/hlsl/bxdf/common.hlsl"
8+
#include "nbl/builtin/hlsl/bxdf/config.hlsl"
9+
#include "nbl/builtin/hlsl/sampling/cos_weighted_spheres.hlsl"
10+
11+
namespace nbl
12+
{
13+
namespace hlsl
14+
{
15+
namespace bxdf
16+
{
17+
namespace base
18+
{
19+
20+
template<class Config, bool IsBSDF NBL_PRIMARY_REQUIRES(config_concepts::BasicConfiguration<Config>)
21+
struct SOrenNayarBase
22+
{
23+
using this_t = SOrenNayarBase<Config, IsBSDF>;
24+
BXDF_CONFIG_TYPE_ALIASES(Config);
25+
26+
NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value<IsBSDF, BxDFClampMode, BxDFClampMode::BCM_ABS, BxDFClampMode::BCM_MAX>::value;
27+
28+
struct SCreationParams
29+
{
30+
scalar_type A;
31+
};
32+
using creation_type = SCreationParams;
33+
34+
struct SQuery
35+
{
36+
scalar_type getVdotL() NBL_CONST_MEMBER_FUNC { return VdotL; }
37+
scalar_type VdotL;
38+
};
39+
40+
static this_t create(NBL_CONST_REF_ARG(creation_type) params)
41+
{
42+
this_t retval;
43+
retval.A2 = params.A * 0.5;
44+
retval.AB = vector2_type(1.0, 0.0) + vector2_type(-0.5, 0.45) * vector2_type(retval.A2, retval.A2) / vector2_type(retval.A2 + 0.33, retval.A2 + 0.09);
45+
return retval;
46+
}
47+
48+
scalar_type __rec_pi_factored_out_wo_clamps(scalar_type VdotL, scalar_type clampedNdotL, scalar_type clampedNdotV)
49+
{
50+
scalar_type C = 1.0 / max<scalar_type>(clampedNdotL, clampedNdotV);
51+
scalar_type cos_phi_sin_theta = max<scalar_type>(VdotL - clampedNdotL * clampedNdotV, 0.0);
52+
return (AB.x + AB.y * cos_phi_sin_theta * C);
53+
}
54+
template<typename Query>
55+
spectral_type __eval(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction)
56+
{
57+
scalar_type NdotL = _sample.getNdotL(_clamp);
58+
return hlsl::promote<spectral_type>(NdotL * numbers::inv_pi<scalar_type> * hlsl::mix(1.0, 0.5, IsBSDF) * __rec_pi_factored_out_wo_clamps(query.getVdotL(), NdotL, interaction.getNdotV(_clamp)));
59+
}
60+
61+
spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction)
62+
{
63+
SQuery query;
64+
query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection());
65+
return __eval<SQuery>(query, _sample, interaction);
66+
}
67+
68+
sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u)
69+
{
70+
// static_assert(!IsBSDF);
71+
ray_dir_info_type L;
72+
L.direction = sampling::ProjectedHemisphere<scalar_type>::generate(u);
73+
return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace());
74+
}
75+
76+
sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u)
77+
{
78+
// static_assert(IsBSDF);
79+
ray_dir_info_type L;
80+
L.direction = sampling::ProjectedSphere<scalar_type>::generate(u);
81+
return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace());
82+
}
83+
84+
scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample)
85+
{
86+
if (IsBSDF)
87+
return sampling::ProjectedSphere<scalar_type>::pdf(_sample.getNdotL(_clamp));
88+
else
89+
return sampling::ProjectedHemisphere<scalar_type>::pdf(_sample.getNdotL(_clamp));
90+
}
91+
92+
template<typename Query>
93+
quotient_pdf_type __quotient_and_pdf(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction)
94+
{
95+
scalar_type _pdf = pdf(_sample);
96+
scalar_type q = __rec_pi_factored_out_wo_clamps(query.getVdotL(), _sample.getNdotL(_clamp), interaction.getNdotV(_clamp));
97+
return quotient_pdf_type::create(q, _pdf);
98+
}
99+
quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction)
100+
{
101+
SQuery query;
102+
query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection());
103+
return __quotient_and_pdf<SQuery>(query, _sample, interaction);
104+
}
105+
106+
scalar_type A2;
107+
vector2_type AB;
108+
};
109+
110+
}
111+
}
112+
}
113+
}
114+
115+
#endif

include/nbl/builtin/hlsl/bxdf/reflection/lambertian.hlsl

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44
#ifndef _NBL_BUILTIN_HLSL_BXDF_REFLECTION_LAMBERTIAN_INCLUDED_
55
#define _NBL_BUILTIN_HLSL_BXDF_REFLECTION_LAMBERTIAN_INCLUDED_
66

7-
#include "nbl/builtin/hlsl/bxdf/common.hlsl"
8-
#include "nbl/builtin/hlsl/bxdf/config.hlsl"
97
#include "nbl/builtin/hlsl/bxdf/bxdf_traits.hlsl"
10-
#include "nbl/builtin/hlsl/sampling/cos_weighted_spheres.hlsl"
8+
#include "nbl/builtin/hlsl/bxdf/base/lambertian.hlsl"
119

1210
namespace nbl
1311
{
@@ -28,39 +26,37 @@ struct SLambertian
2826

2927
spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction)
3028
{
31-
return hlsl::promote<spectral_type>(_sample.getNdotL(_clamp) * numbers::inv_pi<scalar_type>);
29+
return __base.eval(_sample, interaction);
3230
}
3331
spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction)
3432
{
35-
return eval(_sample, interaction.isotropic);
33+
return __base.eval(_sample, interaction.isotropic);
3634
}
3735

38-
sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u)
36+
sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u)
3937
{
40-
ray_dir_info_type L;
41-
L.direction = sampling::ProjectedHemisphere<scalar_type>::generate(u);
42-
return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace());
38+
return __base.generate(anisotropic_interaction_type::create(interaction), u);
4339
}
44-
45-
sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u)
40+
sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u)
4641
{
47-
return generate(anisotropic_interaction_type::create(interaction), u);
42+
return __base.generate(interaction, u);
4843
}
4944

5045
scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample)
5146
{
52-
return sampling::ProjectedHemisphere<scalar_type>::pdf(_sample.getNdotL(_clamp));
47+
return __base.pdf(_sample);
5348
}
5449

5550
quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction)
5651
{
57-
sampling::quotient_and_pdf<monochrome_type, scalar_type> qp = sampling::ProjectedHemisphere<scalar_type>::template quotient_and_pdf(_sample.getNdotL(_clamp));
58-
return quotient_pdf_type::create(qp.quotient[0], qp.pdf);
52+
return __base.quotient_and_pdf(_sample, interaction);
5953
}
6054
quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction)
6155
{
62-
return quotient_and_pdf(_sample, interaction.isotropic);
56+
return __base.quotient_and_pdf(_sample, interaction.isotropic);
6357
}
58+
59+
base::SLambertianBase<Config, false> __base;
6460
};
6561

6662
}

include/nbl/builtin/hlsl/bxdf/reflection/oren_nayar.hlsl

Lines changed: 14 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44
#ifndef _NBL_BUILTIN_HLSL_BXDF_REFLECTION_OREN_NAYAR_INCLUDED_
55
#define _NBL_BUILTIN_HLSL_BXDF_REFLECTION_OREN_NAYAR_INCLUDED_
66

7-
#include "nbl/builtin/hlsl/bxdf/common.hlsl"
8-
#include "nbl/builtin/hlsl/bxdf/config.hlsl"
97
#include "nbl/builtin/hlsl/bxdf/bxdf_traits.hlsl"
10-
#include "nbl/builtin/hlsl/sampling/cos_weighted_spheres.hlsl"
8+
#include "nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl"
119

1210
namespace nbl
1311
{
@@ -26,87 +24,49 @@ struct SOrenNayar
2624

2725
NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_MAX;
2826

29-
struct SCreationParams
30-
{
31-
scalar_type A;
32-
};
33-
using creation_type = SCreationParams;
34-
35-
struct SQuery
36-
{
37-
scalar_type getVdotL() NBL_CONST_MEMBER_FUNC { return VdotL; }
38-
scalar_type VdotL;
39-
};
27+
using base_type = base::SOrenNayarBase<Config, false>;
28+
using creation_type = typename base_type::creation_type;
4029

4130
static this_t create(NBL_CONST_REF_ARG(creation_type) params)
4231
{
4332
this_t retval;
44-
retval.A2 = params.A * 0.5;
45-
retval.AB = vector2_type(1.0, 0.0) + vector2_type(-0.5, 0.45) * vector2_type(retval.A2, retval.A2) / vector2_type(retval.A2 + 0.33, retval.A2 + 0.09);
33+
retval.__base = base_type::create(params);
4634
return retval;
4735
}
4836

49-
scalar_type __rec_pi_factored_out_wo_clamps(scalar_type VdotL, scalar_type clampedNdotL, scalar_type clampedNdotV)
50-
{
51-
scalar_type C = 1.0 / max<scalar_type>(clampedNdotL, clampedNdotV);
52-
scalar_type cos_phi_sin_theta = max<scalar_type>(VdotL - clampedNdotL * clampedNdotV, 0.0);
53-
return (AB.x + AB.y * cos_phi_sin_theta * C);
54-
}
55-
template<typename Query>
56-
spectral_type __eval(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction)
57-
{
58-
scalar_type NdotL = _sample.getNdotL(_clamp);
59-
return hlsl::promote<spectral_type>(NdotL * numbers::inv_pi<scalar_type> * __rec_pi_factored_out_wo_clamps(query.getVdotL(), NdotL, interaction.getNdotV(_clamp)));
60-
}
61-
6237
spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction)
6338
{
64-
SQuery query;
65-
query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection());
66-
return __eval<SQuery>(query, _sample, interaction);
39+
return __base.eval(_sample, interaction);
6740
}
6841
spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction)
6942
{
70-
return eval(_sample, interaction.isotropic);
43+
return __base.eval(_sample, interaction.isotropic);
7144
}
7245

73-
sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u)
46+
sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u)
7447
{
75-
ray_dir_info_type L;
76-
L.direction = sampling::ProjectedHemisphere<scalar_type>::generate(u);
77-
return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace());
48+
return __base.generate(anisotropic_interaction_type::create(interaction), u);
7849
}
79-
80-
sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u)
50+
sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u)
8151
{
82-
return generate(anisotropic_interaction_type::create(interaction), u);
52+
return __base.generate(interaction, u);
8353
}
8454

8555
scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample)
8656
{
87-
return sampling::ProjectedHemisphere<scalar_type>::pdf(_sample.getNdotL(_clamp));
57+
return __base.pdf(_sample);
8858
}
8959

90-
template<typename Query>
91-
quotient_pdf_type __quotient_and_pdf(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction)
92-
{
93-
scalar_type _pdf = pdf(_sample);
94-
scalar_type q = __rec_pi_factored_out_wo_clamps(query.getVdotL(), _sample.getNdotL(_clamp), interaction.getNdotV(_clamp));
95-
return quotient_pdf_type::create(q, _pdf);
96-
}
9760
quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction)
9861
{
99-
SQuery query;
100-
query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection());
101-
return __quotient_and_pdf<SQuery>(query, _sample, interaction);
62+
return __base.quotient_and_pdf(_sample, interaction);
10263
}
10364
quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction)
10465
{
105-
return quotient_and_pdf(_sample, interaction.isotropic);
66+
return __base.quotient_and_pdf(_sample, interaction.isotropic);
10667
}
10768

108-
scalar_type A2;
109-
vector2_type AB;
69+
base_type __base;
11070
};
11171

11272
}

0 commit comments

Comments
 (0)