Aline Normoyle
Home   Publications   Projects   About  
Pen and Ink Shader

This project implements several pen and ink shading effects using the shading techniques described in

Additionally, this demo draws internal line details and the silhouette outlines to complete the effect.

Results

The following images show sample PLY models with the corresponding halftone texture in the right corner. Click on any of the images to see them in more detail.

apple cow foot sandal

Implementation Details

The shading is implemented in a fragment shader. The shading style is controlled by a user specified halftone texture. For each pixel, we calculate the intensity based on the shaded color value. We then add our halftone color to it and compare the result to a simple threshold function. For example, if the result is binary we do the following:

intensity = .30*color.r + .59*color.g + .11*color.b;
tmpColor = add(textureColor, intensity - 0.5);
outColor = tmpColor <= 0.5? 0 : 1;

In other words, if the brightness of a pixel is below the threshold, the pixel is clamped to black; otherwise, it is clamped to white. This gives harsh, aliased transitions. To achieve a smoother transition, the authors suggest the following modification that naturally antialiases the final result:

tmpColor = add(textureColor, intensity);
outColor = 1 - scaleFactor*(1 - tmpColor);

To create the halftone textures, we can build up the texture in layers of increasing grey called a prioritized stroke texture). Here are several used for this project:

noise hbars hash

The silhouette is drawn using two render passes. In the first pass, the object is expanded along its normals and drawn in black. The shaded object is then drawn in front.

Internal line details are drawn at locations in the model where adjacent faces form a valley or ridge. I can pre-calculate these by testing the angle between adjacent model faces and then drawing the associated edges as lines each frame.

Readme and Code


You can download my pen and ink application from here. To view the README, click here.