Project3Fall14
Contents |
Project 3: Rasterization
In this project you will need to implement your own software rasterizer. This means that you are going to need to implement the entire graphics pipeline from 3D vertices in object space to pixels on the screen yourself, which means without OpenGL. We provide a code template for the interface between your software rasterizer and OpenGL, which will display your software frame buffer on the screen.
This assignment is due Friday, November 7th, at 3:30pm. It will be discussed by the TAs on Monday, November 3rd at 5pm in CSB 001.
We provide a code template for you which displays a software frame buffer on the screen. Your task is to rasterize your scene (described below) into this frame buffer. Throughout this assignment you are not allowed to use any OpenGL routines which aren't already in the rasterizer code template. Instead, use your own vector and matrix classes from assignment #1 and add your own rasterization code.
The goal of this project is to write a software rasterizer (i.e., the rendering is done on the CPU rather than the GPU), which can display the point cloud models from homework assignment #2.
1. Rasterizing Points (40 points)
First you will need to project the points from the object space they are given in to the correct locations in the output image (frame buffer).
You can re-use your model (M), camera (C), and projection (P) matrices from the previous assignment, or use different ones. Add a viewport matrix (D). Implement a method to set the viewport matrix based on the window size (window_width and window_height) and call it from GLUT's reshape function. Your program must correctly adjust projection and viewport matrix, as well as frame buffer size when the user changes the window size. Correctly means that the 3D objects need to remain centered in the window and get uniformly scaled to match the window size. (10 points)
Then write a method to rasterize a point. You can use drawPoint from the code template to set the values in the frame buffer. Call this method in the display callback function for every point in the file. We will worry about shading a later time. Write a loop which projects all points from the point cloud to the screen. (20 points)
Add your keyboard and/or mouse routines to allow at least rotations about the y axis and scaling of the point cloud models. (5 points)
Add support to switch between the two point cloud models with the function keys 'F1' (bunny), 'F2' (dragon). These need to be supported in all parts of this homework assignment. (5 points)
Note: while we only expect that you represent each point by one pixel, you are free to make the points larger by representing them by more than one pixel (e.g., 2x2 pixels or 3x3 pixels). We will ask you to address this issue in part 3.
2. Shading (20 Points)
Pick a color for your point model. Define a point light source for your scene, place it in world coordinates so that it is stationary, and illuminate the points based on their normals. Place the light source so that the difference in the resulting image compared to part one becomes obvious. You do not need to attenuate the intensity of the light. (15 points)
Allow switching between raw and shaded points with number keys '1' and '2'. (5 points)
Note that the functionality for the number keys in this homework assignment should be cumulative: '2' should do whatever '1' does plus additional features. '6' would include all features from '1' through '5'.
3. Z-Buffer (20 points)
So far the points are rendered in the order in which they are listed in the file. Points rendered later will overwrite those that were rendered before them. But this does not generally achieve correct occlusion.
Implement a z-buffer data structure to resolve visibility when multiple points get projected into the same pixel. For z-buffering, you should linearly interpolate z/w for every point and scale it to the range of 0 to 1. This is your z-value, which you need to compare with the previously stored value in the z-buffer at this pixel location. Make sure that you clear the z-buffer (initialize with the value for the farthest possible distance) whenever you clear the frame buffer. (15 points)
Enable the z-buffer functionality with key '3'. (5 points)
4. Variable Point Sizes (20 Points)
Up until now your points are all the same size. This is, however, not very realistic, as all objects should become larger as they get closer to the camera.
Implement functionality to scale the point size depending on the point's distance from the camera. You will need to come up with a size function f(distance). The distance is the point's z/w value, which you previously calculated for the z-buffer. Greater distance should decrease the size of the points.
Modify the drawPoint method to additionally accept a point size, and write a function which renders a point at the given size. Your points do not need to be circular, they can be square and flat shaded. But you need to make sure that when rendering the pixels of your points, you also update the z-buffer for each pixel. (15 points)
Enable this functionality when number key '4' is pressed. (5 points)
5. Optional: Spherical Points (10 Points)
Modify your drawPoint function to render nicer looking points which look like spheres.
So far the points are square. Modify your code to draw circular points (filled circles). Their size should be determined like in part 4. Set the z-buffer values as they would be with spherical points: greater depth in the center, smaller depth towards the edge of the sphere. Enable the rendering of these points with the '5' key. (5 points)
Your points have a uniform color up until now. To indicate where the light comes from, add a 'fake' diffuse lighting effect. Pretend that you are rendering projected spheres for points. Find the location on the sphere at which it would be the brightest assuming diffuse reflection. You only need to support one light source. Color the pixels of the circle drawPoint generates gradually with darker colors the further they are from the bright spot. Enable this mode with the number '6' key. (5 points)