/*
* brick.sl -- Surface shader for a bricks.
*
* DESCRIPTION:
* Makes a wall of bricks. Need more be said? OK. It makes a good
* looking staggered brick masonry. It is especially convincing when
* used in conjunction with the "brickbump" displacement shader (and
* identical parameters). Every other row of bricks is staggered.
* The staggering isn't exact, however, and this variance is controlled
* by the "rowvary" parameter.
*
* PARAMETERS:
* Ka, Kd The usual
* brickcolor, mortarcolor Pretty obvious (default is red bricks)
* brickvary How much does the brick color vary from
* brick to brick?
* brickwidth Width of a brick (in st space)
* brickheight Height of a brick (in st space)
* mortarthickness Thickness of the mortar (in st space)
* rowvary How much does each row shift?
* jagged How much do bricks deviate from squares?
*
* AUTHOR: written by Larry Gritz, 1992
* This shader is very similar to (and based upon) brick shaders
* by Darwyn Peachey.
*
*
* HISTORY:
* 28 May 1992 -- written by lg for the "Timbre Trees" video (saucer)
* 12 Jan 1994 -- recoded by lg in correct shading language.
*
* last modified 12 Jan 1994 by Larry Gritz
*/
surface
LGBrick ( float Ka = 1, Kd = 1;
color brickcolor = color "rgb" (.6,.1,.1);
color mortarcolor = color "rgb" (.6,.6,.6);
float jagged = 0.006, brickvary = 0.3;
float brickwidth = .25, brickheight = .08;
float mortarthickness = .01;
float rowvary = .25; )
{
#define BMWIDTH (brickwidth+mortarthickness)
#define BMHEIGHT (brickheight+mortarthickness)
#define MWF (mortarthickness*0.5/BMWIDTH)
#define MHF (mortarthickness*0.5/BMHEIGHT)
#define snoise(x) (2 * noise((x)) - 1)
#define boxstep(a,b,x) (clamp(((x)-(a))/((b)-(a)),0,1))
#define MINFILTERWIDTH 1.0e-7
color bcolor, Ct;
point PP2, Nf;
float sbrick, tbrick, w, h;
float scoord, tcoord, ss, tt;
float swidth, twidth;
float Nfactor;
/* Determine how wide in s-t space one pixel projects to */
swidth = max (abs(Du(s)*du) + abs(Dv(s)*dv), MINFILTERWIDTH);
twidth = max (abs(Du(t)*du) + abs(Dv(t)*dv), MINFILTERWIDTH);
Nf = faceforward (normalize(N),I);
/* Make the shapes of the bricks vary just a bit */
PP2 = point noise (s/BMWIDTH, t/BMHEIGHT);
scoord = s + jagged * xcomp (PP2);
tcoord = t + jagged * ycomp (PP2);
ss = scoord / BMWIDTH; /* Determine which brick the point is in */
tt = tcoord / BMHEIGHT; /* " */
swidth /= BMWIDTH;
twidth /= BMHEIGHT;
/* shift alternate rows */
if (mod (tt*0.5, 1) > 0.5)
ss += 0.5;
tbrick = floor (tt); /* which brick row? */
/* Shift the columns randomly by row */
ss += rowvary * (noise (tbrick+0.5) - 0.5);
sbrick = floor (ss); /* which brick column? */
ss -= sbrick; /* Now ss and tt are coords within the brick */
tt -= tbrick;
/* Choose a color for the surface */
if (swidth >= 1)
w = 1 - 2*MWF;
else w = clamp (boxstep(MWF-swidth,MWF,ss), max(1-MWF/swidth,0), 1)
- clamp (boxstep(1-MWF-swidth,1-MWF,ss), 0, 2*MWF/swidth);
if (twidth >= 1)
h = 1 - 2*MHF;
else h = clamp (boxstep(MHF-twidth,MHF,tt), max(1-MHF/twidth,0),1)
- clamp (boxstep(1-MHF-twidth,1-MHF,tt), 0, 2*MHF/twidth);
/* Choose a brick color that varies from brick to brick */
bcolor = brickcolor * (1 + (brickvary * snoise (tbrick+(100*sbrick)+0.5)));
Ct = mix (mortarcolor, bcolor, w*h);
Oi = Os;
Ci = Os * Ct * (Ka * ambient() + Kd*diffuse(Nf));
}