/* --------------------------------------------------------------------------
 *  'stone' shades objects as though they were made out granular stone
 *  Creates speckles with intensity varying between the surface color
 *  and graincolor.
 *
 *  Ks, Ka, Kd, roughness, specularcolor - the usual meaning
 *  scale - the size in shader space of the stone granules
 *  nshades - the number of intensity levels in the stone
 *  exponent - used to make the distribution come out more toward graincolor
 *  graincolor - the color of the stone grain
 * -------------------------------------------------------------------------- */
surface
stone( float Ks=.9, float Kd=.8, float Ka=.2, float roughness=.3,
	float scale=.02, float nshades=4, float exponent=2,
	    color specularcolor=1, color graincolor=0)
{
    normal Nf;
    vector V;
    float tone;
    color grain;

 /* N and I are not automatically normalized in this implementation. */
    Nf = faceforward( normalize(N), I);
    V = -normalize(I) ;

 /* high-frequency noise */
    tone = noise( transform("shader",P) / scale);
 /* exponent sharpens peaks and pushes average toward darker end */
 /* round chops into nshades different intensity levels */
    tone = round(nshades * pow(tone, exponent)) / nshades;

 /* interpolate between different colors using tone to get speckles */
    grain = mix(graincolor,C,tone);
    C = opacity * (grain * (Ka*ambient() + Kd*diffuse(Nf)) +
    		specularcolor * Ks * specular(Nf,V,roughness) );
}
