| 1 | 
greg | 
1.1 | 
/* Copyright (c) 1986 Regents of the University of California */ | 
| 2 | 
  | 
  | 
 | 
| 3 | 
  | 
  | 
#ifndef lint | 
| 4 | 
  | 
  | 
static char SCCSid[] = "$SunId$ 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 | 
  | 
  | 
 *  If we appear to hit the back side of the surface, then we | 
| 36 | 
  | 
  | 
 *  turn the normal around. | 
| 37 | 
  | 
  | 
 */ | 
| 38 | 
  | 
  | 
 | 
| 39 | 
  | 
  | 
#define  RINDEX         1.52            /* refractive index of glass */ | 
| 40 | 
  | 
  | 
 | 
| 41 | 
  | 
  | 
 | 
| 42 | 
  | 
  | 
m_glass(m, r)           /* color a ray which hit a thin glass surface */ | 
| 43 | 
  | 
  | 
OBJREC  *m; | 
| 44 | 
  | 
  | 
register RAY  *r; | 
| 45 | 
  | 
  | 
{ | 
| 46 | 
  | 
  | 
        double  sqrt(), pow(); | 
| 47 | 
  | 
  | 
        COLOR  mcolor; | 
| 48 | 
  | 
  | 
        double  pdot; | 
| 49 | 
  | 
  | 
        FVECT  pnorm; | 
| 50 | 
  | 
  | 
        double  cos2; | 
| 51 | 
  | 
  | 
        COLOR  trans, refl; | 
| 52 | 
  | 
  | 
        double  d, r1; | 
| 53 | 
  | 
  | 
        RAY  p; | 
| 54 | 
  | 
  | 
        register int  i; | 
| 55 | 
  | 
  | 
 | 
| 56 | 
  | 
  | 
        if (m->oargs.nfargs != 3) | 
| 57 | 
  | 
  | 
                objerror(m, USER, "bad arguments"); | 
| 58 | 
  | 
  | 
 | 
| 59 | 
  | 
  | 
        setcolor(mcolor, m->oargs.farg[0], m->oargs.farg[1], m->oargs.farg[2]); | 
| 60 | 
  | 
  | 
 | 
| 61 | 
  | 
  | 
        if (r->rod < 0.0)                       /* reorient if necessary */ | 
| 62 | 
  | 
  | 
                flipsurface(r); | 
| 63 | 
  | 
  | 
                                                /* get modifiers */ | 
| 64 | 
  | 
  | 
        raytexture(r, m->omod); | 
| 65 | 
  | 
  | 
        pdot = raynormal(pnorm, r); | 
| 66 | 
  | 
  | 
                                                /* angular transmission */ | 
| 67 | 
  | 
  | 
        cos2 = sqrt( (1.0-1.0/RINDEX/RINDEX) + | 
| 68 | 
  | 
  | 
                     pdot*pdot/(RINDEX*RINDEX) ); | 
| 69 | 
  | 
  | 
        setcolor(mcolor, pow(colval(mcolor,RED), 1.0/cos2), | 
| 70 | 
  | 
  | 
                         pow(colval(mcolor,GRN), 1.0/cos2), | 
| 71 | 
  | 
  | 
                         pow(colval(mcolor,BLU), 1.0/cos2)); | 
| 72 | 
  | 
  | 
 | 
| 73 | 
  | 
  | 
                                                /* compute reflection */ | 
| 74 | 
  | 
  | 
        r1 = (pdot - RINDEX*cos2) / (pdot + RINDEX*cos2); | 
| 75 | 
  | 
  | 
        d = (1.0/pdot - RINDEX/cos2) / (1.0/pdot + RINDEX/cos2); | 
| 76 | 
  | 
  | 
        r1 = (r1*r1 + d*d) / 2.0; | 
| 77 | 
  | 
  | 
                                                /* compute transmittance */ | 
| 78 | 
  | 
  | 
        for (i = 0; i < 3; i++) { | 
| 79 | 
  | 
  | 
                d = colval(mcolor, i); | 
| 80 | 
  | 
  | 
                colval(trans,i) = (1.0-r1)*(1.0-r1)*d / (1.0 - r1*r1*d*d); | 
| 81 | 
  | 
  | 
        } | 
| 82 | 
  | 
  | 
                                                /* transmitted ray */ | 
| 83 | 
greg | 
1.2 | 
        if (rayorigin(&p, r, TRANS, bright(trans)) == 0) { | 
| 84 | 
greg | 
1.1 | 
                VCOPY(p.rdir, r->rdir); | 
| 85 | 
  | 
  | 
                rayvalue(&p); | 
| 86 | 
  | 
  | 
                multcolor(p.rcol, r->pcol);     /* modify */ | 
| 87 | 
  | 
  | 
                multcolor(p.rcol, trans); | 
| 88 | 
  | 
  | 
                addcolor(r->rcol, p.rcol); | 
| 89 | 
greg | 
1.3 | 
                r->rt = r->rot + p.rt; | 
| 90 | 
greg | 
1.1 | 
        } | 
| 91 | 
greg | 
1.3 | 
 | 
| 92 | 
greg | 
1.1 | 
        if (r->crtype & SHADOW)                 /* skip reflected ray */ | 
| 93 | 
  | 
  | 
                return; | 
| 94 | 
  | 
  | 
                                                /* compute reflectance */ | 
| 95 | 
  | 
  | 
        for (i = 0; i < 3; i++) { | 
| 96 | 
  | 
  | 
                d = colval(mcolor, i); | 
| 97 | 
  | 
  | 
                d *= d; | 
| 98 | 
  | 
  | 
                colval(refl,i) = r1 * (1.0 + (1.0-2.0*r1)*d) / (1.0 - r1*r1*d); | 
| 99 | 
  | 
  | 
        } | 
| 100 | 
  | 
  | 
                                                /* reflected ray */ | 
| 101 | 
greg | 
1.2 | 
        if (rayorigin(&p, r, REFLECTED, bright(refl)) == 0) { | 
| 102 | 
greg | 
1.1 | 
                for (i = 0; i < 3; i++) | 
| 103 | 
  | 
  | 
                        p.rdir[i] = r->rdir[i] + 2.0*pdot*pnorm[i]; | 
| 104 | 
  | 
  | 
                rayvalue(&p); | 
| 105 | 
  | 
  | 
                multcolor(p.rcol, refl); | 
| 106 | 
  | 
  | 
                addcolor(r->rcol, p.rcol); | 
| 107 | 
greg | 
1.3 | 
                if (bright(refl) > bright(trans)) | 
| 108 | 
  | 
  | 
                        r->rt = r->rot + p.rt; | 
| 109 | 
greg | 
1.1 | 
        } | 
| 110 | 
  | 
  | 
} |