Cartoon Rendering

Ioannis Giotis and Daniel Hasselrot

CSE 557 final project

 

 

Figure1:1

 

 

Figure2: Here piggy... A dark shaded pig

 

 

Introduction:

For our final project we implemented an OpenGL cartoon renderer.  Cartoon rendering falls into the category of Non-Photorealistic Rendering and has been of interest in the last few years in computer graphics and game development. Our goal was to produce a simple animator that could “cartoonize” 3d models with no additional information from the user. We also used acceleration techniques to achieve smooth frame rates even in complex models.

 

Implementation:

The main characteristics of cartoon rendering are cartoon shading and cartoon edges. Cartoon shading can be performed by using a minimal number of colors (usually only 2) and applying those colors to perceive shadows in a simple yet very effective way. Cartoons are also filled with additional edges that were either a by-product of early cartoon production or are there to emphasize scene characteristics. Crease edges are there to provide a “highlight” effect, while silhouette edges highlight and define a character from the background.

Cartoon shading:

 

 

The cartoon shading is implemented by using an 1-dimensional texture as an look-up table for the shading. The texture coordinate is set buy taking the unit product between the vector from the light to the vertex and the vertex normal. The usual way to set up the texture is by just using an 2-pixel wide texture containing the shadow color and the highlight color. Bi-linear interpolation is turn off cause otherwise unwanted smearing of the colors will occur and the boundary between the shadow region and the highlighted region will be blurred.

 

What we do is instead of just using an 2-pixel wide texture we use an 1024-pixels wide texture with just two colors. In the boundary between the two colors we do an linear interpolation and apply that to the texture. This actually gives a much nicer impression of the shading giving it an anti-aliased look and still works on all graphics cards. One option would be to turn on bi-linear interpolation instead of doing the interpolation on the texture. In theory this should give the same result but at least when we tried it it looked worse maybe due to some factor when doing bi-linear interpolation on a 1-dimensional texture.

 

 

"Anti-aliased" shading

Cartoon edges:

Crease edges:

To check for crease edges, we perform a simple check of the angle between the faces of adjacent polygons. If that angle is greater than a predefined threshold we draw the edge. This can be expressed as an upper bound on the dot product of the normals.

 

                                 

 

Figure3: Crease edegs in action

Silhouette edges:

To determine silhouette edges we have to figure out the pairs of polygons where one is facing towards the camera and the other one is facing backwards. In the first step, we go through all the edges and determine which of those are silhouette edges by evaluating the following formula.

                

            A simple working solution can now be implemented by going through all the edges and drawing the ones that satisfy the above constraint.

 

However, in order to achieve acceleration on complex scenes we implemented a different approach. First, we perform a conversion to 4d space. For the camera vector we set the 4th coordinate 1 if the vector is a scene point or 0 if it’s a directional vector. Then, we represent each polygon face by its plane equation . A front face will have the dot product  evaluated to a positive value while a back face to a negative value. Silhouette edges are found in the edges of faces where the two planes evaluate to different signed valued.

 

To find those edges fast, we store each edge in a 4D octree. Each node of the octree is associated with a bounding box to specify the points included in that node. The initial node of the tree contains points from  to . Each edge is inserted in a node that contains both of its plane end points (normalized). When a predetermined amount of edges in a node is reached then that node is split into 16 children nodes by splitting each coordinate respectively. This simple octree structure will hold all candidate silhouette edges in the end.

 

At runtime, we traverse through this tree and we only explore those bounding boxes that their dot products with the eye vector give different signed values. While theoretically this does not necessarily guarantee a great improvement, practically very few of the tree nodes are explored, resulting in a speed improvement when used in complex models.

 

Figure4: Silhouette edges in action

 

Figure5: Again, silhouette edges in our hippo

Discussion/Issues:

Overall the project was fun and rewarding. The keys issues and difficulties we encountered are discussed below.

 

           

Octree as implemented with fixed object and depth thresholds requires a per-model customization on these values to achieve optimal results. Therefore, you have to have either an idea of the number of triangles in a model or use a simple counter (as we did) to figure out good threshold values. One can easily solve that by inserting a simple formula to figure out those threshold and updating them when loading the model. Something that should also be mentioned is that when animating a model we would have to update the octree to correctly represent the new edge normals.

 

 

Sometimes we “lose” some of the silhouette edges due to the fact that the edge is lost just behind the triangle under the downsampling performed to visualize the final frame. This seems more tricky to solve because we would probably need to add non-existing edges to help visualize the silhouette. An alternative would be to make those edges wider.

 

Something that should also be mentioned is that when animating a model we would have to update the octree to correctly represent the new edge normals.

 

Readings:

 

-Stylized Rendering Techniques For Scalable Real-Time 3D Animation

Adam Lake Carl Marshall Mark Harris† Marc Blackstein

 

-Fast 3D Cartoon Rendering with Improved Quality by

Exploiting Graphics Hardware

Johan Claes, Fabian Di Fiore, Gert Vansichem, Frank Van Reeth