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
00042 struct EPhoton {
00043 EPhoton(const Point &pp, const SWCSpectrum &wt, const Vector & w)
00044 : p(pp), alpha(wt.ToXYZ()), wi(w) {
00045 }
00046
00047 EPhoton() {
00048 }
00049 Point p;
00050 XYZColor alpha;
00051 Vector wi;
00052 };
00053
00054 struct ERadiancePhoton {
00055 ERadiancePhoton(const Point &pp, const Normal & nn)
00056 : p(pp), n(nn), Lo(0.f) {
00057 }
00058
00059 ERadiancePhoton() {
00060 }
00061 Point p;
00062 Normal n;
00063 XYZColor Lo;
00064 };
00065
00066 struct ERadiancePhotonProcess {
00067
00068
00069 ERadiancePhotonProcess(const Point &pp, const Normal & nn)
00070 : p(pp), n(nn) {
00071 photon = NULL;
00072 }
00073
00074 void operator()(const ERadiancePhoton &rp,
00075 float distSquared, float &maxDistSquared) const {
00076 if (Dot(rp.n, n) > 0) {
00077 photon = &rp;
00078 maxDistSquared = distSquared;
00079 }
00080 }
00081 const Point &p;
00082 const Normal &n;
00083 mutable const ERadiancePhoton *photon;
00084 };
00085
00086 inline float Ekernel(const EPhoton *photon, const Point &p,
00087 float md2) {
00088
00089 float s = (1.f - DistanceSquared(photon->p, p) / md2);
00090 return 3.f / (md2 * M_PI) * s * s;
00091 }
00092
00093 struct EPhotonProcess {
00094
00095 EPhotonProcess(u_int mp, const Point & p);
00096 void operator()(const EPhoton &photon, float dist2, float &maxDistSquared) const;
00097 const Point &p;
00098 EClosePhoton *photons;
00099 u_int nLookup;
00100 mutable u_int foundPhotons;
00101 };
00102
00103 struct EClosePhoton {
00104
00105 EClosePhoton(const EPhoton *p = NULL,
00106 float md2 = INFINITY) {
00107 photon = p;
00108 distanceSquared = md2;
00109 }
00110
00111 bool operator<(const EClosePhoton & p2) const {
00112 return distanceSquared == p2.distanceSquared ? (photon < p2.photon) :
00113 distanceSquared < p2.distanceSquared;
00114 }
00115 const EPhoton *photon;
00116 float distanceSquared;
00117 };
00118
00119 class ExPhotonIntegrator : public SurfaceIntegrator {
00120 public:
00121
00122 enum LightStrategy {
00123 SAMPLE_ALL_UNIFORM, SAMPLE_ONE_UNIFORM,
00124 SAMPLE_AUTOMATIC
00125 };
00126 enum RRStrategy { RR_EFFICIENCY, RR_PROBABILITY, RR_NONE };
00127
00128
00129 ExPhotonIntegrator(
00130 LightStrategy st,
00131 int ncaus, int nindir, int maxDirPhotons,
00132 int nLookup, int mdepth,
00133 float maxdist, bool finalGather, int gatherSamples, float ga,
00134 RRStrategy grrStrategy, float grrContinueProbability,
00135 bool dbgEnableDirect, bool dbgEnableCaustic,
00136 bool dbgEnableIndirect, bool dbgEnableSpecular);
00137 ~ExPhotonIntegrator();
00138
00139 SWCSpectrum Li(const Scene *scene, const RayDifferential &ray,
00140 const Sample *sample, float *alpha) const;
00141 void RequestSamples(Sample *sample, const Scene *scene);
00142 void Preprocess(const Scene *);
00143 virtual ExPhotonIntegrator* clone() const;
00144
00145 IntegrationSampler* HasIntegrationSampler(IntegrationSampler *is) {
00146 return NULL;
00147 };
00148
00149 static SurfaceIntegrator *CreateSurfaceIntegrator(const ParamSet ¶ms);
00150
00151 private:
00152
00153 static inline bool unsuccessful(int needed, int found, int shot) {
00154 return (found < needed &&
00155 (found == 0 || found < shot / 1024));
00156 }
00157 static SWCSpectrum LPhoton(KdTree<EPhoton, EPhotonProcess> *map,
00158 int nPaths, int nLookup, BSDF *bsdf, const Intersection &isect,
00159 const Vector &w, float maxDistSquared);
00160
00161 SWCSpectrum estimateE(KdTree<EPhoton, EPhotonProcess> *map, int count,
00162 const Point &p, const Normal &n) const;
00163 SWCSpectrum LiInternal(const int specularDepth, const Scene *scene,
00164 const RayDifferential &ray, const Sample *sample,
00165 float *alpha) const;
00166
00167
00168 LightStrategy lightStrategy;
00169 u_int nCausticPhotons, nIndirectPhotons, maxDirectPhotons;
00170 u_int nLookup;
00171 int maxSpecularDepth;
00172 float maxDistSquared;
00173 int maxDepth;
00174
00175 bool finalGather;
00176 float cosGatherAngle;
00177 int gatherSamples;
00178 RRStrategy gatherRRStrategy;
00179 float gatherRRContinueProbability;
00180
00181
00182
00183 bool debugEnableDirect, debugEnableCaustic,
00184 debugEnableIndirect, debugEnableSpecular;
00185
00186
00187 int sampleOffset;
00188 int sampleFinalGather1Offset;
00189 int sampleFinalGather2Offset;
00190
00191 int nCausticPaths, nIndirectPaths;
00192 mutable KdTree<EPhoton, EPhotonProcess> *causticMap;
00193 mutable KdTree<EPhoton, EPhotonProcess> *indirectMap;
00194 mutable KdTree<ERadiancePhoton, ERadiancePhotonProcess> *radianceMap;
00195 };
00196
00197 }
00198
00199 #endif