/* Crater Shader 
   Raul 'Joni' Chu - cs184-bq - 12782756
   Yuan Kui Shen   - cs184-ac - 12940472
   An adaptation of the BMRT dented shader
   This shader creates a believable rocky bumpy surface for
   the moon in our picture */

displacement crater (float Ka = 1;
         	     float Kd = .5;
         	     float roughness = .1;
		     float Km = 10;
		     float maxoctaves = 6;
		     float power = 3;
		     float frequency = 1) 
{
  /* The following section is copied from
     dented.sl from the BMRT/examples directory 
  */
  float size;
  float magnitude = 0;
  float i;
  
  point 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);

/* Below I am attempting to draw rings...craters on the surface
   but the final result looked worse with the craters than with
   out it. So I commented it all out. */
#if 0    
  #include rmannotes.sl
  color surface_color = 0;
  float fuzz = 0.025;	 
  float base_surface = 0.0;
  float dist, radius, half_width, crater_layer;  
  float i, col, row, noi, ss, tt;
  float layers = 1;
  point center = (0.5, 0.5, 0);

  /* Trying to create layers of differing
     size craters */
  for( freq = 4; freq <= 16; freq += 2) {
    /* set freq and fuzz of pattern based on layer # */
    fuzz = 0.005;
    /* base seed to udn on current row and column of tile */
    col = whichtile(s, freq);
    row = whichtile(t, freq);
    noi = noise(col * 10 + 0.5, row * 10 + 0.5) * noise(i * 10 + 0.5);
    ss = repeat(s, freq) + udn(noi * 1183, -0.35, 0.35);
    tt = repeat(t, freq) + udn(noi * 999, -0.35, 0.35);
    radius = 0.01 * freq;
    half_width = 0.01;
    dist = distance(center, (ss, tt, 0));
    crater_layer = pulse (radius - half_width, radius + half_width, 
			  fuzz, dist);
    base_surface = max(crater_layer, base_surface);
  }
  P += P - (Km * pow (base_surface, power)) * normalize (N);
#endif
  /* normalize the point */
  N = calculatenormal(P);

  /* output */
  normal Nf = faceforward (normalize(N),I);
  Oi = Os;
  Ci = Os * ( Cs * (Ka*ambient() + Kd*diffuse(Nf)));
}