Monte Carlo Renderer
The goal of the project was to implement a Monte Carlo Raytracer. This project was implemented in 3 seperate phases. The project was coded in Java and it used a basic framework which had the classes for certain primitives and ray intersection code.
Overview of Features:
Monte-Carlo Raytracer
Antialiasing
Supports Sphere and Triangle Primitives
Supports Lambertian, Ward and Cook Torrance Models
Supports Direct and Indirect Lighting
Uses KD-Tree Acceleration Structure
Supports XML scripted Scenes
The Project Implementation
The first phase was as follows:
Primary visibility (the surface you see through a pixel should be the first intersected along a ray from the eye through the center of that pixel).

Pixel anti-aliasing, using Monte Carlo sampling supporting 2 different methods:
If method is "uniform" then pick the rays uniformly over the pixel
If method is "stratified" then subdivide the pixel into bins and shoot one ray randomly within each bin. Have the same number of bins horizontally and vertically and make the number of bins be as close as possible to the number of pixel rays per point.

Direct lighting

Shading of Lambertian materials.

Shading of emissive materials.
Shading of materials with a Cook-Torrance reflectance model for materials
Shading of materials with an isotropic Ward reflectance model.

The second phase was as follows
Area sampling of light sources using 3 different methods:
1. If method is "uniform" then each light in the scene should get the same number of shadow rays on average.
2. If method is "area", the probability of a light having a shadow ray cast to it should be proportional to its area. The total number of shadow rays shot per point should still be the number specified by shadowRaysPerPoint.
3. If method is "power", the probability of a light having a shadow ray cast to it should be proportional to its power. The total number of shadow rays shot per point should still be the number specified by shadowRaysPerPoint.

Soft shadows |
Multiple Light Sampling
|

BRDF Sampling |
Indirect Illumination
Hemispherical sampling to compute illumination in two different forms,
1. If Next Event Estimation is "off", both direct and indirect lighting are computed using hemispherical sampling.
2. If Next Event Estimation is "on", direct illumination is computed normally and indirect illumination is computed using hemispherical sampling.
Hemispherical sampling is done according to 3 methods:
# If the method is "uniform", pick rays uniformly over the surface of the hemisphere.
# If the method is "cos", pick rays according to a cos(theta) distribution.
# If the method is "brdf", pick rays using importance sampling of the BRDF.

Cornell Box : With all the indirect illumination
|

Soft Shadows with Ward Isotropic Model
|
The third phase was implementing a KD-Tree acceleration structure in the program. This was done as follows:
Heuristic Used:
The difference of the number of primitives in the two regions
+ number of primitives in the above region * above region volome / total volume
+ number of primitives in the below region * below region volome / total volume
This primitive gives more weight to the intersections (or overlaps) of greater volume
Thus, we would select the axis in which the volume of the overlap is the least
Traversal Algorithm:
1. We initialise the start node to the root
2. We check whether "This" node is a leaf
3. If not, We shoot "test" rays to the above and below regions of the Tree
4. If both above and below are not intersected, we return false
5. Either one is intersected, we simply recurse on that region
6. If both above and below are intersected,
we first recurse on the above region
the result of that is a clipped ray (to the primitive in the above region)
we test whether this clipped ray intersects the below region (mailboxing)
we then recurse on the below region
7. The end point of recursion is a list of primitives on a leaf (ie, if "This" node is a leaf)
8. We do the intersection on this list and return appropriately
Results of KD Tree Acceleration Structure (Results on a P4 3.4 GHZ) (Unit is milliseconds, and lower is better)
| Scene |
Time without Acceleration |
Time with Acceleration |
KdTree1.xml (3658 poly)
KdTree2.xml (3685 poly)
Bike.xml (12943 poly)
|
202765
172672
516844 |
39813 (500% improvement)
38172 (450% improvement)
110704 (466% improvement) |
Click on the images for a bigger view

kdtree1.xml |

kdtree2.xml |

bike.xml |

Contact
Venkat Krishnaraj
venkat.krishnaraj@gmail.com
Masters,
Computer Science
Cornell University