-
Notifications
You must be signed in to change notification settings - Fork 1
/
material.h
158 lines (130 loc) · 4.49 KB
/
material.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#ifndef _MATERIAL_H_
#define _MATERIAL_H_
#include "common.h"
#include "named_object.h"
#include "rgb.h"
#include "vec2.h"
#include "local_geometry.h"
#include "hitrecord.h"
#include "bsdf.h"
#include "marshal.h"
#include "lambertian.h"
#include "phong.h"
#include "ward.h"
#include "mirror.h"
#include "glass.h"
namespace Renzoku {
/**
* Material class defines the common interface for all materials and material decorators.
*
* The Material and BsdfMaterial have the same interface. However, we do not want to merge them
* since TexturedMaterial (or other decorator materials) inherits from Material but it should not store a BSDF internally.
* It should rely on the material it decorates for BSDF sampling.
*/
class Material : public NamedObject, public IMarshalable {
public:
Material() : index(-1) {}
/**
* Fill in the general material that can be transferred to GPU or network.
*/
virtual void marshal(MarshalObject &m) = 0;
/**
* Returns a color to represent this material.
* This is used in displaying the scene in wireframe or preview mode (non-physically based rendering).
*
* White is returned by default.
*/
virtual Rgb get_representative_color() const { return DefaultRgb::white; }
virtual Bsdf* get_bsdf() = 0;
virtual Rgb sample(Random &rd, const LocalGeometry &dg, const Vec3 &wo, Vec3 &wi, Float &pdf) = 0;
virtual Rgb eval(const LocalGeometry &dg, const Vec3 &wo, const Vec3 &wi) = 0;
virtual Float pdf(const LocalGeometry &dg, const Vec3 &wo, const Vec3 &wi) = 0;
inline int get_material_index() const;
inline void set_material_index(int index);
enum Type {
BSDF,
TEXTURED
};
virtual Material::Type get_material_type() const = 0;
bool has_texture() const {
return this->get_material_type() == TEXTURED;
}
protected:
int index; // index to the global material array
};
class BsdfMaterial : public Material {
public:
BsdfMaterial(Bsdf *bsdf) : bsdf(bsdf) {}
virtual Material::Type get_material_type() const {
return Material::BSDF;
}
virtual void marshal(MarshalObject &m) {
m.dict.clear();
// for consistency, we use a switch here. Another option is to implement marshal in each BSDF,
// but we don't want to pollute such classes.
m.dict.add("bsdf_type", (int)bsdf->get_bsdf_type());
switch (bsdf->get_bsdf_type()) {
case Bsdf::LAMBERTIAN:
{
m.dict.add("kd", ((Lambertian *)bsdf)->get_diffuse_component().to_vec3());
break;
}
case Bsdf::PHONG:
{
ModifiedPhong *phong = (ModifiedPhong *)bsdf;
m.dict.add("kd", phong->get_diffuse_component().to_vec3());
m.dict.add("ks", phong->get_specular_component().to_vec3());
m.dict.add("glossy", phong->get_glossy_coefficients());
break;
}
case Bsdf::WARD:
{
Ward *ward = (Ward *)bsdf;
m.dict.add("kd", ward->get_diffuse_component().to_vec3());
m.dict.add("ks", ward->get_specular_component().to_vec3());
m.dict.add("glossy", ward->get_glossy_coefficients());
break;
}
}
}
/**
* Sample an in-going direction from the BRDF given an out-going direction.
*/
virtual Rgb sample(Random &rd, const LocalGeometry &dg, const Vec3 &wo, Vec3 &wi, Float &pdf) {
return bsdf->sample(rd, dg.uvn, wo, wi, pdf);
}
/**
* Evaluate the BRDF value given an in, out direction.
*/
virtual Rgb eval(const LocalGeometry &dg, const Vec3 &wo, const Vec3 &wi) {
return bsdf->eval(dg.uvn, wo, wi);
}
/**
* Compute the probability of sampling the direction \wi.
*/
virtual Float pdf(const LocalGeometry &dg, const Vec3 &wo, const Vec3 &wi) {
return bsdf->pdf(dg.uvn, wo, wi);
}
/**
* Return a unique ID for the material type
*/
virtual Bsdf* get_bsdf() { return bsdf; }
protected:
Bsdf *bsdf;
};
int Material::get_material_index() const {
return index;
}
void Material::set_material_index(int index) {
this->index = index;
}
class DefaultMaterial {
public:
static BsdfMaterial *white();
static BsdfMaterial *pi();
protected:
static BsdfMaterial *_white;
static BsdfMaterial *_pi;
};
} // end namespace
#endif