96 |
|
normalize(vres); |
97 |
|
} |
98 |
|
|
99 |
+ |
/* Evaluate BSDF for direct component, returning true if OK to proceed */ |
100 |
+ |
static int |
101 |
+ |
direct_bsdf_OK(COLOR cval, FVECT ldir, BSDFDAT *ndp) |
102 |
+ |
{ |
103 |
+ |
FVECT vsrc, vjit; |
104 |
+ |
SDValue sv; |
105 |
+ |
SDError ec; |
106 |
+ |
/* transform source direction */ |
107 |
+ |
if (SDmapDir(vsrc, ndp->toloc, ldir) != SDEnone) |
108 |
+ |
return(0); |
109 |
+ |
/* jitter query direction */ |
110 |
+ |
bsdf_jitter(vjit, ndp); |
111 |
+ |
/* avoid indirect over-counting */ |
112 |
+ |
if (ndp->thick != .0 && ndp->pr->crtype & (SPECULAR|AMBIENT) && |
113 |
+ |
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->sr_vpsa*ndp->sr_vpsa) |
117 |
+ |
return(0); |
118 |
+ |
} |
119 |
+ |
ec = SDevalBSDF(&sv, vjit, vsrc, ndp->sd); |
120 |
+ |
if (ec) |
121 |
+ |
objerror(ndp->mp, USER, transSDError(ec)); |
122 |
+ |
|
123 |
+ |
if (sv.cieY <= FTINY) /* not worth using? */ |
124 |
+ |
return(0); |
125 |
+ |
/* else we're good to go */ |
126 |
+ |
cvt_sdcolor(cval, &sv); |
127 |
+ |
return(1); |
128 |
+ |
} |
129 |
+ |
|
130 |
|
/* Compute source contribution for BSDF (reflected & transmitted) */ |
131 |
|
static void |
132 |
|
dir_bsdf( |
137 |
|
) |
138 |
|
{ |
139 |
|
BSDFDAT *np = (BSDFDAT *)nnp; |
109 |
– |
SDError ec; |
110 |
– |
SDValue sv; |
111 |
– |
FVECT vsrc; |
112 |
– |
FVECT vjit; |
140 |
|
double ldot; |
141 |
|
double dtmp; |
142 |
|
COLOR ctmp; |
168 |
|
/* |
169 |
|
* Compute scattering coefficient using BSDF. |
170 |
|
*/ |
171 |
< |
if (SDmapDir(vsrc, np->toloc, ldir) != SDEnone) |
171 |
> |
if (!direct_bsdf_OK(ctmp, ldir, np)) |
172 |
|
return; |
146 |
– |
bsdf_jitter(vjit, np); |
147 |
– |
ec = SDevalBSDF(&sv, vjit, vsrc, np->sd); |
148 |
– |
if (ec) |
149 |
– |
objerror(np->mp, USER, transSDError(ec)); |
150 |
– |
|
151 |
– |
if (sv.cieY <= FTINY) /* not worth using? */ |
152 |
– |
return; |
153 |
– |
cvt_sdcolor(ctmp, &sv); |
173 |
|
if (ldot > .0) { /* pattern only diffuse reflection */ |
174 |
|
COLOR ctmp1, ctmp2; |
175 |
|
dtmp = (np->pr->rod > .0) ? np->sd->rLambFront.cieY |
176 |
|
: np->sd->rLambBack.cieY; |
177 |
< |
dtmp /= PI * sv.cieY; /* diffuse fraction */ |
177 |
> |
/* diffuse fraction */ |
178 |
> |
dtmp /= PI * bright(ctmp); |
179 |
|
copycolor(ctmp2, np->pr->pcol); |
180 |
|
scalecolor(ctmp2, dtmp); |
181 |
|
setcolor(ctmp1, 1.-dtmp, 1.-dtmp, 1.-dtmp); |
200 |
|
) |
201 |
|
{ |
202 |
|
BSDFDAT *np = (BSDFDAT *)nnp; |
183 |
– |
SDError ec; |
184 |
– |
SDValue sv; |
185 |
– |
FVECT vsrc; |
186 |
– |
FVECT vjit; |
203 |
|
double ldot; |
204 |
|
double dtmp; |
205 |
|
COLOR ctmp, ctmp1, ctmp2; |
223 |
|
/* |
224 |
|
* Compute reflection coefficient using BSDF. |
225 |
|
*/ |
226 |
< |
if (SDmapDir(vsrc, np->toloc, ldir) != SDEnone) |
226 |
> |
if (!direct_bsdf_OK(ctmp, ldir, np)) |
227 |
|
return; |
212 |
– |
bsdf_jitter(vjit, np); |
213 |
– |
ec = SDevalBSDF(&sv, vjit, vsrc, np->sd); |
214 |
– |
if (ec) |
215 |
– |
objerror(np->mp, USER, transSDError(ec)); |
216 |
– |
|
217 |
– |
if (sv.cieY <= FTINY) /* not worth using? */ |
218 |
– |
return; |
219 |
– |
cvt_sdcolor(ctmp, &sv); |
228 |
|
/* pattern only diffuse reflection */ |
229 |
|
dtmp = (np->pr->rod > .0) ? np->sd->rLambFront.cieY |
230 |
|
: np->sd->rLambBack.cieY; |
231 |
< |
dtmp /= PI * sv.cieY; /* diffuse fraction */ |
231 |
> |
dtmp /= PI * bright(ctmp); /* diffuse fraction */ |
232 |
|
copycolor(ctmp2, np->pr->pcol); |
233 |
|
scalecolor(ctmp2, dtmp); |
234 |
|
setcolor(ctmp1, 1.-dtmp, 1.-dtmp, 1.-dtmp); |
249 |
|
) |
250 |
|
{ |
251 |
|
BSDFDAT *np = (BSDFDAT *)nnp; |
244 |
– |
SDError ec; |
245 |
– |
SDValue sv; |
246 |
– |
FVECT vsrc; |
247 |
– |
FVECT vjit; |
252 |
|
double ldot; |
253 |
|
double dtmp; |
254 |
|
COLOR ctmp; |
272 |
|
/* |
273 |
|
* Compute scattering coefficient using BSDF. |
274 |
|
*/ |
275 |
< |
if (SDmapDir(vsrc, np->toloc, ldir) != SDEnone) |
275 |
> |
if (!direct_bsdf_OK(ctmp, ldir, np)) |
276 |
|
return; |
273 |
– |
bsdf_jitter(vjit, np); |
274 |
– |
ec = SDevalBSDF(&sv, vjit, vsrc, np->sd); |
275 |
– |
if (ec) |
276 |
– |
objerror(np->mp, USER, transSDError(ec)); |
277 |
– |
|
278 |
– |
if (sv.cieY <= FTINY) /* not worth using? */ |
279 |
– |
return; |
280 |
– |
cvt_sdcolor(ctmp, &sv); |
277 |
|
/* full pattern on transmission */ |
278 |
|
multcolor(ctmp, np->pr->pcol); |
279 |
|
dtmp = -ldot * omega; |
422 |
|
return(1); /* or shadow */ |
423 |
|
} |
424 |
|
/* check other rays to pass */ |
425 |
< |
if (nd.thick != 0 && (!(r->crtype & (SPECULAR|AMBIENT)) || |
425 |
> |
if (nd.thick != .0 && (!(r->crtype & (SPECULAR|AMBIENT)) || |
426 |
|
nd.thick > .0 ^ hitfront)) { |
427 |
|
raytrans(r); /* hide our proxy */ |
428 |
|
return(1); |