OSL Toon Shader

For this project, we have to create a shader with OSL which is the Open Shading Language, so I created a toon shader. The issue I encountered was that I didn’t know how to get information from the light t calculate shadow. Therefore, I created a parameter to input the position of the light in order to add shadow.

Here is my OSL code for creating the toon shader:

shader toon(
    // Checkerboard
    color Base = color(1,1,0),
    color Dot = color(0,1,1),
    color Line = color(0,0,0),
    float Radius = 1            [[float min = 0, float max = 10]],
    float Blur = 0              [[float min = 0, float max = 10]],
    float Repeat = 1            [[float min = 0, float max = 10]],
    float resx = 0              [[float min = 0, float max = 2000]],
    float resy = 0              [[float min = 0, float max = 2000]],
    
    // Toon Shader
    float edge_width = 0.1      [[float min = 0, float max = 1]],
    float edge_gradient = 0   [[float min = 0, float max = 1]],
    
    //Halftone grid
    //Light Position
    float L_Posx = 0            [[float min = -1, float max = 1]],
    float L_Posy = 0            [[float min = -1, float max = 1]],
    float L_Posz = 0            [[float min = -1, float max = 1]],
    float hl = 0.8              [[float min = 0, float max = 1]],
    float grid_gradient = 0.5   [[float min = -1, float max = 1]],
    float amp = 1               [[float min = 0, float max = 5]],
    
    output color resultColor = 0,
    output color resultMask = 0,
    output color resultEdge = 0
)
{

    color black = color(0,0,0);
    color white = color(1,1,1);

    // Toon Edge Mask
    // Normalized i and n
    vector i = normalize(I);
    vector n = normalize(N);
    // Use Dot Product to Get Value from 0 - 1 Base on the Angle Facing the Camera
    float d = abs(dot(i,n));
    if (d < 0)
        d = 1;
    // Adjust the Width of the Edge
    if (d < edge_width)
        d = 0;
        d = smoothstep(edge_gradient, 1.0, d);
    color edge_color = mix(Line, Base, d);
    color edge_bw = mix(black,white,d);
    
    
    // Halftone Mask
    // Get Light I
    vector lighti = vector (-L_Posx,-L_Posy,-L_Posz);
    lighti = normalize(lighti);
    // Calculate the facing ratio to the light
    float lightd = dot(-lighti,n);
    lightd =  lightd * 0.5 + 0.5;
    // Create the Gradient
    if (lightd > hl)
       lightd = 0;
    else
       lightd = (1 - smoothstep(grid_gradient,1.0,lightd)) * amp;
       
       
    // Circle Texture
    // Set Screen Space
    point pnt = transform("raster",P);
    float pnt_x = pnt[0];
    float pnt_y = pnt[1];
    // Create Repeat Pattern
    float repeat = Repeat * 0.1;
    float pnt_xx = mod(pnt_x * repeat,1);
    float pnt_yy = mod(pnt_y * repeat,1);
    // Point Position
    point ppos = point(pnt_xx,pnt_yy,0);
    //point center = point(resx/2,resy/2,0);
    point center = point(0.5,0.5,0);
    float dist = distance(center,ppos);
    float grid = smoothstep((Radius - Blur) * lightd, (Radius + Blur) * lightd, dist);
    
    
    // OUTPUT
    resultColor = mix(Dot,Base,grid) * edge_color;
    resultMask = mix(black,white,grid) * edge_bw;
    resultEdge = edge_bw;    
}