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