/* -------------------------------------------------------------------------- * 'stippled' shades objects as though they were made out of plastic with * lots of little bumps. * This shader makes a fairly good attempt at automatic anti-aliasing. * * Ks, Ka, Kd, roughness, specularcolor - the usual meaning * grainsize - the size in shader space of the granules * stippling - magnitude of speckling intensity variation * -------------------------------------------------------------------------- */ surface grass( float Ks=.3, Kd=.8, Ka=.1, roughness=.3, grainsize=1000, stippling=1000; color specularcolor=1 ) { point V, Nf, Nfake, Ndiddle,PP; float disp, pixelsize, Kflat; color Cstippled,Cflat; /* N and I are not automatically normalized in this implementation. */ Nf = faceforward( normalize(N), I); V = -normalize(I) ; PP = transform("shader",P); /* get a vector pointing in some random direction and add it to normal */ Ndiddle = stippling * (point noise(PP / grainsize) - .5); Nfake = normalize(Nf + Ndiddle); Cstippled = Os * (Cs * (Ka*ambient() + Kd*diffuse(Nfake)) + specularcolor * Ks * specular(Nfake,V,roughness) ); /* anti-alias by mixing between flat color and stippled color as pixels */ /* get small */ pixelsize = sqrt(area(PP)); Oi = Os; if (grainsize >= pixelsize) { if (pixelsize >= 0) { Ci = Cstippled; } Cflat = Os * (Cs * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks * specular(Nf,V,roughness) ); Ci = mix(Cflat,Cstippled,smoothstep(0,1,grainsize/pixelsize)); } else { /* calculate flat color to shade toward for anti-aliasing */ Cflat = Os * (Cs * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks * specular(Nf,V,roughness) ); Ci = mix(Cflat,Cstippled,smoothstep(0,1,grainsize/pixelsize)); } }