After careful examination of the article, I found, that implementing this technique for N64 graphics plugin is VERY simple, unless I miss something important. All lighting calculations are already done as described in the article, so the only thing we should do is to use a value from the Sharp Lighting Map instead of light’s color.
Cite from Cel-Shading Textures section:
1. Load the Sharp Lighting map from file and store in an array (remember to convert values to a range of 0-1).
2. Calculate the lighting as normal, but multiply the dot product by the width of the texture - 1 (remember 0-15), and cast it to an integer.
3. When drawing, lookup the color to use in the Sharp Lighting map array, using the lighting value as the index.
4. Use this value for the red, green and blue values of the vertex color.
5. Render the object like you would normally, but remember to update the color for each vertex. Don't forget to disable lighting, etc.
Here is my code:
//Load the Sharp Lighting map from file and store in an array
BYTE shade_light_map[16] = {90, 90, 90, 180, 180, 180, 180, 180, 255, 255, 255, 255, 255, 255, 255, 255};
void calc_celshade_light (VERTEX *v)
{
float light_intensity = 0.0f;
//Calculate the lighting as normal
for (DWORD l=0; l<rdp.num_lights; l++)
{
float dp = DotProduct (rdp.light_vector[l], v->vec);
/*if we have another light lighting that vertex, you compare the existing lighting value with the newly created one. If the new light value is higher, then replace the existing one with that. If it's darker, then ignore it. That's just another stupidly simple trick that will make your scene look nicer*/
if (dp > light_intensity)
light_intensity = dp;
}
if (light_intensity > 1.0f)
light_intensity = 1.0f;
// multiply the dot product by the width of the texture - 1 (remember 0-15), and cast it to an integer.
int index = (int)(light_intensity * 15.0f);
// When drawing, lookup the color to use in the Sharp Lighting map array, using the lighting value as the index.
// Use this value for the red, green and blue values of the vertex color.
v->r = v->g = v->b = shade_light_map[index];
//Now Render the object like you would normally
}
Just call it instead of standard calc_light, and you will get your cel-shading.
This can be implemented with any plugin, 5 min of work.
Currently it looks terrible. Sometimes it looks like good cel-shading, but most of time it looks like khaki – all in dark and light spots.
It’s just a test. You may adjust brightness by changing values in the light map array. You may make it less sharp. Also, this cel-shading probably will look better with outlines, which I did not implement.
And of course, I might just miss something.