-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMaterial.h
126 lines (99 loc) · 2.65 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
#pragma once
#include "vec3.h"
#include "Ray.h"
#include "Math.h"
#include "Traceable.h"
#include "Texture.h"
class Material
{
public:
virtual bool scatter( const Ray& ray, const HitRecord& hit,
vec3& attenuation, Ray& scattered ) const = 0;
virtual vec3 emitted( float u, float v, const vec3& p ) const
{
return vec3( 0.0f, 0.0f, 0.0f );
}
}; // class Material
class Lambertian : public Material
{
public:
Lambertian( const vec3& albedo )
{
mAlbedo = new ConstantTexture( albedo );
}
// Takes ownership of the given Texture pointer
Lambertian( Texture* albedo )
: mAlbedo( albedo )
{}
virtual ~Lambertian()
{
if( mAlbedo != nullptr )
delete mAlbedo;
}
// Material interface implementation
virtual bool scatter( const Ray& ray, const HitRecord& hit,
vec3& attenuation, Ray& scattered ) const
{
vec3 target = hit.p + hit.normal + RandomInUnitSphere();
scattered = Ray( hit.p, target - hit.p, ray.getTime() );
attenuation = mAlbedo->getValue( 0.0f, 0.0f, hit.p );
return true;
}
private:
Texture* mAlbedo;
}; // class Lambertian
class Metal : public Material
{
public:
Metal( const vec3& albedo, float fuzziness )
: mAlbedo( albedo )
{
if( fuzziness > 1.0f )
mFuzziness = 1.0f;
else
mFuzziness = fuzziness;
}
// Material interface implementation
virtual bool scatter( const Ray& ray, const HitRecord& hit,
vec3& attenuation, Ray& scattered ) const
{
vec3 reflected = Reflect( ray.getDirection().getNormalized(), hit.normal );
scattered = Ray( hit.p, reflected + mFuzziness * RandomInUnitSphere() );
attenuation = mAlbedo;
return Dot( scattered.getDirection(), hit.normal ) > 0.0f;
}
private:
vec3 mAlbedo;
float mFuzziness;
}; // class Metal
// This class is called dialetric in "Ray Tracing in One Weekend"
class Glass : public Material
{
public:
Glass( float index )
: mRefractIndex( index )
{}
// Material interface implementation
virtual bool scatter( const Ray& ray, const HitRecord& hit,
vec3& attenuation, Ray& scattered ) const;
private:
float mRefractIndex;
}; // class Glass
class DiffuseLight : public Material
{
public:
DiffuseLight() : mEmitter( nullptr ) {}
DiffuseLight( Texture* emitter ) : mEmitter( emitter ) {}
// Material interface implementation
virtual bool scatter( const Ray& ray, const HitRecord& hit,
vec3& attenuation, Ray& scattered ) const
{
return false;
}
virtual vec3 emitted( float u, float v, const vec3& p ) const
{
return mEmitter->getValue( u, v, p );
}
private:
Texture* mEmitter;
}; // DiffuseLight