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_VOLUME_H
00024 #define LUX_VOLUME_H
00025
00026 #include "lux.h"
00027 #include "spectrum.h"
00028 #include "geometry.h"
00029 #include "transport.h"
00030
00031 namespace lux
00032 {
00033
00034
00035 float PhaseIsotropic(const Vector &w, const Vector &wp);
00036
00037 float PhaseRayleigh(const Vector &w, const Vector &wp);
00038
00039 float PhaseMieHazy(const Vector &w, const Vector &wp);
00040
00041 float PhaseMieMurky(const Vector &w, const Vector &wp);
00042 float PhaseHG(const Vector &w, const Vector &wp, float g);
00043 float PhaseSchlick(const Vector &w, const Vector &wp, float g);
00044 class VolumeRegion {
00045 public:
00046
00047 virtual ~VolumeRegion() { }
00048 virtual BBox WorldBound() const = 0;
00049 virtual bool IntersectP(const Ray &ray, float *t0,
00050 float *t1) const = 0;
00051 virtual Spectrum sigma_a(const Point &,
00052 const Vector &) const = 0;
00053 virtual Spectrum sigma_s(const Point &,
00054 const Vector &) const = 0;
00055 virtual
00056 Spectrum Lve(const Point &, const Vector &) const = 0;
00057 virtual float p(const Point &, const Vector &,
00058 const Vector &) const = 0;
00059 virtual Spectrum sigma_t(const Point &, const Vector &) const;
00060 virtual Spectrum Tau(const Ray &ray,
00061 float step = 1.f, float offset = 0.5) const = 0;
00062 };
00063 class DensityRegion : public VolumeRegion {
00064 public:
00065
00066 DensityRegion(const Spectrum &sig_a, const Spectrum &sig_s,
00067 float g, const Spectrum &Le, const Transform &VolumeToWorld);
00068 virtual float Density(const Point &Pobj) const = 0;
00069 Spectrum sigma_a(const Point &p, const Vector &) const {
00070 return Density(WorldToVolume(p)) * sig_a;
00071 }
00072 Spectrum sigma_s(const Point &p, const Vector &) const {
00073 return Density(WorldToVolume(p)) * sig_s;
00074 }
00075 Spectrum sigma_t(const Point &p, const Vector &) const {
00076 return Density(WorldToVolume(p)) * (sig_a + sig_s);
00077 }
00078 Spectrum Lve(const Point &p, const Vector &) const {
00079 return Density(WorldToVolume(p)) * le;
00080 }
00081 float p(const Point &p, const Vector &w,
00082 const Vector &wp) const {
00083 return PhaseHG(w, wp, g);
00084 }
00085 Spectrum Tau(const Ray &r, float stepSize, float offset) const;
00086 protected:
00087
00088 Transform WorldToVolume;
00089 Spectrum sig_a, sig_s, le;
00090 float g;
00091 };
00092 class AggregateVolume : public VolumeRegion {
00093 public:
00094
00095 AggregateVolume(const vector<VolumeRegion *> &r);
00096 ~AggregateVolume();
00097 BBox WorldBound() const;
00098 bool IntersectP(const Ray &ray, float *t0, float *t1) const;
00099 Spectrum sigma_a(const Point &, const Vector &) const;
00100 Spectrum sigma_s(const Point &, const Vector &) const;
00101 Spectrum Lve(const Point &, const Vector &) const;
00102 float p(const Point &, const Vector &, const Vector &) const;
00103 Spectrum sigma_t(const Point &, const Vector &) const;
00104 Spectrum Tau(const Ray &ray, float, float) const;
00105 private:
00106
00107 vector<VolumeRegion *> regions;
00108 BBox bound;
00109 };
00110
00111 }
00112
00113 #endif // LUX_VOLUME_H