Computer Graphics
CAP 4730

 

Fall 2000
Tuesday/Thursday 9:30am
103 Love Building
Dr. David C. Banks

 

Computer Graphics
Homework 10
6 hours
 
Copyright © 2000 David C. Banks

  1. 2.00 hours
    Ray-caster output

    Modify your ray-casting Inventor program from homework 05 so that it writes out data for each intersection.

    Recall that you have a ray in direction V that intersects a point p on some sphere in the scene. If the viewpoint is at q, then

      V = (p-q).normalize()
    

    The unit-normal to the sphere at p is the vector N. If the sphere is centered at point C,

      N = (p-C).normalize()
    

    Assume the sphere emits light according to the formula

      colorOut = N.dot(-V) * sphereColor
    

    where colorOut and sphereColor contain the RGB components of the color. You will write out the values

      V.x  V.y V.z  colorOut.red colorOut.green colorOut.blue
    

    for each intersection. Begin your file with a header that you can parse, such as

      #Raycast V1.0 ascii 
    

    or

      <rayinfo numRays="1" version="1.0">
        <direction x="0.6" y="0.3" z="0.7"></direction>
        <color     r="1.0" g="0.5" b="0.8"></color>
      </rayinfo>
    
  2. 2.00 hours
    Rendering the output to an image.


    To render a point, you need to specify the filter to use (constant, linear, quadratic, cubic) and the filter radius. You also need to put the point into a rectangular coordinate system. This is what you did for homework 2.

    The coordinate system is given by 3D vectors u1, u2, u3 that are mutually perpendicular to each other. The u1,u2 vectors define directions of the image plane, and the u3 vector defines the depth direction. Here is an inventor file to illustrate the geometry. To convert your vector V from (u1,u2,u3) into the plane's (s,t) coordinate system, first normalize V (make it unit length) and then use the following formula.

      if (V.dot(u3) > 0.0)     // V points in front of you
        {
        s = V.dot(u1)/V.dot(u3)
        t = V.dot(u2)/V.dot(u3)
    
        image.drawPoint(s,t,  color);
        }
    

    If v.dot(u3) is non positive, don't draw the sample.

    Your rendering tool will accept command line parameters that specify the name of the image file, the 3D vectors u1 u2 u3, the dimensions sDim and tDim of the image pixels, the rectangular domain sMin sMax tMin tMax, the desired filter, and the filter's radius.

    Run your ray caster on a scene with spheres of various colors and have it write the ray intersections to a file. Link to the file from your Web page.

    Take a snapshot of the Inventor viewer showing the scene (with spheres of various colors) and showing the ray intersections that are described in the file.

    Run your renderer using command line arguments that you record in your README file. Run the renderer using your data file.

      renderSamples u1 1.0 0.0 0.0  u2 0.0 1.0 0.0  u3 0.0 0.0 1.0 file rayFile.01.ray > ray.01.ppm
    

    Generate a ppm file. Convert to gif and put it on your Web page.

    Here is an image rendered from data for the intersections in the 3D scene above. It is composed of 4 dots. If you put your eye at the proper distance from the center of the flat image, you will see approximately the same thing that the viewer inside the 3D sphere sees.

  3. 1.00 hours
    Animating.

    Write a script that rotates the vectors u1 u2 u3. This corresponds to turning your head as you look at the ray intersections. For each set of these view parameters, generate an image file. Convert them into an animated gif and put on your Web page. Tar and gzip your code, Makefile, and documentation and link from you Web page. Your documentation will include an explanation of the command line arguments and will include an example of how to invoke your programs successfully.

  4. Extra credit (200 points)
    Spherical texture map.

    Instead of generating a rectangular image to display on the screen, you can generate a texture map suitable for wrapping over a sphere.

    Assume, for example, that the vector u3 points toward the north pole, specifying a local z-direction. In spherical coordinates,

      z = V.dot(u3) 
        = cos(phi)
    

    so

      phi = arccos(V.dot(u3))
    

    The local x- and y-directions are harder.

      x = V.dot(u1) 
        = cos(theta)*sin(phi)
    
    Since we know phi, we can compute theta (almost):
      theta = arccos(v.dot(u1)/sin(phi))
    
    But the arccos() function is ambiguous. Since
      y = sin(theta)*sin(phi)
    
    you can put the two together using the math library function atan2() in order to perfectly recover theta. Read the man page for atan2.

    For each sample in the raycast file, convert the sample to phi,theta coordinates. To filter the sample, convert your filter neighborhood (phi,theta)+(dphi,dtheta) into vectors v, du. Use the dot product v.dot(du) as input to the filter function. Write out the image in ppm format. Convert it to gif and put it on your Web page. Place a sphere centered at the viewpoint in the Inventor scene. Apply the image a texture map onto the sphere. It should align with the ray-intersection samples on the sphere. Take a picture and put it on your Web page. Link to your code.

  5. Extra credit (100 points)
    Shrinking filter.

    It is reasonable to expect that the first ray-intersection gives you a point and a color with a lot of uncertainty. As you collect more samples, you become more certain of the way the image should look. To reflect this increasing confidence in the samples, make the filter function's radius shrink as the number of samples increases. On possible choice is to make the radius for the nth sample be r0*sqrt(n), where r0 is the radius of the initial sample that is drawn in your image rectangle.

    Make an animation of the process of filling in the image, point by point. Put it on your Web page.

  6. Extra credit (100 points)
    Oriented filter

    When your (unit-length) ray direction V intersects a sphere with center C and radius r, the normal n at the intersection point P is given by N = P-C. The unit-length normal is N = n/||n||. If the unit normal N is not parallel to V (that is, |N.dot(V)| != 1), you can find a tangent T1 to the sphere.

      t1 = N - N.dot(V)*V
      T1 = t1 / ||t1||
    

    A complementary tangent T2 can be found as the cross product T2 = N.cross(T1). T1 and T2 define a tangent plane at the point P on the sphere. Write out these tangent vectors together with the view vector for each intersection.

    Project the points (p+T1) and (p+T2) into your 2D coordinate system for the image. Normalize them to produce vectors W1 and W2. These vectors define an ellipse that can be used for the filter function. Instead of applying f(d), with d(x,y)=sqrt(x2+y2), use the distance d in the W1,W2 coordinate system. That is, transform (x,y) into W1,W2 coordinates. Make an animation of the image being created. Put it on your Web page.