--- ray/src/rt/normal.c 2003/02/22 02:07:29 2.38 +++ ray/src/rt/normal.c 2005/01/05 19:34:11 2.49 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: normal.c,v 2.38 2003/02/22 02:07:29 greg Exp $"; +static const char RCSid[] = "$Id: normal.c,v 2.49 2005/01/05 19:34:11 greg Exp $"; #endif /* * normal.c - shading function for normal materials. @@ -11,76 +11,21 @@ static const char RCSid[] = "$Id: normal.c,v 2.38 2003 * Later changes described in delta comments. */ -/* ==================================================================== - * The Radiance Software License, Version 1.0 - * - * Copyright (c) 1990 - 2002 The Regents of the University of California, - * through Lawrence Berkeley National Laboratory. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes Radiance software - * (http://radsite.lbl.gov/) - * developed by the Lawrence Berkeley National Laboratory - * (http://www.lbl.gov/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Radiance," "Lawrence Berkeley National Laboratory" - * and "The Regents of the University of California" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact radiance@radsite.lbl.gov. - * - * 5. Products derived from this software may not be called "Radiance", - * nor may "Radiance" appear in their name, without prior written - * permission of Lawrence Berkeley National Laboratory. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of Lawrence Berkeley National Laboratory. For more - * information on Lawrence Berkeley National Laboratory, please see - * . - */ +#include "copyright.h" #include "ray.h" - +#include "ambient.h" +#include "source.h" #include "otypes.h" - +#include "rtotypes.h" #include "random.h" #ifndef MAXITER #define MAXITER 10 /* maximum # specular ray attempts */ #endif /* estimate of Fresnel function */ -#define FRESNE(ci) (exp(-6.0*(ci)) - 0.00247875217) +#define FRESNE(ci) (exp(-5.85*(ci)) - 0.00287989916) -static void gaussamp(); /* * This routine implements the isotropic Gaussian @@ -119,16 +64,21 @@ typedef struct { double pdot; /* perturbed dot product */ } NORMDAT; /* normal material data */ +static srcdirf_t dirnorm; +static void gaussamp(RAY *r, NORMDAT *np); + static void -dirnorm(cval, np, ldir, omega) /* compute source contribution */ -COLOR cval; /* returned coefficient */ -register NORMDAT *np; /* material data */ -FVECT ldir; /* light source direction */ -double omega; /* light source size */ +dirnorm( /* compute source contribution */ + COLOR cval, /* returned coefficient */ + void *nnp, /* material data */ + FVECT ldir, /* light source direction */ + double omega /* light source size */ +) { + register NORMDAT *np = nnp; double ldot; - double ldiff; + double lrdiff, ltdiff; double dtmp, d2; FVECT vtmp; COLOR ctmp; @@ -141,18 +91,23 @@ double omega; /* light source size */ return; /* wrong side */ /* Fresnel estimate */ - ldiff = np->rdiff; - if (np->specfl & SP_PURE && (np->rspec > FTINY & ldiff > FTINY)) - ldiff *= 1. - FRESNE(fabs(ldot)); + lrdiff = np->rdiff; + ltdiff = np->tdiff; + if (np->specfl & SP_PURE && np->rspec > FTINY && + (lrdiff > FTINY) | (ltdiff > FTINY)) { + dtmp = 1. - FRESNE(fabs(ldot)); + lrdiff *= dtmp; + ltdiff *= dtmp; + } - if (ldot > FTINY && ldiff > FTINY) { + if (ldot > FTINY && lrdiff > FTINY) { /* * Compute and add diffuse reflected component to returned * color. The diffuse reflected component will always be * modified by the color of the material. */ copycolor(ctmp, np->mcolor); - dtmp = ldot * omega * ldiff / PI; + dtmp = ldot * omega * lrdiff * (1.0/PI); scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } @@ -165,7 +120,7 @@ double omega; /* light source size */ dtmp = np->alpha2; /* + source if flat */ if (np->specfl & SP_FLAT) - dtmp += omega/(4.0*PI); + dtmp += omega * (0.25/PI); /* half vector */ vtmp[0] = ldir[0] - np->rp->rdir[0]; vtmp[1] = ldir[1] - np->rp->rdir[1]; @@ -174,21 +129,21 @@ double omega; /* light source size */ d2 *= d2; d2 = (DOT(vtmp,vtmp) - d2) / d2; /* gaussian */ - dtmp = exp(-d2/dtmp)/(4.*PI*dtmp); + dtmp = exp(-d2/dtmp)/(4.*PI * np->pdot * dtmp); /* worth using? */ if (dtmp > FTINY) { copycolor(ctmp, np->scolor); - dtmp *= omega * sqrt(ldot/np->pdot); + dtmp *= omega; scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } } - if (ldot < -FTINY && np->tdiff > FTINY) { + if (ldot < -FTINY && ltdiff > FTINY) { /* * Compute diffuse transmission. */ copycolor(ctmp, np->mcolor); - dtmp = -ldot * omega * np->tdiff / PI; + dtmp = -ldot * omega * ltdiff * (1.0/PI); scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } @@ -198,13 +153,14 @@ double omega; /* light source size */ * is always modified by material color. */ /* roughness + source */ - dtmp = np->alpha2 + omega/PI; + dtmp = np->alpha2 + omega*(1.0/PI); /* gaussian */ - dtmp = exp((2.*DOT(np->prdir,ldir)-2.)/dtmp)/(PI*dtmp); + dtmp = exp((2.*DOT(np->prdir,ldir)-2.)/dtmp) / + (PI*np->pdot*dtmp); /* worth using? */ if (dtmp > FTINY) { copycolor(ctmp, np->mcolor); - dtmp *= np->tspec * omega * sqrt(-ldot/np->pdot); + dtmp *= np->tspec * omega; scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } @@ -212,10 +168,11 @@ double omega; /* light source size */ } -int -m_normal(m, r) /* color a ray that hit something normal */ -register OBJREC *m; -register RAY *r; +extern int +m_normal( /* color a ray that hit something normal */ + register OBJREC *m, + register RAY *r +) { NORMDAT nd; double fest; @@ -237,8 +194,10 @@ register RAY *r; raytrans(r); return(1); } + raytexture(r, m->omod); flipsurface(r); /* reorient if backvis */ - } + } else + raytexture(r, m->omod); nd.mp = m; nd.rp = r; /* get material color */ @@ -250,16 +209,15 @@ register RAY *r; nd.alpha2 = m->oargs.farg[4]; if ((nd.alpha2 *= nd.alpha2) <= FTINY) nd.specfl |= SP_PURE; - if (r->ro != NULL && isflat(r->ro->otype)) - nd.specfl |= SP_FLAT; - /* get modifiers */ - raytexture(r, m->omod); - if (hastexture = DOT(r->pert,r->pert) > FTINY*FTINY) + + if ( (hastexture = (DOT(r->pert,r->pert) > FTINY*FTINY)) ) { nd.pdot = raynormal(nd.pnorm, r); /* perturb normal */ - else { + } else { VCOPY(nd.pnorm, r->ron); nd.pdot = r->rod; } + if (r->ro != NULL && isflat(r->ro->otype)) + nd.specfl |= SP_FLAT; if (nd.pdot < .001) nd.pdot = .001; /* non-zero for dirnorm() */ multcolor(nd.mcolor, r->pcol); /* modify material color */ @@ -405,9 +363,10 @@ register RAY *r; static void -gaussamp(r, np) /* sample gaussian specular */ -RAY *r; -register NORMDAT *np; +gaussamp( /* sample gaussian specular */ + RAY *r, + register NORMDAT *np +) { RAY sr; FVECT u, v, h;