Digital Fodder > PROJECTS

    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