erebus

annotate liberebus/src/brdf.h @ 48:9971a08f4104

merged
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 24 Feb 2016 00:29:31 +0200
parents 53a98c148bf8
children
rev   line source
nuclear@2 1 #ifndef BRDF_H_
nuclear@2 2 #define BRDF_H_
nuclear@2 3
nuclear@21 4 #include <vector>
nuclear@2 5 #include "texture.h"
nuclear@2 6
nuclear@31 7 class Material;
nuclear@31 8
nuclear@31 9 class SurfaceGeometry {
nuclear@31 10 public:
nuclear@46 11 Vec3 normal, tangent;
nuclear@46 12 Vec2 uv;
nuclear@31 13
nuclear@31 14 enum VecLength { unit, unknown };
nuclear@31 15
nuclear@46 16 explicit SurfaceGeometry(const Vec3 &norm, VecLength st = unknown);
nuclear@46 17 SurfaceGeometry(const Vec3 &norm, const Vec2 &uv, VecLength st = unknown);
nuclear@46 18 SurfaceGeometry(const Vec3 &norm, const Vec3 &tang, VecLength st = unknown);
nuclear@46 19 SurfaceGeometry(const Vec3 &norm, const Vec3 &tang, const Vec2 &uv, VecLength st = unknown);
nuclear@31 20
nuclear@31 21 /** create a cartesian direction vector in sample space (zenith = +Z) and
nuclear@31 22 * transform it to world space.
nuclear@31 23 * \param theta the horizontal angle (azimuth, in radians) around the Z axis [0, 2pi]
nuclear@31 24 * \param phi the vertical angle (elevation, in radians) away from the Z axis [0, pi]
nuclear@31 25 */
nuclear@46 26 Vec3 spherical_to_world(float theta, float phi) const;
nuclear@31 27 /// transforms a direction vector from sample space (centered around Z) to world space
nuclear@46 28 Vec3 sample_to_world(const Vec3 &v) const;
nuclear@31 29 /// transforms a direction vector from world space to sample space (centered around Z)
nuclear@46 30 Vec3 world_to_sample(const Vec3 &v) const;
nuclear@31 31 };
nuclear@31 32
nuclear@31 33 /// abstract bidirection reflectance distribution function base class
nuclear@2 34 class Reflectance {
nuclear@31 35 protected:
nuclear@31 36 const Material *mtl; // pointer to the material we belong to
nuclear@31 37
nuclear@2 38 public:
nuclear@2 39 Reflectance();
nuclear@31 40 explicit Reflectance(const Material *mtl);
nuclear@2 41 virtual ~Reflectance() = default;
nuclear@2 42
nuclear@31 43 void set_material(const Material *mtl);
nuclear@31 44 const Material *get_material() const;
nuclear@31 45
nuclear@31 46 /// given an outgoing light direction generate an incidence direction to sample the BRDF
nuclear@46 47 virtual Vec3 sample_dir(const SurfaceGeometry &geom, const Vec3 &outdir) const = 0;
nuclear@31 48 /// given an outgoing direction, generate an incidence direction, and evaluate its probability
nuclear@46 49 virtual float sample(const SurfaceGeometry &geom, const Vec3 &outdir, Vec3 *indir) const;
nuclear@31 50 /// given an outgoing direction and an incidence direction, evaluate the probability of this path
nuclear@46 51 virtual float eval(const SurfaceGeometry &geom, const Vec3 &outdir, const Vec3 &indir) const = 0;
nuclear@2 52 };
nuclear@2 53
nuclear@46 54 typedef float (*CompReflWeightFunc)(const SurfaceGeometry &geom, const Vec3 &outdir);
nuclear@21 55
nuclear@31 56 /// composite BRDF, with multiple weighted sub-reflectances.
nuclear@21 57 class CompositeRefl : public Reflectance {
nuclear@21 58 private:
nuclear@21 59 struct SubRefl {
nuclear@21 60 Reflectance *brdf;
nuclear@21 61 float weight;
nuclear@21 62 CompReflWeightFunc weight_func; // if null, use static weight above
nuclear@21 63 };
nuclear@21 64 std::vector<SubRefl> sub_brdf;
nuclear@21 65 mutable bool valid_checked;
nuclear@21 66
nuclear@46 67 int pick_brdf(const SurfaceGeometry &geom, const Vec3 &outdir) const;
nuclear@21 68
nuclear@21 69 public:
nuclear@21 70 CompositeRefl();
nuclear@31 71 explicit CompositeRefl(const Material *mtl);
nuclear@21 72
nuclear@21 73 virtual void add_brdf(Reflectance *brdf, float weight);
nuclear@21 74 virtual void add_brdf(Reflectance *brdf, CompReflWeightFunc weight_func);
nuclear@21 75
nuclear@21 76 bool check_valid() const;
nuclear@21 77
nuclear@46 78 Vec3 sample_dir(const SurfaceGeometry &geom, const Vec3 &outdir) const override;
nuclear@46 79 float sample(const SurfaceGeometry &geom, const Vec3 &outdir, Vec3 *indir) const override;
nuclear@46 80 float eval(const SurfaceGeometry &geom, const Vec3 &outdir, const Vec3 &indir) const override;
nuclear@21 81 };
nuclear@21 82
nuclear@31 83 /// lambertian perfect diffuse reflectance
nuclear@2 84 class LambertRefl : public Reflectance {
nuclear@2 85 public:
nuclear@46 86 Vec3 sample_dir(const SurfaceGeometry &geom, const Vec3 &outdir) const override;
nuclear@46 87 float eval(const SurfaceGeometry &geom, const Vec3 &outdir, const Vec3 &indir) const override;
nuclear@2 88 };
nuclear@2 89
nuclear@31 90 /// perfect specular reflectance
nuclear@21 91 class MirrorRefl : public Reflectance {
nuclear@21 92 public:
nuclear@46 93 Vec3 sample_dir(const SurfaceGeometry &geom, const Vec3 &outdir) const override;
nuclear@46 94 float eval(const SurfaceGeometry &geom, const Vec3 &outdir, const Vec3 &indir) const override;
nuclear@21 95 };
nuclear@21 96
nuclear@31 97 /// glossy phong reflectance with lafortune sampling
nuclear@28 98 class PhongRefl : public Reflectance {
nuclear@28 99 public:
nuclear@46 100 Vec3 sample_dir(const SurfaceGeometry &geom, const Vec3 &outdir) const override;
nuclear@46 101 float eval(const SurfaceGeometry &geom, const Vec3 &outdir, const Vec3 &indir) const override;
nuclear@28 102 };
nuclear@28 103
nuclear@2 104 #endif // BRDF_H_