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_VOLUME_H 00037 #define PBRT_CORE_VOLUME_H 00038 00039 // core/volume.h* 00040 #include "pbrt.h" 00041 #include "spectrum.h" 00042 #include "geometry.h" 00043 #include "transform.h" 00044 #include "integrator.h" 00045 00046 // Volume Scattering Declarations 00047 float PhaseIsotropic(const Vector &w, const Vector &wp); 00048 float PhaseRayleigh(const Vector &w, const Vector &wp); 00049 float PhaseMieHazy(const Vector &w, const Vector &wp); 00050 float PhaseMieMurky(const Vector &w, const Vector &wp); 00051 float PhaseHG(const Vector &w, const Vector &wp, float g); 00052 float PhaseSchlick(const Vector &w, const Vector &wp, float g); 00053 class VolumeRegion { 00054 public: 00055 // VolumeRegion Interface 00056 virtual ~VolumeRegion(); 00057 virtual BBox WorldBound() const = 0; 00058 virtual bool IntersectP(const Ray &ray, float *t0, float *t1) const = 0; 00059 virtual Spectrum sigma_a(const Point &, const Vector &, 00060 float time) const = 0; 00061 virtual Spectrum sigma_s(const Point &, const Vector &, 00062 float time) const = 0; 00063 virtual Spectrum Lve(const Point &, const Vector &, 00064 float time) const = 0; 00065 virtual float p(const Point &, const Vector &, 00066 const Vector &, float time) const = 0; 00067 virtual Spectrum sigma_t(const Point &p, const Vector &wo, float time) const; 00068 virtual Spectrum tau(const Ray &ray, float step = 1.f, 00069 float offset = 0.5) const = 0; 00070 }; 00071 00072 00073 class DensityRegion : public VolumeRegion { 00074 public: 00075 // DensityRegion Public Methods 00076 DensityRegion(const Spectrum &sa, const Spectrum &ss, float gg, 00077 const Spectrum &emit, const Transform &VolumeToWorld) 00078 : sig_a(sa), sig_s(ss), le(emit), g(gg), 00079 WorldToVolume(Inverse(VolumeToWorld)) { } 00080 virtual float Density(const Point &Pobj) const = 0; 00081 Spectrum sigma_a(const Point &p, const Vector &, float) const { 00082 return Density(WorldToVolume(p)) * sig_a; 00083 } 00084 Spectrum sigma_s(const Point &p, const Vector &, float) const { 00085 return Density(WorldToVolume(p)) * sig_s; 00086 } 00087 Spectrum sigma_t(const Point &p, const Vector &, float) const { 00088 return Density(WorldToVolume(p)) * (sig_a + sig_s); 00089 } 00090 Spectrum Lve(const Point &p, const Vector &, float) const { 00091 return Density(WorldToVolume(p)) * le; 00092 } 00093 float p(const Point &p, const Vector &w, const Vector &wp, float) const { 00094 return PhaseHG(w, wp, g); 00095 } 00096 Spectrum tau(const Ray &r, float stepSize, float offset) const; 00097 protected: 00098 // DensityRegion Protected Data 00099 Spectrum sig_a, sig_s, le; 00100 float g; 00101 Transform WorldToVolume; 00102 }; 00103 00104 00105 class AggregateVolume : public VolumeRegion { 00106 public: 00107 // AggregateVolume Public Methods 00108 AggregateVolume(const vector<VolumeRegion *> &r); 00109 ~AggregateVolume(); 00110 BBox WorldBound() const; 00111 bool IntersectP(const Ray &ray, float *t0, float *t1) const; 00112 Spectrum sigma_a(const Point &, const Vector &, float) const; 00113 Spectrum sigma_s(const Point &, const Vector &, float) const; 00114 Spectrum Lve(const Point &, const Vector &, float) const; 00115 float p(const Point &, const Vector &, const Vector &, float) const; 00116 Spectrum sigma_t(const Point &, const Vector &, float) const; 00117 Spectrum tau(const Ray &ray, float, float) const; 00118 private: 00119 // AggregateVolume Private Data 00120 vector<VolumeRegion *> regions; 00121 BBox bound; 00122 }; 00123 00124 00125 bool GetVolumeScatteringProperties(const string &name, Spectrum *sigma_a, 00126 Spectrum *sigma_prime_s); 00127 class VolumeIntegrator : public Integrator { 00128 public: 00129 // VolumeIntegrator Interface 00130 virtual Spectrum Li(const Scene *scene, const Renderer *renderer, 00131 const RayDifferential &ray, const Sample *sample, RNG &rng, 00132 Spectrum *transmittance, MemoryArena &arena) const = 0; 00133 virtual Spectrum Transmittance(const Scene *scene, 00134 const Renderer *renderer, const RayDifferential &ray, 00135 const Sample *sample, RNG &rng, MemoryArena &arena) const = 0; 00136 }; 00137 00138 00139 void SubsurfaceFromDiffuse(const Spectrum &Kd, float meanPathLength, float eta, 00140 Spectrum *sigma_a, Spectrum *sigma_prime_s); 00141 00142 #endif // PBRT_CORE_VOLUME_H