68 |
|
FVECT pnorm; /* perturbed surface normal */ |
69 |
|
FVECT vray; /* local outgoing (return) vector */ |
70 |
|
double sr_vpsa[2]; /* sqrt of BSDF projected solid angle extrema */ |
71 |
< |
double thru_psa; /* through direction projected solid angle */ |
71 |
> |
double thru_r2; /* through rejection angle squared */ |
72 |
|
RREAL toloc[3][3]; /* world to local BSDF coords */ |
73 |
|
RREAL fromloc[3][3]; /* local BSDF coords to world */ |
74 |
|
double thick; /* surface thickness */ |
110 |
|
/* jitter query direction */ |
111 |
|
bsdf_jitter(vjit, ndp, 0); |
112 |
|
/* avoid indirect over-counting */ |
113 |
< |
if (ndp->thick != 0 && ndp->pr->crtype & (SPECULAR|AMBIENT) && |
114 |
< |
vsrc[2] > 0 ^ vjit[2] > 0) { |
113 |
> |
if (ndp->thru_r2 > FTINY && vsrc[2] > 0 ^ vjit[2] > 0) { |
114 |
|
double dx = vsrc[0] + vjit[0]; |
115 |
|
double dy = vsrc[1] + vjit[1]; |
116 |
< |
if (dx*dx + dy*dy <= ndp->thru_psa) |
116 |
> |
if (dx*dx + dy*dy <= ndp->thru_r2) |
117 |
|
return(0); |
118 |
|
} |
119 |
|
ec = SDevalBSDF(&sv, vjit, vsrc, ndp->sd); |
286 |
|
sample_sdcomp(BSDFDAT *ndp, SDComponent *dcp, int usepat) |
287 |
|
{ |
288 |
|
int nstarget = 1; |
289 |
< |
int nsent = 0; |
289 |
> |
int nsent; |
290 |
|
SDError ec; |
291 |
|
SDValue bsv; |
292 |
< |
double sthick; |
293 |
< |
FVECT vjit, vsmp; |
292 |
> |
double xrand; |
293 |
> |
FVECT vsmp; |
294 |
|
RAY sr; |
296 |
– |
int ntrials; |
295 |
|
/* multiple samples? */ |
296 |
|
if (specjitter > 1.5) { |
297 |
|
nstarget = specjitter*ndp->pr->rweight + .5; |
298 |
|
if (nstarget < 1) |
299 |
|
nstarget = 1; |
300 |
|
} |
301 |
< |
/* run through our trials */ |
302 |
< |
for (ntrials = 0; nsent < nstarget && ntrials < 9*nstarget; ntrials++) { |
303 |
< |
SDerrorDetail[0] = '\0'; |
304 |
< |
/* sample direction & coef. */ |
305 |
< |
bsdf_jitter(vjit, ndp, 0); |
306 |
< |
ec = SDsampComponent(&bsv, vsmp, vjit, ntrials ? frandom() |
307 |
< |
: urand(ilhash(dimlist,ndims)+samplendx), dcp); |
301 |
> |
/* run through our samples */ |
302 |
> |
for (nsent = 0; nsent < nstarget; nsent++) { |
303 |
> |
if (nstarget == 1) /* stratify random variable */ |
304 |
> |
xrand = urand(ilhash(dimlist,ndims)+samplendx); |
305 |
> |
else |
306 |
> |
xrand = (nsent + frandom())/(double)nstarget; |
307 |
> |
SDerrorDetail[0] = '\0'; /* sample direction & coef. */ |
308 |
> |
bsdf_jitter(vsmp, ndp, 0); |
309 |
> |
ec = SDsampComponent(&bsv, vsmp, xrand, dcp); |
310 |
|
if (ec) |
311 |
|
objerror(ndp->mp, USER, transSDError(ec)); |
312 |
< |
/* zero component? */ |
313 |
< |
if (bsv.cieY <= FTINY) |
312 |
> |
if (bsv.cieY <= FTINY) /* zero component? */ |
313 |
|
break; |
314 |
|
/* map vector to world */ |
315 |
|
if (SDmapDir(sr.rdir, ndp->fromloc, vsmp) != SDEnone) |
316 |
|
break; |
318 |
– |
/* unintentional penetration? */ |
319 |
– |
if (DOT(sr.rdir, ndp->pr->ron) > 0 ^ vsmp[2] > 0) |
320 |
– |
continue; |
317 |
|
/* spawn a specular ray */ |
318 |
|
if (nstarget > 1) |
319 |
|
bsv.cieY /= (double)nstarget; |
320 |
< |
cvt_sdcolor(sr.rcoef, &bsv); /* use color */ |
321 |
< |
if (usepat) /* pattern on transmission */ |
320 |
> |
cvt_sdcolor(sr.rcoef, &bsv); /* use sample color */ |
321 |
> |
if (usepat) /* apply pattern? */ |
322 |
|
multcolor(sr.rcoef, ndp->pr->pcol); |
323 |
|
if (rayorigin(&sr, SPECULAR, ndp->pr, sr.rcoef) < 0) { |
324 |
< |
if (maxdepth > 0) |
324 |
> |
if (maxdepth > 0) |
325 |
|
break; |
326 |
< |
++nsent; /* Russian roulette victim */ |
331 |
< |
continue; |
326 |
> |
continue; /* Russian roulette victim */ |
327 |
|
} |
328 |
|
/* need to offset origin? */ |
329 |
|
if (ndp->thick != 0 && ndp->pr->rod > 0 ^ vsmp[2] > 0) |
331 |
|
rayvalue(&sr); /* send & evaluate sample */ |
332 |
|
multcolor(sr.rcol, sr.rcoef); |
333 |
|
addcolor(ndp->pr->rcol, sr.rcol); |
339 |
– |
++nsent; |
334 |
|
} |
335 |
|
return(nsent); |
336 |
|
} |
484 |
|
if (!ec) |
485 |
|
ec = SDsizeBSDF(nd.sr_vpsa, nd.vray, NULL, |
486 |
|
SDqueryMin+SDqueryMax, nd.sd); |
487 |
< |
nd.thru_psa = .0; |
487 |
> |
nd.thru_r2 = .0; |
488 |
|
if (!ec && nd.thick != 0 && r->crtype & (SPECULAR|AMBIENT)) { |
489 |
|
FVECT vthru; |
490 |
|
vthru[0] = -nd.vray[0]; |
491 |
|
vthru[1] = -nd.vray[1]; |
492 |
|
vthru[2] = -nd.vray[2]; |
493 |
< |
ec = SDsizeBSDF(&nd.thru_psa, nd.vray, vthru, |
493 |
> |
ec = SDsizeBSDF(&nd.thru_r2, nd.vray, vthru, |
494 |
|
SDqueryMin, nd.sd); |
495 |
+ |
nd.thru_r2 *= 1./PI; |
496 |
|
} |
497 |
|
if (ec) { |
498 |
|
objerror(m, WARNING, transSDError(ec)); |