COS 426:
|
|
COS 426 General | Assignment 4
In this assignment you will create a software rasterizer in javascript. The rasterizer loads meshes with multiple textures and outputs rendered images in (almost) real-time.
Deadline: This assignment is due 11:59pm on Sunday, April 21th.
Like previous assignments, you are able to adjust several parameters using the GUI. The URL also encodes all the parameters and it is ok to refresh when necessary. The only difference is that there is no batch mode in this assignment because your rasterizer is expected to render images on the fly. Besides this, everything else should be familiar.
To get started, download this zip file and unzip it on your computer. Change to the subdirectory
cos426-assign4
and run the commandpython -m SimpleHTTPServer
in the terminal. (That command is for python 2.7. In python 3 it should bepython3 -m http.server
. There are also many other ways to start a web server, for example usingphp -S localhost:8000
or by installing WAMP or MAMP or Node. Various other options are discussed here.) A web server will be launched locally on your computer, rooted at this directory. Note that our assignments will not work if you simply open the html file in the browser directly usingfile://...
due to the same-origin security policy. Therefore we run a local web server.Please remember to use your favorite text/code editor to edit the file
js/student.js
and fill in your name and NetID. Reload the web page in your browser, and now your information should appear above the image.
This assignment is worth 15 points. The following is a list of features that you may implement (listed roughly from easiest to hardest). The number in front of a feature corresponds to how many points the feature is worth for the full implementation. Partial or partially-correct solutions will receive partial credit. Unlike previous assignments, in this assignment, all features are required. Refer to the examples web page for example output images as well as implementation hints. You are encouraged to optimize the performance of your rasterizer as much as possible to achieve satisfactory framerate. For example, an easy optimization of scanning pixels in a triangle is to terminate scanning a line when it hits the right side of the triangle.
- Basic
- (2.0) Perspective projection: Complete projectVertices(). See this slide deck. By completing this, you will automatically enable a trackball camera like in assignment 2.
- (1.0) Phong reflection model: Complete phongReflectionModel(). You already have the diffuse term, and you need to add ambient and specular terms.
- Helpers
- (1.0) Bounding box: Complete computeBoundingBox() which computes the screen-space bounding box for a triangle.
- (1.0) Barycentric coordinates: Complete computeBarycentric() which computes the barycentric coordinates for a point inside the triangle. See this article and pages 30-33 of this slides (the only difference from A3 is that the points are all 2D and that efficiency is even more important).
- Shaders (assuming Phong reflection model)
- (2.0) Flat shader: Color of the each face is computed based on the face normal and face centroid.
- (2.0) Gouraud shader: Interpolate the color for each pixel in the triangle using the barycentric coordinate.
- (2.0) Phong shader: Interpolate the normal for each pixel in the triangle using the barycentric coordinate.
- Texture Mapping
- (2.0) Diffuse and Specular Mapping: Map a phong material texture (if it is available) to the mesh (use afrhead.obj for example).
- (2.0) XYZ normal mapping: Use the detailed normal specified in a XYZ normal texture to make the mesh more realistic. See Wiki page about how to map RGB to XYZ. Normal mapping is for the Phong shader only.
- Optional Optimization Contest
- Instead of an art contest, try your best to optimize the framerate of your code. Describe what optimizations you implement in the writeup. In order to participate in this contest, report the fps ratio of the following two renders, as well as their absolute framerates: For example, for the unoptimized instructor solution on a late 2013 MBP with an NVIDIA GT 750M, the wireframe render gets 34 fps and the phong render gets 4 fps. So you would report a framerate ratio of 0.118. Do not modify the wireframe shader at all (of course), and note that optimizations resulting in incorrect outputs will disqualify the entry. All required features must be implemented to participate. If the reported ratio is high enough, then we will run the submitted code on our hardware to determine the winner. Participating in the optimization contest will be worth between 0.5 and 2.0 points, depending on the effort and final framerate achieved.
By implementing all the features (in bold), you get the full credit for this assignment (15 points). For additional points, you may choose to participate in the contest. You final score will be the sum of all points above (no diminishing returns).
All the related functions are in
js/renderer.js
. Before starting on that, we recommend you take a quick look atcoursejs/main.js
andcoursejs/image.js
because they contain some useful definitions. You are welcome to look at any of the other files, but it should not be necessary and some of them have some pretty byzantine javascript magic.
Similar to Assignment 2, this assignment uses Three.js, the Javascript 3D library. In addition to convenient data structure classes Vector2 / Vector3 / Vector4 / Matrix4 , we will use PerspectiveCamera class from Three.js to represent camera. You may refer to those APIs during your implementations of the features to have a better understanding.
You should submit your solution via CS dropbox here. The submitted zip file should preserve the directory structure of the skeleton code we provided in the zip file above. CS dropbox requires that the size of a single file is below 50MB. You can put a few large files in your own web space / google drive / dropbox and include a link to that in the write-up to save space.
The
writeup.html
file should be an HTML document demonstrating the effects of the features you have implemented and would like scored. For the features you would like to demonstrate, make sure that you include the required results by replacingplaceholder.png(s)
with your results. You are encouraged to include more representative results, but extra results only affect your score when your implementation is partially correct. You don't have to show the input images for the required results.You should start from the the example
writeup.html
provided. At the top of that file are a list of features that you might implement, linking to the section where you talk about them. Please remove any features that you do not implement from the list as well as the corresponding sections, but otherwise leave this header section intact. When you include an extra result, also include a url that creates that image.To save space, please submit images in
png
format.Note that you are expected to use good programming style at all times, including meaningful variable names, a comment or three describing what the code is doing, etc. Partial credit may not be assigned for code without comments. We have mostly tried to conform to the idiomatic JS style conventions.
A few hints:
- Make the flat shader work first! Here is the recommended workflow: perspecitve projection -> bounding box -> barycentric coordinates -> flat shader -> Phong reflection model (you can implement the phong reflection model later than the flat shader bacause the given diffuse term is already good enough for debugging).
- Not all meshes come with uv coordinates or textures. Always check whether those are defined simply by "===undefined". Here is list of optional parameters that you should pay attention to:
- uv coordinates (in "mesh")
- diffuse texture map (in "material")
- specular texture map (in "material")
- XYZ normal map (in "material")
- Look at the example page.
- Post a message to Piazza if you have questions.
- Take note of the late policy and the collaboration policy.
Here are some answers to frequently asked questions. Check back here occasionally, as we may add FAQs to this list:
- How do I add my own meshes or .json files?
The file lists are hardcoded incoursejs/guiConfig.js
because javascript does not have access to the filesystem. Please modify this file when needed.
Some meshes as well textures are downloaded from https://github.com/ssloy/tinyrenderer. COS426 course staff would like to thank the author Dmitry Sokolov for make the very useful test data available.