Cel shading is a shader technique that gives a cartoony or hand-drawn effect to a scene. It does this by averaging the colour on certain sections of the model. This is often combined with lighting calculations to achieve dynamic shading on a model.
Here is an example of cel shading on a model. The picture below is a normal mapped head with per fragment lighting.
You can definitely see certain contrasts in the brightness changes on the model. However, the lighting seems very smooth across the model.
Here is the same head, with a cel shader applied to it.
As you can see, the lighting on the head has been broken down in to 5 sections of intensity.
To achieve this effect, you first need to calculate your lighting. Take a look at my object space normal mapping blog if you want to see how to calculate per fragment lighting. Once you have calculated your specular, diffuse, and ambient lighting, add the 3 together and save that value as your intensity variable.
float intensity = ambient + diffuse + specular;
Now we need to set a limit on the intensity, in order to get those heavy brightness changes.
if(intensity > 1.0) intensity = 1.0;
else if(intensity > 0.75) intensity = 0.75;
else if(intensity > 0.5) intensity = 0.5;
else if(intensity > 0.25) intensity = 0.25;
else intensity = 0.1;
As you can see, we are cutting out the middle brightness values between each intensity. The only intensity values are going to be 1, 0.75, 0.50, 0.25, and 0.10.
Now, factor your intensity value in to your final colour output.
vec3 final = texture_colour * intensity;
gl_FragColor.rgb = final;
And you're done! Thanks for reading.
For a list of some video games that use Cel Shading, check out: http://en.wikipedia.org/wiki/List_of_cel-shaded_video_games