message: use the Beckmann distribution for the flake normals
diff: @@ -27,6 +27,24 @@ struct Flakes
  //int layers;
  };
  +inline vec3f Beckmann_sample(float alpha, const vec2f& s)
  +{
  + float alpha2 = sqr(alpha);
  + float tanTheta2 = -alpha2 * log(1.f-s.x);
  + float cosTheta = rsqrt(1.f + tanTheta2);
  + float sinTheta = cos2sin(cosTheta);
  +
  + float phi = 2.f*pi * s.y;
  +
  + float sinPhi, cosPhi;
  + sincos(phi, &sinPhi, &cosPhi);
  +
  + float x = cosPhi * sinTheta;
  + float y = sinPhi * sinTheta;
  + float z = cosTheta;
  + return make_vec3f(x,y,z);
  +}
  +
  inline vec3f Flakes_eval(const varying Flakes* uniform self, vec3f p)
  {
  vec3f N = make_vec3f(0.f, 0.f, 1.f);
  @@ -35,9 +53,7 @@ inline vec3f Flakes_eval(const varying Flakes* uniform self, vec3f p)
  return N;
  p = p * self->scale;
  -
  - vec3f flakeN = make_vec3f(0.f);
  - float flakeMask = 0.f;
  + float mask = 0.f;
  // Simple Worley cellular noise with jittered feature points
  // [Apodaca and Gritz, 1999, "Advanced RenderMan: Creating CGI for Motion Pictures", pp. 255-261]
  @@ -77,13 +93,10 @@ inline vec3f Flakes_eval(const varying Flakes* uniform self, vec3f p)
  if (LCG_getFloat(cellRnd) <= self->density)
  {
  // generate a random normal for the flake
  - flakeN = uniformSampleHemisphere(LCG_getFloat2(cellRnd));
  - flakeMask = 1.f;
  + N = Beckmann_sample(sqr(self->spread), LCG_getFloat2(cellRnd));
  + mask = 1.f;
  }
  - // compute the final normal
  - N = normalize(N + (flakeN * self->spread));
  -
  return N;
  }
  