1#ifndef _BBM_AGGREGATEMODEL_H_
2#define _BBM_AGGREGATEMODEL_H_
22 template<string_literal NAME,
typename... MODELS>
requires (
sizeof...(MODELS) >= 2) && concepts::matching_config<MODELS...> && (concepts::bsdfmodel<MODELS> && ...)
42 ((
static_cast<MODELS&
>(*this) =
static_cast<MODELS
>(src)), ...);
62 return (MODELS::eval(in, out, component, unit, mask) + ...);
86 std::array<Value,
sizeof...(MODELS)> weights = {bbm::hsum(MODELS::reflectance(out, component, unit, mask)) ...};
89 auto sum = std::accumulate(std::begin(weights), std::end(weights), Value(0));
94 auto weight = std::begin(weights);
95 auto xi0 = xi[0] * sum;
100 Mask m = mask && (xi0 >= 0 && xi0 <= *weight);
103 Value normalized_xi0 =
bbm::select( m && (*weight > Constants::Epsilon()), xi0 / *weight, 0);
108 result =
bbm::select(m,
static_cast<const MODEL*
>(
this)->
sample(out, Vec2d(normalized_xi0, xi[1]), component, unit, m), result);
116 std::array<Value,
sizeof...(MODELS)> pdfs = {MODELS::pdf(result.direction, out, component, unit, mask) ...};
117 result.pdf =
bbm::select(sum > Constants::Epsilon(), std::inner_product(std::begin(pdfs), std::end(pdfs), std::begin(weights), Value(0)) / sum, 0);
139 if(bbm::none(mask))
return 0;
142 std::array<Value,
sizeof...(MODELS)> pdfs = {MODELS::pdf(in, out, component, unit, mask) ...};
145 std::array<Value,
sizeof...(MODELS)> weights = {bbm::hsum(MODELS::reflectance(out, component, unit, mask)) ...};
148 auto sum = std::accumulate(std::begin(weights), std::end(weights), Value(0));
149 return bbm::select(sum > Constants::Epsilon(), std::inner_product(std::begin(pdfs), std::end(pdfs), std::begin(weights), Value(0)) / sum, 0);
168 if(bbm::none(mask))
return Spectrum(0);
171 return (MODELS::reflectance(out, component, unit, mask) + ...);
182 if(!str.empty()) str +=
", ";
186 return std::string(
name) +
"(" + str +
")";
197 if(key != std::string(
name))
throw std::invalid_argument(std::string(
"BBM: mismatched object name ") + key +
", expected: " + std::string(
name));
203 if(
sizeof...(MODELS) !=
args.
size())
throw std::invalid_argument(std::string(
"BBM: expected ") + std::to_string(
sizeof...(MODELS)) +
" models, only found " + std::to_string(
args.
size()) +
" in: " + str);
206 auto make_aggregate = [&]<
size_t... IDX>(std::index_sequence<IDX...>)
212 return make_aggregate(std::make_index_sequence<
sizeof...(MODELS)>{});
221 template<
typename... MODELS>
All includes and helpers needed for declaring new bsdfmodels.
bsdfmodel concept
Definition: bsdfmodel.h:33
Compile-time for each loop.
#define CONSTFOREACH(ITR_TYPE, TYPE_LIST,...)
HELPER MACRO.
Definition: constforeach.h:53
std::pair< std::string, std::string > get_keyword(const std::string &str)
Return the keyword substring appearing an open bracket, and the arguments appearing in the brackets: ...
Definition: string_util.h:65
std::string remove_brackets(const std::string &str)
remove surrounding backets
Definition: string_util.h:37
std::vector< std::string > split_args(const std::string &str)
Split a string based on comma's if not surrounded by brackets.
Definition: string_util.h:94
Definition: aggregatebsdf.h:29
constexpr auto select(MASK &&mask, const A &a, const A &b)
Definition: backbone.h:255
std::string toString(const T &)
toString alias
Definition: stringconvert.h:594
auto aggregate(const bsdf< BSDFMODELs > &... src)
Helper methods for simplifying the creation of a aggregate bsdf.
Definition: aggregatebsdf.h:329
decltype(auto) value(T &&t)
return the value of an attribute, or if not an attribute the object
Definition: attribute_value.h:20
unit_t
Light Unit.
Definition: unit.h:21
The sum of different BSDF models.
Definition: aggregatemodel.h:24
BsdfSample sample(const Vec3d &out, const Vec2d &xi, BsdfFlag component=bsdf_flag::All, unit_t unit=unit_t::Radiance, Mask mask=true) const
Sample the aggregate BSDF given a direction and two random variables.
Definition: aggregatemodel.h:81
aggregatemodel_base & operator=(const aggregatemodel_base &src)
Assignment operator.
Definition: aggregatemodel.h:40
aggregatemodel_base(void)
Default constructor.
Definition: aggregatemodel.h:31
std::string toString(void) const
toString to overwrite default printing behavior
Definition: aggregatemodel.h:177
static aggregatemodel_base fromString(const std::string &str)
construct an aggregate model from a string
Definition: aggregatemodel.h:192
BBM_BSDF_FORWARD
Definition: aggregatemodel.h:28
Value pdf(const Vec3d &in, const Vec3d &out, BsdfFlag component=bsdf_flag::All, unit_t unit=unit_t::Radiance, Mask mask=true) const
Compute the pdf given an in and out direction.
Definition: aggregatemodel.h:136
aggregatemodel_base(const aggregatemodel_base &src)
Copy constructor.
Definition: aggregatemodel.h:37
Spectrum eval(const Vec3d &in, const Vec3d &out, BsdfFlag component=bsdf_flag::All, unit_t unit=unit_t::Radiance, Mask mask=true) const
Evaluate the BSDF for a given in out direction.
Definition: aggregatemodel.h:60
Spectrum reflectance(const Vec3d &out, BsdfFlag component=bsdf_flag::All, unit_t unit=unit_t::Radiance, Mask mask=true) const
Return the (approximate) hemispherical reflectance of the BSDF.
Definition: aggregatemodel.h:165
BBM_IMPORT_CONFIG(std::tuple_element_t< 0, std::tuple< MODELS... > >)
static constexpr string_literal name
Definition: aggregatemodel.h:27
aggregatemodel_base(const MODELS &... models)
Construction from each model.
Definition: aggregatemodel.h:34
Forward declaration.
Definition: args.h:248
static constexpr size_t size
Definition: args.h:282
Definition: string_literal.h:16