nuclear@2: #ifndef BRDF_H_ nuclear@2: #define BRDF_H_ nuclear@2: nuclear@21: #include nuclear@2: #include "texture.h" nuclear@2: nuclear@2: class Reflectance { nuclear@2: public: nuclear@2: Reflectance(); nuclear@2: virtual ~Reflectance() = default; nuclear@2: nuclear@2: virtual Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const = 0; nuclear@2: virtual float sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const; nuclear@2: virtual float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const = 0; nuclear@2: }; nuclear@2: nuclear@21: typedef float (*CompReflWeightFunc)(const Vector3 &norm, const Vector3 &outdir); nuclear@21: nuclear@21: class CompositeRefl : public Reflectance { nuclear@21: private: nuclear@21: struct SubRefl { nuclear@21: Reflectance *brdf; nuclear@21: float weight; nuclear@21: CompReflWeightFunc weight_func; // if null, use static weight above nuclear@21: }; nuclear@21: std::vector sub_brdf; nuclear@21: mutable bool valid_checked; nuclear@21: nuclear@21: int pick_brdf(const Vector3 &norm, const Vector3 &outdir) const; nuclear@21: nuclear@21: public: nuclear@21: CompositeRefl(); nuclear@21: nuclear@21: virtual void add_brdf(Reflectance *brdf, float weight); nuclear@21: virtual void add_brdf(Reflectance *brdf, CompReflWeightFunc weight_func); nuclear@21: nuclear@21: bool check_valid() const; nuclear@21: nuclear@21: Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; nuclear@21: float sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const override; nuclear@21: float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; nuclear@21: }; nuclear@21: nuclear@2: class LambertRefl : public Reflectance { nuclear@2: public: nuclear@2: Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; nuclear@2: float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; nuclear@2: }; nuclear@2: nuclear@21: class MirrorRefl : public Reflectance { nuclear@21: public: nuclear@21: Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; nuclear@21: float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; nuclear@21: }; nuclear@21: nuclear@28: class PhongRefl : public Reflectance { nuclear@28: public: nuclear@28: float shininess; nuclear@28: nuclear@28: PhongRefl(); nuclear@28: nuclear@28: Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; nuclear@28: float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; nuclear@28: }; nuclear@28: nuclear@2: #endif // BRDF_H_