ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_bsdf.c
(Generate patch)

Comparing ray/src/rt/m_bsdf.c (file contents):
Revision 2.1 by greg, Fri Feb 18 00:40:25 2011 UTC vs.
Revision 2.4 by greg, Sat Feb 19 23:42:09 2011 UTC

# Line 8 | Line 8 | static const char RCSid[] = "$Id$";
8   #include "copyright.h"
9  
10   #include  "ray.h"
11 #include  "paths.h"
11   #include  "ambient.h"
12   #include  "source.h"
13   #include  "func.h"
# Line 48 | Line 47 | static const char RCSid[] = "$Id$";
47   *              rdt     gdt     bdt
48   */
49  
50 + /*
51 + * Note that our reverse ray-tracing process means that the positions
52 + * of incoming and outgoing vectors may be reversed in our calls
53 + * to the BSDF library.  This is fine, since the bidirectional nature
54 + * of the BSDF (that's what the 'B' stands for) means it all works out.
55 + */
56 +
57   typedef struct {
58          OBJREC  *mp;            /* material pointer */
59          RAY     *pr;            /* intersected ray */
60          FVECT   pnorm;          /* perturbed surface normal */
61 <        FVECT   vinc;           /* local incident vector */
61 >        FVECT   vray;           /* local outgoing (return) vector */
62 >        double  sr_vpsa;        /* sqrt of BSDF projected solid angle */
63          RREAL   toloc[3][3];    /* world to local BSDF coords */
64          RREAL   fromloc[3][3];  /* local BSDF coords to world */
65          double  thick;          /* surface thickness */
# Line 65 | Line 72 | typedef struct {
72  
73   #define cvt_sdcolor(cv, svp)    ccy2rgb(&(svp)->spec, (svp)->cieY, cv)
74  
75 < /* Convert error from BSDF library */
76 < static char *
77 < cvt_sderr(SDError ec)
75 > /* Jitter ray sample according to projected solid angle and specjitter */
76 > static void
77 > bsdf_jitter(FVECT vres, BSDFDAT *ndp)
78   {
79 <        if (!SDerrorDetail[0])
80 <                return(strcpy(errmsg, SDerrorEnglish[ec]));
81 <        sprintf(errmsg, "%s: %s", SDerrorEnglish[ec], SDerrorDetail);
82 <        return(errmsg);
79 >        double  sr_psa = ndp->sr_vpsa;
80 >
81 >        VCOPY(vres, ndp->vray);
82 >        if (specjitter < 1.)
83 >                sr_psa *= specjitter;
84 >        if (sr_psa <= FTINY)
85 >                return;
86 >        vres[0] += sr_psa*(.5 - frandom());
87 >        vres[1] += sr_psa*(.5 - frandom());
88 >        normalize(vres);
89   }
90  
91   /* Compute source contribution for BSDF */
# Line 84 | Line 97 | dirbsdf(
97          double  omega                   /* light source size */
98   )
99   {
100 <        BSDFDAT         *np = nnp;
100 >        BSDFDAT         *np = (BSDFDAT *)nnp;
101          SDError         ec;
102          SDValue         sv;
103 <        FVECT           vout;
103 >        FVECT           vsrc;
104 >        FVECT           vjit;
105          double          ldot;
106          double          dtmp;
107          COLOR           ctmp;
# Line 119 | Line 133 | dirbsdf(
133          /*
134           *  Compute scattering coefficient using BSDF.
135           */
136 <        if (SDmapDir(vout, np->toloc, ldir) != SDEnone)
136 >        if (SDmapDir(vsrc, np->toloc, ldir) != SDEnone)
137                  return;
138 <        ec = SDevalBSDF(&sv, vout, np->vinc, np->sd);
138 >        bsdf_jitter(vjit, np);
139 >        ec = SDevalBSDF(&sv, vjit, vsrc, np->sd);
140          if (ec)
141 <                objerror(np->mp, USER, cvt_sderr(ec));
141 >                objerror(np->mp, USER, transSDError(ec));
142  
143          if (sv.cieY <= FTINY)           /* not worth using? */
144                  return;
# Line 137 | Line 152 | dirbsdf(
152                  scalecolor(ctmp2, dtmp);
153                  setcolor(ctmp1, 1.-dtmp, 1.-dtmp, 1.-dtmp);
154                  addcolor(ctmp1, ctmp2);
155 <                multcolor(ctmp, ctmp1); /* apply desaturated pattern */
155 >                multcolor(ctmp, ctmp1); /* apply derated pattern */
156                  dtmp = ldot * omega;
157          } else {                        /* full pattern on transmission */
158                  multcolor(ctmp, np->pr->pcol);
# Line 156 | Line 171 | sample_sdcomp(BSDFDAT *ndp, SDComponent *dcp, int usep
171          SDError ec;
172          SDValue bsv;
173          double  sthick;
174 <        FVECT   vout;
174 >        FVECT   vjit, vsmp;
175          RAY     sr;
176          int     ntrials;
177                                                  /* multiple samples? */
# Line 169 | Line 184 | sample_sdcomp(BSDFDAT *ndp, SDComponent *dcp, int usep
184          for (ntrials = 0; nsent < nstarget && ntrials < 9*nstarget; ntrials++) {
185                  SDerrorDetail[0] = '\0';
186                                                  /* sample direction & coef. */
187 <                ec = SDsampComponent(&bsv, vout, ndp->vinc,
188 <                                ntrials ? frandom()
189 <                                        : urand(ilhash(dimlist,ndims)+samplendx),
175 <                                                dcp);
187 >                bsdf_jitter(vjit, ndp);
188 >                ec = SDsampComponent(&bsv, vsmp, vjit, ntrials ? frandom()
189 >                                : urand(ilhash(dimlist,ndims)+samplendx), dcp);
190                  if (ec)
191 <                        objerror(ndp->mp, USER, cvt_sderr(ec));
191 >                        objerror(ndp->mp, USER, transSDError(ec));
192                                                  /* zero component? */
193                  if (bsv.cieY <= FTINY)
194                          break;
195                                                  /* map vector to world */
196 <                if (SDmapDir(sr.rdir, ndp->fromloc, vout) != SDEnone)
196 >                if (SDmapDir(sr.rdir, ndp->fromloc, vsmp) != SDEnone)
197                          break;
198                                                  /* unintentional penetration? */
199 <                if (DOT(sr.rdir, ndp->pr->ron) > .0 ^ vout[2] > .0)
199 >                if (DOT(sr.rdir, ndp->pr->ron) > .0 ^ vsmp[2] > .0)
200                          continue;
201                                                  /* spawn a specular ray */
202                  if (nstarget > 1)
# Line 196 | Line 210 | sample_sdcomp(BSDFDAT *ndp, SDComponent *dcp, int usep
210                          ++nsent;                /* Russian roulette victim */
211                          continue;
212                  }
213 <                                                /* need to move origin? */
214 <                sthick = (ndp->pr->rod > .0) ? -ndp->thick : ndp->thick;
215 <                if (sthick < .0 ^ vout[2] > .0)
216 <                        VSUM(sr.rorg, sr.rorg, ndp->pr->ron, sthick);
217 <
213 >                if (ndp->thick > FTINY) {       /* need to move origin? */
214 >                        sthick = (ndp->pr->rod > .0) ? -ndp->thick : ndp->thick;
215 >                        if (sthick < .0 ^ vsmp[2] > .0)
216 >                                VSUM(sr.rorg, sr.rorg, ndp->pr->ron, sthick);
217 >                }
218                  rayvalue(&sr);                  /* send & evaluate sample */
219                  multcolor(sr.rcol, sr.rcoef);
220                  addcolor(ndp->pr->rcol, sr.rcol);
# Line 236 | Line 250 | sample_sdf(BSDFDAT *ndp, int sflags)
250                  return(0);
251                                                  /* below sampling threshold? */
252          if (dfp->maxHemi <= specthresh+FTINY) {
253 <                if (dfp->maxHemi > FTINY) {     /* XXX no color from BSDF! */
254 <                        double  d = SDdirectHemi(ndp->vinc, sflags, ndp->sd);
253 >                if (dfp->maxHemi > FTINY) {     /* XXX no color from BSDF */
254 >                        FVECT   vjit;
255 >                        double  d;
256                          COLOR   ctmp;
257 +                        bsdf_jitter(vjit, ndp);
258 +                        d = SDdirectHemi(vjit, sflags, ndp->sd);
259                          if (sflags == SDsampSpT) {
260                                  copycolor(ctmp, ndp->pr->pcol);
261                                  scalecolor(ctmp, d);
# Line 273 | Line 290 | m_bsdf(OBJREC *m, RAY *r)
290                                  (m->oargs.nfargs % 3))
291                  objerror(m, USER, "bad # arguments");
292  
293 <        SDerrorDetail[0] = '\0';                /* get BSDF data */
294 <        nd.sd = SDgetCache(m->oargs.sarg[1]);
278 <        if (nd.sd == NULL)
279 <                error(SYSTEM, "out of memory in m_bsdf");
280 <        if (!SDisLoaded(nd.sd)) {
281 <                char    *pname = getpath(m->oargs.sarg[1], getrlibpath(), R_OK);
282 <                if (pname == NULL) {
283 <                        sprintf(errmsg, "cannot find BSDF file \"%s\"",
284 <                                                m->oargs.sarg[1]);
285 <                        objerror(m, USER, errmsg);
286 <                }
287 <                ec = SDloadFile(nd.sd, pname);
288 <                if (ec)
289 <                        objerror(m, USER, cvt_sderr(ec));
290 <                SDretainSet = SDretainAll;
291 <        }
293 >                                                /* get BSDF data */
294 >        nd.sd = loadBSDF(m->oargs.sarg[1]);
295                                                  /* load cal file */
296          mf = getfunc(m, 5, 0x1d, 1);
297                                                  /* get thickness */
# Line 297 | Line 300 | m_bsdf(OBJREC *m, RAY *r)
300                  nd.thick = .0;
301                                                  /* check shadow */
302          if (r->crtype & SHADOW) {
303 <                SDfreeCache(nd.sd);
301 <                if (nd.thick > FTINY && nd.sd->tf != NULL &&
302 <                                nd.sd->tf->maxHemi > FTINY)
303 >                if ((nd.thick > FTINY) & (nd.sd->tf != NULL))
304                          raytrans(r);            /* pass-through */
305 +                SDfreeCache(nd.sd);
306                  return(1);                      /* else shadow */
307          }
308                                                  /* check unscattered ray */
309 <        if (!(r->crtype & (SPECULAR|AMBIENT)) && nd.thick > FTINY &&
310 <                        nd.sd->tf != NULL && nd.sd->tf->maxHemi > FTINY) {
309 >        if (!(r->crtype & (SPECULAR|AMBIENT)) &&
310 >                        (nd.thick > FTINY) & (nd.sd->tf != NULL)) {
311                  SDfreeCache(nd.sd);
312                  raytrans(r);                    /* pass-through */
313                  return(1);
# Line 320 | Line 322 | m_bsdf(OBJREC *m, RAY *r)
322                                          m->oargs.farg[2]);
323          } else {
324                  if (m->oargs.nfargs < 6) {      /* check invisible backside */
325 <                        if (!backvis && (nd.sd->rb == NULL ||
326 <                                                nd.sd->rb->maxHemi <= FTINY) &&
325 <                                        (nd.sd->tf == NULL ||
326 <                                                nd.sd->tf->maxHemi <= FTINY)) {
325 >                        if (!backvis && (nd.sd->rb == NULL) &
326 >                                                (nd.sd->tf == NULL)) {
327                                  SDfreeCache(nd.sd);
328                                  raytrans(r);
329                                  return(1);
# Line 365 | Line 365 | m_bsdf(OBJREC *m, RAY *r)
365                                                  /* compute local BSDF xform */
366          ec = SDcompXform(nd.toloc, nd.pnorm, upvec);
367          if (!ec) {
368 <                nd.vinc[0] = -r->rdir[0];
369 <                nd.vinc[1] = -r->rdir[1];
370 <                nd.vinc[2] = -r->rdir[2];
371 <                ec = SDmapDir(nd.vinc, nd.toloc, nd.vinc);
368 >                nd.vray[0] = -r->rdir[0];
369 >                nd.vray[1] = -r->rdir[1];
370 >                nd.vray[2] = -r->rdir[2];
371 >                ec = SDmapDir(nd.vray, nd.toloc, nd.vray);
372          }
373          if (!ec)
374                  ec = SDinvXform(nd.fromloc, nd.toloc);
375 <        if (ec) {
376 <                objerror(m, WARNING, cvt_sderr(ec));
375 >                                                /* determine BSDF resolution */
376 >        if (!ec)
377 >                ec = SDsizeBSDF(&nd.sr_vpsa, nd.vray, SDqueryMin, nd.sd);
378 >        if (!ec)
379 >                nd.sr_vpsa = sqrt(nd.sr_vpsa);
380 >        else {
381 >                objerror(m, WARNING, transSDError(ec));
382                  SDfreeCache(nd.sd);
383                  return(1);
384          }
385 +        
386          if (r->rod < .0) {                      /* perturb normal towards hit */
387                  nd.pnorm[0] = -nd.pnorm[0];
388                  nd.pnorm[1] = -nd.pnorm[1];

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines