00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef LUX_EXPHOTONMAP_H
00025 #define LUX_EXPHOTONMAP_H
00026
00027
00028 #include "lux.h"
00029 #include "transport.h"
00030 #include "scene.h"
00031 #include "kdtree.h"
00032 #include "mc.h"
00033 #include "sampling.h"
00034
00035 namespace lux
00036 {
00037
00038 struct EClosePhoton;
00039
00040
00041 struct EPhoton {
00042 EPhoton(const Point &pp, const Spectrum &wt, const Vector &w)
00043 : p(pp), alpha(wt), wi(w) {
00044 }
00045 EPhoton() { }
00046 Point p;
00047 Spectrum alpha;
00048 Vector wi;
00049 };
00050 struct ERadiancePhoton {
00051 ERadiancePhoton(const Point &pp, const Normal &nn)
00052 : p(pp), n(nn), Lo(0.f) {
00053 }
00054 ERadiancePhoton() { }
00055 Point p;
00056 Normal n;
00057 Spectrum Lo;
00058 };
00059 struct ERadiancePhotonProcess {
00060
00061 ERadiancePhotonProcess(const Point &pp, const Normal &nn)
00062 : p(pp), n(nn) {
00063 photon = NULL;
00064 }
00065 void operator()(const ERadiancePhoton &rp,
00066 float distSquared, float &maxDistSquared) const {
00067 if (Dot(rp.n, n) > 0) {
00068 photon = &rp;
00069 maxDistSquared = distSquared;
00070 }
00071 }
00072 const Point &p;
00073 const Normal &n;
00074 mutable const ERadiancePhoton *photon;
00075 };
00076 inline float Ekernel(const EPhoton *photon, const Point &p,
00077 float md2) {
00078
00079 float s = (1.f - DistanceSquared(photon->p, p) / md2);
00080 return 3.f / (md2 * M_PI) * s * s;
00081 }
00082
00083 struct EPhotonProcess {
00084
00085 EPhotonProcess(u_int mp, const Point &p);
00086 void operator()(const EPhoton &photon, float dist2, float &maxDistSquared) const;
00087 const Point &p;
00088 EClosePhoton *photons;
00089 u_int nLookup;
00090 mutable u_int foundPhotons;
00091 };
00092 struct EClosePhoton {
00093 EClosePhoton(const EPhoton *p = NULL,
00094 float md2 = INFINITY) {
00095 photon = p;
00096 distanceSquared = md2;
00097 }
00098 bool operator<(const EClosePhoton &p2) const {
00099 return distanceSquared == p2.distanceSquared ? (photon < p2.photon) :
00100 distanceSquared < p2.distanceSquared;
00101 }
00102 const EPhoton *photon;
00103 float distanceSquared;
00104 };
00105
00106
00107
00108 class ExPhotonIntegrator : public SurfaceIntegrator {
00109 public:
00110
00111 ExPhotonIntegrator(int ncaus, int nindir, int nLookup, int mdepth,
00112 float maxdist, bool finalGather, int gatherSamples,
00113 float rrt, float ga);
00114 ~ExPhotonIntegrator();
00115 Spectrum Li(const Scene *scene, const RayDifferential &ray,
00116 const Sample *sample, float *alpha) const;
00117 void RequestSamples(Sample *sample, const Scene *scene);
00118 void Preprocess(const Scene *);
00119 virtual ExPhotonIntegrator* clone() const;
00120 IntegrationSampler* HasIntegrationSampler(IntegrationSampler *is) { return NULL; };
00121 static SurfaceIntegrator *CreateSurfaceIntegrator(const ParamSet ¶ms);
00122 private:
00123 static inline bool unsuccessful(int needed, int found, int shot) {
00124 return (found < needed &&
00125 (found == 0 || found < shot / 1024));
00126 }
00127 static Spectrum LPhoton(KdTree<EPhoton, EPhotonProcess> *map,
00128 int nPaths, int nLookup, BSDF *bsdf, const Intersection &isect,
00129 const Vector &w, float maxDistSquared);
00130
00131 Spectrum estimateE(KdTree<EPhoton, EPhotonProcess> *map, int count,
00132 const Point &p, const Normal &n) const;
00133
00134
00135 int gatherSampleOffset[2], gatherComponentOffset[2];
00136 u_int nCausticPhotons, nIndirectPhotons;
00137 u_int nLookup;
00138 mutable int specularDepth;
00139 int maxSpecularDepth;
00140 float maxDistSquared, rrTreshold;
00141 bool finalGather;
00142 float cosGatherAngle;
00143 int gatherSamples;
00144
00145 int *lightSampleOffset, lightNumOffset;
00146 int *bsdfSampleOffset, *bsdfComponentOffset;
00147 int nCausticPaths, nIndirectPaths;
00148 mutable KdTree<EPhoton, EPhotonProcess> *causticMap;
00149 mutable KdTree<EPhoton, EPhotonProcess> *indirectMap;
00150 mutable KdTree<ERadiancePhoton, ERadiancePhotonProcess> *radianceMap;
00151 };
00152
00153 }
00154
00155 #endif