15-462 Programming Assignment 4: Toon Shading

Due Saturday December 6, 11:59pm

Overview

In this assignment, you will be writing shaders to render objects using Phong shading and Toon shading.

Shaders are powerful tools that enable programs to skip the traditional Fixed Function Pipeline in favor of the more powerful Programmable Pipeline in rendering objects to the screen.

At the end of this assignment, your shaders should minimally be able to render a perfectly Phong shaded torus, as well as give a good approximation in rendering the same torus with toon shading. Given the difficulty of setting up GLSL, advanced starter code has been provided for you that performs most of the set up; all you are required is to code up the shaders, as well as add any other objects and contexts as you see fit.

You will be writing your shaders in GLSL, which is a shading language supported by OpenGL 2.1 and above.

Vertex and Pixel shaders

Vertex shaders give per-vertex control. In short, they modify each vertex based on a fixed algorithm and affect every vertex processed while activated. The input position of the vertex is given by the vector gl_Vertex, and the final position of the vertex is determined by the vector gl_Position, which the vertex shader must set.

Pixel shaders, which are also sometimes known as fragment shaders, give per-pixel control. They affect the color of each pixel rendered to the screen. The color of the pixel is simply determined by the value of the vector gl_FragColor, which the pixel shader is supposed to set.

Note that the shader variables listed above are not the only ones you can set. (and certainly not the only ones you should set!)

A full list of vertex and pixel shader variables can be found here [2].

GLSL shader basics

The first thing you should look at are the shader files vs_phong.glsl, ps_phong.glsl, and ps_toon.glsl.

vs_phong.glsl and ps_phong.glsl represent the vertex and pixel shaders for phong shading and ps_toon.glsl represents the pixel shader for toon shading.

Looking into any of the files, take note of what seems to be “global” variables in the file.

Apart from their type (eg. float, vec4, etc.), they are preceded by a keyword uniform or varying.

The uniform keyword implies that GLSL expects the variable to be bound via the glGetUniformLocationARB and glUniform… functions in the program. The variable can then be used throughout the shader.

The varying keyword implies that GLSL expects the variable to be set by the vertex shader. This variable in turn can be read by the pixel shader. Note that this is one of the ways in which the vertex shader can ‘pass’ arguments or variables over to the pixel shader.

The shader itself is declared in a function void main, with code which is very similar to C.

An entire list of functions and their descriptions is listed in the GLSL specification file [3] released by the Khronos group.

Phong shading

In vs_phong.glsl, note that varying variables phong_diffuse, phong_specular, phong_edge have been declared for you.

To implement phong shading, you will need to calculate the value of phong_diffuse and phong_specular. The ambient component will not be used here to give a better approximation to actual lighting.

Using the Phong Illumination Equation covered in class, calculate the value of these 2 variable. Note that both variables are floats – GLSL does type-checking and will give an error if you assign them to the wrong type.

Hint: What other information might you need? Positions of the light? Camera? Maybe they should be passed to the program via additional uniforms.

ps_phong.glsl has already been completed for you. Note that it simply calculates the phong lighting components on the material by doing an inner product (similar to that when you did in your ray tracer), then sums them up to give the illumination from phong lighting. The value of the material uniforms has already been set for you by the starter code.

Toon Shading

Toon shading consists of mapping colors to a staggered color space. Imagine what it looks like when normal shading maps colors linearly, RGB(n,n,n) maps to RGB(n,n,n). In toon shading, we want colors to map non-linearly and have a visible break as it crosses over certain boundaries. Now imagine if RGB(r,g,b) maps to RGB(50, 50, 50) for all r < 100 and maps to RGB(200, 200, 200) for all r >= 100.

We would then have a rudimentary sort of toon shading. Note that this only uses one transition boundary – you should use more than one and customize to give an effect which you find to be aesthetically pleasing.

This mapping can be done by procedurally generating a texture in OpenGL via glTexImage1D, (use a 1D texture for simplicity’s sake) and using the tex1D pixel shader instruction to grab the corresponding color from the texture.

Different textures should be used for diffuse, specular and edges for best effect.

Edges are highlighted to give a more cartoon-ish look to the scene.
To calculate phong_edge, the equation below might be useful:

The ‘toon’ program

The objective of the program is to have 2 objects rendered side by side – the left rendered via the phong shader and the right rendered via the toon shader. The object being rendered can be toggled between a torus and a teapot via the right click menu.
Basic starter code has already been provided for you, with basic GLSL shaders set up to render a torus and a teapot via the programmable pipeline.

The image below shows what the program looks like when run raw after compiling the starter code.

15462_p4_scrshot2.jpg

Fig 1.1 Starter Code

In the starter code, the phong vertex shader returns arbitrary values for the phong lighting components (please change them!) and the toon pixel shader returns the color red - vec4(1.0, 0.0, 0.0, 1.0).

You will be required to implement the shaders to render the objects correctly by modifying vs_phong.glsl and ps_toon.glsl as described in the earlier paragraphs.

The video below shows sample output from rendering an implementation of the phong and toon shaders with a single light directly behind the camera.
Note the visible color banding in the toon shaded version of the torus and the teapot.

  

Implementation

Starter Code

Starter code in C/C++, a Makefile, and some useful libraries can be accessed at http://www.cs.cmu.edu/~462/projects/p4/p4-starter.tar.gz [1].

The starter code is intended to provide you with an appropriate set up for ease of coding the necessary functions. You may find some parts of the program to be unnecessary or inefficient to your program. In that case, please feel free to change or remove them.

You will need to implement all the parts which have a TODO comment tag.
A helpful command to execute would be ‘
% grep -r "TODO" .

It is imperative that you comment your vertex and pixel shaders profusely.
This shows that you have implemented the shaders to do what you want.
As such, shader comments represent 40% of the shader grading component.

There is no need to submit readme.txt – instead, place your comments and instructions in the header of each file that you submit. The headers should be written in a format for Doxygen documentation – see toon.cpp for a sample. Unless otherwise specified, toon.cpp should contain the core instructions of how the program should be run and a description of your designs and implementations.

DO NOT CHEAT and hand in on time. Cheating immediately gives you 0% for the assignment and you will be subject to the university’s cheating policies.

Grading Criteria

Your program must:

Submission

Please submit your code along with your Makefile to your hand-in directory. Fill in the header of toon.cpp to explain what you have completed, what problems you have encountered and how you solved them, and a description of your extra credit work. Also place your TIFF screenshots inside the subdirectory images. Your handin folder is at '/afs/cs.cmu.edu/academic/class/15462-f08-users/<your_andrew_id>/p4'. The folder has already been created for you. When we run "make" in this directory it should compile your program successfully. In this assignment we shall be strict about this policy. An assignment that does not compile successfully shall receive no points.

If you experience any difficulty with the hand-in directory, please email a tar.gz of your submission to one of the TAs. The time of submission will be determined by the time the email arrives at the final mail server (i.e. MAILXX.ANDREW.CMU.EDU).

For scp/sftp users: since the handin directory resides on SCS AFS network, your username on the directory is actually "<username>@ANDREW.CMU.EDU", not just "<username>". To transfer your submission to the handin directory, please scp/sftp as "<username>@ANDREW.CMU.EDU" via weh5336-?.intro.cs.cmu.edu.

Tips

Extras

Credits are given based on the difficulty, technicality, and creativity. It will be harder to earn extra credit in this assignment. Please list all of your extra work in the writeup.txt file. The maximum assignment point you can earn is 110%. Here are some suggestions for extra credit ideas:

Note: If you do this, make sure that it is a side option and the default screen that is rendered when the program is started should be that of the 2 toruses.

Other cool things will get extra credit as well (talk to the TAs before you actually implement it).

Links

[1] Starter code 
[2] 
OpenGL Shading Language (GLSL) Quick Reference Guide
[3] 
OpenGL Shading Language v 1.20

Writeup, Code by Alexander Chia
Mirror