28 |
|
/* Photon map lookup functions per type */ |
29 |
|
void (*pmapLookup [NUM_PMAP_TYPES])(PhotonMap*, RAY*, COLOR) = { |
30 |
|
photonDensity, photonPreCompDensity, photonDensity, volumePhotonDensity, |
31 |
< |
photonDensity, NULL |
31 |
> |
photonDensity, photonDensity |
32 |
|
}; |
33 |
|
|
34 |
|
|
109 |
|
/* Photon density estimate. Returns irradiance at ray -> rop. */ |
110 |
|
{ |
111 |
|
unsigned i; |
112 |
< |
float r; |
112 |
> |
float r2; |
113 |
|
COLOR flux; |
114 |
|
Photon *photon; |
115 |
|
const PhotonSearchQueueNode *sqn; |
141 |
|
/* No bias compensation. Just do a plain vanilla estimate */ |
142 |
|
sqn = pmap -> squeue.node + 1; |
143 |
|
|
144 |
< |
/* Average radius between furthest two photons to improve accuracy */ |
145 |
< |
r = max(sqn -> dist2, (sqn + 1) -> dist2); |
146 |
< |
r = 0.25 * (pmap -> maxDist2 + r + 2 * sqrt(pmap -> maxDist2 * r)); |
144 |
> |
/* Average radius^2 between furthest two photons to improve accuracy */ |
145 |
> |
r2 = max(sqn -> dist2, (sqn + 1) -> dist2); |
146 |
> |
r2 = 0.25 * (pmap -> maxDist2 + r2 + 2 * sqrt(pmap -> maxDist2 * r2)); |
147 |
|
|
148 |
|
/* Skip the extra photon */ |
149 |
|
for (i = 1 ; i < pmap -> squeue.tail; i++, sqn++) { |
151 |
|
getPhotonFlux(photon, flux); |
152 |
|
#ifdef PMAP_EPANECHNIKOV |
153 |
|
/* Apply Epanechnikov kernel to photon flux based on photon dist */ |
154 |
< |
scalecolor(flux, 2 * (1 - sqn -> dist2 / r)); |
154 |
> |
scalecolor(flux, 2 * (1 - sqn -> dist2 / r2)); |
155 |
|
#endif |
156 |
|
addcolor(irrad, flux); |
157 |
|
} |
158 |
|
|
159 |
|
/* Divide by search area PI * r^2, 1 / PI required as ambient |
160 |
|
normalisation factor */ |
161 |
< |
scalecolor(irrad, 1 / (PI * PI * r)); |
161 |
> |
scalecolor(irrad, 1 / (PI * PI * r2)); |
162 |
|
|
163 |
|
return; |
164 |
|
} |
192 |
|
/* Photon volume density estimate. Returns irradiance at ray -> rop. */ |
193 |
|
{ |
194 |
|
unsigned i; |
195 |
< |
float r, gecc2, ph; |
195 |
> |
float r2, gecc2, ph; |
196 |
|
COLOR flux; |
197 |
|
Photon *photon; |
198 |
|
const PhotonSearchQueueNode *sqn; |
217 |
|
gecc2 = ray -> gecc * ray -> gecc; |
218 |
|
sqn = pmap -> squeue.node + 1; |
219 |
|
|
220 |
< |
/* Average radius between furthest two photons to improve accuracy */ |
221 |
< |
r = max(sqn -> dist2, (sqn + 1) -> dist2); |
222 |
< |
r = 0.25 * (pmap -> maxDist2 + r + 2 * sqrt(pmap -> maxDist2 * r)); |
220 |
> |
/* Average radius^2 between furthest two photons to improve accuracy */ |
221 |
> |
r2 = max(sqn -> dist2, (sqn + 1) -> dist2); |
222 |
> |
r2 = 0.25 * (pmap -> maxDist2 + r2 + 2 * sqrt(pmap -> maxDist2 * r2)); |
223 |
|
|
224 |
|
/* Skip the extra photon */ |
225 |
|
for (i = 1; i < pmap -> squeue.tail; i++, sqn++) { |
241 |
|
|
242 |
|
/* Divide by search volume 4 / 3 * PI * r^3 and phase function |
243 |
|
normalization factor 1 / (4 * PI) */ |
244 |
< |
scalecolor(irrad, 3 / (16 * PI * PI * r * sqrt(r))); |
244 |
> |
scalecolor(irrad, 3 / (16 * PI * PI * r2 * sqrt(r2))); |
245 |
|
return; |
246 |
|
} |
247 |
|
#if 0 |