00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "lux.h"
00025 #include "light.h"
00026 #include "mc.h"
00027 #include "texture.h"
00028 #include "shape.h"
00029 #include "scene.h"
00030 #include "mipmap.h"
00031
00032 namespace lux
00033 {
00034
00035
00036 struct Distribution1D {
00037
00038 Distribution1D(float *f, int n) {
00039 func = new float[n];
00040 cdf = new float[n+1];
00041 count = n;
00042 memcpy(func, f, n*sizeof(float));
00043 ComputeStep1dCDF(func, n, &funcInt, cdf);
00044 invFuncInt = 1.f / funcInt;
00045 invCount = 1.f / count;
00046 }
00047 float Sample(float u, float *pdf) {
00048
00049 float *ptr = std::lower_bound(cdf, cdf+count+1, u);
00050 int offset = (int) (ptr-cdf-1);
00051
00052 u = (u - cdf[offset]) / (cdf[offset+1] - cdf[offset]);
00053 *pdf = func[offset] * invFuncInt;
00054 return offset + u;
00055 }
00056
00057 float *func, *cdf;
00058 float funcInt, invFuncInt, invCount;
00059 int count;
00060 };
00061
00062 class InfiniteAreaLightIS : public Light {
00063 public:
00064
00065 InfiniteAreaLightIS(const Transform &light2world, const Spectrum &power, int ns,
00066 const string &texmap);
00067 ~InfiniteAreaLightIS();
00068 SWCSpectrum Power(const Scene *scene) const {
00069 Point worldCenter;
00070 float worldRadius;
00071 scene->WorldBound().BoundingSphere(&worldCenter,
00072 &worldRadius);
00073 return Lbase * radianceMap->Lookup(.5f, .5f, .5f) *
00074 M_PI * worldRadius * worldRadius;
00075 }
00076 bool IsDeltaLight() const { return false; }
00077 SWCSpectrum Le(const RayDifferential &r) const;
00078 SWCSpectrum Sample_L(const Point &p, float u1, float u2, float u3,
00079 Vector *wi, float *pdf, VisibilityTester *visibility) const;
00080 SWCSpectrum Sample_L(const Scene *scene, float u1, float u2,
00081 float u3, float u4, Ray *ray, float *pdf) const;
00082 float Pdf(const Point &, const Vector &) const;
00083 SWCSpectrum Sample_L(const Point &P, Vector *w, VisibilityTester *visibility) const;
00084
00085 static Light *CreateLight(const Transform &light2world,
00086 const ParamSet ¶mSet);
00087
00088 private:
00089
00090 Spectrum Lbase;
00091 MIPMap<Spectrum> *radianceMap;
00092 Distribution1D *uDistrib, **vDistribs;
00093 };
00094
00095 }
00096