home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Multimedia / k3d-setup-0.7.11.0.exe / share / k3d / shaders / surface / k3d_orennayar.sl < prev    next >
Encoding:
Text File  |  2008-01-23  |  2.5 KB  |  81 lines

  1. /* renamed LG_orennayar.sl -- tal@SpamSucks_cs.caltech.edu */
  2.  
  3. /*
  4.  * orennayar.sl - rough diffuse surface
  5.  *
  6.  * 
  7.  * DESCRIPTION:
  8.  *   Makes a rough surface using a BRDF which is more accurate than
  9.  *   Lambert.  Based on Oren & Nayar's model (see Proc. SIGGRAPH 94).
  10.  *
  11.  *   Lambertian (isotropic) BRDF is a simple approximation, but not
  12.  *   an especially accurate one for rough surfaces.  Truly rough surfacs
  13.  *   tend to act more like retroreflectors than like isotropic scatterers.
  14.  * 
  15.  * PARAMETERS:
  16.  *   Ka, Kd - just like matte.sl
  17.  *   sigma - roughness (0 is lambertian, larger values are rougher)
  18.  *
  19.  * AUTHOR:  Larry Gritz
  20.  *
  21.  * REFERENCES:
  22.  *   Oren, Michael and Shree K. Nayar.  "Generalization of Lambert's
  23.  *         Reflectance Model," Computer Graphics Annual Conference
  24.  *         Series 1994 (Proceedings of SIGGRAPH '94), pp. 239-246.
  25.  *
  26.  * NOTES:
  27.  *   1. Note that this is really just an illuminance loop that gathers
  28.  *      light from the sources and applies Oren & Nayar's local reflectance
  29.  *      model to the result.  It could easily be packaged up as a macro
  30.  *      or a function and used in any other shader, in place of diffuse().
  31.  *   2. Examination of why rough surfaces are not Lambertian will lead
  32.  *      you to the solution to the famous "flat full moon" problem.
  33.  *
  34.  * HISTORY:
  35.  *   14 June 1994 -- written by Larry Gritz
  36.  *
  37.  */
  38.  
  39.  
  40. surface
  41. k3d_orennayar (float Ka = 1;
  42.        float Kd = .5;
  43.        float sigma = 0.0; )
  44. {
  45.     point Nf, IN, Eye, LN;
  46.     color lightC = 0;
  47.     color L1, L2;
  48.     float C1, C2, C3;
  49.     float theta_r, theta_i, cos_theta_i;
  50.     float alpha, beta, sigma2, cos_phi_diff;
  51.  
  52.     Nf = faceforward (normalize(N),I);
  53.     IN = normalize (I);
  54.     Eye = -IN;
  55.     theta_r = acos (Eye . Nf);
  56.     sigma2 = sigma*sigma;
  57.  
  58.     illuminance (P, Nf, PI/2) {
  59.     LN = normalize(L);
  60.     cos_theta_i = LN . Nf;
  61.     cos_phi_diff = normalize(Eye-Nf*(Eye.Nf)) . normalize(LN - Nf*(LN.Nf));
  62.     theta_i = acos (cos_theta_i);
  63.     alpha = max (theta_i, theta_r);
  64.     beta = min (theta_i, theta_r);
  65.     C1 = 1 - 0.5 * sigma2/(sigma2+0.33);
  66.     C2 = 0.45 * sigma2 / (sigma2 + 0.09);
  67.     if (cos_phi_diff >= 0)
  68.         C2 *= sin(alpha);
  69.     else C2 *= (sin(alpha) - pow(2*beta/PI,3));
  70.     C3 = 0.125 * sigma2 / (sigma2+0.09) * pow ((4*alpha*beta)/(PI*PI),2);
  71.     L1 = Cs * (cos_theta_i * (C1 + cos_phi_diff * C2 * tan(beta) +
  72.                   (1 - abs(cos_phi_diff)) * C3 * tan((alpha+beta)/2)));
  73.     L2 = (Cs * Cs) * (0.17 * cos_theta_i * sigma2/(sigma2+0.13) *
  74.               (1 - cos_phi_diff*(4*beta*beta)/(PI*PI)));
  75.     lightC += (L1 + L2) * Cl;
  76.     }
  77.  
  78.     Oi = Os;
  79.     Ci = Os * (Cs * (Ka*ambient()) + Kd*lightC);
  80. }
  81.