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 "geometry/transform.h"
00028 #include "geometry/bbox.h"
00029 #include "color.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 RGBColor sigma_a(const Point &,
00052 const Vector &) const = 0;
00053 virtual RGBColor sigma_s(const Point &,
00054 const Vector &) const = 0;
00055 virtual
00056 RGBColor Lve(const Point &, const Vector &) const = 0;
00057 virtual float P(const Point &, const Vector &,
00058 const Vector &) const = 0;
00059 virtual RGBColor sigma_t(const Point &, const Vector &) const;
00060 virtual RGBColor Tau(const Ray &ray,
00061 float step = 1.f, float offset = 0.5) const = 0;
00062 };
00063
00064 class DensityRegion : public VolumeRegion {
00065 public:
00066
00067 DensityRegion(const RGBColor &sig_a, const RGBColor &sig_s,
00068 float g, const RGBColor &Le, const Transform &VolumeToWorld);
00069 virtual ~DensityRegion() { }
00070 virtual float Density(const Point &Pobj) const = 0;
00071 virtual RGBColor sigma_a(const Point &p, const Vector &) const {
00072 return Density(WorldToVolume(p)) * sig_a;
00073 }
00074 virtual RGBColor sigma_s(const Point &p, const Vector &) const {
00075 return Density(WorldToVolume(p)) * sig_s;
00076 }
00077 virtual RGBColor sigma_t(const Point &p, const Vector &) const {
00078 return Density(WorldToVolume(p)) * (sig_a + sig_s);
00079 }
00080 virtual RGBColor Lve(const Point &p, const Vector &) const {
00081 return Density(WorldToVolume(p)) * le;
00082 }
00083 virtual float P(const Point &p, const Vector &w,
00084 const Vector &wp) const {
00085 return PhaseHG(w, wp, g);
00086 }
00087 virtual RGBColor Tau(const Ray &r, float stepSize, float offset) const;
00088 protected:
00089
00090 Transform WorldToVolume;
00091 RGBColor sig_a, sig_s, le;
00092 float g;
00093 };
00094
00095 class AggregateVolume : public VolumeRegion {
00096 public:
00097
00098 AggregateVolume(const vector<VolumeRegion *> &r);
00099 virtual ~AggregateVolume();
00100 virtual BBox WorldBound() const;
00101 virtual bool IntersectP(const Ray &ray, float *t0, float *t1) const;
00102 virtual RGBColor sigma_a(const Point &, const Vector &) const;
00103 virtual RGBColor sigma_s(const Point &, const Vector &) const;
00104 virtual RGBColor Lve(const Point &, const Vector &) const;
00105 virtual float P(const Point &, const Vector &, const Vector &) const;
00106 virtual RGBColor sigma_t(const Point &, const Vector &) const;
00107 virtual RGBColor Tau(const Ray &ray, float, float) const;
00108 private:
00109
00110 vector<VolumeRegion *> regions;
00111 BBox bound;
00112 };
00113
00114 }
00115
00116 #endif // LUX_VOLUME_H