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

CC BY-SA 4.0
2020-01-17T04:47:50.137Z
2020-01-17T04:47:50.137Z
lightxbulb
<p>Peter Shirely's <em>Ray Tracing in One Weekend</em> presents the following function to calculate the color of a lambertian material (See chapter's 7 and 8):</p>

<pre class="lang-cpp prettyprint-override"><code>bool lambertian::scatter(ray ray_in, hit_record rec, vec3&amp; attenuation, ray &amp;scattered) {
  vec3 target = rec.p + rec.normal + random_in_unit_sphere();
  scattered = ray(rec.p, target - rec.p);
  attenuation = this-&gt;albedo;
  return true;
}
</code></pre>

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

<pre class="lang-cpp prettyprint-override"><code>  attenuation = this-&gt;albedo * dot(rec.normal, ray_in.direction);
</code></pre>

<raytracing><mathematics><diffuse>
Confusion around Lambert's Cosine Law in Ray Tracing in One Weekend
countfromzero
# Confusion around Lambert's Cosine Law in Ray Tracing in One Weekend

(Asked by: username_0 on 2020-01-17)

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);

**Tags:** raytracing, mathematics, diffuse

---

## 1 answers

### Answer by username_1 on 2020-01-17. Score: 3 | Accepted answer

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.


---

