Loading...
Searching...
No Matches
wardduer.h
Go to the documentation of this file.
1#ifndef _BBM_WARD_DUER_H_
2#define _BBM_WARD_DUER_H_
3
4#include "bsdfmodel/ward.h"
5
6/************************************************************************/
7/*! \file wardduer.h
8
9 \brief Implements: "An Improved Normalization for the Ward Reflectance
10 Model" [Arne Duer 2006]: https://doi.org/10.1080/2151237X.2006.10129215
11
12*************************************************************************/
13
14namespace bbm {
15
16 /**********************************************************************/
17 /*! \brief The anisotropic Ward-Duer BSDF model.
18
19 \tparam CONF = bbm configuration
20 \tparam Symmetry = isotropic or anisotropic (default: symmetry_v::anisotropic)
21 \tparam NAME = name of the BSDF model (Default: 'WardDuer')
22
23 This model differs from the regular Ward BSDF model in the normalization
24 (sqrt(cos(theta(in)) * cos(theta((out))) for Ward versus
25 cos(theta(in))*cos(theta(out)) for Ward-Duer).
26
27 Implements: concepts::bsdfmodel
28 **********************************************************************/
29 template<typename CONF, symmetry_v Symmetry = symmetry_v::Anisotropic, string_literal NAME="WardDuer"> requires concepts::config<CONF>
30 class wardduer : public ward<CONF, Symmetry>
31 {
34
35 public:
37 static constexpr string_literal name = NAME;
39
40 // Copy sample, pdf, and reflectance unchanged from ward
41 using base::sample;
42 using base::pdf;
44
45 /********************************************************************/
46 /*! \brief Evaluate the BSDF for a given in and out direction
47
48 \param in = incident direction
49 \param out = outgoing direction
50 \param component = which reflectance component to eval
51 \param unit = unit of computation (ignored)
52 \param mask = masking of lanes (e.g., for Packet eval)
53 \returns Evaluation of the BSDF per spectrum.
54 *********************************************************************/
55 Spectrum eval(const Vec3d& in, const Vec3d& out, BsdfFlag component=bsdf_flag::All, unit_t /*unit*/=unit_t::Radiance, Mask mask=true) const
56 {
57 // specular?
58 mask &= is_set(component, bsdf_flag::Specular);
59
60 // above surface?
61 mask &= (vec::z(in) >= 0) && (vec::z(out) >= 0);
62
63 // Quick exit if mask is all negative
64 if(bbm::none(mask)) return Spectrum(0);
65
66 // Evaluate BRDF
67 Vec2d r(base::roughness); // copy anisotropic | map isotropic to Vec2d.
68 Vec3d H = in + out;
69 Value normalizationFactor = Constants::Pi(4) * vec::x(r) * vec::y(r) * ( vec::z(in) * vec::z(out) );
70 Value exponent = bbm::squared_norm(vec::xy(H) / r) / bbm::pow(vec::z(H), 2);
71
72 Spectrum result = base::albedo;
73 result *= bbm::exp(-exponent) / normalizationFactor;
74
75 // Done.
76 return bbm::select(mask, result, 0);
77 }
78
79 //! \brief Default constructor
81 };
82
84
85} // end bbm namespace
86
87#endif /* _BBM_WARD_DUER_H_ */
88
#define BBM_EXPORT_BSDFMODEL(BsdfModel)
Definition: bbm_fromstring.h:49
The anisotropic Ward BSDF model.
Definition: ward.h:28
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 BSDF given a direction and two random variables.
Definition: ward.h:79
specular_roughness< symmetry_t< Symmetry, Value > > roughness
Definition: ward.h:161
specular_scale< Spectrum > albedo
Definition: ward.h:160
Value pdf(const Vec3d &in, const Vec3d &out, BsdfFlag component=bsdf_flag::All, unit_t=unit_t::Radiance, Mask mask=true) const
Compute the pdf given an in and out direction.
Definition: ward.h:120
Spectrum reflectance(const Vec3d &, BsdfFlag component=bsdf_flag::All, unit_t=unit_t::Radiance, Mask mask=true) const
Return the (approximate) hemispherical reflectance of the BSDF.
Definition: ward.h:152
The anisotropic Ward-Duer BSDF model.
Definition: wardduer.h:31
Spectrum eval(const Vec3d &in, const Vec3d &out, BsdfFlag component=bsdf_flag::All, unit_t=unit_t::Radiance, Mask mask=true) const
Evaluate the BSDF for a given in and out direction.
Definition: wardduer.h:55
BBM_IMPORT_CONFIG(CONF)
BBM_BSDF_FORWARD
Definition: wardduer.h:38
BBM_DEFAULT_CONSTRUCTOR(wardduer)
Default constructor.
Definition: wardduer.h:80
BBM_BASETYPES(base)
static constexpr string_literal name
Definition: wardduer.h:37
bsdfmodel concept
Definition: bsdfmodel.h:33
#define BBM_CHECK_CONCEPT(CONCEPTNAME, CLASSNAME,...)
Check a class for a concept with bbm::concepts::archetypes in the namespace.
Definition: macro.h:35
constexpr decltype(auto) y(bbm::vec3d< T > &v)
Definition: vec.h:23
constexpr decltype(auto) z(bbm::vec3d< T > &v)
Definition: vec.h:26
constexpr decltype(auto) x(bbm::vec3d< T > &v)
Definition: vec.h:20
constexpr const vec2d< T > xy(const vec3d< T > &v)
Definition: vec.h:47
Definition: aggregatebsdf.h:29
symmetry_v
symmetry variants.
Definition: bsdf_symmetry.h:19
constexpr auto select(MASK &&mask, const A &a, const A &b)
Definition: backbone.h:255
constexpr auto is_set(const FLAGNAME &a, const FLAG &flag)
Check if all in 'flag' are also set in 'a'; compatible with packet types.
Definition: flags.h:100
unit_t
Light Unit.
Definition: unit.h:21
Definition: string_literal.h:16
Implements: "Measuring and modeling anisotropic reflection" [Ward 1992]: https://doi....