Loading...
Searching...
No Matches
phong.h
Go to the documentation of this file.
1#ifndef _BBM_PHONG_NDF_H_
2#define _BBM_PHONG_NDF_H_
3
4#include "bbm/ndf.h"
5
6/************************************************************************/
7/*! \file phong.h
8
9 \brief Implements the Phong Microfacet Normal Distribution from: "Microfacet
10 Models for Refraction through Rough Surfaces" [Walter et al. 2007]:
11 http://dx.doi.org/10.2312/EGWR/EGSR07/195-206
12
13***********************************************************************/
14
15namespace bbm {
16 namespace ndf {
17
18 /**********************************************************************/
19 /*! \brief The Phong Microfacet distribution
20
21 \tparam CONF = bbm configuration
22 \tparam NAME = ndf name (default = Phong)
23
24 Implements: concepts::ndf
25 ************************************************************************/
26 template<typename CONF, string_literal NAME="Phong"> requires concepts::config<CONF>
27 class phong
28 {
29 public:
31 static constexpr string_literal name = NAME;
32
33 /********************************************************************/
34 /*! \brief Evaluate the NDF
35
36 \param halfway = vector to eval the NDF for
37 \param mask = enable/disbale lanes [default = true]
38 \returns the resulting evaluation of the NDF
39 *********************************************************************/
40 Value eval(const Vec3d& halfway, Mask mask=true) const
41 {
42 // above surface?
43 mask &= (vec::z(halfway) > 0);
44
45 // Quick exit
46 if(bbm::none(mask)) return 0;
47
48 // eval NDF
49 Value normalization = (sharpness + 2) / Constants::Pi(2);
50 Value D = bbm::pow( spherical::cosTheta(halfway), sharpness ) * normalization;
51
52 // Done.
53 return bbm::select(mask, D, 0);
54 }
55
56 /********************************************************************/
57 /*! \brief Sample the NDF
58
59 \param view = view direction (ignored)
60 \param xi = 2D uniform random variables in [0..1] range
61 \param Mask = enable/disbale lanes
62 \returns A sampled microfacet normal.
63 ********************************************************************/
64 Vec3d sample(const Vec3d& /*view*/, const Vec2d& xi, Mask mask=true) const
65 {
66 // check valid xi
67 mask &= (xi[0] >= 0) && (xi[1] >= 0) && (xi[0] <= 1) && (xi[1] <= 1);
68
69 // quick exit
70 if(bbm::none(mask)) return 0;
71
72 // sample microfacet normal
73 Value cosTheta = bbm::pow( xi[0], 1.0 / (sharpness + 2) );
74 Value sinTheta = bbm::safe_sqrt(1.0 - cosTheta*cosTheta);
75 Vec2d csp = bbm::cossin( xi[1] * Constants::Pi(2) );
76
77 // Done.
78 return bbm::select(mask, vec::expand(csp*sinTheta, cosTheta), 0);
79 }
80
81 /********************************************************************/
82 /*! \brief PDF of sampling the NDF
83
84 \param view = view direction (ignored)
85 \param m = sampled microfacet normal
86 \param mask = enable/disable lanes [default = true]
87 \returns the PDF of sampling 'm' using the sample method.
88 *********************************************************************/
89 Value pdf(const Vec3d& /*view*/, const Vec3d& m, Mask mask=true) const
90 {
91 // m above surface?
92 mask &= (vec::z(m) > 0);
93
94 // quick bail out
95 if(bbm::none(mask)) return 0;
96
97 // eval PDF: D(m) |m.n|
98 Value pdf = eval(m, mask) * bbm::abs( vec::z(m) );
99
100 // Done.
101 return bbm::select(mask, pdf, 0);
102 }
103
104 /********************************************************************/
105 /*! \brief Monodirectional shadowing and masking term
106
107 \param v = incident/outgoing vector
108 \param m = microfacet normal
109 \\param mask = enable/disable lanes
110 \returns the monodirectional shadowing and masking attentuation factor
111
112 There does not exist a closed form solution; use the same polynomial
113 approximation as for Beckmann, except with a different 'a' value.
114 *******************************************************************/
115 Value G1(const Vec3d& v, const Vec3d& m, Mask mask=true) const
116 {
117 // check (dot(v,m) / dot(v,n)) > 0.
118 mask &= (vec::z(v) > 0) && (bbm::dot(v, m) > 0);
119
120 // Quick exit
121 if(bbm::none(mask)) return 0;
122
123 // compute 'a'
124 Value a = bbm::sqrt( 0.5*sharpness +1 ) / spherical::tanTheta(v);
125
126 // eval
127 Value g = bbm::select(a < 1.6, (3.535*a + 2.181*a*a) / (1 + 2.276*a + 2.577*a*a), 1.0);
128
129 // rational approximation
130 return bbm::select(mask, g, 0.0);
131 }
132
133 ///////////////////////////////
134 //! @{ \name Class Attributes
135 ///////////////////////////////
137
139 //! @}
140
141 //! \brief Default constructor
143 };
144
146
147 } // end ndf namespace
148} // end bbm namespace
149
150#endif /* _BBM_PHONG_NDF_H_ */
All includes and helpers needed for declaring new ndfs.
The Phong Microfacet distribution.
Definition: phong.h:28
Value G1(const Vec3d &v, const Vec3d &m, Mask mask=true) const
Monodirectional shadowing and masking term.
Definition: phong.h:115
BBM_IMPORT_CONFIG(CONF)
specular_sharpness< Value > sharpness
Definition: phong.h:136
Value pdf(const Vec3d &, const Vec3d &m, Mask mask=true) const
PDF of sampling the NDF.
Definition: phong.h:89
Value eval(const Vec3d &halfway, Mask mask=true) const
Evaluate the NDF.
Definition: phong.h:40
Vec3d sample(const Vec3d &, const Vec2d &xi, Mask mask=true) const
Sample the NDF.
Definition: phong.h:64
BBM_ATTRIBUTES(sharpness)
BBM_DEFAULT_CONSTRUCTOR(phong)
Default constructor.
Definition: phong.h:142
static constexpr string_literal name
Definition: phong.h:31
ndf concept
Definition: ndf.h:29
#define BBM_CHECK_CONCEPT(CONCEPTNAME, CLASSNAME,...)
Check a class for a concept with bbm::concepts::archetypes in the namespace.
Definition: macro.h:35
T cosTheta(const vec2d< T > &v)
Definition: spherical.h:109
T tanTheta(const vec2d< T > &v)
Definition: spherical.h:177
constexpr const vec3d< T > expand(const vec2d< T > &v, V &&a)
Definition: vec.h:55
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
vec3d< T > halfway(const vec3d< T > &a, const vec3d< T > &b)
Halfway vector (3D)
Definition: vec_transform.h:77
Base declaration of attribute; further specialized below.
Definition: attribute.h:26
Definition: string_literal.h:16