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;
}