|
Primitives: The supported primitives are triangles, spheres, infinite planes. Triangles and spheres are inserted into a uniform grid (see below). Because planes are infinite their intersection tests are performed outside of grid traversal. Intersection tests for spheres and planes come directly from their equations. Triangle intersections are performed using the method described in "Fast, Minimum Storage Ray/Triangle Intersection" by Tomas Möller and Ben Trumbore in the Journal of Graphics Tools 1997. This intersection test produces a t, u, and v value where t is the ray parameter value of the intersection and u and v are bary-centric coordinates. u and v are used in normal and texture interpolation. Uniform-Grid acceleration: Triangles and Spheres are inserted into a uniform grid. The spatial extent of the grid is the bounding box of all the input spheres and triangles (plus a little cushion to make sure that precision errors don't lead to intersections taking place outside the grid space.) The resolution of the grid is a user specified parameter. Currently it is a constant in a source file, but the UI could easily be augmented to allow changing of the grid size during execution. For smaller scenes, such as model1.ray (from the first assignment page), can be rendered at 128x128 interactively. Using the mouse and keyboard controls one can navigate through the model. Texture Mapping: (triangles) The color value computed at an intersection from local illumination, reflected rays, and refracted rays are multiplied by the texture value if a texture and texture coordinates have been specified. This is equivalent to the modulation texture mode in OpenGL. As explained above u and v from the triangle intersection test above are used to interpolate texture values from triangle vertices. Lighting:
Antialiasing : The rays are jittered within a pixels neighborhood and normalized (per-pixel) Gaussian weights are assigned to each ray. Jittering is accomplished in the same manner as shadow rays. Glossy Reflections: Reflection rays are jittered in the same manner as the soft-shadow rays. The radius of jittering controls the level of gloss. Ray-Queue: Rays are rendered in the order they are computed by placing all rays in a queue as the are generated. For each frame the eye rays are queued. When a ray is popped off the queue its type is determined (shadow or object) and it is processed. If it is an object ray, it traverses the grid and finds an intersection. Reflection, refraction rays are then queued for this intersection. If a shadow ray is popped off the queue it is traversed and if necessary lighting calculations are performed. Rays carry with them through the queue all necessary data which includes the pixel to which they are contributing and the fraction of the pixel's color which they are to compute. Using this ray-queue the image on the screen can be updated on specified time intervals. Rendering can also be interrupted when the user makes view changes with the mouse or keyboard or resizes the window by flushing the queue and queuing a new set of eye rays. The screen refresh rate was set at 1/10th second. It actually occurred less frequently because the 1/10th second did not account for the time to call glDrawPixels() to update the screen. Renderings: All Images were rendered using 16 jittered rays per pixel. The normally mirror-like spheres have a frosted look when glossy reflections are enabled. In the above image he banding as the plane recedes is an artifact of image compression and was not present in the original image. I believe the stipled look on the podiums and cubes comes from an improperly set intersection threshold. Some reflection/refraction rays hit the face they were reflecting off or refracting through. Again the banding on the plane and on the red ball is from the compression. I believe the discrepancy in the the color of the ball from the images on the assignment page comes from different default lighting parameters. |