<p>You always need to multiply by the cosine term indeed (that's part of the rendering equation). Though when you do indirect diffuse using ray-tracing and thus monte-carol integration (which is the most common technique in this case), you have to <strong>divide</strong> the contribution of each sample by your <strong>PDF</strong>. This is well exampled <a href="https://www.scratchapixel.com/lessons/3d-basic-rendering/global-illumination-path-tracing/global-illumination-path-tracing-practical-implementation">here</a>.</p>

<p>Note also that in the mentioned reference, if the PDF has terms that you also find in the rendering equations then you can optimise the code if you wish by cancelling out these terms.</p>

<blockquote>
  <p>Don't forget that the BRDF of a diffuse surface is ρ/π where ρ stands for the surface albedo. So we need to divide the result by π. Though in the case of the indirect diffuse component, don't forget that we should have divided the result of castRay by the PDF of the random variable, which as we showed earlier in this chapter is 1/(2π). Dividing indirectDiffuseby 1/(2π) mis the same as multiplying this value by 2π. And since the albedo is also divided by π we can simplify the code...</p>
</blockquote>

<p>You have a similar situation. If you look at the PDF for the cosine sampling, then you will realise that terms can be cancelled out. Which doesn't mean they are 'not' strictly necessary. They are, they just cancel each other out which allows to optimize the code slightly (and avoid a few division, multiplication, etc.). You are more in the micro-optimisation here... which can be confusing if you try to learn the theory by just looking at optimised code (which is often not properly commented).</p>

<p>$ \dfrac{(cos(\theta) ... )}{PDF} = \dfrac{(cos(\theta) ... )}{\dfrac{cos(\theta)}{\pi}} = ... $</p>

CC BY-SA 3.0
2017-02-05T16:38:18.003Z
Thank you! That makes sense. Intuitively I knew it was required but I didn't recognize that it was an optimization.
Steven
CC BY-SA 3.0
2017-02-05T21:06:42.837Z
Just to make sure this is explicit.. not only is cosine weighted hemisphere an optimisation because it takes fewer instructions, it's also an optimisation because it converges more quickly. It takes fewer samples to get a better result. This is a form of importance sampling.
Alan Wolfe
CC BY-SA 3.0
2017-02-05T22:30:06.860Z
Exactly - that was my desire as I'm trying to reduce the number of samples for indirect calculations in my lightmapper.
Steven
CC BY-SA 3.0
2017-02-05T10:24:41.067Z
2017-02-05T10:57:39.233Z
2017-02-05T10:57:39.233Z
user18490
<p>When converting from uniform hemisphere sampling to cosine weighted hemisphere sampling I am confused by a statement in an article.</p>

<p>My current indirect contribution is calculated as:</p>

<pre><code>Vec3 RayDir = UniformGenerator.Next()
Color3 indirectDiffuse = Normal.dot(RayDir) * castRay(Origin, RayDir)
</code></pre>

<p>Where the dot product is cos(θ)</p>

<p>But in this article on better sampling (<a href="http://www.rorydriscoll.com/2009/01/07/better-sampling/">http://www.rorydriscoll.com/2009/01/07/better-sampling/</a>) the author suggests the PDF is (cos(θ) / pi), and there is no evidence of the N dot L calculation.</p>

<p>My question is - does that mean that I no longer need to perform the normal dot rayDirection because it is included in the PDF, or is it in addition to the pdf?</p>

<raytracing><sampling><monte-carlo><importance-sampling>
Does cosine weighted hemisphere sampling still require NdotL when calculating contribution for indirect light?
Steven
# Does cosine weighted hemisphere sampling still require NdotL when calculating contribution for indirect light?

(Asked by: username_0 on 2017-02-05)

When converting from uniform hemisphere sampling to cosine weighted hemisphere sampling I am confused by a statement in an article.

My current indirect contribution is calculated as:

```
Vec3 RayDir = UniformGenerator.Next()
Color3 indirectDiffuse = Normal.dot(RayDir) * castRay(Origin, RayDir)

```

Where the dot product is cos(θ)

But in this article on better sampling (<http://www.rorydriscoll.com/2009/01/07/better-sampling/>) the author suggests the PDF is (cos(θ) / pi), and there is no evidence of the N dot L calculation.

My question is - does that mean that I no longer need to perform the normal dot rayDirection because it is included in the PDF, or is it in addition to the pdf?

**Tags:** raytracing, sampling, monte-carlo, importance-sampling


---

## 1 answers

### Answer by username_1 on 2017-02-05. Score: 12 | Accepted answer

You always need to multiply by the cosine term indeed (that's part of the rendering equation). Though when you do indirect diffuse using ray-tracing and thus monte-carol integration (which is the most common technique in this case), you have to **divide** the contribution of each sample by your **PDF**. This is well exampled [here](https://www.scratchapixel.com/lessons/3d-basic-rendering/global-illumination-path-tracing/global-illumination-path-tracing-practical-implementation).

Note also that in the mentioned reference, if the PDF has terms that you also find in the rendering equations then you can optimise the code if you wish by cancelling out these terms.

> Don't forget that the BRDF of a diffuse surface is ρ/π where ρ stands for the surface albedo. So we need to divide the result by π. Though in the case of the indirect diffuse component, don't forget that we should have divided the result of castRay by the PDF of the random variable, which as we showed earlier in this chapter is 1/(2π). Dividing indirectDiffuseby 1/(2π) mis the same as multiplying this value by 2π. And since the albedo is also divided by π we can simplify the code...

You have a similar situation. If you look at the PDF for the cosine sampling, then you will realise that terms can be cancelled out. Which doesn't mean they are 'not' strictly necessary. They are, they just cancel each other out which allows to optimize the code slightly (and avoid a few division, multiplication, etc.). You are more in the micro-optimisation here... which can be confusing if you try to learn the theory by just looking at optimised code (which is often not properly commented).

$ \dfrac{(cos(\theta) ... )}{PDF} = \dfrac{(cos(\theta) ... )}{\dfrac{cos(\theta)}{\pi}} = ... $

> **Comments:**
> **username_0**: Thank you! That makes sense. Intuitively I knew it was required but I didn't recognize that it was an optimization.  
> **username_2**: Just to make sure this is explicit.. not only is cosine weighted hemisphere an optimisation because it takes fewer instructions, it's also an optimisation because it converges more quickly. It takes fewer samples to get a better result. This is a form of importance sampling.  
> **username_0**: Exactly - that was my desire as I'm trying to reduce the number of samples for indirect calculations in my lightmapper.  

---

