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 
00026 #include "stdafx.h"
00027 #include "lights/point.h"
00028 #include "sh.h"
00029 #include "scene.h"
00030 #include "paramset.h"
00031 #include "montecarlo.h"
00032 
00033 
00034 PointLight::PointLight(const Transform &light2world,
00035                        const Spectrum &intensity)
00036     : Light(light2world) {
00037     lightPos = LightToWorld(Point(0,0,0));
00038     Intensity = intensity;
00039 }
00040 
00041 
00042 Spectrum PointLight::Sample_L(const Point &p, float pEpsilon,
00043          const LightSample &ls, float time, Vector *wi, float *pdf,
00044          VisibilityTester *visibility) const {
00045     *wi = Normalize(lightPos - p);
00046     *pdf = 1.f;
00047     visibility->SetSegment(p, pEpsilon, lightPos, 0., time);
00048     return Intensity / DistanceSquared(lightPos, p);
00049 }
00050 
00051 
00052 Spectrum PointLight::Power(const Scene *) const {
00053     return 4.f * M_PI * Intensity;
00054 }
00055 
00056 
00057 PointLight *CreatePointLight(const Transform &light2world,
00058         const ParamSet ¶mSet) {
00059     Spectrum I = paramSet.FindOneSpectrum("I", Spectrum(1.0));
00060     Spectrum sc = paramSet.FindOneSpectrum("scale", Spectrum(1.0));
00061     Point P = paramSet.FindOnePoint("from", Point(0,0,0));
00062     Transform l2w = Translate(Vector(P.x, P.y, P.z)) * light2world;
00063     return new PointLight(l2w, I * sc);
00064 }
00065 
00066 
00067 float PointLight::Pdf(const Point &, const Vector &) const {
00068     return 0.;
00069 }
00070 
00071 
00072 Spectrum PointLight::Sample_L(const Scene *scene, const LightSample &ls,
00073         float u1, float u2, float time, Ray *ray, Normal *Ns,
00074         float *pdf) const {
00075     *ray = Ray(lightPos, UniformSampleSphere(ls.uPos[0], ls.uPos[1]),
00076                0.f, INFINITY, time);
00077     *Ns = (Normal)ray->d;
00078     *pdf = UniformSpherePdf();
00079     return Intensity;
00080 }
00081 
00082 
00083 void PointLight::SHProject(const Point &p, float pEpsilon, int lmax,
00084         const Scene *scene, bool computeLightVisibility, float time,
00085         RNG &rng, Spectrum *coeffs) const {
00086     for (int i = 0; i < SHTerms(lmax); ++i)
00087         coeffs[i] = 0.f;
00088     if (computeLightVisibility &&
00089         scene->IntersectP(Ray(p, Normalize(lightPos - p), pEpsilon,
00090                               Distance(lightPos, p), time)))
00091         return;
00092     
00093     float *Ylm = ALLOCA(float, SHTerms(lmax));
00094     Vector wi = Normalize(lightPos - p);
00095     SHEvaluate(wi, lmax, Ylm);
00096     Spectrum Li = Intensity / DistanceSquared(lightPos, p);
00097     for (int i = 0; i < SHTerms(lmax); ++i)
00098         coeffs[i] = Li * Ylm[i];
00099 }
00100 
00101