## Introduction

I’ve recently been diving into the world of importance sampling and I decided to share my derivation for importance sampling the cosine lobe.

When we’re shading a point in path tracing, we typically shoot a ray from our surface in a uniformity random direction contained on a hemisphere centered about our normal. This has the downside of introducing quite a bit of variance into our renders.

Imagine that we have a very bright light that only occupies a very small projected area from our shaded point.

We would be very likely to miss this light with most of our samples and our render could turn out much darker than we would expect.

This is where importance sampling comes in.

If you imagine that your illumination is a polar function

If we were to sample a random variable with a distribution that matches this function, we would be much more likely to hit the important points of our function. (Hence importance sampling)

I won’t dive deeply into this topic, as there are a variety of excellent resources detailing this topic. [1]

The essence of it however, is that you want to find a Probability Density Function (PDF) that matches the shape of your illumination function. Once you’ve define this PDF, you can sample it using the Cumulative Density Function (CDF).

## Derivation

Since our cosine lobe illumination will look like this:

We will use this as the basis to derive our distribution since we’re most likely to get the most light from directions arriving parallel to our normal.

Thankfully, our cosine lobe has an analytical formula that we can use as our PDF.

$PDF(\omega) = C*cos(\theta)$ (1)

Our PDF must integrate to 1, we integrate the PDF across our hemisphere

$\int_{\Omega}PDF(\omega)d\omega$

$\int_0^{2\pi}\int_0^{\frac{\pi}{2}}PDF(\omega)sin\theta d\theta d\phi$

Plug in (1)

$\int_0^{2\pi}\int_0^{\frac{\pi}{2}}C*cos\theta sin\theta d\theta d\phi$

$C*\int_0^{2\pi}\int_0^{\frac{\pi}{2}}cos\theta sin\theta d\theta d\phi$

$\int cos\theta sin\theta d\theta = -\frac{1}{4}cos2\theta$

$\int_0^{\frac{\pi}{2}}cos\theta sin\theta d\theta$

$-\frac{1}{4}cos\pi+ \frac{1}{4}cos0$

$\frac{1}{4}+\frac{1}{4}$

$\int_0^{\frac{\pi}{2}}cos\theta sin\theta d\theta=\frac{1}{2}$ (2)

Plug in (2)

$C*\int_0^{2\pi}\frac{1}{2} d\phi$

$C*\frac{1}{2}*2\pi$

$C*\int_0^{2\pi}\int_0^{\frac{\pi}{2}}cos\theta sin\theta d\theta d\phi=C*\pi$ (3)

Since our PDF has to integrate to 1,

$\int_0^{2\pi}\int_0^{\frac{\pi}{2}}PDF(\omega)sin\theta d\theta d\phi = 1$

Plug in (3),

$C*\pi=1$

$C=\frac{1}{pi}$ (4)

Finally, plug in (4) into our PDF,

$PDF(\omega) = \frac{cos(\theta)}{\pi}$ (5)

Now that we have our PDF, we can calculate our PDF in terms of $\theta$ and $\phi$.

$PDF(\theta,\phi)d\theta d\phi = PDF(\omega)d\omega$

$PDF(\theta,\phi)d\theta d\phi = PDF(\omega)sin\theta d\theta d\phi$

$PDF(\theta,\phi)=PDF(\omega)sin\theta$

$PDF(\theta,\phi)=\frac{cos\theta sin\theta}{\pi}$ (6)

Now we integrate with respect to $\phi$ to get $PDF(\theta)$

$\int_0^{2\pi}\frac{cos\theta sin\theta}{\pi}d\phi = 2cos\theta sin\theta$

$PDF(\theta)=2cos\theta sin\theta$

And then to get $PDF(\phi)$,

$\frac{PDF(\theta,\phi)}{PDF(\theta)}=PDF(\phi)$

$\frac{cos\theta sin\theta}{2cos\theta sin\theta \pi}=\frac{1}{2\pi}$

$PDF(\phi)=\frac{1}{2\phi}$

Now we want to calculate the CDF of each function,

$CDF(\theta)=\int_0^\theta PDF(\theta) d\theta$

$CDF(\theta)=\int_0^\theta 2cos(\theta)sin(\theta) d\theta$

$CDF(\theta)=\int_0^\theta sin(2\theta) d\theta$

$CDF(\theta)=\frac{1}{2}-\frac{cos(2\theta)}{2}$

$CDF(\phi)=\int_0^\phi PDF(\phi) d\phi$

$CDF(\phi)=\int_0^\phi\frac{1}{2\pi} d\phi$

$CDF(\phi)=\frac{\phi}{2\pi}$

Now we want to invert our CDF to sample it using our random variable $y$,

$y=CDF(\theta)$

$y=\frac{1}{2}-\frac{cos(2\theta)}{2}$

$\frac{1}{2}-y=\frac{cos(2\theta)}{2}$

$1-2y=cos(2\theta)$

$\frac{cos^{-1}(1-2y)}{2}=\theta$ (7)

For $\phi$,

$y=CDF(\phi)$

$y=\frac{\phi}{2\pi}$

$y*2\pi = \phi$ (8)

Now we have our CDFs and our PDFs, we can finally calculate our direction.

In pseudo code you can simply do:

$\theta=\frac{cos^{-1}(1-2rand01())}{2}$

$\phi=rand01()*2\pi$

With these directions, you can now sample your scene:

$\frac{SampleScene(SphericalTo3D(\theta, \phi))}{PDF(\omega)}$

Plug in (5)

$\frac{SampleScene(SphericalTo3D(\theta, \phi))\pi}{cos\theta}$

## Conclusion

That’s it! These formulas will sample the hemisphere where it is receiving more light defined by the cosine lobe. The results are pretty awesome.
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 0, "mathjax_display_tex": 0, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 52, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0, "math_score": 0.6314913630485535, "perplexity": 935.007237710996}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.3, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "plain"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "warc_path": "s3://commoncrawl/crawl-data/CC-MAIN-2021-25/segments/1623487584018.1/warc/CC-MAIN-20210612132637-20210612162637-00201.warc.gz"}