Project3Fall14

From Immersive Visualization Lab Wiki
Revision as of 00:17, 24 October 2014 by Jschulze (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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. 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, October 31st, at 3:30pm. It will be discussed by the TAs on Monday, October 27th 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. 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 house needs 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. For this part of the assignment, create a method rasterizeVertex which projects each vertex of the house to image coordinates and sets the color of the corresponding pixel to white using drawPoint. We will worry about shading the points at a later time. Write a loop which projects all points from the point cloud to the screen. (25 points)

Add support to switch between the two point cloud models with the number keys '1' and '2'. (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)

Define a point light source for your scene, 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. (15 points)

Allow switching between white and shaded points with function keys 'F1' and 'F2'. (5 points)

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)

Make the z-buffer functionality available when function key 'F3' is pressed. (5 points)

3. Varying 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, which should be easier to implement (by two nested for loops, for instance). Extra credit is to be obtained for nicer points (see below).

Enable this functionality when function key 'F4' is pressed. (5 points)

4. Optional: Prettier Points (10 Points)

Modify your drawPoint function to render nicer looking points.

So far the points are square. Modify your code to draw circular points. (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. (5 points)