/*
 * grass.sl -- displacement shader for grass on hilly terrain.
 *		Grass displacement occurs within an elevation range,
 *              and fractal displacement for rock occurs elsewhere.
 *
 * DESCRIPTION:
 *   Makes a surface fuzzy like grass at a distance.
 *
 * PARAMETERS:
 *   gHeight		maximum grass height
 *   Km                 the amplitude of rock displacement
 *   power, frequency	control fractal dimension of the rock
 *   maxoctaves
 *
 *
 * AUTHOR: Grass section written by Nancy Kiang
 *	   Rock section borrowed from dented.sl by Larry Gritz.
 *
 * HISTORY:
 *
 *
 * last modified  30 Nov 1998 by Nancy Kiang
 *
 *
 */



displacement
grass ( float gHeight = 0.1, elevlo=0.0, elevhi=0.1, Km = 1, power=3, frequency=1, maxoctaves=6; )
{
  //Used for grass shader
  float d = 0.0;
  float Py = ycomp(P);
  //Used for rock shader
  float size;
  float magnitude = 0;
  float i;
  point PP;

  d = gHeight*random();
  if (d < 0.5*gHeight) d = 0.0; //constrain grass to be within height range or 0.

  //Grass
  //Offset vertical component of P
//  if (Py >= scale*(-0.01 + 0.05*(random()-0.5)) && Py < scale*(0.07 + 0.05*random())  && d > 0.0) { 
  if (Py >= elevlo + 0.5*(random()-0.5)  && Py < elevhi*(1 + 0.5*random()) && d > 0.0) { 
	/* Displace upward for grass spike. */
	setycomp(P, ycomp(P) + d);
	N = calculatenormal (P);


	/* Make grass green -- Darn, can't set colors in a displacement shader */
//   	normal Nf = faceforward (normalize(N),I);
//    	vector V = -normalize(I);
//	Oi = Os;
//        Ci = Os * (color "rgb" (0.2, 0.25, 0.15))*
//		(ambient() + 0.5*diffuse(Nf) + 0.5*specular(Nf,V,.1));  
		/*dark green*/
  }
  else {
  //Rock
	  PP = transform ("shader", P);
	  size = frequency;
	  for (i = 0;  i < maxoctaves;  i += 1) {
	      magnitude += abs (.5 - noise (PP*size)) / size;
	      size *= 2;
	    }
	  P = P + (Km * pow (magnitude, power)) * normalize (N);
	  N = calculatenormal (P);
  }
}