/* @(#)carpet.sl 1.1 (Pixar - RenderMan Division) 10/10/89 */ /*-______________________________________________________________________ ** ** Copyright (c) 1989 PIXAR. All rights reserved. This program or ** documentation contains proprietary confidential information and trade ** secrets of PIXAR. Reverse engineering of object code is prohibited. ** Use of copyright notice is precautionary and does not imply ** publication. ** ** RESTRICTED RIGHTS NOTICE ** ** Use, duplication, or disclosure by the Government is subject to the ** following restrictions: For civilian agencies, subparagraphs (a) through ** (d) of the Commercial Computer Software--Restricted Rights clause at ** 52.227-19 of the FAR; and, for units of the Department of Defense, DoD ** Supplement to the FAR, clause 52.227-7013 (c)(1)(ii), Rights in ** Technical Data and Computer Software. ** ** Pixar ** 3240 Kerner Blvd. ** San Rafael, CA 94901 ** ** ______________________________________________________________________ */ /*------------------------------------------------------------------------- * carpet - creates a carpeted surface with variable nap and scuffing. * Makes a reasonable attempt at anti-aliasing. * * Kd, Ka - the usual meaning * scuff - the "amount of scuffing": footprints, vacuum cleaner marks, * etc. (the relative frequency of intensity variation) * nap - the "shagginess" of the carpet (size of the speckles) *-------------------------------------------------------------------------*/ surface carpet( float Kd=.6, Ka=.1, scuff = 1, nap = 1) { varying point Nf, PP; varying float pixelsize, twice, scale, weight, turbulence, napfreq, speckle, mottling; Nf = faceforward( normalize(N), I); /* large-scale mottling */ if (scuff==0) mottling = 1; else { /* get pixel size */ PP = transform("shader",P) * scuff; PP = PP/2; /* frequency adjustment (S-shaped curve) */ pixelsize = sqrt(area(PP)); twice = 2 * pixelsize; /* create some turbulence */ turbulence = 0; for (scale = 1; scale > twice; scale /= 2) { turbulence += scale * abs(noise(PP/scale)-0.5); } /* gradual fade out of highest frequency component near limit */ if (scale > pixelsize) { weight = (scale / pixelsize) - 1; weight = clamp(weight, 0, 1); turbulence += weight * scale * abs(noise(PP/scale)-0.5); } /* scuffing will be between 0.5 and 1 */ mottling = min(turbulence+0.5, 1); } /* small-scale speckling */ if (nap==0) speckle = 1; else { /* get high-frequency speckles */ napfreq = nap/100; /* scale up speckle frequency */ speckle = noise(transform("shader",P)/napfreq); speckle = speckle * speckle; /* two-level speckles */ speckle = (speckle <= 0.25) ? 0.2 : 1; /* smooth out speckles as they get smaller */ pixelsize = sqrt(area(transform("shader",P))); if (speckle<1) speckle = (1-smoothstep(0,1,napfreq/pixelsize)) *(1-speckle) + speckle; } /* get color */ Oi = Os; Ci = Os * Cs * mottling * speckle * (Ka*ambient() + Kd*diffuse(Nf)); }