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

Comparing ray/src/rt/pmapcontrib.c (file contents):
Revision 2.12 by rschregle, Tue May 17 17:39:47 2016 UTC vs.
Revision 2.13 by greg, Thu Sep 29 21:51:58 2016 UTC

# Line 4 | Line 4 | static const char RCSid[] = "$Id$";
4  
5   /*
6     ======================================================================
7 <   Photon map support for light source contributions
7 >   Photon map support for building light source contributions
8  
9     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
10     (c) Lucerne University of Applied Sciences and Arts,
# Line 28 | Line 28 | static const char RCSid[] = "$Id$";
28  
29  
30  
31 static void setPmapContribParams (PhotonMap *pmap, LUTAB *srcContrib)
32 /* Set parameters for light source contributions */
33 {
34   /* Set light source modifier list and appropriate callback to extract
35    * their contributions from the photon map */
36   if (pmap) {
37      pmap -> srcContrib = srcContrib;
38      pmap -> lookup = photonContrib;
39      /* Ensure we get all requested photon contribs during lookups */
40      pmap -> gatherTolerance = 1.0;
41   }
42 }
43
44
45
46 static void checkPmapContribs (const PhotonMap *pmap, LUTAB *srcContrib)
47 /* Check modifiers for light source contributions */
48 {
49   const PhotonPrimary  *primary = pmap -> primaries;
50   PhotonPrimaryIdx     i, found = 0;
51   OBJREC *srcMod;
52  
53   /* Make sure at least one of the modifiers is actually in the pmap,
54    * otherwise findPhotons() winds up in an infinite loop! */
55   for (i = pmap -> numPrimary; i; --i, ++primary) {
56      if (primary -> srcIdx < 0 || primary -> srcIdx >= nsources)
57         error(INTERNAL, "invalid light source index in photon map");
58        
59      srcMod = findmaterial(source [primary -> srcIdx].so);
60      if ((MODCONT*)lu_find(srcContrib, srcMod -> oname) -> data)
61         ++found;
62   }
63  
64   if (!found)
65      error(USER, "modifiers not in photon map");
66 }
67
68  
69
70 void initPmapContrib (LUTAB *srcContrib, unsigned numSrcContrib)
71 {
72   unsigned t;
73  
74   for (t = 0; t < NUM_PMAP_TYPES; t++)
75      if (photonMaps [t] && t != PMAP_TYPE_CONTRIB) {
76         sprintf(errmsg, "%s photon map does not support contributions",
77                 pmapName [t]);
78         error(USER, errmsg);
79      }
80  
81   /* Get params */
82   setPmapContribParams(contribPmap, srcContrib);
83  
84   if (contribPhotonMapping) {
85      if (contribPmap -> maxGather < numSrcContrib) {
86         /* Adjust density estimate bandwidth if lower than modifier
87          * count, otherwise contributions are missing */
88         error(WARNING, "contrib density estimate bandwidth too low, "
89                        "adjusting to modifier count");
90         contribPmap -> maxGather = numSrcContrib;
91      }
92      
93      /* Sanity check */
94      checkPmapContribs(contribPmap, srcContrib);
95   }
96 }
97
98
99
31   static PhotonPrimaryIdx newPhotonPrimary (PhotonMap *pmap,
32                                            const RAY *primRay,
33                                            FILE *primHeap)
# Line 652 | Line 583 | void distribPhotonContrib (PhotonMap* pm, unsigned num
583    
584     /* Build underlying data structure; heap is destroyed */
585     buildPhotonMap(pm, srcFlux, primaryOfs, numProc);  
655 }
656
657
658
659 void photonContrib (PhotonMap *pmap, RAY *ray, COLOR irrad)
660 /* Sum up light source contributions from photons in pmap->srcContrib */
661 {
662   unsigned                i;
663   PhotonSearchQueueNode   *sqn;
664   float                   r, invArea;
665   RREAL                   rayCoeff [3];
666   Photon                  *photon;
667   static char             warn = 1;
668
669   setcolor(irrad, 0, 0, 0);
670
671   if (!pmap -> maxGather)
672      return;
673      
674   /* Ignore sources */
675   if (ray -> ro && islight(objptr(ray -> ro -> omod) -> otype))
676      return;
677
678   /* Get cumulative path coefficient up to photon lookup point */
679   raycontrib(rayCoeff, ray, PRIMARY);
680
681   /* Lookup photons */
682   pmap -> squeue.tail = 0;
683   findPhotons(pmap, ray);
684  
685   /* Need at least 2 photons */
686   if (pmap -> squeue.tail < 2) {
687 #ifdef PMAP_NONEFOUND
688      sprintf(errmsg, "no photons found on %s at (%.3f, %.3f, %.3f)",
689              ray -> ro ? ray -> ro -> oname : "<null>",
690              ray -> rop [0], ray -> rop [1], ray -> rop [2]);
691      error(WARNING, errmsg);
692 #endif
693      
694      return;
695   }
696
697   /* Average (squared) radius between furthest two photons to improve
698    * accuracy and get inverse search area 1 / (PI * r^2), with extra
699    * normalisation factor 1 / PI for ambient calculation */
700   sqn = pmap -> squeue.node + 1;
701   r = max(sqn -> dist2, (sqn + 1) -> dist2);
702   r = 0.25 * (pmap -> maxDist2 + r + 2 * sqrt(pmap -> maxDist2 * r));  
703   invArea = 1 / (PI * PI * r);
704  
705   /* Skip the extra photon */
706   for (i = 1 ; i < pmap -> squeue.tail; i++, sqn++) {        
707      COLOR flux;
708      
709      /* Get photon's contribution to density estimate */
710      photon = getNearestPhoton(&pmap -> squeue, sqn -> idx);
711      getPhotonFlux(photon, flux);
712      scalecolor(flux, invArea);      
713 #ifdef PMAP_EPANECHNIKOV
714      /* Apply Epanechnikov kernel to photon flux based on photon distance */
715      scalecolor(flux, 2 * (1 - sqn -> dist2 / r));
716 #endif
717      addcolor(irrad, flux);
718      
719      if (pmap -> srcContrib) {      
720         const PhotonPrimary  *primary = pmap -> primaries +
721                                         photon -> primary;
722         const SRCREC         *sp = &source [primary -> srcIdx];
723         OBJREC               *srcMod = findmaterial(sp -> so);
724         MODCONT *srcContrib = (MODCONT*)lu_find(pmap -> srcContrib,
725                                                 srcMod -> oname) -> data;
726         double   srcBinReal;
727         int      srcBin;
728         RAY      srcRay;                                                
729                                                
730         if (!srcContrib)
731            continue;
732
733         /* Photon's emitting light source has modifier whose contributions
734          * are sought */
735         if (srcContrib -> binv -> type != NUM) {
736            /* Use intersection function to set shadow ray parameters if
737             * it's not simply a constant */
738            rayorigin(&srcRay, SHADOW, NULL, NULL);
739            srcRay.rsrc = primary -> srcIdx;
740 #ifdef PMAP_PRIMARYPOS
741            VCOPY(srcRay.rorg, primary -> pos);
742 #else
743            /* No primary hitpoints; set dummy ray origin and warn once */
744            srcRay.rorg [0] = srcRay.rorg [1] = srcRay.rorg [2] = 0;
745            if (warn) {
746               error(WARNING, "no photon primary hitpoints for bin evaluation;"
747                     " using dummy (0,0,0) !");
748               warn = 0;
749            }
750 #endif          
751            decodedir(srcRay.rdir, primary -> dir);
752
753            if (!(sp->sflags & SDISTANT
754                  ? sourcehit(&srcRay)
755                  : (*ofun[sp -> so -> otype].funp)(sp -> so, &srcRay)))
756               continue;                /* XXX shouldn't happen! */
757
758            worldfunc(RCCONTEXT, &srcRay);
759            set_eparams((char *)srcContrib -> params);
760         }
761
762         if ((srcBinReal = evalue(srcContrib -> binv)) < -.5)
763            continue;           /* silently ignore negative bins */
764  
765         if ((srcBin = srcBinReal + .5) >= srcContrib -> nbins) {
766            error(WARNING, "bad bin number (ignored)");
767            continue;
768         }
769            
770         if (!contrib) {
771            /* Ray coefficient mode; normalise by light source radiance
772             * after applying distrib pattern */
773            int j;
774            
775            raytexture(ray, srcMod -> omod);
776            setcolor(ray -> rcol, srcMod -> oargs.farg [0],
777                     srcMod -> oargs.farg [1], srcMod -> oargs.farg [2]);
778            multcolor(ray -> rcol, ray -> pcol);
779            for (j = 0; j < 3; j++)
780               flux [j] = ray -> rcol [j] ? flux [j] / ray -> rcol [j] : 0;
781         }
782                    
783         multcolor(flux, rayCoeff);
784         addcolor(srcContrib -> cbin [srcBin], flux);
785      }
786   }
787        
788   return;
586   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines