00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef LUX_LIGHT_H
00024 #define LUX_LIGHT_H
00025
00026 #include "lux.h"
00027 #include "geometry.h"
00028 #include "spectrum.h"
00029 #include "error.h"
00030 #include "rgbillum.h"
00031
00032
00033 namespace lux
00034 {
00035
00036 class Light {
00037 public:
00038
00039 virtual ~Light();
00040 Light(const Transform &l2w, int ns = 1)
00041 : nSamples(max(1, ns)), LightToWorld(l2w),
00042 WorldToLight(l2w.GetInverse()) {
00043 if (WorldToLight.HasScale())
00044 luxError(LUX_UNIMPLEMENT,LUX_WARNING,"Scaling detected in world-to-light transformation!\nThe system has numerous assumptions, implicit and explicit,\nthat this transform will have no scale factors in it.\nProceed at your own risk; your image may have errors or\nthe system may crash as a result of this.");
00045 havePortalShape = false;
00046 nrPortalShapes = 0;
00047 PortalArea = 0;
00048 }
00049 virtual SWCSpectrum Sample_L(const Point &p,
00050 Vector *wi, VisibilityTester *vis) const = 0;
00051 virtual SWCSpectrum Power(const Scene *) const = 0;
00052 virtual bool IsDeltaLight() const = 0;
00053 virtual SWCSpectrum Le(const RayDifferential &r) const;
00054 virtual SWCSpectrum Le(const Scene *scene, const Ray &r,
00055 const Normal &n, BSDF **bsdf, float *pdf, float *pdfDirect) const;
00056 virtual SWCSpectrum Sample_L(const Point &p, float u1,
00057 float u2, float u3, Vector *wi, float *pdf,
00058 VisibilityTester *vis) const = 0;
00059 virtual float Pdf(const Point &p,
00060 const Vector &wi) const = 0;
00061 virtual SWCSpectrum Sample_L(const Point &p, const Normal &n,
00062 float u1, float u2, float u3, Vector *wi, float *pdf,
00063 VisibilityTester *visibility) const {
00064 return Sample_L(p, u1, u2, u3, wi, pdf, visibility);
00065 }
00066 virtual float Pdf(const Point &p, const Normal &n,
00067 const Vector &wi) const {
00068 return Pdf(p, wi);
00069 }
00070 virtual SWCSpectrum Sample_L(const Scene *scene, float u1,
00071 float u2, float u3, float u4,
00072 Ray *ray, float *pdf) const = 0;
00073 virtual SWCSpectrum Sample_L(const Scene *scene, float u1, float u2, BSDF **bsdf, float *pdf) const {luxError(LUX_BUG, LUX_SEVERE, "Unimplemented Light::Sample_L"); return 0.f;}
00074 virtual SWCSpectrum Sample_L(const Scene *scene, const Point &p, const Normal &n, float u1, float u2, float u3, BSDF **bsdf, float *pdf, float *pdfDirect, VisibilityTester *visibility) const {luxError(LUX_BUG, LUX_SEVERE, "Unimplemented Light::Sample_L"); return 0.f;}
00075 virtual float Pdf(const Scene *scene, const Point &p) const {luxError(LUX_BUG, LUX_SEVERE, "Unimplemented Light::Pdf"); return 0.f;}
00076
00077 void AddPortalShape(boost::shared_ptr<Shape> shape);
00078
00079 virtual void SamplePosition(float u1, float u2, Point *p, Normal *n, float *pdf) const
00080 {
00081 luxError(LUX_BUG,LUX_SEVERE,"Unimplemented Light::SamplePosition() method called");
00082 }
00083 virtual void SampleDirection(float u1, float u2,const Normal &nn, Vector *wo, float *pdf) const
00084 {
00085 luxError(LUX_BUG,LUX_SEVERE,"Unimplemented Light::SampleDirection() method called");
00086 }
00087 virtual float EvalPositionPdf(const Point p, const Normal &n, const Vector &w) const
00088 {
00089 luxError(LUX_BUG,LUX_SEVERE,"Unimplemented Light::EvalPositionPdf() method called");
00090 return 0;
00091 }
00092 virtual float EvalDirectionPdf(const Point p, const Normal &n, const Vector &w) const
00093 {
00094 luxError(LUX_BUG,LUX_SEVERE,"Unimplemented Light::EvalDirectionPdf() method called");
00095 return 0;
00096 }
00097 virtual SWCSpectrum Eval(const Normal &n, const Vector &w) const
00098 {
00099 luxError(LUX_BUG,LUX_SEVERE,"Unimplemented Light::Eval() method called");
00100 return SWCSpectrum(0.);
00101 }
00102
00103
00104 const int nSamples;
00105 bool havePortalShape;
00106 int nrPortalShapes;
00107 vector<boost::shared_ptr<Shape> > PortalShapes;
00108 float PortalArea;
00109 protected:
00110
00111 const Transform LightToWorld, WorldToLight;
00112 };
00113 struct VisibilityTester {
00114
00115 void SetSegment(const Point &p1, const Point &p2) {
00116 r = Ray(p1, p2-p1, RAY_EPSILON, 1.f - RAY_EPSILON);
00117 }
00118 void SetRay(const Point &p, const Vector &w) {
00119 r = Ray(p, w, RAY_EPSILON);
00120 }
00121 bool Unoccluded(const Scene *scene) const;
00122 bool TestOcclusion(const Scene *scene, SWCSpectrum *f) const;
00123 SWCSpectrum Transmittance(const Scene *scene) const;
00124 Ray r;
00125 };
00126 class AreaLight : public Light {
00127 public:
00128
00129 AreaLight(const Transform &light2world,
00130 const Spectrum &power, float g, int ns, const boost::shared_ptr<Shape> &shape);
00131 ~AreaLight() { delete LSPD; }
00132 virtual SWCSpectrum L(const Point &p, const Normal &n,
00133 const Vector &w) const {
00134 return Dot(n, w) > 0 ? SWCSpectrum(LSPD) : 0.;
00135 }
00136 virtual SWCSpectrum L(const Ray &ray, const DifferentialGeometry &dg, const Normal &n, BSDF **bsdf, float *pdf, float *pdfDirect) const;
00137 SWCSpectrum Power(const Scene *) const {
00138 return SWCSpectrum(LSPD) * area * M_PI;
00139 }
00140 bool IsDeltaLight() const { return false; }
00141 float Pdf(const Point &, const Vector &) const;
00142 float Pdf(const Point &, const Normal &, const Vector &) const;
00143 SWCSpectrum Sample_L(const Point &P, Vector *w, VisibilityTester *visibility) const;
00144 virtual SWCSpectrum Sample_L(const Point &P, const Normal &N,
00145 float u1, float u2, float u3, Vector *wo, float *pdf,
00146 VisibilityTester *visibility) const;
00147 virtual SWCSpectrum Sample_L(const Point &P, float u1, float u2, float u3,
00148 Vector *wo, float *pdf, VisibilityTester *visibility) const;
00149 SWCSpectrum Sample_L(const Scene *scene, float u1, float u2,
00150 float u3, float u4, Ray *ray, float *pdf) const;
00151 virtual SWCSpectrum Sample_L(const Scene *scene, float u1, float u2, BSDF **bsdf, float *pdf) const;
00152 virtual SWCSpectrum Sample_L(const Scene *scene, const Point &p, const Normal &n, float u1, float u2, float u3, BSDF **bsdf, float *pdf, float *pdfDirect, VisibilityTester *visibility) const;
00153 virtual float Pdf(const Scene *scene, const Point &p) const;
00154 void SamplePosition(float u1, float u2, Point *p, Normal *n, float *pdf) const;
00155 void SampleDirection(float u1, float u2,const Normal &nn, Vector *wo, float *pdf) const;
00156 float EvalPositionPdf(const Point p, const Normal &n, const Vector &w) const;
00157 float EvalDirectionPdf(const Point p, const Normal &n, const Vector &w) const;
00158 SWCSpectrum Eval(const Normal &n, const Vector &w) const;
00159
00160 static AreaLight *CreateAreaLight(const Transform &light2world, const ParamSet ¶mSet,
00161 const boost::shared_ptr<Shape> &shape);
00162 protected:
00163
00164 SPD *LSPD;
00165 boost::shared_ptr<Shape> shape;
00166 float area;
00167 };
00168
00169 }
00170
00171 #endif // LUX_LIGHT_H