1.Calculate outline by using the dot product of the surface normal and incident vector.
2.Calculate the fill by partitioning the the surface color into 3 distinct regions.
Toon Shader final source:
surface npr_final_toonshader(
float outlineWidth = 0.30;
float outlineOffset = 0.09;
float outlineBlendIn = 0.4;
float outlineBlendOut = 0.05;
float Kd = 0.6;
float region1 = 0.33;
float region2 = 0.66;
color region1color = (0.8,0.4,0.5);
color region2color = (1.0,0.7,0.7);
color region3color = (1.0,0.9,0.9);
float regionBlend = 0.05;
float Ks = 0.45;
float roughness = 0.5;
)
{
normal n = normalize(N);
normal nf = faceforward(n, I);
normal Nn = normalize (-nf);
vextor i = normalize(-I);
color outlineColor = (0,0,0);
//calculate fill color
color difuseColor = 0;
color specularColor = 0;
if(Kd != 0){
difuseColor = diffuse(nf);
difuseColor = fillBlend(difuseColor,regionBlend,
region1, region2,region1color,region2color, region3color) * Kd;
}
if(Ks != 0){
specularColor = specular(nf, i, roughness);
specularColor = fillBlend(specularColor,regionBlend*2,
region1, region2,region1color,region2color, region3color) * Ks;
}
color fillcolor = difuseColor + specularColor;
//calculate outline
float dot = Nn . normalize(I);
if(outlineWidth != 0){
color blendOutline = mix(outlineColor,fillcolor,
smoothstep(outlineWidth,outlineBlendIn,dot));
color offsetEdge = mix(outlineColor,fillcolor,
1-smoothstep(outlineOffset,outlineBlendOut,dot));
fillcolor = blendOutline+offsetEdge;
}
Oi = Os;
Ci = fillcolor;
}
color fillBlend(
color inColor;
float regionBlend;
float region1;
float region2;
color region1color;
color region2color;
color region3color;){
color outColor = 0;
if(comp(inColor, 0) < (region1+region2)/2){
outColor = mix(region1color,region2color,
smoothstep(region1-regionBlend,region1+regionBlend,comp(inColor, 0)));
}else{
outColor = mix(region2color,region3color,
smoothstep(region2-regionBlend,region2+regionBlend,comp(inColor, 0)));
}
return outColor;
}
Toon development with the dog model
Subdivisions model in Maya
Maya Render with one spotlight
Aliased intial version of outline
antialiased version with fill color based on du,dv
Final toon shader applied with default settings
The final shader developed supports 3 separate regions and has diffuse and speculat components taken into consideration when calculating fill color. Image below shows the final slim interface for the toon shader.