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.3 by greg, Sat Feb 19 01:48:59 2011 UTC vs.
Revision 2.4 by greg, Sat Feb 19 23:42:09 2011 UTC

# Line 47 | 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 64 | Line 72 | typedef struct {
72  
73   #define cvt_sdcolor(cv, svp)    ccy2rgb(&(svp)->spec, (svp)->cieY, cv)
74  
75 + /* Jitter ray sample according to projected solid angle and specjitter */
76 + static void
77 + bsdf_jitter(FVECT vres, BSDFDAT *ndp)
78 + {
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 */
92   static void
93   dirbsdf(
# Line 76 | Line 100 | dirbsdf(
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 108 | 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, transSDError(ec));
142  
# Line 145 | 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 158 | 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),
164 <                                                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, 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 187 | Line 212 | sample_sdcomp(BSDFDAT *ndp, SDComponent *dcp, int usep
212                  }
213                  if (ndp->thick > FTINY) {       /* need to move origin? */
214                          sthick = (ndp->pr->rod > .0) ? -ndp->thick : ndp->thick;
215 <                        if (sthick < .0 ^ vout[2] > .0)
215 >                        if (sthick < .0 ^ vsmp[2] > .0)
216                                  VSUM(sr.rorg, sr.rorg, ndp->pr->ron, sthick);
217                  }
218                  rayvalue(&sr);                  /* send & evaluate sample */
# Line 226 | Line 251 | sample_sdf(BSDFDAT *ndp, int sflags)
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);
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 337 | 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) {
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