message: minor fix in GGXDistribution, added more comments
diff: #include "math/math.ih"
  +// GGX (Trowbridge-Reitz) microfacet distribution
  +// [Walter et al., 2007, "Microfacet Models for Refraction through Rough Surfaces"]
  +// [Heitz, 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"]
  +// [Heitz and d'Eon, 2014, "Importance Sampling Microfacet-Based BSDFs using the Distribution of Visible Normals"]
  struct GGXDistribution
  {
  float alpha;
  @@ -30,6 +34,7 @@ inline GGXDistribution make_GGXDistribution(float alpha)
  return m;
  }
  +// D(\omega_m) = \frac{\alpha^2}{\pi \cos^4\theta_m (\alpha^2 + \tan^2\theta_m)^2}
  inline float eval(const GGXDistribution& self,
  float cosTheta)
  {
  @@ -38,15 +43,18 @@ inline float eval(const GGXDistribution& self,
  return alpha2 * rcp(pi*sqr(tmp));
  }
  -// TODO: remove dup, or return pdf
  +// p(\omega_m) = D(\omega_m) \cos\theta_m
  inline float eval(const GGXDistribution& self,
  float cosTheta, float& pdf)
  {
  - float alpha2 = sqr(self.alpha);
  - float tmp = (alpha2*cosTheta - cosTheta) * cosTheta + 1.f;
  - return alpha2 * rcp(pi*sqr(tmp));
  + float D = eval(self, cosTheta);
  + pdf = D * abs(cosTheta);
  + return D;
  }
  +// \theta_m = \arctan \left( \frac{\alpha\sqrt{\xi_1}}{\sqrt{1-\xi_1}} \right)
  +// \phi_m = 2\pi \xi_2
  +// p(\omega_m) = D(\omega_m) \cos\theta_m
  inline vec3f sample(const GGXDistribution& self,
  float& pdf, const vec2f& s)
  {
  @@ -69,6 +77,9 @@ inline vec3f sample(const GGXDistribution& self,
  return make_vec3f(x,y,z);
  }
  +// Smith Lambda function [Heitz, 2014]
  +// \Lambda(\omega_o) = \frac{-1 + \sqrt{1+\frac{1}{a^2}}}{2}
  +// a = \frac{1}{\alpha \tan\theta_o}
  inline float Lambda(const GGXDistribution& self,
  float cosTheta)
  {
  @@ -87,6 +98,8 @@ inline float G1(const GGXDistribution& self,
  return rcp(1.f + Lambda(self, cosThetaO));
  }
  +// Smith's height-correlated masking-shadowing function
  +// [Heitz, 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"]
  inline float G2(const GGXDistribution& self,
  float cosThetaO, float cosThetaI, float cosThetaOH, float cosThetaIH)
  {
  @@ -104,6 +117,7 @@ inline float evalVisible(const GGXDistribution& self,
  return D;
  }
  +// Visible normal sampling code for the alpha=1 case
  inline vec2f sampleVisible11(const GGXDistribution& self,
  float thetaI, const vec2f& s)
  {
  @@ -180,5 +194,6 @@ inline vec3f sampleVisible(const GGXDistribution& self,
  inline float roughnessToAlpha(float roughness)
  {
  + // Roughness is squared for perceptual reasons
  return max(sqr(roughness), 0.001f);
  }
  