Back to index

radiance  4R0+20100331
Defines | Functions | Variables
dielectric.c File Reference
#include "copyright.h"
#include "ray.h"
#include "otypes.h"
#include "rtotypes.h"

Go to the source code of this file.

Defines

#define MLAMBDA   500 /* mean lambda */
#define MAXLAMBDA   779 /* maximum lambda */
#define MINLAMBDA   380 /* minimum lambda */
#define MINCOS   0.997 /* minimum dot product for dispersion */

Functions

static double mylog (double x)
int m_dielectric (OBJREC *m, register RAY *r)

Variables

static const char RCSid [] = "$Id: dielectric.c,v 2.20 2005/04/19 01:15:06 greg Exp $"

Define Documentation

#define MAXLAMBDA   779 /* maximum lambda */

Definition at line 48 of file dielectric.c.

#define MINCOS   0.997 /* minimum dot product for dispersion */

Definition at line 51 of file dielectric.c.

#define MINLAMBDA   380 /* minimum lambda */

Definition at line 49 of file dielectric.c.

#define MLAMBDA   500 /* mean lambda */

Definition at line 47 of file dielectric.c.


Function Documentation

int m_dielectric ( OBJREC m,
register RAY r 
)

Definition at line 68 of file dielectric.c.

{
       double  cos1, cos2, nratio;
       COLOR  ctrans;
       COLOR  talb;
       int  hastexture;
       double  transdist, transtest=0;
       double  mirdist, mirtest=0;
       int    flatsurface;
       double  refl, trans;
       FVECT  dnorm;
       double  d1, d2;
       RAY  p;
       register int  i;

       if (m->oargs.nfargs != (m->otype==MAT_DIELECTRIC ? 5 : 8))
              objerror(m, USER, "bad arguments");

       raytexture(r, m->omod);                   /* get modifiers */

       if ( (hastexture = DOT(r->pert,r->pert) > FTINY*FTINY) )
              cos1 = raynormal(dnorm, r); /* perturb normal */
       else {
              VCOPY(dnorm, r->ron);
              cos1 = r->rod;
       }
       flatsurface = !hastexture && r->ro != NULL && isflat(r->ro->otype);

                                          /* index of refraction */
       if (m->otype == MAT_DIELECTRIC)
              nratio = m->oargs.farg[3] + m->oargs.farg[4]/MLAMBDA;
       else
              nratio = m->oargs.farg[3] / m->oargs.farg[7];
       
       if (cos1 < 0.0) {                  /* inside */
              hastexture = -hastexture;
              cos1 = -cos1;
              dnorm[0] = -dnorm[0];
              dnorm[1] = -dnorm[1];
              dnorm[2] = -dnorm[2];
              setcolor(r->cext, -mylog(m->oargs.farg[0]*colval(r->pcol,RED)),
                             -mylog(m->oargs.farg[1]*colval(r->pcol,GRN)),
                             -mylog(m->oargs.farg[2]*colval(r->pcol,BLU)));
              setcolor(r->albedo, 0., 0., 0.);
              r->gecc = 0.;
              if (m->otype == MAT_INTERFACE) {
                     setcolor(ctrans,
                            -mylog(m->oargs.farg[4]*colval(r->pcol,RED)),
                            -mylog(m->oargs.farg[5]*colval(r->pcol,GRN)),
                            -mylog(m->oargs.farg[6]*colval(r->pcol,BLU)));
                     setcolor(talb, 0., 0., 0.);
              } else {
                     copycolor(ctrans, cextinction);
                     copycolor(talb, salbedo);
              }
       } else {                           /* outside */
              nratio = 1.0 / nratio;

              setcolor(ctrans, -mylog(m->oargs.farg[0]*colval(r->pcol,RED)),
                             -mylog(m->oargs.farg[1]*colval(r->pcol,GRN)),
                             -mylog(m->oargs.farg[2]*colval(r->pcol,BLU)));
              setcolor(talb, 0., 0., 0.);
              if (m->otype == MAT_INTERFACE) {
                     setcolor(r->cext,
                            -mylog(m->oargs.farg[4]*colval(r->pcol,RED)),
                            -mylog(m->oargs.farg[5]*colval(r->pcol,GRN)),
                            -mylog(m->oargs.farg[6]*colval(r->pcol,BLU)));
                     setcolor(r->albedo, 0., 0., 0.);
                     r->gecc = 0.;
              }
       }

       d2 = 1.0 - nratio*nratio*(1.0 - cos1*cos1);      /* compute cos theta2 */

       if (d2 < FTINY)                    /* total reflection */

              refl = 1.0;

       else {                      /* refraction occurs */
                                   /* compute Fresnel's equations */
              cos2 = sqrt(d2);
              d1 = cos1;
              d2 = nratio*cos2;
              d1 = (d1 - d2) / (d1 + d2);
              refl = d1 * d1;

              d1 = 1.0 / cos1;
              d2 = nratio / cos2;
              d1 = (d1 - d2) / (d1 + d2);
              refl += d1 * d1;

              refl *= 0.5;
              trans = 1.0 - refl;

              trans *= nratio*nratio;            /* solid angle ratio */

              setcolor(p.rcoef, trans, trans, trans);

              if (rayorigin(&p, REFRACTED, r, p.rcoef) == 0) {

                                          /* compute refracted ray */
                     d1 = nratio*cos1 - cos2;
                     for (i = 0; i < 3; i++)
                            p.rdir[i] = nratio*r->rdir[i] + d1*dnorm[i];
                                          /* accidental reflection? */
                     if (hastexture &&
                            DOT(p.rdir,r->ron)*hastexture >= -FTINY) {
                            d1 *= (double)hastexture;
                            for (i = 0; i < 3; i++)     /* ignore texture */
                                   p.rdir[i] = nratio*r->rdir[i] +
                                                 d1*r->ron[i];
                            normalize(p.rdir);   /* not exact */
                     }
#ifdef  DISPERSE
                     if (m->otype != MAT_DIELECTRIC
                                   || r->rod > 0.0
                                   || r->crtype & SHADOW
                                   || !directvis
                                   || m->oargs.farg[4] == 0.0
                                   || !disperse(m, r, p.rdir,
                                                 trans, ctrans, talb))
#endif
                     {
                            copycolor(p.cext, ctrans);
                            copycolor(p.albedo, talb);
                            rayvalue(&p);
                            multcolor(p.rcol, p.rcoef);
                            addcolor(r->rcol, p.rcol);
                                          /* virtual distance */
                            if (flatsurface ||
                                   (1.-FTINY <= nratio &&
                                          nratio <= 1.+FTINY)) {
                                   transtest = 2*bright(p.rcol);
                                   transdist = r->rot + p.rt;
                            }
                     }
              }
       }
       setcolor(p.rcoef, refl, refl, refl);

       if (!(r->crtype & SHADOW) &&
                     rayorigin(&p, REFLECTED, r, p.rcoef) == 0) {

                                   /* compute reflected ray */
              for (i = 0; i < 3; i++)
                     p.rdir[i] = r->rdir[i] + 2.0*cos1*dnorm[i];
                                   /* accidental penetration? */
              if (hastexture && DOT(p.rdir,r->ron)*hastexture <= FTINY)
                     for (i = 0; i < 3; i++)            /* ignore texture */
                            p.rdir[i] = r->rdir[i] + 2.0*r->rod*r->ron[i];

              rayvalue(&p);               /* reflected ray value */

              multcolor(p.rcol, p.rcoef); /* color contribution */
              addcolor(r->rcol, p.rcol);
                                          /* virtual distance */
              if (flatsurface) {
                     mirtest = 2*bright(p.rcol);
                     mirdist = r->rot + p.rt;
              }
       }
                            /* check distance to return */
       d1 = bright(r->rcol);
       if (transtest > d1)
              r->rt = transdist;
       else if (mirtest > d1)
              r->rt = mirdist;
                            /* rayvalue() computes absorption */
       return(1);
}

Here is the call graph for this function:

static double mylog ( double  x) [static]

Definition at line 55 of file dielectric.c.

{
       if (x < 1e-40)
              return(-100.);
       if (x >= 1.)
              return(0.);
       return(log(x));
}

Here is the caller graph for this function:


Variable Documentation

const char RCSid[] = "$Id: dielectric.c,v 2.20 2005/04/19 01:15:06 greg Exp $" [static]

Definition at line 2 of file dielectric.c.