ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmcontrib2.c
Revision: 2.3
Committed: Mon Aug 14 21:12:10 2017 UTC (6 years, 9 months ago) by rschregle
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R1
Changes since 2.2: +9 -2 lines
Log Message:
Updated photon map code for Windows; no multproc or ooC for now

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 rschregle 2.3 static const char RCSid[] = "$Id: pmcontrib2.c,v 2.2 2016/09/30 16:51:46 greg Exp $";
3 greg 2.1 #endif
4    
5     /*
6     ======================================================================
7     Photon map support for using light source contributions
8    
9     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
10     (c) Lucerne University of Applied Sciences and Arts,
11     supported by the Swiss National Science Foundation (SNSF, #147053)
12     ======================================================================
13    
14 rschregle 2.3 $Id: pmcontrib2.c,v 2.2 2016/09/30 16:51:46 greg Exp $
15 greg 2.1 */
16    
17    
18     #include "pmapcontrib.h"
19     #include "pmapmat.h"
20     #include "pmapsrc.h"
21     #include "pmaprand.h"
22     #include "pmapio.h"
23     #include "pmapdiag.h"
24     #include "rcontrib.h"
25     #include "otypes.h"
26    
27    
28    
29     static void setPmapContribParams (PhotonMap *pmap, LUTAB *srcContrib)
30     /* Set parameters for light source contributions */
31     {
32     /* Set light source modifier list and appropriate callback to extract
33     * their contributions from the photon map */
34     if (pmap) {
35     pmap -> srcContrib = srcContrib;
36     pmap -> lookup = photonContrib;
37     /* Ensure we get all requested photon contribs during lookups */
38     pmap -> gatherTolerance = 1.0;
39     }
40     }
41    
42    
43    
44     static void checkPmapContribs (const PhotonMap *pmap, LUTAB *srcContrib)
45     /* Check modifiers for light source contributions */
46     {
47     const PhotonPrimary *primary = pmap -> primaries;
48     PhotonPrimaryIdx i, found = 0;
49     OBJREC *srcMod;
50    
51     /* Make sure at least one of the modifiers is actually in the pmap,
52     * otherwise findPhotons() winds up in an infinite loop! */
53     for (i = pmap -> numPrimary; i; --i, ++primary) {
54     if (primary -> srcIdx < 0 || primary -> srcIdx >= nsources)
55     error(INTERNAL, "invalid light source index in photon map");
56    
57     srcMod = findmaterial(source [primary -> srcIdx].so);
58     if ((MODCONT*)lu_find(srcContrib, srcMod -> oname) -> data)
59     ++found;
60     }
61    
62     if (!found)
63     error(USER, "modifiers not in photon map");
64     }
65    
66    
67    
68     void initPmapContrib (LUTAB *srcContrib, unsigned numSrcContrib)
69     {
70     unsigned t;
71    
72     for (t = 0; t < NUM_PMAP_TYPES; t++)
73     if (photonMaps [t] && t != PMAP_TYPE_CONTRIB) {
74     sprintf(errmsg, "%s photon map does not support contributions",
75     pmapName [t]);
76     error(USER, errmsg);
77     }
78    
79     /* Get params */
80     setPmapContribParams(contribPmap, srcContrib);
81    
82     if (contribPhotonMapping) {
83     if (contribPmap -> maxGather < numSrcContrib) {
84 rschregle 2.3 #if 0
85 greg 2.1 /* Adjust density estimate bandwidth if lower than modifier
86     * count, otherwise contributions are missing */
87     error(WARNING, "contrib density estimate bandwidth too low, "
88     "adjusting to modifier count");
89     contribPmap -> maxGather = numSrcContrib;
90 rschregle 2.3 #else
91     /* Warn if density estimate bandwidth is lower than modifier
92     * count, since some contributions will be missing */
93     error(WARNING, "photon density estimate bandwidth too low,"
94     " contributions may be underestimated");
95     #endif
96 greg 2.1 }
97    
98     /* Sanity check */
99     checkPmapContribs(contribPmap, srcContrib);
100     }
101     }
102    
103    
104    
105     void photonContrib (PhotonMap *pmap, RAY *ray, COLOR irrad)
106     /* Sum up light source contributions from photons in pmap->srcContrib */
107     {
108     unsigned i;
109     PhotonSearchQueueNode *sqn;
110     float r, invArea;
111     RREAL rayCoeff [3];
112     Photon *photon;
113     static char warn = 1;
114    
115     setcolor(irrad, 0, 0, 0);
116    
117     if (!pmap -> maxGather)
118     return;
119    
120     /* Ignore sources */
121     if (ray -> ro && islight(objptr(ray -> ro -> omod) -> otype))
122     return;
123    
124     /* Get cumulative path coefficient up to photon lookup point */
125     raycontrib(rayCoeff, ray, PRIMARY);
126    
127     /* Lookup photons */
128     pmap -> squeue.tail = 0;
129     findPhotons(pmap, ray);
130    
131     /* Need at least 2 photons */
132     if (pmap -> squeue.tail < 2) {
133     #ifdef PMAP_NONEFOUND
134     sprintf(errmsg, "no photons found on %s at (%.3f, %.3f, %.3f)",
135     ray -> ro ? ray -> ro -> oname : "<null>",
136     ray -> rop [0], ray -> rop [1], ray -> rop [2]);
137     error(WARNING, errmsg);
138     #endif
139    
140     return;
141     }
142    
143     /* Average (squared) radius between furthest two photons to improve
144     * accuracy and get inverse search area 1 / (PI * r^2), with extra
145     * normalisation factor 1 / PI for ambient calculation */
146     sqn = pmap -> squeue.node + 1;
147     r = max(sqn -> dist2, (sqn + 1) -> dist2);
148     r = 0.25 * (pmap -> maxDist2 + r + 2 * sqrt(pmap -> maxDist2 * r));
149     invArea = 1 / (PI * PI * r);
150    
151     /* Skip the extra photon */
152     for (i = 1 ; i < pmap -> squeue.tail; i++, sqn++) {
153     COLOR flux;
154    
155     /* Get photon's contribution to density estimate */
156     photon = getNearestPhoton(&pmap -> squeue, sqn -> idx);
157     getPhotonFlux(photon, flux);
158     scalecolor(flux, invArea);
159     #ifdef PMAP_EPANECHNIKOV
160     /* Apply Epanechnikov kernel to photon flux based on photon distance */
161     scalecolor(flux, 2 * (1 - sqn -> dist2 / r));
162     #endif
163     addcolor(irrad, flux);
164    
165     if (pmap -> srcContrib) {
166     const PhotonPrimary *primary = pmap -> primaries +
167     photon -> primary;
168     const SRCREC *sp = &source [primary -> srcIdx];
169     OBJREC *srcMod = findmaterial(sp -> so);
170     MODCONT *srcContrib = (MODCONT*)lu_find(pmap -> srcContrib,
171     srcMod -> oname) -> data;
172     double srcBinReal;
173     int srcBin;
174     RAY srcRay;
175    
176     if (!srcContrib)
177     continue;
178    
179     /* Photon's emitting light source has modifier whose contributions
180     * are sought */
181     if (srcContrib -> binv -> type != NUM) {
182     /* Use intersection function to set shadow ray parameters if
183     * it's not simply a constant */
184     rayorigin(&srcRay, SHADOW, NULL, NULL);
185     srcRay.rsrc = primary -> srcIdx;
186     #ifdef PMAP_PRIMARYPOS
187     VCOPY(srcRay.rorg, primary -> pos);
188     #else
189     /* No primary hitpoints; set dummy ray origin and warn once */
190     srcRay.rorg [0] = srcRay.rorg [1] = srcRay.rorg [2] = 0;
191     if (warn) {
192     error(WARNING, "no photon primary hitpoints for bin evaluation;"
193     " using dummy (0,0,0) !");
194     warn = 0;
195     }
196     #endif
197     decodedir(srcRay.rdir, primary -> dir);
198    
199     if (!(sp->sflags & SDISTANT
200     ? sourcehit(&srcRay)
201     : (*ofun[sp -> so -> otype].funp)(sp -> so, &srcRay)))
202     continue; /* XXX shouldn't happen! */
203    
204     worldfunc(RCCONTEXT, &srcRay);
205     set_eparams((char *)srcContrib -> params);
206     }
207    
208     if ((srcBinReal = evalue(srcContrib -> binv)) < -.5)
209     continue; /* silently ignore negative bins */
210    
211     if ((srcBin = srcBinReal + .5) >= srcContrib -> nbins) {
212     error(WARNING, "bad bin number (ignored)");
213     continue;
214     }
215    
216     if (!contrib) {
217     /* Ray coefficient mode; normalise by light source radiance
218     * after applying distrib pattern */
219     int j;
220    
221     raytexture(ray, srcMod -> omod);
222     setcolor(ray -> rcol, srcMod -> oargs.farg [0],
223     srcMod -> oargs.farg [1], srcMod -> oargs.farg [2]);
224     multcolor(ray -> rcol, ray -> pcol);
225     for (j = 0; j < 3; j++)
226     flux [j] = ray -> rcol [j] ? flux [j] / ray -> rcol [j] : 0;
227     }
228    
229     multcolor(flux, rayCoeff);
230     addcolor(srcContrib -> cbin [srcBin], flux);
231     }
232     }
233    
234     return;
235     }