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 "distant.h"
00025 #include "mc.h"
00026 #include "paramset.h"
00027 #include "dynload.h"
00028
00029 using namespace lux;
00030
00031
00032 DistantLight::DistantLight(const Transform &light2world,
00033 const boost::shared_ptr< Texture<SWCSpectrum> > L,
00034 float g, const Vector &dir)
00035 : Light(light2world) {
00036 lightDir = Normalize(LightToWorld(dir));
00037 Lbase = L;
00038 Lbase->SetIlluminant();
00039 gain = g;
00040 }
00041 DistantLight::~DistantLight()
00042 {
00043 }
00044 SWCSpectrum DistantLight::Sample_L(const TsPack *tspack, const Point &p, float u1, float u2, float u3,
00045 Vector *wi, float *pdf, VisibilityTester *visibility) const {
00046 *pdf = 1.f;
00047 *wi = lightDir;
00048 visibility->SetRay(p, *wi, tspack->time);
00049 return Lbase->Evaluate(tspack, dummydg) * gain;
00050 }
00051 float DistantLight::Pdf(const Point &, const Vector &) const {
00052 return 0.f;
00053 }
00054 float DistantLight::Pdf(const Point &p, const Normal &N,
00055 const Point &po, const Normal &ns) const
00056 {
00057 return 0.f;
00058 }
00059 SWCSpectrum DistantLight::Sample_L(const TsPack *tspack, const Scene *scene,
00060 float u1, float u2, float u3, float u4,
00061 Ray *ray, float *pdf) const {
00062
00063 Point worldCenter;
00064 float worldRadius;
00065 scene->WorldBound().BoundingSphere(&worldCenter,
00066 &worldRadius);
00067 Vector v1, v2;
00068 CoordinateSystem(lightDir, &v1, &v2);
00069 float d1, d2;
00070 ConcentricSampleDisk(u1, u2, &d1, &d2);
00071 Point Pdisk =
00072 worldCenter + worldRadius * (d1 * v1 + d2 * v2);
00073
00074 ray->o = Pdisk + worldRadius * lightDir;
00075 ray->d = -lightDir;
00076 *pdf = 1.f / (M_PI * worldRadius * worldRadius);
00077 return Lbase->Evaluate(tspack, dummydg) * gain;
00078 }
00079 Light* DistantLight::CreateLight(const Transform &light2world,
00080 const ParamSet ¶mSet, const TextureParams &tp) {
00081 boost::shared_ptr<Texture<SWCSpectrum> > L = tp.GetSWCSpectrumTexture("L", RGBColor(1.f));
00082 float g = paramSet.FindOneFloat("gain", 1.f);
00083 Point from = paramSet.FindOnePoint("from", Point(0,0,0));
00084 Point to = paramSet.FindOnePoint("to", Point(0,0,1));
00085 Vector dir = from-to;
00086 return new DistantLight(light2world, L, g, dir);
00087 }
00088
00089 static DynamicLoader::RegisterLight<DistantLight> r("distant");
00090