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 |
|
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 |
|
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
|