CS 184: Computer Graphics and Imaging, Spring 2023

Project 3-2: Ray Tracing II

Varun Neal Srivastava

Website URL: https://varunnsrivastava.github.io/cs184-project3-2/.

Overview

This project is a brief extension of our previous ray tracing project, which can be found here. This extension allows our engine to simulate new textures via the implementation of their BSDFs. In particular, the engine now supports mirror and glass surfaces, as well as "isotropic rough conductors", e.g. most metals.


Part 1. Mirror and Glass Materials

(Perfect) mirrors only have specular reflectance: they reflect each light ray exactly across the normal vector. This is a very basic, deterministic BSDF, and is easy to implement given our existing framework. Glass, in contrast, refracts light rays (according to the index of refraction of the glass material). In the case where there is total internal reflection, which occurs when the angle the ray intersects the glass is sufficiently high, the light ray is reflected rather than refracted. We can easily model refraction via Snell's Law.


Mirror (left) and glass (right) spheres

In order to achieve the advanced lighting effects such as the reflected brightness on the walls from the spheres, we need to simulate many bounces per ray of light. Deeper recursions of ray traversal correspond to more advanced lighting effects:

Depth = 0; no illumination.
Depth = 1; no reflection or refraction yet, so the spheres are invisible.
Depth = 2; reflection and refraction of the environment appear.
Depth = 3; notice the illumination of the shadow beneath the glass sphere.
Depth = 4; the illumination of the walls from spheres re-appears on the spheres.
Depth = 5; deeper recursion creates a brighter image.
Depth = 100; all multibounce effects have stabilized and converged.

As we increase the depth of recursion, multiple bounces first create basic environmental reflection and refraction, and later create complex self-similar reflection and shadow patterns. For example, the mirror ball reflects the glass ball, in which the mirror ball's glimmer can be seen in the reflected glass ball. By the time we get to a depth of 4, most obvious multibounce effects appear to converge. The image continues to get brighter as we increase the recursion depth as the global illumination steadily increases.

Part 2. Microfacet Materials

Isotropic rough conductors are imperfect mirrors. Essentially, each microfacet reflects light rays specularly, but the normals of the surface are given according to a rough Normal Distribution Function. Surfaces have a roughness coefficient as well as a distribution of refraction indices and extinction coefficients. The latter coefficients determine the Fresnel coefficient, which essentially tells us how to recolor the light ray after a bounce.

Varying the roughness coefficient \(\alpha\):

\(\alpha = 0.5\)
\(\alpha = 0.25\)
\(\alpha = 0.05\)
\(\alpha = 0.005\)

Decreasing \(\alpha\) makes the surface appear "smoother". This can be considered somewhat akin to sanding or filing the surface. Smoother surfaces look more similar to a mirror than a diffuse texture; e.g. at \(\alpha = 0.5\), the gold dragon appears to be almost diffuse, whereas at \(\alpha = 0.005\), it appears to almost be a perfect mirror.


It is difficult to implement importance sampling when all the normals are scattered according to the Normal Distribution Function. The implementation essentially requires us to sample from the Beckman NDF. The equations we use and their derivations can be found on this website. Importance sampling of course gives much faster convergence.

Importance sampling vs (naive) uniform sampling at the same number of samples per pixel:

Uniform (hemisphere) sampling
Importance sampling

It is obviously clear that importance sampling converges much more quickly. There is less noise and we have a better understanding of the texture of the bunny at the same number of rays cast with importance sampling.

In order to model an arbitrary isotropic rough conductor, we only need to know its refraction index and extinction coefficients along the visible light spectrum. For example, this website has a collection of these coefficients for many materials. Instead of integrating over the entire visible light spectrum, we simply take note of the coefficients at red (614nm), green (549 nm), and blue (466nm) wavelengths of the spectrum. From there, we can can approximate the Fresnel coefficient using the RGB values of the light ray.

The refraction index of iron at those wavelengths turns out to be 1.5454, 1.2216, and 1.0355, respectively. The extinction coefficients are 6.9982, 5.9220, and 4.6354, respectively. Thus, with those values, we can model an iron texture:

An iron dragon with \(\alpha = 0.25\).