/*
* hextile.sl -- surface shader for hexagonal tiles in st space
*
* DESCRIPTION
* This surface shader operates in s-t space and gives a pattern of
* hexagonal tiles, similar to that found as floor patterns in public
* places and such.
* The basic pattern is a hexagonal tiling, with a little bit of
* color variation from tile to tile. On top of that is some staining
* (presumably due to water or something), which darkens the tile or
* mortar underneath it. Finally, there is scuffing due to people's
* shoes, which really only affects the tile part not the mortar part.
*
*
* PARAMTERS
* Ka, Kd, Ks, roughness, specularcolor - work just like plastic
* tilecolor - the color of the tiles
* mortarcolor - the color of the mortar (space between the tiles)
* tileradius - the "radius" (in s-t units) of a single tile
* mortarwidth - the width of the mortar (in s-t units)
* tilevary - the color variance from tile to tile
*
* ANTIALIASING
* Some rudimentary antialiasing is performed on the borders between
* tile and mortar.
*
* HINTS & APPLICATIONS
* If all of the default parameters are used, the tiles look just like
* the floors in the public areas of the Washington DC subway system.
*
* AUTHOR: written by Larry Gritz, 1994
*
* HISTORY:
* 15 Feb 1994 -- written by lg
*
* last modified 15 Feb 94 by Larry Gritz
*/
#define snoise(x) (2*noise(x)-1)
#define snoise2(x,y) (2*noise((x),(y))-1)
surface
LGHexTile (float Ka = .5;
float Kd = .5;
float Ks = .2;
float roughness = .1;
color specularcolor = 1;
color tilecolor = color(.55,0,0);
color mortarcolor = color(.5,.5,.5);
float tileradius = 0.2;
float mortarwidth = 0.02;
float tilevary = 0.15;
float scuffing = 0.5;
float stains = 0.4;
float stainfrequency = 2;
float scufffrequency = 4;
color scuffcolor = color (.05,.05,.05))
{
point Nf;
color Ct, Ctile;
float tilewidth;
float ss, tt;
float ttile, stile;
float x, y;
float mortar;
float swidth, twidth, sfuzz, tfuzz, fuzzmax;
float mw2;
float tileindex;
float stain, scuff;
float ks;
/* Determine how wide in s-t space one pixel projects to */
swidth = abs(Du(s)*du) + abs(Dv(s)*dv);
twidth = abs(Du(t)*du) + abs(Dv(t)*dv);
sfuzz = 0.5 * swidth;
tfuzz = 0.5 * twidth;
fuzzmax = max (sfuzz, tfuzz);
tilewidth = tileradius * 1.7320508; /* sqrt(3) */
tt = mod (t, 1.5*tileradius);
ttile = floor (t/(1.5*tileradius));
if (mod (ttile/2, 1) == 0.5)
ss = s + tilewidth/2;
else ss = s;
stile = floor (ss / tilewidth);
ss = mod (ss, tilewidth);
mortar = 0;
mw2 = mortarwidth/2;
if (tt < tileradius) {
mortar = 1 - (smoothstep(mw2,mw2+sfuzz,ss) *
(1 - smoothstep(tilewidth-mw2-sfuzz,tilewidth-mw2,ss)));
}
else {
x = tilewidth/2 - abs (ss - tilewidth/2);
y = 1.7320508 * (tt - tileradius);
if (y > x) {
if (mod (ttile/2, 1) == 0.5)
stile -= 1;
ttile += 1;
if (ss > tilewidth/2)
stile += 1;
}
mortar = (smoothstep (x-1.73*mw2-tfuzz, x-1.73*mw2, y) *
(1 - smoothstep (x+1.73*mw2, x+1.73*mw2+tfuzz, y)));
}
tileindex = stile+41*ttile;
Ctile = tilecolor * (1 + tilevary * snoise(tileindex+0.5));
stain = stains * smoothstep (.5,1, noise(s*stainfrequency,t*stainfrequency));
scuff = scuffing * smoothstep (.6,1, noise(t*scufffrequency-90.26,
s*scufffrequency+123.82));
ks = Ks * (1-scuff/2);
Ct = (1-stain) * mix (mix (Ctile, scuffcolor, scuff), mortarcolor, mortar);
Oi = Os;
Nf = faceforward (normalize(N),I);
Ci = Os * ( Ct * (Ka*ambient() + Kd*diffuse(Nf)) +
specularcolor * ks*specular(Nf,-normalize(I),roughness));
}