Assignment 2: Lazy KD Tree (LZKD-Tree)

Due: Tuesday April 25th, 11:59PM

Questions? Need help? Post them on the Assignment2Discussion page so everyone else can see!

Please link to your final Assignment 2 writeup wiki page from Assignment2Writeups.

Description

In this assignment, you will improve pbrt's implementation of the kd-tree accelerator. As described in Chapter 4 of the textbook, before rendering, pbrt constructs a kd-tree containing all geometric primitives in the scene. This approach can be inefficient for several reasons. First, as you will observe in this assignment, building a complete kd-tree for a scene containing many geometric elements can be very costly. Depending on the camera's location, or on how large objects in the scene hide others from view, it is possible that many kd-tree nodes created in the initial build process may never be hit by any rays. In this case, both the processing spent building these nodes and the memory used to store them is wasted. As an example, the following images show the same scene from three different camera positions.

killeroos-view1 killeroos-view2 killeroos-view3

In all images, the rendered scene contains 4 killeroos, a ground plane, and two walls. In the left image, the camera faces the killeroos and all the objects in the scene are visible. In the center image, the camera is placed such that the killeroos are hidden behind the walls. In the image at right, the camera is zoomed in on one of the killeroo's head, occluding large regions of the scene.

For this scene, pbrt builds the kd-tree consisting of 273.1k tree nodes irregardless of camera position. However, it is clear there is no need to create nodes in the space surrounding the killeroos in the second image, since they are occluded from view and no rays will traverse through that part of the scene. The following segment shows statistics from rendering the left and center scenes in pbrt.

Geometry
    Total shapes created                                    133.1k
    Triangle Ray Intersections                              1.475M:9.220M (16.00%)
    Triangles created                                       133.1k
Kd-Tree Accelerator
    Avg. number of primitives in leaf nodes                 865.8k:273.1k (3.17x)
    Interior kd-tree nodes made                             273.1k
    Leaf kd-tree nodes made                                 273.1k
    Maximum number of primitives in leaf node               155

Constructing these extra kd-tree nodes can be expensive. One solution is to avoid building the entire structure as a preprocess, and instead dynamically build the necessary parts of the kd-tree while tracing rays. This attempt of delayed computation or lazy evaluation is a common technique used in many computer science algorithms. The point of this assignment is to implement a lazy kd-tree to improve pbrt's performance when rendering complex scenes whose geometry extends well beyond the space traversed by the rays generated to render an image, such as in the examples above. Your implementation should be lazy in two key ways: (1) kd-tree nodes will be constructed dynamically as needed, and (2) Scene objects will be refined into their primitive components only when required.

Step 1: Understanding pbrt's kd-tree

It is critical that you first obtain a detailed understanding of the current kd-tree implementation in pbrt. Read Section 4.4 of the textbook and make sure you can follow the code in kd-tree.cpp, located in the accelerator directory of the code base. You should be able to answer the following questions about the current implementation (we do not expect you to hand in answers to these questions).

Step 2: Implement a Lazy kd-tree

evaluation

Suggestions

Additional Optimizations

We want you to go town town on this assignment. Here are some ideas for further kd-tree optimizations.

Submission

Detailed submission instructions will be posted shortly.

Create a wiki page named 'Assignment2' under your home directory that includes a description of your approach and your final rendered images. In addition to rendering several views from the test scene discussed above, you will also test the quality of your implementation on a much more complex outdoor scene. For both of these scenes, you will need to report the following rendering statistics for both your implementation and pbrt's default kd-tree: (1) total rendering time including any pre-build (2) number of created tree nodes (3) the number of ray-triangle intersections. Please provide the actual numbers, and well as the ratios between the two implementations. Please follow the layout of the page template given here. Do not include your source file in the wiki page. Send an email to cs348b-spr0506-staff@lists.stanford.edu with title exactly as "cs348b HW2" and your lz-kdtree.cpp as an attachment.