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