/* $Revision: 1.0 $ */
/*-
**  Kbtiledisp is meant to be used with with kbtile to create
**  Kitchen and Bath Tiles.
**  It will displacement for the grout grid which will be a negative value
**  It will produce wavey bumps that will part of each tile as positve
** 
**  This draws upon samples of code from Textures and Pocedures 
**  RenderMan Notes - How to create an anti-aliad grid.
** ________________________________________________________________
*/
#define pulse(a,b,fuzz,x) (smoothstep((a)-(fuzz),(a),(x)) - \
			   smoothstep((b)-(fuzz),(b),(x)))
#define repeat(x,freq)    (mod((x) * (freq), 1.0))
#define union(a,b)        ((a) + (b) - (a) * (b))
#define blend(a,b,x) ((a) * (1 - (x)) + (b) * (x))

displacement
kbtiledisp ( float Km = 1;
             float scale = 1.0;
             float groutscale = 2.0;
	     float sfrequency  = 1,
	           tfrequency  = 1,
                   gridwidth   = 0.1,
                   gridoffsetu = 0.5,
                   gridoffsetv = 0.5;
	   )
{
  float d, d2, d3, offset;
  float ss, tt, grout_offset;
  point PP;
  
/* calculations done in shader space */
  PP = transform ("shader", P);
  
/* first layer of bumps - small dents */
  d=abs(noise(50*PP/scale));
  d=pow(d,10); /* flatten */
 /* offset = Km * d * 0.55;
  offset = Km - offset;*/
  
/* second layer of bumps - bigger dents */ 
  d2=abs(noise(20*PP/scale));
  d2=pow(d2,10); /* flatten */
  
/* combined dents */  
  offset = Km * ((d * 1.0) + (d2 * 1.0));
  offset = Km - offset;
  
 /* third layer of bumps - rolling bumps */ 
  d3=abs(noise(18*PP/scale)*1.0);
  d3=pow(d3,5); /* roll */
  d3=sin(0.5*3.14*d3)*0.75; /* round then off */
  
  offset = Km * d3 + offset;
  
 /* grout lines  */
  
  ss = repeat(s, sfrequency);
  tt = repeat(t, tfrequency);
  grout_offset = union(pulse(gridoffsetu - gridwidth - 0.02, gridoffsetu + gridwidth + 0.02, 0.035, ss),
    		       pulse(gridoffsetv - gridwidth - 0.02, gridoffsetv + gridwidth + 0.02, 0.035, tt));
  
  grout_offset = Km * grout_offset * groutscale;
    
/* displace surface by grout_offset, compute normal based on both offsets*/  
  P -= grout_offset * normalize (N);

/*  compute normal only for bumpmap*/   
  N = calculatenormal(P + offset * normalize(N));
}
