00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if defined(_MSC_VER)
00025 #pragma once
00026 #endif
00027
00028 #ifndef PBRT_CORE_LIGHT_H
00029 #define PBRT_CORE_LIGHT_H
00030
00031
00032 #include "pbrt.h"
00033 #include "geometry.h"
00034 #include "transform.h"
00035 #include "spectrum.h"
00036 #include "rng.h"
00037 #include "memory.h"
00038
00039
00040 class Light {
00041 public:
00042
00043 virtual ~Light();
00044 Light(const Transform &l2w, int ns = 1)
00045 : nSamples(max(1, ns)), LightToWorld(l2w),
00046 WorldToLight(Inverse(l2w)) {
00047
00048 if (WorldToLight.HasScale())
00049 Warning("Scaling detected in world to light transformation!\n"
00050 "The system has numerous assumptions, implicit and explicit,\n"
00051 "that this transform will have no scale factors in it.\n"
00052 "Proceed at your own risk; your image may have errors or\n"
00053 "the system may crash as a result of this.");
00054 }
00055 virtual Spectrum Sample_L(const Point &p, float pEpsilon,
00056 const LightSample &ls, float time, Vector *wi, float *pdf,
00057 VisibilityTester *vis) const = 0;
00058 virtual Spectrum Power(const Scene *) const = 0;
00059 virtual bool IsDeltaLight() const = 0;
00060 virtual Spectrum Le(const RayDifferential &r) const;
00061 virtual float Pdf(const Point &p, const Vector &wi) const = 0;
00062 virtual Spectrum Sample_L(const Scene *scene, const LightSample &ls,
00063 float u1, float u2, float time, Ray *ray,
00064 Normal *Ns, float *pdf) const = 0;
00065 virtual void SHProject(const Point &p, float pEpsilon, int lmax,
00066 const Scene *scene, bool computeLightVisibility, float time,
00067 RNG &rng, Spectrum *coeffs) const;
00068
00069
00070 const int nSamples;
00071 protected:
00072
00073 const Transform LightToWorld, WorldToLight;
00074 };
00075
00076
00077 struct VisibilityTester {
00078
00079 void SetSegment(const Point &p1, float eps1,
00080 const Point &p2, float eps2, float time) {
00081 float dist = Distance(p1, p2);
00082 r = Ray(p1, (p2-p1) / dist, eps1, dist * (1.f - eps2), time);
00083 Assert(!r.HasNaNs());
00084 }
00085 void SetRay(const Point &p, float eps, const Vector &w, float time) {
00086 r = Ray(p, w, eps, INFINITY, time);
00087 Assert(!r.HasNaNs());
00088 }
00089 bool Unoccluded(const Scene *scene) const;
00090 Spectrum Transmittance(const Scene *scene, const Renderer *renderer,
00091 const Sample *sample, RNG &rng, MemoryArena &arena) const;
00092 Ray r;
00093 };
00094
00095
00096 class AreaLight : public Light {
00097 public:
00098
00099 AreaLight(const Transform &l2w, int ns) : Light(l2w, ns) { }
00100 virtual Spectrum L(const Point &p, const Normal &n,
00101 const Vector &w) const = 0;
00102 };
00103
00104
00105 struct LightSample {
00106
00107 LightSample() { }
00108 LightSample(const Sample *sample, const LightSampleOffsets &offsets, uint32_t num);
00109 LightSample(RNG &rng) {
00110 uPos[0] = rng.RandomFloat();
00111 uPos[1] = rng.RandomFloat();
00112 uComponent = rng.RandomFloat();
00113 }
00114 LightSample(float up0, float up1, float ucomp) {
00115 Assert(up0 >= 0.f && up0 < 1.f);
00116 Assert(up1 >= 0.f && up1 < 1.f);
00117 Assert(ucomp >= 0.f && ucomp < 1.f);
00118 uPos[0] = up0; uPos[1] = up1;
00119 uComponent = ucomp;
00120 }
00121 float uPos[2], uComponent;
00122 };
00123
00124
00125 struct LightSampleOffsets {
00126 LightSampleOffsets() { }
00127 LightSampleOffsets(int count, Sample *sample);
00128 int nSamples, componentOffset, posOffset;
00129 };
00130
00131
00132
00133
00134 class ShapeSet {
00135 public:
00136
00137 ShapeSet(const Reference<Shape> &s);
00138 float Area() const { return sumArea; }
00139 ~ShapeSet();
00140 Point Sample(const Point &p, const LightSample &ls, Normal *Ns) const;
00141 Point Sample(const LightSample &ls, Normal *Ns) const;
00142 float Pdf(const Point &p, const Vector &wi) const;
00143 float Pdf(const Point &p) const;
00144 private:
00145
00146 vector<Reference<Shape> > shapes;
00147 float sumArea;
00148 vector<float> areas;
00149 Distribution1D *areaDistribution;
00150 };
00151
00152
00153
00154 #endif // PBRT_CORE_LIGHT_H