00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PBRT_LIGHT_H
00025 #define PBRT_LIGHT_H
00026
00027 #include "pbrt.h"
00028 #include "geometry.h"
00029 #include "transform.h"
00030 #include "color.h"
00031 #include "paramset.h"
00032 #include "mc.h"
00033
00034 class COREDLL Light {
00035 public:
00036
00037 virtual ~Light();
00038 Light(const Transform &l2w, int ns = 1)
00039 : nSamples(max(1, ns)), LightToWorld(l2w),
00040 WorldToLight(l2w.GetInverse()) {
00041 if (WorldToLight.HasScale())
00042 Warning("Scaling detected in world-to-light transformation!\n"
00043 "The system has numerous assumptions, implicit and explicit,\n"
00044 "that this transform will have no scale factors in it.\n"
00045 "Proceed at your own risk; your image may have errors or\n"
00046 "the system may crash as a result of this.");
00047 }
00048 virtual Spectrum Sample_L(const Point &p,
00049 Vector *wi, VisibilityTester *vis) const = 0;
00050 virtual Spectrum Power(const Scene *) const = 0;
00051 virtual bool IsDeltaLight() const = 0;
00052 virtual Spectrum Le(const RayDifferential &r) const;
00053 virtual Spectrum Sample_L(const Point &p, float u1,
00054 float u2, Vector *wi, float *pdf,
00055 VisibilityTester *vis) const = 0;
00056 virtual float Pdf(const Point &p,
00057 const Vector &wi) const = 0;
00058 virtual Spectrum Sample_L(const Point &p, const Normal &n,
00059 float u1, float u2, Vector *wi, float *pdf,
00060 VisibilityTester *visibility) const {
00061 return Sample_L(p, u1, u2, wi, pdf, visibility);
00062 }
00063 virtual float Pdf(const Point &p, const Normal &n,
00064 const Vector &wi) const {
00065 return Pdf(p, wi);
00066 }
00067 virtual Spectrum Sample_L(const Scene *scene, float u1,
00068 float u2, float u3, float u4,
00069 Ray *ray, float *pdf) const = 0;
00070
00071 const int nSamples;
00072 protected:
00073
00074 const Transform LightToWorld, WorldToLight;
00075 };
00076 struct COREDLL VisibilityTester {
00077
00078 void SetSegment(const Point &p1, const Point &p2) {
00079 r = Ray(p1, p2-p1, RAY_EPSILON, 1.f - RAY_EPSILON);
00080 }
00081 void SetRay(const Point &p, const Vector &w) {
00082 r = Ray(p, w, RAY_EPSILON);
00083 }
00084 bool Unoccluded(const Scene *scene) const;
00085 Spectrum Transmittance(const Scene *scene) const;
00086 Ray r;
00087 };
00088 class AreaLight : public Light {
00089 public:
00090
00091 AreaLight(const Transform &light2world,
00092 const Spectrum &power, int ns, const Reference<Shape> &shape);
00093 virtual Spectrum L(const Point &p, const Normal &n,
00094 const Vector &w) const {
00095 return Dot(n, w) > 0 ? Lemit : 0.;
00096 }
00097 Spectrum Power(const Scene *) const {
00098 return Lemit * area * M_PI;
00099 }
00100 bool IsDeltaLight() const { return false; }
00101 float Pdf(const Point &, const Vector &) const;
00102 float Pdf(const Point &, const Normal &, const Vector &) const;
00103 Spectrum Sample_L(const Point &P, Vector *w, VisibilityTester *visibility) const;
00104 virtual Spectrum Sample_L(const Point &P, const Normal &N,
00105 float u1, float u2, Vector *wo, float *pdf,
00106 VisibilityTester *visibility) const;
00107 virtual Spectrum Sample_L(const Point &P, float u1, float u2, Vector *wo,
00108 float *pdf, VisibilityTester *visibility) const;
00109 Spectrum Sample_L(const Scene *scene, float u1, float u2,
00110 float u3, float u4, Ray *ray, float *pdf) const;
00111 protected:
00112
00113 Spectrum Lemit;
00114 Reference<Shape> shape;
00115 float area;
00116 };
00117 #endif // PBRT_LIGHT_H