home *** CD-ROM | disk | FTP | other *** search
/ Stone Design / Stone Design.iso / Stone_Friends / Wave / WavesWorld / Source / Shaders / WWShaders / WWCinderBlock.sl < prev    next >
Encoding:
Text File  |  1995-04-23  |  4.7 KB  |  137 lines

  1. /*
  2.  * WWCinderBlock.sl -- a surface (and fake displacement) shader for cinder block walls.
  3.  *
  4.  * DESCRIPTION:
  5.  *   This is a surface shader which combines a matte shader and 
  6.  *   Larry Gritz's brick displacement shader.  It makes nice cinder
  7.  *   block walls, just like I had in my Media Lab office.  I wrote
  8.  *   this because when I did a a real displacement shader coupled with
  9.  *   a surface shader, I always got cracks in my wall when I used a 
  10.  *   renderer that did real displacement (i.e. prman).
  11.  * 
  12.  * PARAMETERS:
  13.  *    brickwidth                Width of a brick (in st space)
  14.  *    brickheight               Height of a brick (in st space)
  15.  *    mortarthickness           Thickness of the mortar (in st space)
  16.  *    rowvary                   How much does each row shift?
  17.  *    jagged                    How much do bricks deviate from squares?
  18.  *    pitting                   The amplitude of the "pits" on the face of
  19.  *                                 the bricks.
  20.  *    pockfrequency             The st frequency of the pits.
  21.  *    groovedepth               The depth of the grooves between bricks.
  22.  *
  23.  * AUTHOR: written by Larry Gritz, 1992, transmuted by wave in 1994
  24.  *
  25.  * HISTORY:
  26.  *      28 May 1992 -- written by lg for the "Timbre Trees" video (saucer)
  27.  *      12 Jan 1994 -- recoded by lg in correct shading language.
  28.  *      8  Dec 1994 -- hacked unmercifully by wave
  29.  *      10 Jan 1995 -- changed defaults
  30.  *      23 Apr 1995 -- changed comments
  31.  *
  32.  * last modified  23 Apr 1995 by wave
  33.  */
  34.  
  35. surface
  36. WWCinderBlock (float Ka    = .7; 
  37.            float Kd    = .7;
  38.                float jagged = 0.006;
  39.               color brickcolor = color "rgb" (1, 1, .82);
  40.            color mortarcolor = color "rgb" (1, 1, .82);
  41.                float brickwidth = .3, brickheight = .15;
  42.            float mortarthickness = .01; 
  43.                float brickvary = 0.15;
  44.            float rowvary = .01, pitting = 0.03;
  45.            float pockfrequency = 15, groovedepth = 0.025; )
  46. {
  47. #define BMWIDTH (brickwidth+mortarthickness)
  48. #define BMHEIGHT (brickheight+mortarthickness)
  49. #define MWF (mortarthickness*0.5/BMWIDTH)
  50. #define MHF (mortarthickness*0.5/BMHEIGHT)
  51. #define snoise(x) (2 * noise((x)) - 1)
  52. #define boxstep(a,b,x) (clamp(((x)-(a))/((b)-(a)),0,1))
  53. #define sqr(x) ((x)*(x))
  54. #define MINFILTERWIDTH 1.0e-7
  55.   point PP2, tmpP;
  56.   float sbrick, tbrick, w, h;
  57.   float scoord, tcoord, ss, tt;
  58.   float fact, disp;
  59.   point Nf;
  60.   float swidth, twidth;
  61.   color bcolor, Ct;
  62.  
  63.   /* Determine how wide in s-t space one pixel projects to */
  64.   swidth = max (abs(Du(s)*du) + abs(Dv(s)*dv), MINFILTERWIDTH);
  65.   twidth = max (abs(Du(t)*du) + abs(Dv(t)*dv), MINFILTERWIDTH);
  66.  
  67.   scoord = s;  tcoord = t;
  68.  
  69.   /* Make the shapes of the bricks vary just a bit */
  70.   PP2 = point noise (s/BMWIDTH, t/BMHEIGHT);
  71.   scoord = s + jagged * xcomp (PP2);
  72.   tcoord = t + jagged * ycomp (PP2);
  73.  
  74.   ss = scoord / BMWIDTH;
  75.   tt = tcoord / BMHEIGHT;
  76.  
  77.   /* shift alternate rows */
  78.   if (mod (tt*0.5, 1) > 0.5)
  79.       ss += 0.5;
  80.  
  81.   tbrick = floor (tt);   /* which brick row? */
  82.   /* Shift the columns randomly by row */
  83.   ss += rowvary * (noise (tbrick+0.5) - 0.5);
  84.  
  85.   sbrick = floor (ss);   /* which brick column? */
  86.   ss -= sbrick;          /* Now ss and tt are coords within the brick */
  87.   tt -= tbrick;
  88.  
  89.   fact = 1;
  90.   disp = 0;
  91.   if (tt < MHF) {
  92.       /* We're in the top horizontal groove */
  93.       disp = groovedepth * (sqr((tt)/MHF) - 1);
  94.     }
  95.   if (tt > (1.0-MHF)) {
  96.       /* Bottom horizontal groove */
  97.       disp = groovedepth * (sqr((1-tt)/MHF) - 1);
  98.     }
  99.   if (ss < MWF) {
  100.       disp = 0.75 * groovedepth * (sqr(ss/MWF) - 1);
  101.     }
  102.   if (ss > (1.0-MWF)) {
  103.       disp = 0.75 * groovedepth * (sqr((1-ss)/MWF) - 1);
  104.     }
  105.  
  106.   fact = smoothstep (0, 1.3*MHF, tt) - smoothstep (1.0-1.3*MHF, 1, tt);
  107.   fact *= (smoothstep (0, 1.3*MWF, ss) - smoothstep (1.0-1.3*MWF, 1, ss));
  108.   fact = pitting * (0.75 * fact + 0.25);
  109.   disp -= fact * pow(noise ((ss+sbrick)*pockfrequency/BMHEIGHT,
  110.                     (tt+tbrick)*pockfrequency/BMWIDTH), 0.25);
  111.  
  112.   tmpP = P + (disp * normalize(N));
  113.   /* okay, we perturb the normal, but not the real point, so we can't see through the wall... */
  114.   N = calculatenormal(tmpP);
  115.   Nf = faceforward(normalize(N),I);
  116.  
  117.   /* Choose a color for the surface */
  118.   if (swidth >= 1)
  119.       w = 1 - 2*MWF;
  120.   else w = clamp (boxstep(MWF-swidth,MWF,ss), max(1-MWF/swidth,0), 1)
  121.      - clamp (boxstep(1-MWF-swidth,1-MWF,ss), 0, 2*MWF/swidth);
  122.  
  123.   if (twidth >= 1)
  124.       h = 1 - 2*MHF;
  125.   else h = clamp (boxstep(MHF-twidth,MHF,tt), max(1-MHF/twidth,0),1)
  126.      - clamp (boxstep(1-MHF-twidth,1-MHF,tt), 0, 2*MHF/twidth);
  127.  
  128.   /* Choose a brick color that varies from brick to brick */
  129.   bcolor = brickcolor * (1 + (brickvary * snoise (tbrick+(100*sbrick)+0.5)));
  130.  
  131.   Ct = mix (mortarcolor, bcolor, w*h);
  132.  
  133.  
  134.   Oi = 1;
  135.   Ci = Ct * ( Ka*ambient() + Kd*diffuse(Nf) ) ;
  136. }
  137.