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