CPSC 102 Computer Science II
(Advanced C Programming)

Assignment 8

Objectives:

To implement a simple ray tracer. This is an extension of the ray caster which adds in diffuse and specular components of the rendering equation, with a recursive reflective component.

Description:

  1. See the online notes and classroom notes for supplemental ray tracing mathematics.
  2. Implement the ray tracer by adding effects to your ray caster piecemeal. Use V the view vector by setting it to the negated dir vector which is passed-by-value to the ray_trace function. A suggested progression can be as follows.

    1. add diffuse reflection to the distance-attenuated image produced by the previous assignment:
      1. if the diffuse material component is not zero, iterate through the list of lights in the scene
      2. for each light, find the direction vector from the hit point to the light (L - hit where L is the light position and hit is the hit point set by the find_closest function)
      3. compute N · L (where N is the normal at the hit point that is also set by the find_closest function)
      4. if N · L is greater than 0 and less than 1, compute Id which is the light color scaled by N · L divided by the distance to the light r, i.e., (N · L)/r
      5. add in the diffuse material color multiplied by Id
      6. clamp the resultant color to the range [0,1] (meaning that if any of the R,G,B components are less than 0 set them to 0 or if they are greater than 1 set them to 1 — write a convenience method clamp: lo: hi for the pixel_t type)

    2. add in processing of lights and specular reflection:
      1. if the specular material component is not zero, compute the reflective color obtained a recursive call to ray_trace followed by adding in specular highlights (see below; in this step just put in a placeholder for the recursive call and add in the specular highlights first)
      2. clamp the resultant color to the range [0,1]

    3. next, add in specular highlights:
      1. if the specular material component is not zero, iterate through the list of lights in the scene
      2. for each light, find the direction vector from the hit point to the light (L - hit where L is the light position and hit is the hit point set by the find_closest function)
      3. compute N · L (where N is the normal at the hit point that is also set by the find_closest function)
      4. if N · L is greater than 0 and less than 1, compute Is which is the light color scaled by (R · V)n divided by the distance to the light r, i.e., (R · V)n/r
      5. add in the specular material color multiplied by Is
      6. clamp the resultant color to the range [0,1]

    4. finally, add in the recursive call to ray_trace to produce the final image:
      1. allocate a new pixel_t *refcolor pixel vector which will hold the color returned by the ray_trace call
      2. compute out the reflection direction vector, 2 (N · -dir) N - -dir (don't forget to normalize)
      3. call ray_trace with hit and out acting acting as the ray position and direction, along with raydist being passed-by-value (this is used to cull the ray if the ray distance is too large, e.g., 100)
      4. blend the current color and refcolor by multiplying color by diffuse and refcolor by specular and adding

  3. Sample input: the following cbox.txt
    camera cam
    {
       pixeldim 512 384
       worlddim  5.12 3.84
       viewpoint 2.56 2 5
    }
    
    light top
    {
       location 2.56 3.80 -1.5
       emissivity 1 1 1
    }
    
    material gray
    {
       ambient 3 3 3
       diffuse  .9 .9 .9
    }
    
    material green
    {
       ambient 0 5 0
       diffuse 0 .5 0
    }
    
    material salamander
    {
       ambient 3 2 2
       diffuse  .9 .9 .9
    }
    
    material slate
    {
       ambient 2 1.8 3
       diffuse  .9 .9 .9
    }
    
    material transparent
    {
       ambient  3 3 3
       diffuse  .1 .1 .1
      specular  .9 .9 .9
        alpha  .9
          ior  1.83
    }
    
    material chrome
    {
       ambient  3 3 3
       diffuse  .1 .1 .1
      specular  .9 .9 .9
    }
    
    plane backwall
    {
       material gray
       normal 0 0 1
       point  0 0 -5
    }
    
    plane leftwall
    {
       material salamander
       normal 1 0 0
       point  0 0 0
    }
    
    plane rightwall
    {
       material slate
       normal -1 0 0
       point   5.12 0 0
    }
    
    plane ceiling
    {
       material gray
       normal  0 -1 0
       point   0 3.84 0
    }
    
    plane floor
    {
       material gray
       normal 0 1 0
       point  0 -0.2 0
    }
    
    sphere left
    {
       material chrome
       center 1.25 .75 -4
       radius .9
    }
    
    sphere right
    {
       material transparent
       center 3.7 .7 -2.3
       radius .9
    }
    	

What to hand in:

A tar.gz archive of your asg8/ directory, including:
  1. A README file containing
    1. Course id--section no
    2. Name
    3. Assignment description
    4. Brief solution description (e.g., program design, description of algorithm, etc., however appropriate).
    5. Lessons learned, identified interesting features of your program
    6. Any special usage instructions
  2. Makefile
  3. source code (.h headers and .c source)
  4. object code (do a make clean before tar)

How to hand in:

See submit notes.