erebus
diff liberebus/src/brdf.h @ 31:53a98c148bf8
- introduced SurfaceGeometry to carry all the geometric information input to
BRDF sampling and evaluation functions.
- made Reflectance keep an (optional) pointer to its material
- simplified PhongRefl::sample_dir, with the help of SurfaceGeometry
- worked around microsoft's broken std::thread implementation's deadlock on join
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 07 Jun 2014 09:14:17 +0300 |
parents | 4a0a288ffb27 |
children | c4d48a21bc4a |
line diff
1.1 --- a/liberebus/src/brdf.h Sat Jun 07 06:10:21 2014 +0300 1.2 +++ b/liberebus/src/brdf.h Sat Jun 07 09:14:17 2014 +0300 1.3 @@ -4,18 +4,56 @@ 1.4 #include <vector> 1.5 #include "texture.h" 1.6 1.7 +class Material; 1.8 + 1.9 +class SurfaceGeometry { 1.10 +public: 1.11 + Vector3 normal, tangent; 1.12 + Vector2 uv; 1.13 + 1.14 + enum VecLength { unit, unknown }; 1.15 + 1.16 + explicit SurfaceGeometry(const Vector3 &norm, VecLength st = unknown); 1.17 + SurfaceGeometry(const Vector3 &norm, const Vector2 &uv, VecLength st = unknown); 1.18 + SurfaceGeometry(const Vector3 &norm, const Vector3 &tang, VecLength st = unknown); 1.19 + SurfaceGeometry(const Vector3 &norm, const Vector3 &tang, const Vector2 &uv, VecLength st = unknown); 1.20 + 1.21 + /** create a cartesian direction vector in sample space (zenith = +Z) and 1.22 + * transform it to world space. 1.23 + * \param theta the horizontal angle (azimuth, in radians) around the Z axis [0, 2pi] 1.24 + * \param phi the vertical angle (elevation, in radians) away from the Z axis [0, pi] 1.25 + */ 1.26 + Vector3 spherical_to_world(float theta, float phi) const; 1.27 + /// transforms a direction vector from sample space (centered around Z) to world space 1.28 + Vector3 sample_to_world(const Vector3 &v) const; 1.29 + /// transforms a direction vector from world space to sample space (centered around Z) 1.30 + Vector3 world_to_sample(const Vector3 &v) const; 1.31 +}; 1.32 + 1.33 +/// abstract bidirection reflectance distribution function base class 1.34 class Reflectance { 1.35 +protected: 1.36 + const Material *mtl; // pointer to the material we belong to 1.37 + 1.38 public: 1.39 Reflectance(); 1.40 + explicit Reflectance(const Material *mtl); 1.41 virtual ~Reflectance() = default; 1.42 1.43 - virtual Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const = 0; 1.44 - virtual float sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const; 1.45 - virtual float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const = 0; 1.46 + void set_material(const Material *mtl); 1.47 + const Material *get_material() const; 1.48 + 1.49 + /// given an outgoing light direction generate an incidence direction to sample the BRDF 1.50 + virtual Vector3 sample_dir(const SurfaceGeometry &geom, const Vector3 &outdir) const = 0; 1.51 + /// given an outgoing direction, generate an incidence direction, and evaluate its probability 1.52 + virtual float sample(const SurfaceGeometry &geom, const Vector3 &outdir, Vector3 *indir) const; 1.53 + /// given an outgoing direction and an incidence direction, evaluate the probability of this path 1.54 + virtual float eval(const SurfaceGeometry &geom, const Vector3 &outdir, const Vector3 &indir) const = 0; 1.55 }; 1.56 1.57 -typedef float (*CompReflWeightFunc)(const Vector3 &norm, const Vector3 &outdir); 1.58 +typedef float (*CompReflWeightFunc)(const SurfaceGeometry &geom, const Vector3 &outdir); 1.59 1.60 +/// composite BRDF, with multiple weighted sub-reflectances. 1.61 class CompositeRefl : public Reflectance { 1.62 private: 1.63 struct SubRefl { 1.64 @@ -26,41 +64,41 @@ 1.65 std::vector<SubRefl> sub_brdf; 1.66 mutable bool valid_checked; 1.67 1.68 - int pick_brdf(const Vector3 &norm, const Vector3 &outdir) const; 1.69 + int pick_brdf(const SurfaceGeometry &geom, const Vector3 &outdir) const; 1.70 1.71 public: 1.72 CompositeRefl(); 1.73 + explicit CompositeRefl(const Material *mtl); 1.74 1.75 virtual void add_brdf(Reflectance *brdf, float weight); 1.76 virtual void add_brdf(Reflectance *brdf, CompReflWeightFunc weight_func); 1.77 1.78 bool check_valid() const; 1.79 1.80 - Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; 1.81 - float sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const override; 1.82 - float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; 1.83 + Vector3 sample_dir(const SurfaceGeometry &geom, const Vector3 &outdir) const override; 1.84 + float sample(const SurfaceGeometry &geom, const Vector3 &outdir, Vector3 *indir) const override; 1.85 + float eval(const SurfaceGeometry &geom, const Vector3 &outdir, const Vector3 &indir) const override; 1.86 }; 1.87 1.88 +/// lambertian perfect diffuse reflectance 1.89 class LambertRefl : public Reflectance { 1.90 public: 1.91 - Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; 1.92 - float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; 1.93 + Vector3 sample_dir(const SurfaceGeometry &geom, const Vector3 &outdir) const override; 1.94 + float eval(const SurfaceGeometry &geom, const Vector3 &outdir, const Vector3 &indir) const override; 1.95 }; 1.96 1.97 +/// perfect specular reflectance 1.98 class MirrorRefl : public Reflectance { 1.99 public: 1.100 - Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; 1.101 - float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; 1.102 + Vector3 sample_dir(const SurfaceGeometry &geom, const Vector3 &outdir) const override; 1.103 + float eval(const SurfaceGeometry &geom, const Vector3 &outdir, const Vector3 &indir) const override; 1.104 }; 1.105 1.106 +/// glossy phong reflectance with lafortune sampling 1.107 class PhongRefl : public Reflectance { 1.108 public: 1.109 - float shininess; 1.110 - 1.111 - PhongRefl(); 1.112 - 1.113 - Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; 1.114 - float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; 1.115 + Vector3 sample_dir(const SurfaceGeometry &geom, const Vector3 &outdir) const override; 1.116 + float eval(const SurfaceGeometry &geom, const Vector3 &outdir, const Vector3 &indir) const override; 1.117 }; 1.118 1.119 #endif // BRDF_H_