Peter Shirely's Ray Tracing in One Weekend presents the following function to calculate the color of a lambertian material (See chapter's 7 and 8):

bool lambertian::scatter(ray ray_in, hit_record rec, vec3& attenuation, ray &scattered) {
  vec3 target = rec.p + rec.normal + random_in_unit_sphere();
  scattered = ray(rec.p, target - rec.p);
  attenuation = this->albedo;
  return true;

I've read through other material that mentions Lambert's Cosine Law when discussing diffuse materials. Why is the cos term omitted from Peter Shirely's text? Is it canceled out somehow? My expectation is that the attenuation term should look something like:

  attenuation = this->albedo * dot(rec.normal, ray_in.direction);

1 Answer 1


It is cancelled out by the probability density function in the estimator. The pdf in their case is exactly: $\frac{\cos\theta}{\pi}$, which is in the denominator: att = albedo * cos_theta / pdf = albedo * pi. They have absorbed pi in the albedo. Note that there's an update on github to the code, since random_in_unit_sphere() actually generates a $\cos^3\theta$ distribution, they fixed it to random_on_unit_sphere() which generates a $\cos\theta$ distribution. So technically you are working with a $\cos^2\theta$ brdf here and not constant.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.