20 |
|
|
21 |
|
#include "random.h" |
22 |
|
|
23 |
+ |
extern double specthresh; /* specular sampling threshold */ |
24 |
+ |
extern double specjitter; /* specular sampling jitter */ |
25 |
+ |
|
26 |
|
/* |
27 |
|
* This routine uses portions of the reflection |
28 |
|
* model described by Cook and Torrance. |
45 |
|
#define SP_TRAN 02 /* has transmitted specular */ |
46 |
|
#define SP_PURE 010 /* purely specular (zero roughness) */ |
47 |
|
#define SP_FLAT 020 /* flat reflecting surface */ |
48 |
+ |
#define SP_RBLT 040 /* reflection below sample threshold */ |
49 |
+ |
#define SP_TBLT 0100 /* transmission below threshold */ |
50 |
|
|
51 |
|
typedef struct { |
52 |
|
OBJREC *mp; /* material pointer */ |
191 |
|
for (i = 0; i < 3; i++) |
192 |
|
colval(nd.scolor,i) += (1.0-colval(nd.scolor,i))*dtmp; |
193 |
|
nd.rspec += (1.0-nd.rspec)*dtmp; |
194 |
+ |
/* check threshold */ |
195 |
+ |
if (specthresh > FTINY && |
196 |
+ |
((specthresh >= 1.-FTINY || |
197 |
+ |
specthresh + (.1 - .2*urand(8199+samplendx)) |
198 |
+ |
> nd.rspec))) |
199 |
+ |
nd.specfl |= SP_RBLT; |
200 |
|
/* compute reflected ray */ |
201 |
|
for (i = 0; i < 3; i++) |
202 |
|
nd.vrefl[i] = r->rdir[i] + 2.0*nd.pdot*nd.pnorm[i]; |
218 |
|
nd.tdiff = nd.trans - nd.tspec; |
219 |
|
if (nd.tspec > FTINY) { |
220 |
|
nd.specfl |= SP_TRAN; |
221 |
+ |
/* check threshold */ |
222 |
+ |
if (specthresh > FTINY && |
223 |
+ |
((specthresh >= 1.-FTINY || |
224 |
+ |
specthresh + |
225 |
+ |
(.1 - .2*urand(7241+samplendx)) |
226 |
+ |
> nd.tspec))) |
227 |
+ |
nd.specfl |= SP_TBLT; |
228 |
|
if (r->crtype & SHADOW || |
229 |
|
DOT(r->pert,r->pert) <= FTINY*FTINY) { |
230 |
|
VCOPY(nd.prdir, r->rdir); |
268 |
|
|
269 |
|
if (nd.rdiff > FTINY) { /* ambient from this side */ |
270 |
|
ambient(ctmp, r); |
271 |
< |
scalecolor(ctmp, nd.rdiff); |
271 |
> |
if (nd.specfl & SP_RBLT) |
272 |
> |
scalecolor(ctmp, 1.0-nd.trans); |
273 |
> |
else |
274 |
> |
scalecolor(ctmp, nd.rdiff); |
275 |
|
multcolor(ctmp, nd.mcolor); /* modified by material color */ |
276 |
|
addcolor(r->rcol, ctmp); /* add to returned color */ |
277 |
|
} |
278 |
|
if (nd.tdiff > FTINY) { /* ambient from other side */ |
279 |
|
flipsurface(r); |
280 |
|
ambient(ctmp, r); |
281 |
< |
scalecolor(ctmp, nd.tdiff); |
281 |
> |
if (nd.specfl & SP_TBLT) |
282 |
> |
scalecolor(ctmp, nd.trans); |
283 |
> |
else |
284 |
> |
scalecolor(ctmp, nd.tdiff); |
285 |
|
multcolor(ctmp, nd.mcolor); /* modified by color */ |
286 |
|
addcolor(r->rcol, ctmp); |
287 |
|
flipsurface(r); |
315 |
|
normalize(u); |
316 |
|
fcross(v, np->pnorm, u); |
317 |
|
/* compute reflection */ |
318 |
< |
if (np->specfl & SP_REFL && |
318 |
> |
if ((np->specfl & (SP_REFL|SP_RBLT)) == SP_REFL && |
319 |
|
rayorigin(&sr, r, SPECULAR, np->rspec) == 0) { |
320 |
|
dimlist[ndims++] = (int)np->mp; |
321 |
|
for (ntries = 0; ntries < 10; ntries++) { |
325 |
|
d = 2.0*PI * rv[0]; |
326 |
|
cosp = cos(d); |
327 |
|
sinp = sin(d); |
328 |
+ |
rv[1] = 1.0 - specjitter*rv[1]; |
329 |
|
if (rv[1] <= FTINY) |
330 |
|
d = 1.0; |
331 |
|
else |