00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "pbrt.h"
00026 #include "light.h"
00027 #include "shape.h"
00028 #include "scene.h"
00029 #include "mipmap.h"
00030
00031 class GonioPhotometricLight : public Light {
00032 public:
00033
00034 GonioPhotometricLight(const Transform &light2world, const Spectrum &, const
00035 string &texname);
00036 Spectrum Sample_L(const Point &p, Vector *wi, VisibilityTester *vis) const;
00037 ~GonioPhotometricLight() { delete mipmap; }
00038 bool IsDeltaLight() const { return true; }
00039 Spectrum Scale(const Vector &w) const {
00040 Vector wp = Normalize(WorldToLight(w));
00041 swap(wp.y, wp.z);
00042 float theta = SphericalTheta(wp);
00043 float phi = SphericalPhi(wp);
00044 float s = phi * INV_TWOPI, t = theta * INV_PI;
00045 return mipmap ? mipmap->Lookup(s, t) : 1.f;
00046 }
00047 Spectrum Power(const Scene *) const {
00048 return 4.f * M_PI * Intensity *
00049 mipmap->Lookup(.5f, .5f, .5f);
00050 }
00051 Spectrum Sample_L(const Point &P, float u1, float u2, Vector *wo,
00052 float *pdf, VisibilityTester *visibility) const;
00053 Spectrum Sample_L(const Scene *scene, float u1, float u2,
00054 float u3, float u4, Ray *ray, float *pdf) const;
00055 float Pdf(const Point &, const Vector &) const;
00056 private:
00057
00058 Point lightPos;
00059 Spectrum Intensity;
00060 MIPMap<Spectrum> *mipmap;
00061
00062 };
00063
00064 Spectrum GonioPhotometricLight::Sample_L(const Point &p, Vector *wi,
00065 VisibilityTester *visibility) const {
00066 *wi = Normalize(lightPos - p);
00067 visibility->SetSegment(p, lightPos);
00068 return Intensity * Scale(-*wi) / DistanceSquared(lightPos, p);
00069 }
00070 GonioPhotometricLight::GonioPhotometricLight(
00071 const Transform &light2world,
00072 const Spectrum &intensity, const string &texname)
00073 : Light(light2world) {
00074 lightPos = LightToWorld(Point(0,0,0));
00075 Intensity = intensity;
00076
00077 int width, height;
00078 Spectrum *texels = ReadImage(texname, &width, &height);
00079 if (texels) {
00080 mipmap = new MIPMap<Spectrum>(width, height, texels);
00081 delete[] texels;
00082 }
00083 else mipmap = NULL;
00084 }
00085 Spectrum GonioPhotometricLight::Sample_L(const Point &P, float u1, float u2,
00086 Vector *wo, float *pdf,
00087 VisibilityTester *visibility) const {
00088 *wo = Normalize(lightPos - P);
00089 *pdf = 1.f;
00090 visibility->SetSegment(P, lightPos);
00091 return Intensity * Scale(-*wo) / DistanceSquared(lightPos, P);
00092 }
00093 Spectrum GonioPhotometricLight::Sample_L(const Scene *scene, float u1, float u2,
00094 float u3, float u4, Ray *ray, float *pdf) const {
00095 ray->o = lightPos;
00096 ray->d = UniformSampleSphere(u1, u2);
00097 *pdf = UniformSpherePdf();
00098 return Intensity * Scale(ray->d);
00099 }
00100 float GonioPhotometricLight::Pdf(const Point &, const Vector &) const {
00101 return 0.;
00102 }
00103 extern "C" DLLEXPORT Light *CreateLight(const Transform &light2world,
00104 const ParamSet ¶mSet) {
00105 Spectrum I = paramSet.FindOneSpectrum("I", Spectrum(1.0));
00106 string texname = paramSet.FindOneString("mapname", "");
00107 return new GonioPhotometricLight(light2world, I, texname);
00108 }