WARNING
Content Under Development

See release page for latest official PDF version.
**Chapter 4: Light Scattering** In this chapter we won't actually implement anything. We will set up for a big lighting change in our program in Chapter 5. Our program from the last books already scatters rays from a surface or volume. This is the commonly used model for light interacting with a surface. One natural way to model this is with probability. First, is the light absorbed? Probability of light scattering: $A$ Probability of light being absorbed: $1-A$ Here $A$ stands for _albedo_ (latin for _whiteness_). Albedo is a precise technical term in some disciplines, but in all uses it means some form of fractional reflectance. As we implemented for glass, the albedo may vary with incident direction, and it varies with color. In the most physically based renderers, we would use a set of wavelengths for the light color rather than RGB. We can almost always harness our intuition by thinking of R, G, and B as specific long, medium, and short wavelengths. If the light does scatter, it will have a directional distribution that we can describe as a pdf over solid angle. I will refer to this as its _scattering pdf_: $s(direction)$. The scattering pdf can also vary with incident direction, as you will notice when you look at reflections off a road-- they become mirror-like as your viewing angle approaches grazing. The color of a surface in terms of these quantities is: $$ Color = \int A \cdot s(direction) \cdot color(direction) $$ Note that $A$ and $s()$ might depend on the view direction, so of course color can vary with view direction. Also $A$ and $s()$ may vary with position on the surface or within the volume. If we apply the MC basic formula we get the following statistical estimate: $$ Color = (A \cdot s(direction) \cdot color(direction)) / p(direction) $$ Where $p(direction)$ is the pdf of whatever direction we randomly generate. For a Lambertian surface we already implicitly implemented this formula for the special case where $p()$ is a cosine density. The $s()$ of a Lambertian surface is proportional to $cos(\theta)$, where $\theta$ is the angle relative to the surface normal. Remember that all pdf need to integrate to one. For $cos(\theta) < 0$ we have $s(direction) = 0$, and the integral of cos over the hemisphere is $\pi$. To see that remember that in spherical coordinates remember that: $$ \delta A = sin(\theta) \delta \theta \delta \phi $$ So: $$ Area = \int_{0}^{2 \pi} \int_{0}^{\pi / 2} cos(\theta)sin(\theta) \delta \theta \delta \phi = 2 \pi \cdot \frac{1}{2} = \pi $$ So for a Lambertian surface the scattering pdf is: $$ s(direction) = cos(\theta) / \pi $$ If we sample using the same pdf, so $p(direction) = cos(\theta) / \pi$, the numerator and denominator cancel out and we get: $$ Color = A * s(direction) $$ This is exactly what we had in our original color() function! But we need to generalize now so we can send extra rays in important directions such as toward the lights. The treatment above is slightly non-standard because I want the same math to work for surfaces and volumes. To do otherwise will make some ugly code. If you read the literature, you’ll see reflection described by the bidirectional reflectance distribution function (BRDF). It relates pretty simply to our terms: $$ BRDF = A * s(direction) / cos(\theta) $$ So for a Lambertian surface for example, $BRDF = A / \pi$. Translation between our terms and BRDF is easy. For participation media (volumes), our albedo is usually called scattering albedo, and our scattering pdf is usually called phase function.