Renderman Shaders

Non-Photorealistic Rendering

Independent Research by Mayilan Krishnamoorthy

(VSFX 785-02 Prof.Malcolm Kesson)

 

Toon Shader

Basic Structure

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.

Toon shader imported into Slim palette(below)


Toon shader on an animated character


 

mayilan krishnamoorthy mayilan@gmail.com