home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / RT / GLASS.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  4KB  |  132 lines

  1. /* Copyright (c) 1991 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)glass.c 2.3 10/2/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  glass.c - simpler shading function for thin glass surfaces.
  9.  *
  10.  *     11/14/86
  11.  */
  12.  
  13. #include  "ray.h"
  14.  
  15. /*
  16.  *  This definition of glass provides for a quick calculation
  17.  *  using a single surface where two closely spaced parallel
  18.  *  dielectric surfaces would otherwise be used.  The chief
  19.  *  advantage to using this material is speed, since internal
  20.  *  reflections are avoided.
  21.  *
  22.  *  The specification for glass is as follows:
  23.  *
  24.  *    modifier glass id
  25.  *    0
  26.  *    0
  27.  *    3 red grn blu
  28.  *
  29.  *  The color is used for the transmission at normal incidence.
  30.  *  To compute transmission (tn) from transmissivity (Tn) use:
  31.  *
  32.  *    tn = (sqrt(.8402528435+.0072522239*Tn*Tn)-.9166530661)/.0036261119/Tn
  33.  *
  34.  *  The transmission of standard 88% transmissivity glass is 0.96.
  35.  *  A refractive index other than the default can be used by giving
  36.  *  it as the fourth real argument.  The above formula no longer applies.
  37.  *
  38.  *  If we appear to hit the back side of the surface, then we
  39.  *  turn the normal around.
  40.  */
  41.  
  42. #define  RINDEX        1.52        /* refractive index of glass */
  43.  
  44.  
  45. m_glass(m, r)        /* color a ray which hit a thin glass surface */
  46. OBJREC  *m;
  47. register RAY  *r;
  48. {
  49.     COLOR  mcolor;
  50.     double  pdot;
  51.     FVECT  pnorm;
  52.     double  rindex, cos2;
  53.     COLOR  trans, refl;
  54.     double  d, r1e, r1m;
  55.     double  transtest, transdist;
  56.     RAY  p;
  57.     register int  i;
  58.                         /* check arguments */
  59.     if (m->oargs.nfargs == 3)
  60.         rindex = RINDEX;        /* default value of n */
  61.     else if (m->oargs.nfargs == 4)
  62.         rindex = m->oargs.farg[3];    /* use their value */
  63.     else
  64.         objerror(m, USER, "bad arguments");
  65.  
  66.     setcolor(mcolor, m->oargs.farg[0], m->oargs.farg[1], m->oargs.farg[2]);
  67.  
  68.     if (r->rod < 0.0)            /* reorient if necessary */
  69.         flipsurface(r);
  70.     transtest = 0;
  71.                         /* get modifiers */
  72.     raytexture(r, m->omod);
  73.     pdot = raynormal(pnorm, r);
  74.                         /* angular transmission */
  75.     cos2 = sqrt( (1.0-1.0/(rindex*rindex)) +
  76.              pdot*pdot/(rindex*rindex) );
  77.     setcolor(mcolor, pow(colval(mcolor,RED), 1.0/cos2),
  78.              pow(colval(mcolor,GRN), 1.0/cos2),
  79.              pow(colval(mcolor,BLU), 1.0/cos2));
  80.  
  81.                         /* compute reflection */
  82.     r1e = (pdot - rindex*cos2) / (pdot + rindex*cos2);
  83.     r1e *= r1e;
  84.     r1m = (1.0/pdot - rindex/cos2) / (1.0/pdot + rindex/cos2);
  85.     r1m *= r1m;
  86.                         /* compute transmittance */
  87.     for (i = 0; i < 3; i++) {
  88.         d = colval(mcolor, i);
  89.         colval(trans,i) = .5*(1.0-r1e)*(1.0-r1e)*d/(1.0-r1e*r1e*d*d);
  90.         colval(trans,i) += .5*(1.0-r1m)*(1.0-r1m)*d/(1.0-r1m*r1m*d*d);
  91.     }
  92.                         /* transmitted ray */
  93.     if (rayorigin(&p, r, TRANS, bright(trans)) == 0) {
  94.         if (!(r->crtype & SHADOW) &&
  95.                 DOT(r->pert,r->pert) > FTINY*FTINY) {
  96.             for (i = 0; i < 3; i++)        /* perturb direction */
  97.                 p.rdir[i] = r->rdir[i] +
  98.                         2.*(1.-rindex)*r->pert[i];
  99.             normalize(p.rdir);
  100.         } else {
  101.             VCOPY(p.rdir, r->rdir);
  102.             transtest = 2;
  103.         }
  104.         rayvalue(&p);
  105.         multcolor(p.rcol, r->pcol);    /* modify */
  106.         multcolor(p.rcol, trans);
  107.         addcolor(r->rcol, p.rcol);
  108.         transtest *= bright(p.rcol);
  109.         transdist = r->rot + p.rt;
  110.     }
  111.  
  112.     if (r->crtype & SHADOW)            /* skip reflected ray */
  113.         return;
  114.                         /* compute reflectance */
  115.     for (i = 0; i < 3; i++) {
  116.         d = colval(mcolor, i);
  117.         d *= d;
  118.         colval(refl,i) = .5*r1e*(1.0+(1.0-2.0*r1e)*d)/(1.0-r1e*r1e*d);
  119.         colval(refl,i) += .5*r1m*(1.0+(1.0-2.0*r1m)*d)/(1.0-r1m*r1m*d);
  120.     }
  121.                         /* reflected ray */
  122.     if (rayorigin(&p, r, REFLECTED, bright(refl)) == 0) {
  123.         for (i = 0; i < 3; i++)
  124.             p.rdir[i] = r->rdir[i] + 2.0*pdot*pnorm[i];
  125.         rayvalue(&p);
  126.         multcolor(p.rcol, refl);
  127.         addcolor(r->rcol, p.rcol);
  128.     }
  129.     if (transtest > bright(r->rcol))
  130.         r->rt = transdist;
  131. }
  132.