The spica renderer
bxdf.h
1 #ifdef _MSC_VER
2 #pragma once
3 #endif
4 
5 #ifndef _SPICA_BXDF_H_
6 #define _SPICA_BXDF_H_
7 
8 #include <memory>
9 
10 #include "core/core.hpp"
11 #include "core/common.h"
12 #include "core/uncopyable.h"
13 #include "core/spectrum.h"
14 
15 #include "core/render.hpp"
16 #include "core/fresnel.h"
17 
18 namespace spica {
19 
20 enum class BxDFType : int {
21  None = 0x00,
22  Reflection = 0x01,
23  Transmission = 0x02,
24  Diffuse = 0x04,
25  Glossy = 0x08,
26  Specular = 0x10,
27  All = Reflection | Transmission | Diffuse | Glossy | Specular,
28 };
29 
30 inline BxDFType operator|(BxDFType t1, BxDFType t2) {
31  return static_cast<BxDFType>(static_cast<int>(t1) | static_cast<int>(t2));
32 }
33 
34 inline BxDFType operator&(BxDFType t1, BxDFType t2) {
35  return static_cast<BxDFType>(static_cast<int>(t1) & static_cast<int>(t2));
36 }
37 
38 inline BxDFType operator~(BxDFType t) {
39  return static_cast<BxDFType>(~static_cast<int>(t));
40 }
41 
45 class SPICA_EXPORTS BxDF : public Uncopyable {
46 public:
47  // Public methods
48  explicit BxDF(BxDFType type = BxDFType::None);
49  virtual ~BxDF();
50 
51  virtual Spectrum f(const Vector3d& wo, const Vector3d& wi) const = 0;
52  virtual Spectrum sample(const Vector3d& wo, Vector3d* wi,
53  const Point2d& rands, double* pdf,
54  BxDFType* sampledType = nullptr) const;
55  virtual double pdf(const Vector3d& wo, const Vector3d& wi) const;
56 
57  inline BxDFType type() const { return type_; }
58 
59 private:
60  const BxDFType type_;
61 
62 }; // class BxDF
63 
67 class SPICA_EXPORTS LambertianReflection : public BxDF {
68 public:
69  explicit LambertianReflection(const Spectrum& ref);
70 
71  Spectrum f(const Vector3d& wo, const Vector3d& wi) const override;
72 
73 private:
74  Spectrum ref_;
75 };
76 
80 class SPICA_EXPORTS LambertianTransmission : public BxDF {
81 public:
82  explicit LambertianTransmission(const Spectrum& tr);
83 
84  Spectrum f(const Vector3d& wo, const Vector3d& wi) const override;
85 
86 private:
87  Spectrum tr_;
88 };
89 
93 class SPICA_EXPORTS SpecularReflection : public BxDF {
94 public:
95  // Public methods
96  SpecularReflection(const Spectrum& ref, Fresnel* fresnel);
97 
98  Spectrum f(const Vector3d& wo, const Vector3d& wi) const override;
99  Spectrum sample(const Vector3d& wo, Vector3d* wi, const Point2d& rands,
100  double* pdf, BxDFType* sampledType) const override;
101  double pdf(const Vector3d& wo, const Vector3d& wi) const override;
102 
103 private:
104  // Private fields
105  Spectrum ref_;
106  Fresnel* fresnel_;
107 };
108 
112 class SPICA_EXPORTS SpecularTransmission : public BxDF {
113 public:
114  // Public methods
115  SpecularTransmission(const Spectrum& tr, double etaA, double etaB);
116 
117  Spectrum f(const Vector3d& wo, const Vector3d& wi) const override;
118  Spectrum sample(const Vector3d& wo, Vector3d* wi, const Point2d& rands,
119  double* pdf, BxDFType* sampledType) const override;
120  double pdf(const Vector3d& wo, const Vector3d& wi) const override;
121 
122 private:
123  // Private fields
124  Spectrum tr_;
125  double etaA_, etaB_;
126  std::unique_ptr<FresnelDielectric> fresnel_;
127 
128 }; // class SpecularTransmission
129 
133 class SPICA_EXPORTS FresnelSpecular : public BxDF {
134 public:
135  // Public methods
136  FresnelSpecular();
137  FresnelSpecular(const Spectrum& ref, const Spectrum& tr, double etaA, double etaB);
138 
139  Spectrum f(const Vector3d& wo, const Vector3d& wi) const override;
140  Spectrum sample(const Vector3d& wo, Vector3d* wi, const Point2d& rands,
141  double* pdf, BxDFType* sampledType) const override;
142  double pdf(const Vector3d& wo, const Vector3d& wi) const override;
143 
144 private:
145  // Private fields
146  Spectrum ref_;
147  Spectrum tr_;
148  double etaA_ = 1.0;
149  double etaB_ = 1.0;
150 };
151 
155 class SPICA_EXPORTS MicrofacetReflection : public BxDF {
156 public:
157  MicrofacetReflection(const Spectrum& ref,
158  MicrofacetDistribution* distrib, Fresnel* fresnel);
159  Spectrum f(const Vector3d& wo, const Vector3d& wi) const override;
160  Spectrum sample(const Vector3d& wo, Vector3d* wi, const Point2d& rands,
161  double* pdf, BxDFType* sampledType) const override;
162  double pdf(const Vector3d& wo, const Vector3d& wi) const override;
163 
164 private:
165  const Spectrum ref_;
166  const MicrofacetDistribution* distrib_;
167  const Fresnel* fresnel_;
168 };
169 
173 class SPICA_EXPORTS MicrofacetTransmission : public BxDF {
174 public:
175  // Public methods
176  MicrofacetTransmission(const Spectrum &re, const Spectrum& tr,
177  MicrofacetDistribution* distrib, double etaA,
178  double etaB);
179  Spectrum f(const Vector3d& wo, const Vector3d& wi) const override;
180  Spectrum f(const Vector3d &wo, const Vector3d &wi, const Vector3d &wh) const;
181  Spectrum sample(const Vector3d& wo, Vector3d* wi, const Point2d& rands,
182  double* pdf, BxDFType* sampledType) const override;
183  double pdf(const Vector3d& wo, const Vector3d& wi) const override;
184  double pdf(const Vector3d &wo, const Vector3d &wi, const Vector3d &wh) const;
185 
186 private:
187  // Private fields
188  const Spectrum re_;
189  const Spectrum tr_;
190  const MicrofacetDistribution* distrib_;
191  const double etaA_, etaB_;
192 };
193 
194 } // namespace spica
195 
196 #endif // _SPICA_BXDF_H_
The base class for microfacet distributions.
Definition: microfacet.h:16
Microfacet transmission.
Definition: bxdf.h:173
Lambertian refrection.
Definition: bxdf.h:67
RGB spectrum.
Definition: spectrum.h:18
Lambertian transmission.
Definition: bxdf.h:80
Specular transmission.
Definition: bxdf.h:112
Fresnel specular refraction (Glass-like effect).
Definition: bxdf.h:133
Specular reflection (Metal-like effect).
Definition: bxdf.h:93
The inteface for Fresnel reflections.
Definition: fresnel.h:16
Interface class which forbids copy and assignment.
Definition: uncopyable.h:15
Microfacet reflaction.
Definition: bxdf.h:155
The base class of BxDFs.
Definition: bxdf.h:45