CS 351: Assignment #9

Shading

Due 20 November, 2014

For this assignment you will implement Gouraud shading for polygons with ambient and point light sources. The end result will be a complete 3D z-buffer rendering system with lighting and shading. If you decide to implement Phong shading as an extension, you may skip the Gouraud shading step and just go straight to Phong shading.


Tasks

Here is the final Graphics System Specification.

The major steps are as follows.

  1. Create the light source data type and supporting functions. The lighting_shading function should calculate the appearance of a surface given its parameters and all of the lights. This test program should create this output (note that my lighting_add function prints out the sum of all the shading calculated so far). The first light line is the contribution of the ambient illuminant. The second light line is the combined ambient and point lighting. These results use the equation in the graphics specification and approximate H as (L+V)/2.

    As a second test of your lighting_shading function, you can run this program, which generates the image below. It does not use your modeling system, only the lighting_shading function.

  2. Update your polygon_drawShade algorithm to do Gouraud shading, and test it on a hand-created polygon to see if the colors interpolate cleanly. Calculate the colors using an ambient and a point light source and the shading function defined in the prior step.

    The updates are primarily in the makeEdgeRec, fillScan, and updateActiveList functions. You will need a new field in the Edge data structure to hold a color, cIntersect, and a dColorPerScan. If you call them cIntersect and dcPerScan, they will act similarly to xIntersect and zIntersect. You will need to add two Color arguments to makeEdgeRec: c1, and c2. They should mirror start and end parameters, and specify the colors at those two vertices.

    To account for perspective projection, calculate dcPerScan using the color value divided by the depth value, as below. edge->dcPerScan.c[0] = ( c2.c[0]/end.val[2] - c1.c[0]/start.val[2] ) / dscan;

    Similarly, calculate the initial cIntersect as the initial color value divided by the initial z value. In your fillScan function, you will need to multiply c/z by z to get the true color value.

  3. Create the function polygon_shade that calculates the color at each vertex of the polygon given a DrawState and Lighting structure. Use the lighting_shading function above to do the actual color calculations. The function should allocate and fill out a color array as part of the Polygon data structure. In addition, write the utility functions polgyon_setNormals, polygon_setColors, and make sure your polygon_clear, polygon_copy, polygon_init, polygon_set, and other utility functions properly handle the new color field and oneSided field. The matrix_xformPolygon should also call matrix_xformVector on each surface normal.
  4. Add the functions to the Module class for handling body and surface colors and the surface reflection coefficient. These additions will also involve changes to the element_init function.
  5. Update your module_draw function to handle Gouraud shading. The main change is in the ObjPolygon case.
  6. To implement Gouraud shading for polygons, you need to calculate shading at the vertices of the polygon. The simplest way to do this is to place the light sources in world coordinates and make the color calculations after multiplying the polygon by the LTM and GTM matrices. Therefore, your polygon case will end up looking something like the following.

    case ObjPolygon:
      Copy the polygon data to a temporary polygon P
      Transform P by the LTM
      Transform P by the GTM
      If doing Gouraud shading
        Call polygon_shade to calculate the color at each vertex using P
      Transform P by the VTM
      Homogenize the X and Y coordinates
      If doing Gouraud shading
        Call polygon_drawShade with P, the draw state and the lighting
    

    Note that your polygon_drawShade function does not need to use the lighting, only the DrawState. If you implement Phong shading, you will need the lighting information.

  7. Test your system to this point using a simple cube.

  8. You can test your system further using the X-wing scene from last week.

  9. A third test program makes use of the files linked below. Run the example program test9c.c using the command:
  10. ./test9c starfury.ply 30

    The first linked code is the test program, the second goes in your library and enables your system to read in .ply files, and the third is the .ply file itself. Note, you may have to modify the read function depending upon the specific fields in your polygon structure. In particular, if you are using doubles for your Point/Vector data structure, you will need to modify the fscanf call for those to %lf instead of %f. Also, the program makes a system call to convert, so if your system does not have the ImageMagick package installed, either install it or reduce the size of the image from 2000x2000 to 500x500 using a different image reduction tool.

    Feel free to create your own .ply models. Several of the Stanford models are available in that format. To obtain the models, you can peruse the Stanford 3D Scanning Repository. Also, 3D modeling programs like Blender3D (which is freely downloadable), can save models in the .ply format.

  11. The required creative image for this assignment is to create your own 3D model and place at least three copies or variants of it into a scene with at least one point light source, an ambient light source, and shading. Each person should create their own scene.

Extensions


Writeup

Make a child wiki page from your main CS 351 wiki page. Give it the label cs351f14project9. Put up your required and portfolio images along with brief descriptions and relevant information.


Handin

Put your code on the handin server. Put your writeup on the wiki.