/* Renamed shader to PQCrayon for RMR -- tal AT renderman DOT org */ /* crayon.sl - a surface shader making crayon like marks DESCRIPTION This shader makes the surface look as if it had been shaded with a pastel crayon. It makes an attempt at antaliasing. PARAMETERS Ka, Kd, Ks, roughness, specularcolor - work as in the plastic shader txtscale - an overall scaling factor width - the width of the crayon strokes - this is scaled by txtscale micro - the size of the dots that make up a crayon stroke, relative to the size of the stroke. By default they are about 15 times smaller stretch - the length of the stroke relative to its width; density0 - controls the amount of topcolor seen - measured as a proportion - this should vary between 0 (no topcolor) to 1, .3 would give 30% topcolor; density1 - if different density0 this is the density when t = 1, with a smooth interpolation of values for density0 when t = 0, thus allowing a graduation of shading from top to bottom of the object color topcolor, basecolor - the color of the crayon strokes and the color of the ground AUTHOR Peter Quint - Revised Monday, January 10, 2000 */ #define snoise(x,y) ((noise(x,y) - 0.5) * 2) float aanoise(float sp, tp, width) { /* an antaliased noise function, which returns noise of a wavelenth always greater than twice the micropolygon width */ float f, mag, ns; /* calculate smallest integer f for which width / f < .5 */ f = ceil(width /.5); mag = max(pow(0.85, f - 1),.1); /*(printf("f = %f, mag = %f\n",f,mag)*/; ns = mag * snoise(sp / f, tp / f) * (1 - smoothstep(0, .5, width / f)) + snoise(sp / (f * 1.33), tp / (f * 1.33)) * mag * .25 * smoothstep(0, .5, width / f); return ns; } #define MINFILTWIDTH 1.0e-6 #define filterwidth(x) max (abs(Du(x)*du) + abs(Dv(x)*dv), MINFILTWIDTH) surface PQCrayon ( float Ka = 1; float Kd = .5; float Ks = .5; float roughness = .1; color specularcolor = 1; float txtscale = 1; float width = .05; float micro = 15.32; float stretch = 10; float density0 = .5; float density1 = .5; color topcolor = 1; color basecolor = 0; ) { color Csurf; float density = density0 + t * (density1 - density0); /* work out the density for the current t */ float trs = spline(1 - density, 0 , -0.195997, -0.128361, -0.0738346, -0.0316483, 0.00807387, 0.0445915, 0.084543, 0.150693, 0.2198, 0.527474); /* use a spline to read across to the appropriate noise value - this equalisation process is described by Steven Worley in Ch 3 of "Texturing and Modelling a procedural approach */ normal Nf = faceforward (normalize(N),I); float m; float fw = max(filterwidth(s), filterwidth(t)); /* the size of the micropolygon */ float smks = aanoise(txtscale * s * micro / width, txtscale * t * micro / width, txtscale * fw * micro / width); float lmks = (aanoise(txtscale * s / width, txtscale * t / (width * stretch), txtscale * fw / width) + 1) / 2; smks = (smks + 1) / 2; lmks = lmks - smks; m = smoothstep(trs - .1, trs + .3, lmks); m = clamp(m, 0, 1); Csurf = mix(basecolor, topcolor, m); Oi = Os; Ci = Os * ( Csurf * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks*specular(Nf,-normalize(I),roughness)); }