Loading...
Searching...
No Matches
ngan.h
Go to the documentation of this file.
1#ifndef _BBM_NGAN_H_
2#define _BBM_NGAN_H_
3
6#include "bsdfmodel/ward.h"
8#include "bsdfmodel/phong.h"
12
13/************************************************************************/
14/*! \file ngan.h
15
16 \brief All the BSDF variants used in "Experimental Analysis of BRDF Model"
17 [Ngan et al. 2005]: https://dl.acm.org/doi/10.5555/2383654.2383671
18
19 Note: these are only the specular component of the models. Use
20 aggregatemodel to combine them with a lambertian model.
21
22*************************************************************************/
23
24namespace bbm {
25
26 /**********************************************************************/
27 /*! \brief Ngan's Ward: standard Ward with isotropic roughness. This can be
28 achieved with a simple alias.
29 ***********************************************************************/
30 template<typename CONF, string_literal NAME="NganWard"> requires concepts::config<CONF>
32
33 /**********************************************************************/
34 /*! \brief Ngan's Ward-Duer: stanard Ward-Duer with isotropic
35 roughness. This can be achieved with a simple alias.
36 ***********************************************************************/
37 template<typename CONF, string_literal NAME="NganWardDuer"> requires concepts::config<CONF>
39
40 /**********************************************************************/
41 /*! \brief Ngan's Blinn-Phong: same as modifed phong; a simple alias suffices.
42 ***********************************************************************/
43 template<typename CONF, string_literal NAME="NganBlinnPhong"> requires concepts::config<CONF>
45
46 /**********************************************************************/
47 /*! \brief Ngan's Lafortune: standard Lafortune times an additional
48 normalization factor:
49
50 \f$ \frac{ (n+2) }{ \2pi * (\max(Cz, Cxy))^n } \f$
51
52 This is achieved with a wrapper class.
53 ***********************************************************************/
54 template<typename CONF, string_literal NAME="NganLafortune"> requires concepts::config<CONF>
55 class nganlafortune : public lafortune<CONF, symmetry_v::Isotropic>
56 {
59 public:
61 static constexpr string_literal name = NAME;
63
64 // pass through sample and pdf
65 using base::base;
66 using base::sample;
67 using base::pdf;
68
69 /********************************************************************/
70 /*! \brief Evaluate the BSDF for a given in and out direction
71
72 \param in = incident direction
73 \param out = outgoing direction
74 \param component = which reflectance component to eval
75 \param unit = unit of computation (ignored)
76 \param mask = masking of lanes (e.g., for Packet eval)
77 \returns Evaluation of the BSDF per spectrum.
78 *********************************************************************/
79 Spectrum eval(const Vec3d& in, const Vec3d& out, BsdfFlag component=bsdf_flag::All, unit_t unit=unit_t::Radiance, Mask mask=true) const
80 {
81 // specular?
82 mask &= is_set(component, bsdf_flag::Specular);
83
84 // above surface?
85 mask &= (vec::z(in) > 0) && (vec::z(out) > 0);
86
87 // Quick exit if mask is all negative
88 if(bbm::none(mask)) return Spectrum(0);
89
90 // Eval Lafortune
91 Spectrum result = base::eval(in, out, component, unit, mask);
92
93 // Scale by Ngan normalization
94 result *= (base::sharpness + 2.0) * Constants::InvPi(0.5) / bbm::pow( bbm::max( bbm::squared_norm(base::Cz), bbm::squared_norm(base::Cxy) ), base::sharpness * Scalar(0.5));
95
96 // Done.
97 return bbm::select(mask, result, 0);
98 }
99
100 /*******************************************************************/
101 /*! \brief Return the (approximate) reflectance of the BSDF
102
103 \param out = the outgoing direction
104 \param component = which reflectance component to eval
105 \param unit = unit of computation (ignored)
106 \param mask = masking of lanes
107 \returns the approximate reflectance of the BSDF for a given direction
108 ********************************************************************/
109 Spectrum reflectance(const Vec3d& out, BsdfFlag component=bsdf_flag::All, unit_t unit=unit_t::Radiance, Mask mask=true) const
110 {
111 // specular?
112 mask &= is_set(component, bsdf_flag::Specular);
113
114 // Quick exit if mask all negative
115 if(bbm::none(mask)) return Spectrum(0);
116
117 // Eval reflectance Lafortune
118 Spectrum result = base::reflectance(out, component, unit, mask);
119
120 // Scale by Ngan normalization
121 result *= (base::sharpness + 2.0) * Constants::InvPi(0.5) / bbm::pow(bbm::max( bbm::squared_norm(base::Cz), bbm::squared_norm(base::Cxy) ), base::sharpness * Scalar(0.5));
122
123 // Done.
124 return bbm::select(mask, result, 0);
125 }
126
127 //! \brief Default constructor
129 };
130
132
133
134 /**********************************************************************/
135 /*! \brief Ngan's Cook-Torrance is normalized by pi, is isotropic, and has
136 vgroove masking and shadowing, schlick fresnel, F0 reflectance, and
137 backman distribution
138
139 This is achieved by a defining a custom microfacet model.
140 ***********************************************************************/
141 template<typename CONF, string_literal NAME="NganCookTorrance"> requires concepts::config<CONF>
146 NAME>,
148
150
151
152 /**********************************************************************/
153 /*! \brief Ngan's Ashkihmin-Shirley model; does not include
154 Ashikhmin-Shirley's diffuse component, and it is isotropic. THis can be
155 achieved with a simple alias.
156 ***********************************************************************/
157 template<typename CONF, string_literal NAME="NganAshikhminShirley"> requires concepts::config<CONF>
159
161
162 /**********************************************************************/
163 /*! \brief Ngan's He et al.'s BSDF likely uses the Westin et al. formulation
164 but with non-complex eta.
165 *********************************************************************/
166 template<typename CONF> requires concepts::config<CONF>
168
170
171} // end bbm namespace
172
173#endif /* _BBM_NGAN_H_ */
174
175
183
The sum of different BSDF models.
Implements the specular component from: "An anisotropic phong BRDF model" [Ashikhmin and Shirley 2000...
#define BBM_EXPORT_BSDFMODEL(BsdfModel)
Definition: bbm_fromstring.h:49
Implements: "The Modifed Phong BSDF model for physically based rendering".
The Lafortune BRDF model. This implements the model in Eq. 4 in the original paper linked above:
Definition: lafortune.h:30
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: lafortune.h:46
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: lafortune.h:77
specular_sharpness< Value > sharpness
Definition: lafortune.h:165
bsdf_parameter< Value, bsdf_attr::SpecularParameter, 0.57735026919, std::numeric_limits< Scalar >::max(), std::numeric_limits< Scalar >::min()> Cz
Definition: lafortune.h:164
bsdf_parameter< symmetry_t< Symmetry, Value >, bsdf_attr::SpecularParameter, -0.57735026919, std::numeric_limits< Scalar >::max(), std::numeric_limits< Scalar >::min()> Cxy
Definition: lafortune.h:163
Spectrum reflectance(const Vec3d &out, BsdfFlag component=bsdf_flag::All, unit_t=unit_t::Radiance, Mask mask=true) const
Return the (approximate) hemispherical reflectance of the BSDF.
Definition: lafortune.h:151
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: lafortune.h:122
Ngan's Lafortune: standard Lafortune times an additional normalization factor:
Definition: ngan.h:56
BBM_BSDF_FORWARD
Definition: ngan.h:62
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 and out direction.
Definition: ngan.h:79
Spectrum reflectance(const Vec3d &out, BsdfFlag component=bsdf_flag::All, unit_t unit=unit_t::Radiance, Mask mask=true) const
Return the (approximate) reflectance of the BSDF.
Definition: ngan.h:109
BBM_DEFAULT_CONSTRUCTOR(nganlafortune)
Default constructor.
Definition: ngan.h:128
static constexpr string_literal name
Definition: ngan.h:61
The modified Phong BSDF model. This is the classic Phong BSDF model with appropriate normalization an...
Definition: phong.h:27
The anisotropic Ward BSDF model.
Definition: ward.h:28
The anisotropic Ward-Duer BSDF model.
Definition: wardduer.h:31
bsdfmodel concept
Definition: bsdfmodel.h:33
config concept
Definition: config.h:31
Implements the Cook-Torrance BSDF Model [SIGGRAPH'82]: https://doi.org/10.1145/357290....
Implements: "Non-Linear Approximation of Reflectance Functions".
The classic diffuse Lambertian BSDF model.
#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) z(bbm::vec3d< T > &v)
Definition: vec.h:26
Definition: aggregatebsdf.h:29
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
Implements the Fresnel reflectance equation as proposed by Schlick [Comp. Graph. Forum '94]: https://...
Definition: fresnel_schlick.h:21
Vgroove shadowing and masking.
Definition: vgroove.h:26
static constexpr literal Cook
Definition: microfacet.h:35
Scaled BSDF model.
Definition: scaledmodel.h:30
Definition: string_literal.h:16
Implements: "Measuring and modeling anisotropic reflection" [Ward 1992]: https://doi....
Implements: "An Improved Normalization for the Ward Reflectance Model" [Arne Duer 2006]: https://doi....