Toon Shading NPR Model Viewer

Jan Lorenz Soliman

For my final project in CPE471 I implemented toon shading, an NPR technique with contour lines to create a silhouette.

Background

Cell shading is a form non-photorealistic rendering that attempts to render 3d objects to look like a cartoon or a comic book. Cell shading calculates smooth lighting for each pixel, but uses discrete shades [2].

For the torus below only uses three shades of blue in the body of the object [3].



Another important aspect of cell shading is silouhette lines. Cell-shading creates an silouhette outline of a 3D object in order to make the rendering look like an illustration. The above torus object shows silouhette lines.

Implementation

I implemented toon shading using GLSL. The bulk of the work occurs in the pixel shader. The first step to figuring out the color at a specific pixel is to calculate the dot product between the pixel normal and light vector.


Source: [4]

Using this dot product, I use a one-dimensional texture map of values to map colors to a specific color. In the example below, dot(n, l) values between 0 and 0.3 will be black, values between 0.3 0.5 will be grey, and anything over 0.5 will be white.


Source: [4]

For example applying these values to the Stanford Dragon using my implementation gives the following image.



In the tutorials I found online, they suggest rendering a model twice to get edge lines to appear. They suggest to render the back faces in wireframe mode, then to render the front faces normally. This is inefficient as the application must render the model twice [1][3]. I attempted to implement edge lines using a technique used to render contour lines [5]. In the pixel shader I calculated the dot(normal, view_vector). When the resulting dot product is 0, my implementation would color the pixel black. A comparison of the two ways of rendering lines is shown below.

Left: One pass using the dot(normal, view)
Right: Two passes rendering the wire frame , then overlaying the model.

I decided to use both. This allow for a more consistant line that captures all of the edges.

I implemented five different modes for my model viewer. The first is just simple contour lines. The second is colored toon shading with contour lines. The third implementation attempts to mimic a black and white comic book style. Screenshots are provided below. The fourth implementation is with color and white highlight lines instead of black. The last is highlight lines with cell shading.

Use

Compile using make.
Run the program using the './toonshader command.' The program will ask for the light position, model color, and model path.
The program looks best viewing the bunny (bunny10k.m) and the dragon(dragon10k.m).

Controls

Mouse
Right Click - Menu for translating, rotating, and scaling.

Keyboard
w,s,a,d - Zoom in/out and strafe left/right.
r - Reset position.
j,l - Move light in positive or negative x.
u,o - Move light in positive or negative y.
i,k - Move light in positive or negative z.
i,k - Move light in positive or negative z.
1 - Change to lines only rendering mode.
2 - Change to cell shading mode.
3 - Change to black and white shading mode.
4 - Change to highlight with color mode.
5 - Change to highlight with cell shading.


Pictures


Outline only



Cell Shading



Black and White Shading



Highlights plus color



Highlights plus Cell Shading




References
[1] NeHe Productions: Cell-Shading
[2] Cell-Shading Explained Visually
[3] OpenGL Cell Shading
[4] Cell-Shading Explained Visually
[5] Suggestive Contours for Conveying Shape