Name Nachapon (Art) Chaidarun
Computing ID nc5rk
Assignment CS 4810 Assignment 2, due October 31, 2012
Environment g++, Sublime Text, Fedora 17 (64-bit)
Commands make; ./results.sh; python monticello.py
Late days used 5
Features Green features are fully implemented; yellow features are partially implemented; red features are unimplemented. Due to the slowness of jittered supersampling, it was implemented only as a proof-of-concept and turned off for the generation of all other image examples shown below.
test.bmp
test.ray, 4.29 seconds
  (1) RayScene::GetRay
  (2) RayGroup::intersect
First version: Local transformation and bounding volume information ignored
  (2) RaySphere::intersect
First version: Texture coordinates ignored
  (2) RayTriangle::intersect
First version: Texture coordinates ignored
  (1) RayScene::GetColor
First version: Only ambient and emissive properties calculated
  (2) RayPointLight::getDiffuse, RaySpotLight::getDiffuse, RayDirectionalLight::getDiffuse
  (2) RayPointLight::getSpecular, RaySpotLight::getSpecular, RayDirectionalLight::getSpecular
  (2) RayPointLight::isInShadow, RaySpotLight::isInShadow, RayDirectionalLight::isInShadow
  (1) RayScene::GetColor
Second version: Diffuse and specular contributions from light sources added
  (2) RayGroup::intersect
Second version: Local transformations taken into account
  (1) RayScene::GetColor
Second version: Reflected color contributions added
dog.bmp
dog.ray, 26.30 seconds
bunny.bmp
bunny.ray, 31.10 seconds
  (1) RayScene::GetColor
Third version: Refracted color contributions added, but refraction indices ignored
  (2) RayPointLight::transparency, RaySpotLight::transparency, RayDirectionalLight::transparency
  (2) RayScene::GetColor
Fourth version: Refraction indices taken into account
  (3) RayShape::setBoundingBox, RayGroup::setBoundingBox, BoundingBox3D::intersect, RayGroup::intersect
  (2) RayGroup::intersect
Fourth version: Bounding boxes ordered and tested before shapes intersected
  (2) RayTriangle::intersect
Second version: Texture coordinates taken into account
  (1) RaySphere::intersect
Second version: Texture coordinates taken into account
  (1) Jittered supersampling
jitter.bmp
test.ray, 29.58 seconds, 8 jittered rays per pixel (note smooth edges)
  (1) Generate .ray with spheres, triangles, all three types of light sources, and primitive with transparent material
The scene below contains a pure red directional light, a pure blue point light, and a pure green spotlight. All other intermediate color values are derived from the combination of these three light sources.
lights.bmp
lights.ray, 38.03 seconds
  (1) Soft shadows
  (1) RayBox::intersect
Example: Walls of nc5rk.art.1.gif
  (1) RayCylinder::intersect
Example: Columns of nc5rk.art.1.gif
  (1) RayCone::intersect
  (2) Perlin noise
  (1) Bump mapping
  (1) SIGGRAPH paper procedure
  (2) Octree or BSP
  (?) Impress us with something we hadn't considered...

I think I've found a problem with line 773 of the provided geometry.cpp, which deals with matrix-ray multiplication. Take the sphere from the provided test.ray for example. Translation along the y-axis by 2.5 units is specified; the inverse transpose of the sphere's transformation matrix then has a bottom row of [0, -2.5, 0, 1]. Line 773 inexplicably calculates the fourth homogeneous coordinate t by simply summing these bottom-row entries. This means that t will be positive or negative depending on whether the translation amount is less than or greater than 1, which has serious implications: any RayGroup transformed with this matrix will have correct normals on one half of an arbitrary plane and backwards normals on the other side!

I initially discovered this effect when I tried decreasing the translation amount specified in test.ray. Half of the resultant ellipsoid appeared correct while the other half was pitch black, due to reversed normals (whose directions I manually checked with generous amounts of std::cout). I've confirmed this behavior with a classmate, Raymond Tang, who was able to reproduce the anomaly with his ray tracer. My workaround was to disregard the t value by altering line 774 to return q instead of q/t.

Other points (1) Submitting one or more images for the art contests
nc5rk.art.1.gif
I wrote the script monticello.py to generate a 50-frame sequence with varying camera locations and directions. I used the Beier-Neeley morph feature of Assignment 1 to morph the rendered scene into the nickel and photo images. The entire animation contains 100 distinct frames, each separated by 40 milliseconds.
  (1) Submitting one or more .ray files for the art contests
See monticello.ray, which was used to create the final three-quarter portrait frame of nc5rk.art.1.gif.
  (?) Trace hundreds of thousands of triangles in few minutes with recursion depth 5
The provided buddha.ray file contains 318416 triangles and was traced in 113.64 seconds with recursion depth 5:
buddha.bmp
And finally... For your viewing pleasure