# Final Project: Rendering Lily Pads

### Tom Brow, Ranjitha Kumar

## Lily Pad Models

All the lily pads and stems were modelled in Mathematica; the screen shot below shows the basic form of the equations used to model both the pads and the stems. The intuition used to create the lily pad models is as follows:

- {x(u,v) = cos(u), y(u,v) = sin(u), z(u,v) = C} creates a circle in the z(u, v) = C plane.
- To create a circle with frills on the outer edge, add cosine terms of varying frequency and amplitude to x(u, v) and sine terms of varying frequency and amplitude to y(u, v).
- Varying u from 0 to a value less than 2*Pi, results in an incomplete circle. To make the circle pucker inwards like a cardiod, multiply x(u,v) and y(u,v) by some degree of v.
- The other terms in x(u,v) and y(u,v) are used to move the location of the center of the lilypad so that stem is not attached to the dead center of the circle.
- Finally, defining z(u,v) as sin(v) makes the lily pad curve inward to meet the stem.

The model of the lily pad stems can be thought of as sweeping a circle along a curve defined by sines and cosines.

After creating all of the models in Mathematica, the geometry was outputted to PBRT scene files and referenced in the main scene file. We used the Mathematica to PBRT converter available at http://pbrt.org/downloads.php. Rotations and translations were applied to the models to place them so they closely matched up with the original photo.

## Subsurface Scattering

## Multiple Volume Scattering

Because the only light entering the visible part of our scene comes through the surface of the water, all of the light that reaches the eye is multiply scattered. So although our scene doesn't exhibit the volume caustics or "god rays" that usually motivate volumetric photon mapping, we needed to implement it anyway.

Following [1] and [2], we extended pbrt's built in photon mapping surface integrator, `photonmap`, to store a volume photon map as described in [3]. Whereas the original `photonmap` shoots a ray from the light source and stores a photon at every point the bouncing ray hits a surface, our extended version allows the ray to be scattered or absorbed at any point in the volume, and stores photons for those interactions as well. The result is a collection of photons that can be used by a volume integrator to estimate the in-scattered radiance at any point.

[3] does not specify a method for determining whether and where a volume interaction occurs. Given a ray through a volume, [1] considers the 1D cross section along the entire length of the ray and samples a _t_ value accordingly. [2] marches along the ray from _mint_ to _maxt_ by randomly-sized intervals, using the transmittance over each interval to determine the probability that an interaction occurs there. If there is an interaction, the upper bound of the interval is the _t_ where it occurs. Because of this rounding up, method [2] is biased towards a higher value of _t_, which results in incorrect-looking volume caustics unless the size of the intervals is small. Since the cost of ray marching is inversely proportional to the interval size, we decided to remove the bias.

Our method combines the two methods described above. Like [2], we step along the ray by intervals, using the interval transmittance to test for an interaction. But if an interaction does occur, we randomly sample a point within the interval for the location of the interaction. We assume that transmittance is uniform within the interval, such that we can analytically calculate the PDF from which we need to sample to correctly select the location. The volume caustics generated by this method appear correct in homogeneous volumes even with large interval sizes.

Another challenge we ran up against was "blotchiness" -- bright, jarring spheres of light around very high-weighted photons. Fortunately for us, this problem occurs in surface photon mapping as well, and has been addressed in the extended photon mapping surface integrator, {{{exphotonmap}}}. One strategy the new integrator implements is an improved form of russian roulette ray termination during photon shooting; higher-weighted rays are less likely to be terminated, and thus have their weight divided by a greater amount if they are not terminated. The result is a more uniform distribution of weights over photons in the map, eliminating blotches. It was easy to adapt this improvement into our own volumetric photon mapping code.

Finally, we modified the `single` volume integrator to include the in-scattered indirect light as given by the volume photon map. The integrator's original code is used to handle direct light.