-
Notifications
You must be signed in to change notification settings - Fork 0
/
Material.h
132 lines (101 loc) · 3.4 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
#ifndef RAYTRACER_MATERIAL_H
#define RAYTRACER_MATERIAL_H
#pragma once
#include "Utils.h"
#include "Vec3.h"
#include "Ray.h"
#include "Texture.h"
#include "ONB.h"
class Material;
class PDF;
struct HitRecord {
double t;
Vec3 p;
Vec3 normal;
Material *mat_ptr;
double u;
double v;
};
struct ScatterRecord {
Ray specularRay;
bool isSpecular;
Vec3 attenuation;
PDF *pdf_ptr;
Vec3 diffuseColor;
Vec3 specularColor;
};
class Material {
public:
virtual bool scatter(const Ray &r_in, const HitRecord &hrec, ScatterRecord &srec) const = 0;
virtual double scateringPDF(const Ray &r_in, const HitRecord &rec, const Ray &scattered) const {
return false;
}
virtual Vec3 Emitted(const Ray& r_in, const HitRecord& rec, double u, double v, const Vec3 &p) const {
return Vec3(0, 0, 0);
}
};
class Lambertian : public Material {
public:
Texture *albedo;
Lambertian(Texture *a) : albedo(a) {}
double scateringPDF(const Ray &r_in, const HitRecord &rec, const Ray &scattered) const override {
double cosine = dot(rec.normal, unit_vector(scattered.getDirection()));
if (cosine < 0) cosine = 0;
return cosine / PI;
}
bool scatter(const Ray &r_in, const HitRecord &hrec, ScatterRecord &srec) const override;
};
class Metal : public Material {
Texture *albedo;
double fuzz;
public:
Metal(Texture *a, double f) : albedo(a) { if (f < 1) fuzz = f; else fuzz = 1; }
bool scatter(const Ray &r_in, const HitRecord &hrec, ScatterRecord &srec) const override;
};
class Microfacet : public Material {
Texture *albedo;
double roughness;
Texture *specular;
public:
Microfacet(Texture *a, double r, Texture *s):albedo(a), roughness(r), specular(s){}
double scateringPDF(const Ray &r_in, const HitRecord &rec, const Ray &scattered) const override {
double cosine = dot(rec.normal, unit_vector(scattered.getDirection()));
if (cosine < 0) cosine = 0;
return cosine / PI;
}
bool scatter(const Ray &r_in, const HitRecord &hrec, ScatterRecord &srec) const override;
};
class Dielectric : public Material {
double ref_idx;
public:
Dielectric(double ri) : ref_idx(ri) {}
bool scatter(const Ray &r_in, const HitRecord &hrec, ScatterRecord &srec) const override;
};
class DiffuseLight : public Material {
public:
Texture *emit;
DiffuseLight(Texture *a) : emit(a) {}
bool scatter(const Ray &r_in, const HitRecord &hrec, ScatterRecord &srec) const override {
return false;
}
Vec3 Emitted(const Ray& r_in, const HitRecord& rec, double u, double v, const Vec3 &p) const override {
if(dot(rec.normal, r_in.getDirection()) > 0.0)
return emit->Value(u, v, p);
else return Vec3(0, 0, 0);
}
};
class AnisotropicPhong : public Material {
Texture* albedo;
Texture* specular;
double nu, nv;
public:
AnisotropicPhong(double u, double v, Texture* diffuse, Texture* specularColor):
albedo(diffuse), specular(specularColor), nu(u), nv(v) {}
bool scatter(const Ray &r_in, const HitRecord &hrec, ScatterRecord &srec) const override;
double scateringPDF(const Ray &r_in, const HitRecord &rec, const Ray &scattered) const override {
double cosine = dot(rec.normal, unit_vector(scattered.getDirection()));
if (cosine < 0) cosine = 0;
return cosine / PI;
}
};
#endif //RAYTRACER_MATERIAL_H