PBRT
|
00001 00002 /* 00003 pbrt source code Copyright(c) 1998-2012 Matt Pharr and Greg Humphreys. 00004 00005 This file is part of pbrt. 00006 00007 Redistribution and use in source and binary forms, with or without 00008 modification, are permitted provided that the following conditions are 00009 met: 00010 00011 - Redistributions of source code must retain the above copyright 00012 notice, this list of conditions and the following disclaimer. 00013 00014 - Redistributions in binary form must reproduce the above copyright 00015 notice, this list of conditions and the following disclaimer in the 00016 documentation and/or other materials provided with the distribution. 00017 00018 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00019 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00020 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00021 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00022 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00023 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00024 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00025 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00026 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00028 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 00030 */ 00031 00032 #if defined(_MSC_VER) 00033 #pragma once 00034 #endif 00035 00036 #ifndef PBRT_CORE_LIGHT_H 00037 #define PBRT_CORE_LIGHT_H 00038 00039 // core/light.h* 00040 #include "pbrt.h" 00041 #include "geometry.h" 00042 #include "transform.h" 00043 #include "spectrum.h" 00044 #include "rng.h" 00045 #include "memory.h" 00046 00047 // Light Declarations 00048 class Light { 00049 public: 00050 // Light Interface 00051 virtual ~Light(); 00052 Light(const Transform &l2w, int ns = 1) 00053 : nSamples(max(1, ns)), LightToWorld(l2w), 00054 WorldToLight(Inverse(l2w)) { 00055 // Warn if light has transformation with scale 00056 if (WorldToLight.HasScale()) 00057 Warning("Scaling detected in world to light transformation!\n" 00058 "The system has numerous assumptions, implicit and explicit,\n" 00059 "that this transform will have no scale factors in it.\n" 00060 "Proceed at your own risk; your image may have errors or\n" 00061 "the system may crash as a result of this."); 00062 } 00063 virtual Spectrum Sample_L(const Point &p, float pEpsilon, 00064 const LightSample &ls, float time, Vector *wi, float *pdf, 00065 VisibilityTester *vis) const = 0; 00066 virtual Spectrum Power(const Scene *) const = 0; 00067 virtual bool IsDeltaLight() const = 0; 00068 virtual Spectrum Le(const RayDifferential &r) const; 00069 virtual float Pdf(const Point &p, const Vector &wi) const = 0; 00070 virtual Spectrum Sample_L(const Scene *scene, const LightSample &ls, 00071 float u1, float u2, float time, Ray *ray, 00072 Normal *Ns, float *pdf) const = 0; 00073 virtual void SHProject(const Point &p, float pEpsilon, int lmax, 00074 const Scene *scene, bool computeLightVisibility, float time, 00075 RNG &rng, Spectrum *coeffs) const; 00076 00077 // Light Public Data 00078 const int nSamples; 00079 protected: 00080 // Light Protected Data 00081 const Transform LightToWorld, WorldToLight; 00082 }; 00083 00084 00085 struct VisibilityTester { 00086 // VisibilityTester Public Methods 00087 void SetSegment(const Point &p1, float eps1, 00088 const Point &p2, float eps2, float time) { 00089 float dist = Distance(p1, p2); 00090 r = Ray(p1, (p2-p1) / dist, eps1, dist * (1.f - eps2), time); 00091 Assert(!r.HasNaNs()); 00092 } 00093 void SetRay(const Point &p, float eps, const Vector &w, float time) { 00094 r = Ray(p, w, eps, INFINITY, time); 00095 Assert(!r.HasNaNs()); 00096 } 00097 bool Unoccluded(const Scene *scene) const; 00098 Spectrum Transmittance(const Scene *scene, const Renderer *renderer, 00099 const Sample *sample, RNG &rng, MemoryArena &arena) const; 00100 Ray r; 00101 }; 00102 00103 00104 class AreaLight : public Light { 00105 public: 00106 // AreaLight Interface 00107 AreaLight(const Transform &l2w, int ns) : Light(l2w, ns) { } 00108 virtual Spectrum L(const Point &p, const Normal &n, 00109 const Vector &w) const = 0; 00110 }; 00111 00112 00113 struct LightSample { 00114 // LightSample Public Methods 00115 LightSample() { } 00116 LightSample(const Sample *sample, const LightSampleOffsets &offsets, uint32_t num); 00117 LightSample(RNG &rng) { 00118 uPos[0] = rng.RandomFloat(); 00119 uPos[1] = rng.RandomFloat(); 00120 uComponent = rng.RandomFloat(); 00121 } 00122 LightSample(float up0, float up1, float ucomp) { 00123 Assert(up0 >= 0.f && up0 < 1.f); 00124 Assert(up1 >= 0.f && up1 < 1.f); 00125 Assert(ucomp >= 0.f && ucomp < 1.f); 00126 uPos[0] = up0; uPos[1] = up1; 00127 uComponent = ucomp; 00128 } 00129 float uPos[2], uComponent; 00130 }; 00131 00132 00133 struct LightSampleOffsets { 00134 LightSampleOffsets() { } 00135 LightSampleOffsets(int count, Sample *sample); 00136 int nSamples, componentOffset, posOffset; 00137 }; 00138 00139 00140 00141 // ShapeSet Declarations 00142 class ShapeSet { 00143 public: 00144 // ShapeSet Public Methods 00145 ShapeSet(const Reference<Shape> &s); 00146 float Area() const { return sumArea; } 00147 ~ShapeSet(); 00148 Point Sample(const Point &p, const LightSample &ls, Normal *Ns) const; 00149 Point Sample(const LightSample &ls, Normal *Ns) const; 00150 float Pdf(const Point &p, const Vector &wi) const; 00151 float Pdf(const Point &p) const; 00152 private: 00153 // ShapeSet Private Data 00154 vector<Reference<Shape> > shapes; 00155 float sumArea; 00156 vector<float> areas; 00157 Distribution1D *areaDistribution; 00158 }; 00159 00160 00161 00162 #endif // PBRT_CORE_LIGHT_H