# Monte-Carlo Ray Tracer

This is a java ray tracer I wrote for a course on advanced rendering (COM S 517) taught by Kavita Bala which I took during the first term of my masters degree. There was some basic code provided for us which loaded up the scene and saved the image. We implemented a bunch of stuff on top.

Here is a list of what we did.

 BRDFs Lambertian reflector Lambertian emitter Ward (anisotropic) Cook-Torrance Acceleration structure KD-tree Box-filter antialiasing Uniform multisampling Stratified multisampling N-Rooks multisampling Direct illumination sampling Uniform sampling (Emitter) Power sampling Weighted balance sampling Indirect illumination sampling Uniform sampling Stratified sampling Cosine weighted sampling Stratified cosine weighted sampling BRDF weighted sampling Depth recursion stopping criterion Russian roulette

## BRDF

These were implemented directly from the original papers. Ward's paper contains a formula for generating BRDF weighted samples already, so we didn't have to sweat over that one. We did not implement BRDF sampling for the Cook-Torrance BRDF.

## Acceleration Structure

We used a KD-tree to improve the performance of the ray tracer. This is basically a binar tree where each cell is partitioned along the x-, y-, or z-axis depending on which split will provide better performance. The splitting heuristic I used compares weighs the number of primitives of each child by the surface area of the child cell and divides it by the surface area of the parent cell. This prevents boxes from becoming too small.

## Anti-Aliasing

We implemented basic antialiasing by running a box filter over every pixel (simple averaging). However, we implemented various pixel sampling strategies. The N-Rooks sampling strategy breaks the pixel into a grid of N2 boxes and takes N samples such that each sample is the only sample in its row and column.

## Direct Illumination

To speed up the ray tracer, we compute direct and indirect illumination separately, both using Monte Carlo sampling. We sampled the lights uniformly or based on the total power emitted by them. We could also compute the direct lighting as part of the indirect lighting computation, but that slows down the rendering quite a bit--in fact, computing these separately is really a type of importance sampling. We also have a hybrid, "weighted-balance" scheme which will alternately sample the lights or do importance sampling on the BRDF. This one is useful to sample the specular direction of highly specular BRDFs.

## Indirect Illumination

We did quite a bit of work here, mixing stratified sampling with the cosine-based importance sampling strategies and a BRDF sampling strategy.

## Depth Recursion Stopping Criterion

Here we used Russian roulette, which is an unbiased stopping criterion that simply kills the ray or recurses with a (user) predefined probability.

## Image-Based Rendering

To conclude the course, we did some image-based rendering. A GUI was provided to move the camera around, and we simply reprojected the ray tracing samples to the new camera location, interpolating the fill in the gaps.

## Results

Here are some of the images we produced along with sampling methods used to generate each one. Note the color bleeding when indirect illumination is enabled.

 Rays/pixel: 1 Antialiasing: none Direct illum.: on Direct illum. rays/point: 1 Sampling: center of emitter Indirect illum. rays/point: 0 Sampling: none Render time: 4.7s Rays/pixel: 1 Antialiasing: none Direct illum.: on Direct illum. rays/point: 1 Sampling: center of emitter Indirect illum. rays/point: 0 Sampling: none Render time: 3.4s Rays/pixel: 1 Antialiasing: none Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 0 Sampling: none Render time: 1.5s Rays/pixel: 9 Antialiasing: uniform Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 0 Sampling: none Render time: 8.2s Rays/pixel: 9 Antialiasing: stratified Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 0 Sampling: none Render time: 8.3s Rays/pixel: 1 Antialiasing: none Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 0 Sampling: none Render time: 1.5s Rays/pixel: 1 Antialiasing: none Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 0 Sampling: none Render time: 1.4s Rays/pixel: 1 Antialiasing: none Direct illum.: on Direct illum. rays/point: 49 Sampling: uniform Indirect illum. rays/point: 0 Sampling: none Render time: 21.1s Rays/pixel: 49 Antialiasing: uniform Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 0 Sampling: none Render time: 42.2s Rays/pixel: 1 Antialiasing: none Direct illum.: on Direct illum. rays/point: 16 Sampling: uniform Indirect illum. rays/point: 0 Sampling: none Render time: 10.9s Rays/pixel: 1 Antialiasing: none Direct illum.: on Direct illum. rays/point: 16 Sampling: uniform Indirect illum. rays/point: 0 Sampling: none Render time: 11.0s Rays/pixel: 1 Antialiasing: none Direct illum.: on Direct illum. rays/point: 16 Sampling: power Indirect illum. rays/point: 0 Sampling: none Render time: 10.3s Rays/pixel: 49 Antialiasing: uniform Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 1 Sampling: uniform Render time: 85.2s Rays/pixel: 49 Antialiasing: uniform Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 1 Sampling: cosine Render time: 83.4s Rays/pixel: 9 Antialiasing: uniform Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 0 Sampling: none Render time: 8.5s Rays/pixel: 49 Antialiasing: uniform Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 1 Sampling: uniform Render time: 84.1s Rays/pixel: 49 Antialiasing: uniform Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 1 Sampling: brdf Render time: 85.0s Rays/pixel: 49 Antialiasing: uniform Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 1 Sampling: brdf Render time: 87.9s Rays/pixel: 200 Antialiasing: uniform Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 1 Sampling: brdf Render time: 369.3s Rays/pixel: 49 Antialiasing: uniform Direct illum.: off Direct illum. rays/point: 0 Sampling: none Indirect illum. rays/point: 1 Sampling: uniform Render time: 45.8s Rays/pixel: 49 Antialiasing: uniform Direct illum.: off Direct illum. rays/point: 0 Sampling: none Indirect illum. rays/point: 1 Sampling: uniform Render time: 47.4s Rays/pixel: 49 Antialiasing: uniform Direct illum.: on Direct illum. rays/point: 1 Sampling: uniform Indirect illum. rays/point: 1 Sampling: uniform Render time: 52.7s Rays/pixel: 49 Antialiasing: uniform Direct illum.: off Direct illum. rays/point: 0 Sampling: none Indirect illum. rays/point: 1 Sampling: brdf Render time: 36.4s Rays/pixel: 49 Antialiasing: uniform Direct illum.: on Direct illum. rays/point: 1 Sampling: weighted balance Indirect illum. rays/point: 1 Sampling: brdf Render time: 85.8s Rays/pixel: 1 Antialiasing: none Direct illum.: on Direct illum. rays/point: 100 Sampling: uniform Indirect illum. rays/point: 0 Sampling: none Render time: 75.9s