surface facehair (string spacename = "shader", ribname = ""; float Kn = 0.1, Kf = 8, len = 0.4, basewidth = 0.006, tipwidth = 0.0001, density = 0.5, neglen = .5) { normal n = normalize(N); color surfcolor = Cs; if(random() > density && ribname != "") { normal nn = normalize(ntransform(spacename, N)); // Used to bias the hair in the 'u' direction vector uBias = normalize(transform(spacename, dPdu)); vector vBias = normalize(transform(spacename, dPdv)); vector bias = vector( (uBias[0] + vBias[0])/2, (uBias[1] + vBias[1])/2, (uBias[2] + vBias[2])/2); point base = transform(spacename, P); point tip = base + nn * len; // Wiggle the mid point float ns = noise(transform(spacename, P) * Kf); ns = ns - 0.5; ns = ns * Kn; point mid = base + (nn * len)/3 + ns; // Handy to see where the hairs are placed surfcolor = color(1,0,0); // Generate the rib file containing the curves (aka hairs) facehair(ribname, base, mid + bias/3, tip + bias, basewidth, tipwidth); } Oi = Os; Ci = Cs * Oi * surfcolor; }