ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapdata.h
(Generate patch)

Comparing ray/src/rt/pmapdata.h (file contents):
Revision 2.9 by greg, Tue Sep 1 16:27:52 2015 UTC vs.
Revision 2.10 by rschregle, Tue May 17 17:39:47 2016 UTC

# Line 1 | Line 1
1   /* RCSid $Id$ */
2 +
3   /*
4 <   ==================================================================
5 <   Photon map data structures and kd-tree handling  
4 >   =========================================================================
5 >   Photon map types and interface to nearest neighbour lookups in underlying
6 >   point cloud data structure.
7  
8 +   The default data structure is an in-core kd-tree (see pmapkdt.{h,c}).
9 +   This can be overriden with the PMAP_OOC compiletime switch, which enables
10 +   an out-of-core octree (see oococt.{h,c}).
11 +  
12 +   Defining PMAP_FLOAT_FLUX stores photon flux as floats rather than packed
13 +   RGBE for greater precision; this may be necessary when the flux differs
14 +   significantly in individual colour channels, e.g. with highly saturated
15 +   colours.
16 +
17     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
18     (c) Fraunhofer Institute for Solar Energy Systems,
19     (c) Lucerne University of Applied Sciences and Arts,
20 <   supported by the Swiss National Science Foundation (SNSF, #147053)
21 <   ==================================================================
20 >       supported by the Swiss National Science Foundation (SNSF, #147053)
21 >   =========================================================================
22    
23 +   $Id$
24   */
25  
26  
27 +
28   #ifndef PMAPDATA_H
29     #define PMAPDATA_H
30  
31     #include "ray.h"  
32     #include "pmaptype.h"
33     #include "lookup.h"
34 +   #include <stdint.h>
35  
36  
37 <   /* Define PMAP_FLOAT_FLUX to store photon flux as floats instead of
24 <    * compact RGBE, which was found to improve accuracy in analytical
25 <    * validation. */
26 <   #ifdef PMAP_FLOAT_FLUX
27 <      #define setPhotonFlux(p,f) copycolor((p) -> flux, f)
28 <      #define getPhotonFlux(p,f) copycolor(f, (p) -> flux)
29 <   #else
30 <      #define setPhotonFlux(p,f) setcolr((p)->flux, (f)[0], (f)[1], (f)[2])
31 <      #define getPhotonFlux(p,f) colr_color(f, (p) -> flux)
32 <   #endif
33 <
34 <
37 >  
38     /* Primary photon ray for light source contributions */
39     typedef struct {
40 <      int32 srcIdx;               /* Index of emitting light source */
41 <      int32 dir;                  /* Encoded ray direction */
42 <      float pos [3];              /* Hit point */
40 >      int16    srcIdx;              /* Index of emitting light source */
41 >                                    /* !!! REDUCED FROM 32 BITS !!! */
42 >      int32    dir;                 /* Encoded ray direction */
43 > #ifdef PMAP_PRIMARYPOS      
44 >      float    pos [3];             /* Hit point */
45 > #endif      
46     } PhotonPrimary;
47        
48 <   #define photonSrcIdx(pm, p) ((pm) -> primary [(p) -> primary].srcIdx)
48 >   #define photonSrcIdx(pm, p)      ((pm)->primaries[(p)->primary].srcIdx)
49  
50 +
51 +
52 +   /* Photon primary ray index type and limit */
53 +   typedef  uint32            PhotonPrimaryIdx;      
54 +   #define  PMAP_MAXPRIMARY   UINT32_MAX
55 +
56 +   /* Macros for photon's generating subprocess field */
57 + #ifdef PMAP_OOC        
58 +   #define  PMAP_PROCBITS  7
59 + #else            
60 +   #define  PMAP_PROCBITS  5  
61 + #endif
62 +   #define  PMAP_MAXPROC         (1 << PMAP_PROCBITS)
63 +   #define  PMAP_GETRAYPROC(r)   ((r) -> crtype >> 8)
64 +   #define  PMAP_SETRAYPROC(r,p) ((r) -> crtype |= p << 8)
65 +
66 +   /* Tolerance for photon normal check during lookups */
67 +   #define  PMAP_NORM_TOL  0.02
68    
45   typedef struct {
46      float pos [3];                 /* Photon position */
47      signed char norm [3];          /* Surface normal at pos (incident
48                                        direction for volume photons) */
49      char flags;                    /* Bit 0-1: kd-tree discriminator axis,
50                                        Bit 2:   caustic photon */
51      #ifdef PMAP_FLOAT_FLUX
52         COLOR flux;
53      #else
54         COLR flux;                  /* Photon flux */
55      #endif
69  
57      uint32 primary;              /* Index to primary ray */
58   } Photon;
70    
71 <   /* Photon flag bitmasks and manipulation macros */
72 <   #define PMAP_DISCR_BIT 3
73 <   #define PMAP_CAUST_BIT 4
74 <   #define photonDiscr(p)       ((p).flags & PMAP_DISCR_BIT)
75 <   #define setPhotonDiscr(p, d) ((p).flags = ((p).flags & ~PMAP_DISCR_BIT) | \
76 <                                              ((d) & PMAP_DISCR_BIT))
71 >   typedef struct {
72 >      float                pos [3];       /* Photon position */
73 >      signed char          norm [3];      /* Surface normal at pos (incident
74 >                                             direction for volume photons) */
75 >      union {
76 >         struct {
77 > #ifndef PMAP_OOC
78 >            unsigned char  discr    : 2;  /* kd-tree discriminator axis */
79 > #endif            
80 >            unsigned char  caustic  : 1;  /* Specularly scattered (=caustic) */
81 >            
82 >            /* Photon's generating subprocess index, used for primary ray
83 >             * index linearisation when building contrib pmaps; note this is
84 >             * reduced for kd-tree to accommodate the discriminator field */
85 >            unsigned char  proc  : PMAP_PROCBITS;
86 >         };
87 >        
88 >         unsigned char     flags;
89 >      };
90 >      
91 > #ifdef PMAP_FLOAT_FLUX
92 >      COLOR                flux;          
93 > #else
94 >      COLR                 flux;          
95 > #endif
96 >      PhotonPrimaryIdx     primary;       /* Index to primary ray */
97 >   } Photon;
98  
67   /* Photon map type tests */
68   #define isGlobalPmap(p)    ((p) -> type == PMAP_TYPE_GLOBAL)
69   #define isCausticPmap(p)   ((p) -> type == PMAP_TYPE_CAUSTIC)
70   #define isContribPmap(p)   ((p) -> type == PMAP_TYPE_CONTRIB)
71   #define isVolumePmap(p)    ((p) -> type == PMAP_TYPE_VOLUME)
99  
100    
101 <   /* Queue node for photon lookups */
102 <   typedef struct {                  
103 <      Photon *photon;
104 <      float dist;
105 <   } PhotonSQNode;
101 >   /* Define PMAP_FLOAT_FLUX to store photon flux as floats instead of
102 >    * compact RGBE, which was found to improve accuracy in analytical
103 >    * validation. */
104 > #ifdef PMAP_FLOAT_FLUX
105 >   #define setPhotonFlux(p,f) copycolor((p) -> flux, f)
106 >   #define getPhotonFlux(p,f) copycolor(f, (p) -> flux)
107 > #else
108 >   #define setPhotonFlux(p,f) setcolr((p)->flux, (f)[0], (f)[1], (f)[2])
109 >   #define getPhotonFlux(p,f) colr_color(f, (p) -> flux)
110 > #endif
111  
112 +
113 +  
114     /* Bias compensation history node */
115     typedef struct {                  
116        COLOR irrad;
117        float weight;
118 <   } PhotonBCNode;
118 >   } PhotonBiasCompNode;
119  
120  
121 <   struct PhotonMap;                 /* Forward declarations */
121 >   /* Forward declaration */
122 >   struct PhotonMap;
123 >  
124 >  
125 >   /* Define search queue and underlying data struct types */
126 > #ifdef PMAP_OOC
127 >   #include "pmapooc.h"
128 > #else
129 >   #include "pmapkdt.h"
130 > #endif
131  
132 +
133     typedef struct PhotonMap {
134 <      PhotonMapType type;            /* See pmaptype.h */
135 <      char *fileName;                /* Photon map file */
92 <      Photon *heap;                  /* Photon k-d tree as linear array */
93 <      PhotonSQNode *squeue;          /* Search queue */
94 <      PhotonBCNode *biasCompHist;    /* Bias compensation history */      
95 <      char lookupFlags;              /* Flags passed to findPhotons() */
134 >      PhotonMapType  type;             /* See pmaptype.h */
135 >      char           *fileName;        /* Photon map file */
136        
97      unsigned long distribTarget,   /* Num stored specified by user */
98                    heapSize,
99                    heapSizeInc,
100                    heapEnd,         /* Num actually stored in heap */
101                    numDensity,      /* Num density estimates */
102                    totalGathered,   /* Total photons gathered */
103                    numLookups,      /* Counters for short photon lookups */
104                    numShortLookups;
105                    
106      unsigned minGather,            /* Specified min/max photons per */
107               maxGather,            /* density estimate */
108               squeueSize,
109               squeueEnd,
110               minGathered,          /* Min/max photons actually gathered */
111               maxGathered,          /* per density estimate */
112               shortLookupPct;       /* Percentage of short lookups (for
113                                        statistics output */
114              
115                                     /* NOTE: All distances are SQUARED */
116      float maxDist,                 /* Max search radius during NN search */
117            maxDist0,                /* Initial value for above */
118            maxDistLimit,            /* Hard limit for above */
119            CoGdist,                 /* Avg distance to centre of gravity */
120            maxPos [3], minPos [3],  /* Max & min photon positions */
121            distribRatio,            /* Probability of photon storage */
122            gatherTolerance,         /* Fractional deviation from minGather/
123                                        maxGather for short lookup */
124            minError, maxError,      /* Min/max/rms density estimate error */
125            rmsError;
126            
127      FVECT CoG;                     /* Centre of gravity (avg photon pos) */
128      COLOR photonFlux;              /* Average photon flux */
129      unsigned short randState [3];  /* Local RNG state */
137        
138 <      void (*lookup)(struct PhotonMap*, RAY*, COLOR);  
139 <                                     /* Callback for type-specific photon
140 <                                      * lookup (usually density estimate) */
138 >      /* ================================================================
139 >       * PRE/POST-BUILD STORAGE
140 >       * ================================================================ */
141 >      FILE           *heap;            /* Unsorted photon heap prior to
142 >                                          construction of store */
143 >      Photon         *heapBuf;         /* Write buffer for above */
144 >      unsigned long  heapBufLen,       /* Current & max size of heapBuf */
145 >                     heapBufSize;
146 >      PhotonStorage  store;            /* Photon storage in spacee
147 >                                          subdividing data struct */            
148 >      
149 >      /* ================================================================
150 >       * PHOTON DISTRIBUTION STUFF
151 >       * ================================================================ */
152 >      unsigned long  distribTarget,    /* Num stored specified by user */
153 >                     numPhotons;       /* Num actually stored */
154 >      float          distribRatio;     /* Probability of photon storage */
155 >      COLOR          photonFlux;       /* Average photon flux */
156 >      unsigned short randState [3];    /* Local RNG state */
157  
158 <      PhotonPrimary *primary;        /* Primary photon rays & associated
159 <                                        counters */
160 <      unsigned primarySize, primaryEnd;
161 <              
162 <      LUTAB *srcContrib;             /* lookup table for source contribs */
158 >
159 >      /* ================================================================
160 >       * PHOTON LOOKUP STUFF
161 >       * ================================================================ */
162 >      union {                          /* Flags passed to findPhotons() */
163 >         char        lookupCaustic : 1;
164 >         char        lookupFlags;
165 >      };
166 >      
167 >      PhotonSearchQueue squeue;        /* Search queue for photon lookups */
168 >      unsigned       minGather,        /* Specified min/max photons per */
169 >                     maxGather;        /* density estimate */
170 >                                      
171 >                                       /* NOTE: All distances are SQUARED */
172 >      float          maxDist2,         /* Max search radius */
173 >                     maxDist0,         /* Initial value for above */
174 >                     maxDist2Limit,    /* Hard limit for above */
175 >                     gatherTolerance;  /* Fractional deviation from minGather/
176 >                                          maxGather for short lookup */
177 >      void (*lookup)(struct PhotonMap*,
178 >                     RAY*, COLOR);     /* Callback for type-specific photon
179 >                                        * lookup (usually density estimate) */                                          
180 >
181 >                    
182 >      /* ================================================================
183 >       * BIAS COMPENSATION STUFF
184 >       * ================================================================ */      
185 >      PhotonBiasCompNode   *biasCompHist;    /* Bias compensation history */
186 >      
187 >
188 >      /* ================================================================
189 >       * STATISTIX
190 >       * ================================================================ */            
191 >      unsigned long  totalGathered,    /* Total photons gathered */
192 >                     numDensity,       /* Num density estimates */
193 >                     numLookups,       /* Counters for short photon lookups */
194 >                     numShortLookups;
195 >                    
196 >      unsigned       minGathered,      /* Min/max photons actually gathered */
197 >                     maxGathered,      /* per density estimate */
198 >                     shortLookupPct;   /* % of short lookups for stats */                                          
199 >                    
200 >      float          minError,         /* Min/max/rms density estimate error */
201 >                     maxError,
202 >                     rmsError,
203 >                     CoGdist,          /* Avg distance to centre of gravity */
204 >                     maxPos [3],       /* Max & min photon positions */
205 >                     minPos [3];
206 >                    
207 >      FVECT          CoG;              /* Centre of gravity (avg photon pos) */
208 >                    
209 >      
210 >      /* ================================================================
211 >       * PHOTON CONTRIB/COEFF STUFF
212 >       * ================================================================ */
213 >      PhotonPrimary  *primaries,    /* Photon primary array for rendering */
214 >                     lastPrimary;   /* Current primary for photon distrib */
215 >      PhotonPrimaryIdx  numPrimary;    /* Number of primary rays */
216 >      LUTAB             *srcContrib;   /* Lookup table for source contribs */
217     } PhotonMap;
218  
219  
220  
221     /* Photon maps by type (see PhotonMapType) */
222 <   extern PhotonMap *photonMaps [];
222 >   extern PhotonMap  *photonMaps [];
223  
224     /* Macros for specific photon map types */
225 <   #define globalPmap            (photonMaps [PMAP_TYPE_GLOBAL])
226 <   #define preCompPmap           (photonMaps [PMAP_TYPE_PRECOMP])
227 <   #define causticPmap           (photonMaps [PMAP_TYPE_CAUSTIC])
228 <   #define volumePmap            (photonMaps [PMAP_TYPE_VOLUME])
229 <   #define directPmap            (photonMaps [PMAP_TYPE_DIRECT])
230 <   #define contribPmap           (photonMaps [PMAP_TYPE_CONTRIB])
225 >   #define globalPmap         (photonMaps [PMAP_TYPE_GLOBAL])
226 >   #define preCompPmap        (photonMaps [PMAP_TYPE_PRECOMP])
227 >   #define causticPmap        (photonMaps [PMAP_TYPE_CAUSTIC])
228 >   #define volumePmap         (photonMaps [PMAP_TYPE_VOLUME])
229 >   #define directPmap         (photonMaps [PMAP_TYPE_DIRECT])
230 >   #define contribPmap        (photonMaps [PMAP_TYPE_CONTRIB])
231  
232 +   /* Photon map type tests */
233 +   #define isGlobalPmap(p)    ((p) -> type == PMAP_TYPE_GLOBAL)
234 +   #define isCausticPmap(p)   ((p) -> type == PMAP_TYPE_CAUSTIC)
235 +   #define isContribPmap(p)   ((p) -> type == PMAP_TYPE_CONTRIB)
236 +   #define isVolumePmap(p)    ((p) -> type == PMAP_TYPE_VOLUME)
237  
238 +   /* Mean size of heapfile write buffer, in number of photons */
239 +   #define PMAP_HEAPBUFSIZE   1e6
240 +  
241 +   /* Mean idle time between heap locking attempts, in usec */
242 +   #define PMAP_HEAPBUFSLEEP  2e6
243 +  
244 +   /* Shared memory file for parallelised photon distribution */
245 + #if 0  
246 +   #define PMAP_SHMFNAME      "/mkpmap-%d"
247 + #else
248 +   #define PMAP_SHMFNAME      "mkpmapXXXXXX"
249 + #endif      
250  
251 +
252     void initPhotonMap (PhotonMap *pmap, PhotonMapType t);
253     /* Initialise empty photon map of specified type */
254  
255 <   const PhotonPrimary* addPhotonPrimary (PhotonMap *pmap, const RAY *ray);
161 <   /* Add primary ray for emitted photon and save light source index, origin
162 <    * on source, and emitted direction; used by contrib photons */
163 <
164 <   const Photon* addPhoton (PhotonMap *pmap, const RAY *ray);
255 >   int newPhoton (PhotonMap *pmap, const RAY *ray);
256     /* Create new photon with ray's direction, intersection point, and flux,
257 <      and add to photon map subject to acceptance probability pmap ->
258 <      distribRatio for global density control; if the photon is rejected,
259 <      NULL is returned. The flux is scaled by ray -> rweight and
260 <      1 / pmap -> distribRatio. */
257 >      and append to unsorted photon heap pmap -> heap. The photon is
258 >      accepted with probability pmap -> distribRatio for global density
259 >      control; if the photon is rejected, -1 is returned, else 0.  The flux
260 >      is scaled by ray -> rweight and 1 / pmap -> distribRatio. */
261  
262 <   void balancePhotons (PhotonMap *pmap, double *photonFlux);
263 <   /* Build a balanced kd-tree as heap to guarantee logarithmic search
173 <    * times. This must be called prior to performing photon search with
174 <    * findPhotons().
175 <    * PhotonFlux is the flux scaling factor per photon averaged over RGB. In
176 <    * the case of a contribution photon map, this is an array with a
177 <    * separate factor specific to each light source due to non-uniform
178 <    * photon emission; Otherwise it is referenced as a scalar value. Flux is
179 <    * not scaled if photonFlux == NULL. */
262 >   void initPhotonHeap (PhotonMap *pmap);
263 >   /* Open photon heap file */
264  
265 <   void buildHeap (Photon *heap, unsigned long *heapIdx,
266 <                   unsigned long *heapXdi, const float min [3],
267 <                   const float max [3], unsigned long left,
268 <                   unsigned long right, unsigned long root);
269 <   /* Recursive part of balancePhotons(..); builds heap from subarray
270 <    * defined by indices left and right. */
271 <      
265 >   void flushPhotonHeap (PhotonMap *pmap);
266 >   /* Flush photon heap buffa pmap -> heapBuf to heap file pmap -> heap;
267 >    * used by newPhoton() and to finalise heap in distribPhotons(). */
268 >
269 >   void buildPhotonMap (PhotonMap *pmap, double *photonFlux,
270 >                        PhotonPrimaryIdx *primaryOfs, unsigned nproc);
271 >   /* Postpress unsorted photon heap pmap -> heap and build underlying data
272 >    * structure pmap -> store.  This is prerequisite to photon lookups with
273 >    * findPhotons(). */
274 >    
275 >   /* PhotonFlux is the flux per photon averaged over RGB; this is
276 >    * multiplied with each photon's flux during the postprocess.  In the
277 >    * case of a contribution photon map, this is an array with a separate
278 >    * flux specific to each light source due to non-uniform photon emission;
279 >    * Otherwise it is referenced as a scalar value.  Flux is not scaled if
280 >    * photonFlux == NULL.  */
281 >
282 >   /* Photon map construction may be parallelised if nproc > 1, if
283 >    * supported. The heap is destroyed on return.  */
284 >    
285 >   /* PrimaryOfs is an array of index offsets for the primaries in pmap ->
286 >    * primaries generated by each of the nproc subprocesses during contrib
287 >    * photon distribution (see distribPhotonContrib()).  These offsets are
288 >    * used to linearise the photon primary indices in the postprocess.  This
289 >    * linearisation is skipped if primaryOfs == NULL.  */
290 >
291     void findPhotons (PhotonMap* pmap, const RAY *ray);
292 <   /* Find pmap -> squeueSize closest photons to ray -> rop with similar
292 >   /* Find pmap -> squeue.len closest photons to ray -> rop with similar
293        normal. For volume photons ray -> rorg is used and the normal is
294        ignored (being the incident direction in this case). Found photons
295 <      are placed in pmap -> squeue, with pmap -> squeueEnd being the number
296 <      actually found. */
295 >      are placed search queue starting with the furthest photon at pmap ->
296 >      squeue.node, and pmap -> squeue.tail being the number actually found. */
297  
298 <   Photon *find1Photon (PhotonMap *pmap, const RAY *ray);
298 >   void find1Photon (PhotonMap *pmap, const RAY *ray, Photon *photon);
299     /* Finds single closest photon to ray -> rop with similar normal.
300        Returns NULL if none found. */
301  
302 +   void getPhoton (PhotonMap *pmap, PhotonIdx idx, Photon *photon);
303 +   /* Retrieve photon referenced by idx from pmap -> store */
304 +
305 +   Photon *getNearestPhoton (const PhotonSearchQueue *squeue, PhotonIdx idx);
306 +   /* Retrieve photon from NN search queue after calling findPhotons() */
307 +  
308 +   PhotonIdx firstPhoton (const PhotonMap *pmap);
309 +   /* Index to first photon, to be passed to getPhoton(). Indices to
310 +    * subsequent photons can be optained via increment operator (++) */
311 +    
312     void deletePhotons (PhotonMap*);
313     /* Free dem mammaries... */
314  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines