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 "infinite.h"
00025 #include "imagereader.h"
00026 #include "mc.h"
00027 #include "paramset.h"
00028 #include "blackbodyspd.h"
00029 #include "reflection/bxdf.h"
00030 #include "dynload.h"
00031
00032 using namespace lux;
00033
00034 class InfiniteBxDF : public BxDF
00035 {
00036 public:
00037 InfiniteBxDF(const InfiniteAreaLight &l, const Transform &WL, const Vector &x, const Vector &y, const Vector &z) : BxDF(BxDFType(BSDF_REFLECTION | BSDF_DIFFUSE)), light(l), WorldToLight(WL), X(x), Y(y), Z(z) {}
00038 virtual ~InfiniteBxDF() { }
00039 virtual void f(const TsPack *tspack, const Vector &wo, const Vector &wi, SWCSpectrum *const f) const
00040 {
00041 Vector w(wi.x * X + wi.y * Y + wi.z * Z);
00042 *f += light.Le(tspack, RayDifferential(Point(0.f), -w));
00043 }
00044 private:
00045 const InfiniteAreaLight &light;
00046 const Transform &WorldToLight;
00047 Vector X, Y, Z;
00048 };
00049
00050 class InfinitePortalBxDF : public BxDF
00051 {
00052 public:
00053 InfinitePortalBxDF(const InfiniteAreaLight &l, const Transform &WL, const Vector &x, const Vector &y, const Vector &z, const Point &p, const vector<boost::shared_ptr<Primitive> > &portalList, u_int portal, float u) : BxDF(BxDFType(BSDF_REFLECTION | BSDF_DIFFUSE)), light(l), WorldToLight(WL), X(x), Y(y), Z(z), ps(p), PortalShapes(portalList), shapeIndex(portal), u3(u) {}
00054 virtual ~InfinitePortalBxDF() { }
00055 virtual bool Sample_f(const TsPack *tspack, const Vector &wo, Vector *wi, float u1, float u2, SWCSpectrum *const f,float *pdf, float *pdfBack = NULL, bool reverse = false) const
00056 {
00057 if (shapeIndex == ~0U || reverse)
00058 return false;
00059 DifferentialGeometry dg;
00060 dg.time = tspack->time;
00061 PortalShapes[shapeIndex]->Sample(ps, u1, u2, u3, &dg);
00062 Vector wiW = Normalize(dg.p - ps);
00063 *f = light.Le(tspack, RayDifferential(Point(0.f), -wiW));
00064 wi->x = Dot(wiW, X);
00065 wi->y = Dot(wiW, Y);
00066 wi->z = Dot(wiW, Z);
00067 *wi = Normalize(*wi);
00068 *pdf = PortalShapes[shapeIndex]->Pdf(ps, dg.p) * DistanceSquared(ps, dg.p) / AbsDot(wiW, dg.nn);
00069 for (u_int i = 0; i < PortalShapes.size(); ++i) {
00070 if (i != shapeIndex) {
00071 Intersection isect;
00072 RayDifferential ray(ps, wiW);
00073 ray.mint = -INFINITY;
00074 if (PortalShapes[i]->Intersect(ray, &isect) && Dot(wiW, isect.dg.nn) > 0.f)
00075 *pdf += PortalShapes[i]->Pdf(ps, isect.dg.p) * DistanceSquared(ps, isect.dg.p) / AbsDot(wiW, isect.dg.nn);
00076 }
00077 }
00078 *pdf /= PortalShapes.size();
00079 if (pdfBack)
00080 *pdfBack = 0.f;
00081 return true;
00082 }
00083 virtual void f(const TsPack *tspack, const Vector &wo, const Vector &wi, SWCSpectrum *const f) const
00084 {
00085 Vector w(wi.x * X + wi.y * Y + wi.z * Z);
00086 *f += light.Le(tspack, RayDifferential(Point(0.f), -w));
00087 }
00088 virtual float Pdf(const TsPack *tspack, const Vector &wi, const Vector &wo) const
00089 {
00090 Vector w(wo.x * X + wo.y * Y + wo.z * Z);
00091 float pdf = 0.f;
00092 for (u_int i = 0; i < PortalShapes.size(); ++i) {
00093 Intersection isect;
00094 RayDifferential ray(ps, w);
00095 ray.mint = -INFINITY;
00096 if (PortalShapes[i]->Intersect(ray, &isect) && Dot(w, isect.dg.nn) > 0.f)
00097 pdf += PortalShapes[i]->Pdf(ps, isect.dg.p) * DistanceSquared(ps, isect.dg.p) / AbsDot(w, isect.dg.nn);
00098 }
00099 return pdf / PortalShapes.size();
00100 }
00101 private:
00102 const InfiniteAreaLight &light;
00103 const Transform &WorldToLight;
00104 Vector X, Y, Z;
00105 Point ps;
00106 const vector<boost::shared_ptr<Primitive> > &PortalShapes;
00107 u_int shapeIndex;
00108 float u3;
00109 };
00110
00111
00112 InfiniteAreaLight::~InfiniteAreaLight() {
00113 delete radianceMap;
00114 delete SPDbase;
00115 delete mapping;
00116 }
00117 InfiniteAreaLight
00118 ::InfiniteAreaLight(const Transform &light2world, const RGBColor &l, int ns, const string &texmap, EnvironmentMapping *m, float gain, float gamma)
00119 : Light(light2world, ns) {
00120 radianceMap = NULL;
00121 if (texmap != "") {
00122 auto_ptr<ImageData> imgdata(ReadImage(texmap));
00123 if(imgdata.get()!=NULL)
00124 {
00125 radianceMap = imgdata->createMIPMap<RGBColor>(BILINEAR, 8.f,
00126 TEXTURE_REPEAT, 1.f, gamma);
00127 }
00128 else
00129 radianceMap=NULL;
00130 }
00131
00132 mapping = m;
00133
00134
00135 SPDbase = new BlackbodySPD();
00136 SPDbase->Normalize();
00137 SPDbase->Scale(gain);
00138
00139
00140 Lbase = l;
00141 }
00142
00143 SWCSpectrum
00144 InfiniteAreaLight::Le(const TsPack *tspack, const RayDifferential &r) const {
00145
00146
00147 RGBColor L = Lbase;
00148 if (radianceMap != NULL) {
00149 Vector wh = Normalize(WorldToLight(r.d));
00150
00151 float s, t;
00152
00153 mapping->Map(wh, &s, &t);
00154
00155 L *= radianceMap->Lookup(s, t);
00156 }
00157
00158 return SWCSpectrum(tspack, SPDbase) * SWCSpectrum(tspack, L);
00159 }
00160 SWCSpectrum InfiniteAreaLight::Le(const TsPack *tspack, const Scene *scene, const Ray &r,
00161 const Normal &n, BSDF **bsdf, float *pdf, float *pdfDirect) const
00162 {
00163 Point worldCenter;
00164 float worldRadius;
00165 scene->WorldBound().BoundingSphere(&worldCenter, &worldRadius);
00166 Vector toCenter(worldCenter - r.o);
00167 float centerDistance = Dot(toCenter, toCenter);
00168 float approach = Dot(toCenter, r.d);
00169 float distance = approach + sqrtf(worldRadius * worldRadius - centerDistance + approach * approach);
00170 Point ps(r.o + distance * r.d);
00171 Normal ns(Normalize(worldCenter - ps));
00172 Vector dpdu, dpdv;
00173 CoordinateSystem(Vector(ns), &dpdu, &dpdv);
00174 DifferentialGeometry dg(ps, ns, dpdu, dpdv, Normal(0, 0, 0), Normal (0, 0, 0), 0, 0, NULL);
00175 dg.time = tspack->time;
00176 if (!havePortalShape) {
00177 *bsdf = BSDF_ALLOC(tspack, SingleBSDF)(dg, ns,
00178 BSDF_ALLOC(tspack, InfiniteBxDF)(*this, WorldToLight, dpdu, dpdv, Vector(ns)));
00179 *pdf = 1.f / (4.f * M_PI * worldRadius * worldRadius);
00180 *pdfDirect = AbsDot(r.d, n) * INV_TWOPI * AbsDot(r.d, ns) / DistanceSquared(r.o, ps);
00181 } else {
00182 float u3 = tspack->rng->floatValue();
00183 *bsdf = BSDF_ALLOC(tspack, SingleBSDF)(dg, ns,
00184 BSDF_ALLOC(tspack, InfinitePortalBxDF)(*this,
00185 WorldToLight, dpdu, dpdv, Vector(ns), ps, PortalShapes,
00186 ~0U, u3));
00187 *pdf = 0.f;
00188 *pdfDirect = 0.f;
00189 for (int i = 0; i < nrPortalShapes; ++i) {
00190 PortalShapes[i]->Sample(.5f, .5f, u3, &dg);
00191 Vector w(dg.p - ps);
00192 if (Dot(w, dg.nn) > 0.f) {
00193 float distance = w.LengthSquared();
00194 *pdf += AbsDot(ns, w) / (sqrtf(distance) * distance);
00195 }
00196 Intersection isect;
00197 RayDifferential ray(r);
00198 ray.mint = -INFINITY;
00199 if (PortalShapes[i]->Intersect(ray, &isect) && Dot(r.d, isect.dg.nn) < 0.f)
00200 *pdfDirect += PortalShapes[i]->Pdf(r.o, isect.dg.p) * DistanceSquared(r.o, isect.dg.p) / DistanceSquared(r.o, ps) * AbsDot(r.d, ns) / AbsDot(r.d, isect.dg.nn);
00201 }
00202 *pdf *= INV_TWOPI / nrPortalShapes;
00203 *pdfDirect /= nrPortalShapes;
00204 }
00205 return Le(tspack, RayDifferential(r));
00206 }
00207 SWCSpectrum InfiniteAreaLight::Sample_L(const TsPack *tspack, const Point &p,
00208 const Normal &n, float u1, float u2, float u3,
00209 Vector *wi, float *pdf,
00210 VisibilityTester *visibility) const {
00211 if(!havePortalShape) {
00212
00213 float x, y, z;
00214 ConcentricSampleDisk(u1, u2, &x, &y);
00215 z = sqrtf(max(0.f, 1.f - x*x - y*y));
00216 if (u3 < .5) z *= -1;
00217 *wi = Vector(x, y, z);
00218
00219 *pdf = fabsf(wi->z) * INV_TWOPI;
00220
00221 Vector v1, v2;
00222 CoordinateSystem(Normalize(Vector(n)), &v1, &v2);
00223 *wi = Vector(v1.x * wi->x + v2.x * wi->y + n.x * wi->z,
00224 v1.y * wi->x + v2.y * wi->y + n.y * wi->z,
00225 v1.z * wi->x + v2.z * wi->y + n.z * wi->z);
00226 } else {
00227
00228 int shapeidx = 0;
00229 if(nrPortalShapes > 1)
00230 shapeidx = min<float>(nrPortalShapes - 1, u3 * nrPortalShapes);
00231 DifferentialGeometry dg;
00232 dg.time = tspack->time;
00233 Point ps;
00234 bool found = false;
00235 for (int i = 0; i < nrPortalShapes; ++i) {
00236 PortalShapes[shapeidx]->Sample(p, u1, u2, u3, &dg);
00237 ps = dg.p;
00238 *wi = Normalize(ps - p);
00239 if (Dot(*wi, dg.nn) < 0.f) {
00240 found = true;
00241 break;
00242 }
00243
00244 if (++shapeidx >= nrPortalShapes)
00245 shapeidx = 0;
00246 }
00247
00248 if (found)
00249 *pdf = PortalShapes[shapeidx]->Pdf(p, *wi);
00250 else {
00251 *pdf = 0.f;
00252 return SWCSpectrum(0.f);
00253 }
00254 }
00255 visibility->SetRay(p, *wi, tspack->time);
00256 return Le(tspack, RayDifferential(p, *wi));
00257 }
00258 float InfiniteAreaLight::Pdf(const Point &, const Normal &n,
00259 const Vector &wi) const {
00260 return AbsDot(n, wi) * INV_TWOPI;
00261 }
00262 float InfiniteAreaLight::Pdf(const Point &p, const Normal &n,
00263 const Point &po, const Normal &ns) const
00264 {
00265 const Vector wi(po - p);
00266 if (!havePortalShape) {
00267 const float d2 = wi.LengthSquared();
00268 return AbsDot(n, wi) * INV_TWOPI * AbsDot(wi, ns) / (d2 * d2);
00269 } else {
00270 float pdf = 0.f;
00271 for (int i = 0; i < nrPortalShapes; ++i) {
00272 Intersection isect;
00273 RayDifferential ray(p, wi);
00274 ray.mint = -INFINITY;
00275 if (PortalShapes[i]->Intersect(ray, &isect) &&
00276 Dot(wi, isect.dg.nn) < 0.f)
00277 pdf += PortalShapes[i]->Pdf(p, isect.dg.p) * DistanceSquared(p, isect.dg.p) / DistanceSquared(p, po) * AbsDot(wi, ns) / AbsDot(wi, isect.dg.nn);
00278 }
00279 pdf /= nrPortalShapes;
00280 return pdf;
00281 }
00282 }
00283 SWCSpectrum InfiniteAreaLight::Sample_L(const TsPack *tspack, const Point &p,
00284 float u1, float u2, float u3, Vector *wi, float *pdf,
00285 VisibilityTester *visibility) const {
00286 if(!havePortalShape) {
00287 *wi = UniformSampleSphere(u1, u2);
00288 *pdf = UniformSpherePdf();
00289 } else {
00290
00291 int shapeidx = 0;
00292 if(nrPortalShapes > 1)
00293 shapeidx = min<float>(nrPortalShapes - 1, u3 * nrPortalShapes);
00294 DifferentialGeometry dg;
00295 dg.time = tspack->time;
00296 Point ps;
00297 bool found = false;
00298 for (int i = 0; i < nrPortalShapes; ++i) {
00299 PortalShapes[shapeidx]->Sample(p, u1, u2, u3, &dg);
00300 ps = dg.p;
00301 *wi = Normalize(ps - p);
00302 if (Dot(*wi, dg.nn) < 0.f) {
00303 found = true;
00304 break;
00305 }
00306
00307 if (++shapeidx >= nrPortalShapes)
00308 shapeidx = 0;
00309 }
00310
00311 if (found)
00312 *pdf = PortalShapes[shapeidx]->Pdf(p, *wi);
00313 else {
00314 *pdf = 0.f;
00315 return SWCSpectrum(0.f);
00316 }
00317 }
00318 visibility->SetRay(p, *wi, tspack->time);
00319 return Le(tspack, RayDifferential(p, *wi));
00320 }
00321 float InfiniteAreaLight::Pdf(const Point &, const Vector &) const {
00322 return 1.f / (4.f * M_PI);
00323 }
00324 SWCSpectrum InfiniteAreaLight::Sample_L(const TsPack *tspack, const Scene *scene,
00325 float u1, float u2, float u3, float u4,
00326 Ray *ray, float *pdf) const {
00327 if(!havePortalShape) {
00328
00329 Point worldCenter;
00330 float worldRadius;
00331 scene->WorldBound().BoundingSphere(&worldCenter, &worldRadius);
00332 worldRadius *= 1.01f;
00333 Point p1 = worldCenter + worldRadius *
00334 UniformSampleSphere(u1, u2);
00335 Point p2 = worldCenter + worldRadius *
00336 UniformSampleSphere(u3, u4);
00337
00338 ray->o = p1;
00339 ray->d = Normalize(p2-p1);
00340
00341 Vector to_center = Normalize(worldCenter - p1);
00342 float costheta = AbsDot(to_center,ray->d);
00343 *pdf =
00344 costheta / ((4.f * M_PI * worldRadius * worldRadius));
00345 } else {
00346
00347
00348 int shapeidx = 0;
00349 if(nrPortalShapes > 1)
00350 shapeidx = min<float>(nrPortalShapes - 1,
00351 Floor2Int(tspack->rng->floatValue() * nrPortalShapes));
00352
00353 DifferentialGeometry dg;
00354 dg.time = tspack->time;
00355 PortalShapes[shapeidx]->Sample(u1, u2, tspack->rng->floatValue(), &dg);
00356 ray->o = dg.p;
00357 ray->d = UniformSampleSphere(u3, u4);
00358 if (Dot(ray->d, dg.nn) < 0.) ray->d *= -1;
00359
00360 *pdf = PortalShapes[shapeidx]->Pdf(ray->o) * INV_TWOPI / nrPortalShapes;
00361 }
00362
00363 return Le(tspack, RayDifferential(ray->o, -ray->d));
00364 }
00365 bool InfiniteAreaLight::Sample_L(const TsPack *tspack, const Scene *scene, float u1, float u2, float u3, BSDF **bsdf, float *pdf, SWCSpectrum *Le) const
00366 {
00367 Point worldCenter;
00368 float worldRadius;
00369 scene->WorldBound().BoundingSphere(&worldCenter, &worldRadius);
00370 if (!havePortalShape) {
00371 Point ps = worldCenter + worldRadius * UniformSampleSphere(u1, u2);
00372 Normal ns = Normal(Normalize(worldCenter - ps));
00373 Vector dpdu, dpdv;
00374 CoordinateSystem(Vector(ns), &dpdu, &dpdv);
00375 DifferentialGeometry dg(ps, ns, dpdu, dpdv, Normal(0, 0, 0), Normal (0, 0, 0), 0, 0, NULL);
00376 *bsdf = BSDF_ALLOC(tspack, SingleBSDF)(dg, ns,
00377 BSDF_ALLOC(tspack, InfiniteBxDF)(*this, WorldToLight, dpdu, dpdv, Vector(ns)));
00378 *pdf = 1.f / (4.f * M_PI * worldRadius * worldRadius);
00379 } else {
00380
00381 int shapeIndex = 0;
00382 if (nrPortalShapes > 1) {
00383 shapeIndex = min(nrPortalShapes - 1, Floor2Int(u3 * nrPortalShapes));
00384 u3 *= nrPortalShapes;
00385 u3 -= shapeIndex;
00386 }
00387 DifferentialGeometry dgs;
00388 dgs.time = tspack->time;
00389 PortalShapes[shapeIndex]->Sample(.5f, .5f, u3, &dgs);
00390 Vector wi(UniformSampleHemisphere(u1, u2));
00391 wi = Normalize(wi.x * Normalize(dgs.dpdu) + wi.y * Normalize(dgs.dpdv) - wi.z * Vector(dgs.nn));
00392 Vector toCenter(worldCenter - dgs.p);
00393 float centerDistance = Dot(toCenter, toCenter);
00394 float approach = Dot(toCenter, wi);
00395 float distance = approach + sqrtf(worldRadius * worldRadius - centerDistance + approach * approach);
00396 Point ps(dgs.p + distance * wi);
00397 Normal ns(Normalize(worldCenter - ps));
00398 Vector dpdu, dpdv;
00399 CoordinateSystem(Vector(ns), &dpdu, &dpdv);
00400 DifferentialGeometry dg(ps, ns, dpdu, dpdv, Normal(0, 0, 0), Normal(0, 0, 0), 0, 0, NULL);
00401 *bsdf = BSDF_ALLOC(tspack, SingleBSDF)(dg, ns,
00402 BSDF_ALLOC(tspack, InfinitePortalBxDF)(*this, WorldToLight, dpdu, dpdv, Vector(ns), ps, PortalShapes, shapeIndex, u3));
00403 *pdf = AbsDot(ns, wi) / (distance * distance);
00404 for (int i = 0; i < nrPortalShapes; ++i) {
00405 if (i != shapeIndex) {
00406 PortalShapes[i]->Sample(.5f, .5f, u3, &dgs);
00407 wi = ps - dgs.p;
00408 if (Dot(wi, dg.nn) < 0.f) {
00409 distance = wi.LengthSquared();
00410 *pdf += AbsDot(ns, wi) / (sqrtf(distance) * distance);
00411 }
00412 }
00413 }
00414 *pdf *= INV_TWOPI / nrPortalShapes;
00415 }
00416 *Le = SWCSpectrum(1.f);
00417 return true;
00418 }
00419 bool InfiniteAreaLight::Sample_L(const TsPack *tspack, const Scene *scene, const Point &p, const Normal &n,
00420 float u1, float u2, float u3, BSDF **bsdf, float *pdf, float *pdfDirect,
00421 VisibilityTester *visibility, SWCSpectrum *Le) const
00422 {
00423 Vector wi;
00424 int shapeIndex = 0;
00425 Point worldCenter;
00426 float worldRadius;
00427 scene->WorldBound().BoundingSphere(&worldCenter, &worldRadius);
00428 if(!havePortalShape) {
00429
00430 float x, y, z;
00431 ConcentricSampleDisk(u1, u2, &x, &y);
00432 z = sqrtf(max(0.f, 1.f - x*x - y*y));
00433 if (u3 < .5)
00434 z *= -1;
00435 wi = Vector(x, y, z);
00436
00437 *pdfDirect = fabsf(wi.z) * INV_TWOPI;
00438
00439 Vector v1, v2;
00440 CoordinateSystem(Normalize(Vector(n)), &v1, &v2);
00441 wi = Vector(wi.x * v1 + wi.y * v2 + wi.z * Vector(n));
00442 } else {
00443
00444 if(nrPortalShapes > 1) {
00445 shapeIndex = min(nrPortalShapes - 1, Floor2Int(u3 * nrPortalShapes));
00446 u3 *= nrPortalShapes;
00447 u3 -= shapeIndex;
00448 }
00449 DifferentialGeometry dg;
00450 dg.time = tspack->time;
00451 PortalShapes[shapeIndex]->Sample(p, u1, u2, u3, &dg);
00452 Point ps = dg.p;
00453 wi = Normalize(ps - p);
00454 if (Dot(wi, dg.nn) < 0.f) {
00455 *pdfDirect = PortalShapes[shapeIndex]->Pdf(p, ps) / nrPortalShapes;
00456 *pdfDirect *= DistanceSquared(p, dg.p) / AbsDot(wi, dg.nn);
00457 } else {
00458 *Le = 0.f;
00459 return false;
00460 }
00461 }
00462 Vector toCenter(worldCenter - p);
00463 float centerDistance = Dot(toCenter, toCenter);
00464 float approach = Dot(toCenter, wi);
00465 float distance = approach + sqrtf(worldRadius * worldRadius - centerDistance + approach * approach);
00466 Point ps(p + distance * wi);
00467 Normal ns(Normalize(worldCenter - ps));
00468 Vector dpdu, dpdv;
00469 CoordinateSystem(Vector(ns), &dpdu, &dpdv);
00470 DifferentialGeometry dg(ps, ns, dpdu, dpdv, Normal(0, 0, 0), Normal (0, 0, 0), 0, 0, NULL);
00471 if (!havePortalShape) {
00472 *bsdf = BSDF_ALLOC(tspack, SingleBSDF)(dg, ns,
00473 BSDF_ALLOC(tspack, InfiniteBxDF)(*this, WorldToLight, dpdu, dpdv, Vector(ns)));
00474 *pdf = 1.f / (4.f * M_PI * worldRadius * worldRadius);
00475 } else {
00476 *bsdf = BSDF_ALLOC(tspack, SingleBSDF)(dg, ns,
00477 BSDF_ALLOC(tspack, InfinitePortalBxDF)(*this, WorldToLight, dpdu, dpdv, Vector(ns), ps, PortalShapes, shapeIndex, u3));
00478 *pdf = 0.f;
00479 DifferentialGeometry dgs;
00480 dgs.time = tspack->time;
00481 for (int i = 0; i < nrPortalShapes; ++i) {
00482 PortalShapes[i]->Sample(.5f, .5f, u3, &dgs);
00483 Vector w(ps - dgs.p);
00484 if (Dot(wi, dg.nn) < 0.f) {
00485 float distance = w.LengthSquared();
00486 *pdf += AbsDot(ns, w) / (sqrtf(distance) * distance);
00487 }
00488 }
00489 *pdf *= INV_TWOPI / nrPortalShapes;
00490 }
00491 *pdfDirect *= AbsDot(wi, ns) / (distance * distance);
00492 visibility->SetSegment(p, ps, tspack->time);
00493 *Le = SWCSpectrum(1.f);
00494 return true;
00495 }
00496
00497 Light* InfiniteAreaLight::CreateLight(const Transform &light2world,
00498 const ParamSet ¶mSet, const TextureParams &tp) {
00499 RGBColor L = paramSet.FindOneRGBColor("L", RGBColor(1.0));
00500 string texmap = paramSet.FindOneString("mapname", "");
00501 int nSamples = paramSet.FindOneInt("nsamples", 1);
00502
00503 EnvironmentMapping *map = NULL;
00504 string type = paramSet.FindOneString("mapping", "");
00505 if (type == "" || type == "latlong") {
00506 map = new LatLongMapping();
00507 }
00508 else if (type == "angular") map = new AngularMapping();
00509 else if (type == "vcross") map = new VerticalCrossMapping();
00510
00511
00512 float gain = paramSet.FindOneFloat("gain", 1.0f);
00513 float gamma = paramSet.FindOneFloat("gamma", 1.0f);
00514
00515 return new InfiniteAreaLight(light2world, L, nSamples, texmap, map, gain, gamma);
00516 }
00517
00518 static DynamicLoader::RegisterLight<InfiniteAreaLight> r("infinite");
00519