erebus

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