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/distant.h"
00028 #include "paramset.h"
00029 #include "montecarlo.h"
00030
00031
00032 DistantLight::DistantLight(const Transform &light2world,
00033 const Spectrum &radiance, const Vector &dir)
00034 : Light(light2world) {
00035 lightDir = Normalize(LightToWorld(dir));
00036 L = radiance;
00037 }
00038
00039
00040 Spectrum DistantLight::Sample_L(const Point &p, float pEpsilon,
00041 const LightSample &ls, float time, Vector *wi, float *pdf,
00042 VisibilityTester *visibility) const {
00043 *wi = lightDir;
00044 *pdf = 1.f;
00045 visibility->SetRay(p, pEpsilon, *wi, time);
00046 return L;
00047 }
00048
00049
00050 Spectrum DistantLight::Power(const Scene *scene) const {
00051 Point worldCenter;
00052 float worldRadius;
00053 scene->WorldBound().BoundingSphere(&worldCenter, &worldRadius);
00054 return L * M_PI * worldRadius * worldRadius;
00055 }
00056
00057
00058 DistantLight *CreateDistantLight(const Transform &light2world,
00059 const ParamSet ¶mSet) {
00060 Spectrum L = paramSet.FindOneSpectrum("L", Spectrum(1.0));
00061 Spectrum sc = paramSet.FindOneSpectrum("scale", Spectrum(1.0));
00062 Point from = paramSet.FindOnePoint("from", Point(0,0,0));
00063 Point to = paramSet.FindOnePoint("to", Point(0,0,1));
00064 Vector dir = from-to;
00065 return new DistantLight(light2world, L * sc, dir);
00066 }
00067
00068
00069 float DistantLight::Pdf(const Point &, const Vector &) const {
00070 return 0.;
00071 }
00072
00073
00074 Spectrum DistantLight::Sample_L(const Scene *scene,
00075 const LightSample &ls, float u1, float u2, float time,
00076 Ray *ray, Normal *Ns, float *pdf) const {
00077
00078 Point worldCenter;
00079 float worldRadius;
00080 scene->WorldBound().BoundingSphere(&worldCenter, &worldRadius);
00081 Vector v1, v2;
00082 CoordinateSystem(lightDir, &v1, &v2);
00083 float d1, d2;
00084 ConcentricSampleDisk(ls.uPos[0], ls.uPos[1], &d1, &d2);
00085 Point Pdisk = worldCenter + worldRadius * (d1 * v1 + d2 * v2);
00086
00087
00088 *ray = Ray(Pdisk + worldRadius * lightDir, -lightDir, 0.f, INFINITY,
00089 time);
00090 *Ns = (Normal)ray->d;
00091
00092 *pdf = 1.f / (M_PI * worldRadius * worldRadius);
00093 return L;
00094 }
00095
00096