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

```cpp
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:

```cpp
  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.


---

