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

Comparing ray/src/rt/ashikhmin.c (file contents):
Revision 2.1 by greg, Sun Jul 29 19:01:39 2012 UTC vs.
Revision 2.7 by greg, Wed Nov 15 18:02:52 2023 UTC

# Line 14 | Line 14 | static const char RCSid[] = "$Id$";
14   #include  "source.h"
15   #include  "func.h"
16   #include  "random.h"
17 + #include  "pmapmat.h"
18  
19   #ifndef  MAXITER
20   #define  MAXITER        10              /* maximum # specular ray attempts */
# Line 32 | Line 33 | static const char RCSid[] = "$Id$";
33   #define  SPA_REFL       01              /* has reflected specular component */
34   #define  SPA_FLAT       02              /* reflecting surface is flat */
35   #define  SPA_RBLT       010             /* reflection below sample threshold */
35 #define  SPA_BADU       020             /* bad u direction calculation */
36  
37   typedef struct {
38          OBJREC  *mp;            /* material pointer */
39          RAY  *rp;               /* ray pointer */
40          short  specfl;          /* specularity flags, defined above */
41 <        COLOR  mcolor;          /* color of this material */
42 <        COLOR  scolor;          /* color of specular component */
41 >        SCOLOR  mcolor;         /* color of this material */
42 >        SCOLOR  scolor;         /* color of specular component */
43          FVECT  u, v;            /* u and v vectors orienting anisotropy */
44          double  u_power;        /* u power */
45          double  v_power;        /* v power */
# Line 47 | Line 47 | typedef struct {
47          double  pdot;           /* perturbed dot product */
48   }  ASHIKDAT;            /* anisotropic material data */
49  
50 < static void getacoords_as(RAY *r, ASHIKDAT *np);
51 < static void ashiksamp(RAY *r, ASHIKDAT *np);
50 > static void getacoords_as(ASHIKDAT *np);
51 > static void ashiksamp(ASHIKDAT *np);
52  
53 + #undef MAX
54 + #define MAX(a,b)        ((a)>(b) ? (a) : (b))
55  
54 static double
55 max(double a, double b) {
56        if (a > b)
57                return(a);
58        return(b);
59 }
56  
61
57   static double
58   schlick_fres(double dprod)
59   {
# Line 70 | Line 65 | schlick_fres(double dprod)
65  
66   static void
67   dirashik(               /* compute source contribution */
68 <        COLOR  cval,            /* returned coefficient */
68 >        SCOLOR  scval,          /* returned coefficient */
69          void  *nnp,             /* material data */
70          FVECT  ldir,            /* light source direction */
71          double  omega           /* light source size */
# Line 80 | Line 75 | dirashik(              /* compute source contribution */
75          double  ldot;
76          double  dtmp, dtmp1, dtmp2;
77          FVECT  h;
78 <        COLOR  ctmp;
78 >        SCOLOR  sctmp;
79  
80 <        setcolor(cval, 0.0, 0.0, 0.0);
80 >        scolorblack(scval);
81  
82          ldot = DOT(np->pnorm, ldir);
83  
84 <        if (ldot < 0.0)
84 >        if (ldot <= FTINY)
85                  return;         /* wrong side */
86  
87          /*
88           *  Compute and add diffuse reflected component to returned
89           *  color.
90           */
91 <        copycolor(ctmp, np->mcolor);
91 >        copyscolor(sctmp, np->mcolor);
92          dtmp = ldot * omega * (1.0/PI) * (1. - schlick_fres(ldot));
93 <        scalecolor(ctmp, dtmp);        
94 <        addcolor(cval, ctmp);
93 >        scalescolor(sctmp, dtmp);
94 >        saddscolor(scval, sctmp);
95  
96 <        if ((np->specfl & (SPA_REFL|SPA_BADU)) != SPA_REFL)
96 >        if (!(np->specfl & SPA_REFL) || ambRayInPmap(np->rp))
97                  return;
98          /*
99           *  Compute specular reflection coefficient
# Line 115 | Line 110 | dirashik(              /* compute source contribution */
110          dtmp = DOT(np->pnorm, h);
111          dtmp = pow(dtmp, (dtmp1+dtmp2)/(1.-dtmp*dtmp));
112          dtmp *= sqrt((np->u_power+1.)*(np->v_power+1.));
113 <        dtmp /= 8.*PI * DOT(ldir,h) * max(ldot,np->pdot);
113 >        dtmp /= 8.*PI * DOT(ldir,h) * MAX(ldot,np->pdot);
114                                          /* worth using? */
115          if (dtmp > FTINY) {
116 <                copycolor(ctmp, np->scolor);
116 >                copyscolor(sctmp, np->scolor);
117                  dtmp *= ldot * omega;
118 <                scalecolor(ctmp, dtmp);
119 <                addcolor(cval, ctmp);
118 >                scalescolor(sctmp, dtmp);
119 >                saddscolor(scval, sctmp);
120          }
121   }
122  
# Line 133 | Line 128 | m_ashikhmin(                   /* shade ray that hit something anisotr
128   )
129   {
130          ASHIKDAT  nd;
131 <        COLOR  ctmp;
131 >        SCOLOR  sctmp;
132          double  fres;
133          int  i;
134                                                  /* easy shadow test */
# Line 155 | Line 150 | m_ashikhmin(                   /* shade ray that hit something anisotr
150                                                  /* get material color */
151          nd.mp = m;
152          nd.rp = r;
153 <        setcolor(nd.mcolor, m->oargs.farg[0],
153 >        setscolor(nd.mcolor, m->oargs.farg[0],
154                             m->oargs.farg[1],
155                             m->oargs.farg[2]);
156 <        setcolor(nd.scolor, m->oargs.farg[3],
156 >        setscolor(nd.scolor, m->oargs.farg[3],
157                             m->oargs.farg[4],
158                             m->oargs.farg[5]);
159                                                  /* get specular power */
# Line 169 | Line 164 | m_ashikhmin(                   /* shade ray that hit something anisotr
164          nd.pdot = raynormal(nd.pnorm, r);       /* perturb normal */
165          if (nd.pdot < .001)
166                  nd.pdot = .001;                 /* non-zero for dirashik() */
167 <        multcolor(nd.mcolor, r->pcol);          /* modify diffuse color */
167 >        smultscolor(nd.mcolor, r->pcol);        /* modify diffuse color */
168  
169 <        if (bright(nd.scolor) > FTINY) {        /* adjust specular color */
169 >        if (sintens(nd.scolor) > FTINY) {       /* adjust specular color */
170                  nd.specfl |= SPA_REFL;
171                                                  /* check threshold */
172 <                if (specthresh >= bright(nd.scolor)-FTINY)
172 >                if (specthresh >= pbright(nd.scolor)-FTINY)
173                          nd.specfl |= SPA_RBLT;
174                  fres = schlick_fres(nd.pdot);   /* Schick's Fresnel approx */
175 <                for (i = 0; i < 3; i++)
176 <                        colval(nd.scolor,i) += (1.-colval(nd.scolor,i))*fres;
175 >                for (i = NCSAMP; i--; )
176 >                        nd.scolor[i] += (1.-nd.scolor[i])*fres;
177          }
178          if (r->ro != NULL && isflat(r->ro->otype))
179                  nd.specfl |= SPA_FLAT;
180                                                  /* set up coordinates */
181 <        getacoords_as(r, &nd);
181 >        getacoords_as(&nd);
182                                                  /* specular sampling? */
183          if ((nd.specfl & (SPA_REFL|SPA_RBLT)) == SPA_REFL)
184 <                ashiksamp(r, &nd);
184 >                ashiksamp(&nd);
185                                                  /* diffuse interreflection */
186 <        if (bright(nd.mcolor) > FTINY) {
187 <                copycolor(ctmp, nd.mcolor);     /* modified by material color */                
186 >        if (sintens(nd.mcolor) > FTINY) {
187 >                copyscolor(sctmp, nd.mcolor);   /* modified by material color */
188                  if (nd.specfl & SPA_RBLT)       /* add in specular as well? */
189 <                        addcolor(ctmp, nd.scolor);
190 <                multambient(ctmp, r, nd.pnorm);
191 <                addcolor(r->rcol, ctmp);        /* add to returned color */
189 >                        saddscolor(sctmp, nd.scolor);
190 >                multambient(sctmp, r, nd.pnorm);
191 >                saddscolor(r->rcol, sctmp);     /* add to returned color */
192          }
193          direct(r, dirashik, &nd);               /* add direct component */
194  
# Line 203 | Line 198 | m_ashikhmin(                   /* shade ray that hit something anisotr
198  
199   static void
200   getacoords_as(          /* set up coordinate system */
206        RAY  *r,
201          ASHIKDAT  *np
202   )
203   {
# Line 211 | Line 205 | getacoords_as(         /* set up coordinate system */
205          int  i;
206  
207          mf = getfunc(np->mp, 3, 0x7, 1);
208 <        setfunc(np->mp, r);
208 >        setfunc(np->mp, np->rp);
209          errno = 0;
210          for (i = 0; i < 3; i++)
211                  np->u[i] = evalue(mf->ep[i]);
212 <        if ((errno == EDOM) | (errno == ERANGE)) {
213 <                objerror(np->mp, WARNING, "compute error");
220 <                np->specfl |= SPA_BADU;
221 <                return;
222 <        }
212 >        if ((errno == EDOM) | (errno == ERANGE))
213 >                np->u[0] = np->u[1] = np->u[2] = 0.0;
214          if (mf->fxp != &unitxf)
215                  multv3(np->u, np->u, mf->fxp->xfm);
216          fcross(np->v, np->pnorm, np->u);
217          if (normalize(np->v) == 0.0) {
218 <                objerror(np->mp, WARNING, "illegal orientation vector");
219 <                np->specfl |= SPA_BADU;
220 <                return;
221 <        }
222 <        fcross(np->u, np->v, np->pnorm);
218 >                if (fabs(np->u_power - np->v_power) > 0.1)
219 >                        objerror(np->mp, WARNING, "bad orientation vector");
220 >                getperpendicular(np->u, np->pnorm, 1);  /* punting */
221 >                fcross(np->v, np->pnorm, np->u);
222 >                np->u_power = np->v_power =
223 >                        2./(1./(np->u_power+1e-5) + 1./(np->v_power+1e-5));
224 >        } else
225 >                fcross(np->u, np->v, np->pnorm);
226   }
227  
228  
229   static void
230   ashiksamp(              /* sample anisotropic Ashikhmin-Shirley specular */
237        RAY  *r,
231          ASHIKDAT  *np
232   )
233   {
# Line 242 | Line 235 | ashiksamp(             /* sample anisotropic Ashikhmin-Shirley sp
235          FVECT  h;
236          double  rv[2], dtmp;
237          double  cosph, sinph, costh, sinth;
245        COLOR   scol;
238          int  maxiter, ntrials, nstarget, nstaken;
239          int  i;
240  
241 <        if (np->specfl & SPA_BADU ||
250 <                        rayorigin(&sr, SPECULAR, r, np->scolor) < 0)
241 >        if (rayorigin(&sr, SPECULAR, np->rp, np->scolor) < 0)
242                  return;
243  
244          nstarget = 1;
245          if (specjitter > 1.5) {                 /* multiple samples? */
246 <                nstarget = specjitter*r->rweight + .5;
246 >                nstarget = specjitter*np->rp->rweight + .5;
247                  if (sr.rweight <= minweight*nstarget)
248                          nstarget = sr.rweight/minweight;
249                  if (nstarget > 1) {
250                          dtmp = 1./nstarget;
251 <                        scalecolor(sr.rcoef, dtmp);
251 >                        scalescolor(sr.rcoef, dtmp);
252                          sr.rweight *= dtmp;
253                  } else
254                          nstarget = 1;
# Line 269 | Line 260 | ashiksamp(             /* sample anisotropic Ashikhmin-Shirley sp
260                  if (ntrials)
261                          dtmp = frandom();
262                  else
263 <                        dtmp = urand(ilhash(dimlist,ndims)+1823+samplendx);
263 >                        dtmp = urand(ilhash(dimlist,ndims)+647+samplendx);
264                  multisamp(rv, 2, dtmp);
265                  dtmp = 2.*PI * rv[0];
266 <                cosph = sqrt(np->u_power + 1.) * tcos(dtmp);
267 <                sinph = sqrt(np->v_power + 1.) * tsin(dtmp);
268 <                dtmp = 1./(cosph*cosph + sinph*sinph);
266 >                cosph = sqrt(np->v_power + 1.) * tcos(dtmp);
267 >                sinph = sqrt(np->u_power + 1.) * tsin(dtmp);
268 >                dtmp = 1./sqrt(cosph*cosph + sinph*sinph);
269                  cosph *= dtmp;
270                  sinph *= dtmp;
271                  costh = pow(rv[1], 1./(np->u_power*cosph*cosph+np->v_power*sinph*sinph+1.));
# Line 286 | Line 277 | ashiksamp(             /* sample anisotropic Ashikhmin-Shirley sp
277  
278                  if (nstaken)
279                          rayclear(&sr);
280 <                dtmp = -2.*DOT(h, r->rdir);
281 <                VSUM(sr.rdir, r->rdir, h, dtmp);                                
280 >                dtmp = -2.*DOT(h, np->rp->rdir);
281 >                VSUM(sr.rdir, np->rp->rdir, h, dtmp);                          
282                                                  /* sample rejection test */
283 <                if (DOT(sr.rdir, r->ron) <= FTINY)
283 >                if (DOT(sr.rdir, np->rp->ron) <= FTINY)
284                          continue;
285 +                checknorm(sr.rdir);
286                  rayvalue(&sr);
287 <                multcolor(sr.rcol, sr.rcoef);
288 <                addcolor(r->rcol, sr.rcol);
287 >                smultscolor(sr.rcol, sr.rcoef);
288 >                saddscolor(np->rp->rcol, sr.rcol);
289                  ++nstaken;
290          }
291          ndims--;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines