-
Notifications
You must be signed in to change notification settings - Fork 0
/
Material.cc
116 lines (87 loc) · 3.19 KB
/
Material.cc
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
#include "Material.hh"
#include "HitRecord.hh"
#include "Scene.hh"
#include "Primitive.hh"
#include "Ray.hh"
#include "RenderContext.hh"
#include "Light.hh"
#include "Camera.hh"
#include <math.h>
//////////////////////////////////////////////////////////////////////////////
//------------------------------ Lambertian --------------------------------/
////////////////////////////////////////////////////////////////////////////
LambertianMaterial::LambertianMaterial(Color color, float kd, float ka){
this->color = color;
this->kd = kd;
this->ka = ka;
}
void LambertianMaterial::Preprocess(){
}
Color LambertianMaterial::Shade(const RenderContext& rc, const Ray& ray, const HitRecord& hrec, int depth) const{
Point hp = ((Ray&)ray).PointOn(((HitRecord&)hrec).GetT());
Vector normal = ((HitRecord&)hrec).GetPrimitive()->Normal(hp);
hp += 0.0001f * normal;
Scene* scene = (Scene*)rc.GetScene();
int numlights = scene->NumLights();
Color finalc(0.f,0.f,0.f);
for(int i=0; i<numlights; i++){
Vector ldir;
Color lcolor;
float ldist = scene->GetLight(i)->GetLight(lcolor, ldir, rc, hp);
HitRecord shadowhr;
Ray shadowray(hp, ldir);
scene->GetObject()->Intersect(shadowhr, rc, shadowray);
if(shadowhr.GetT()>=ldist || shadowhr.GetT()<0.01){
float dp = Dot(normal, ldir);
if(dp > 0)
finalc += dp*lcolor;
}
}
return color*(finalc*kd + scene->GetAmbient()*ka);
}
////////////////////////////////////////////////////////////
//----------------------- Phong -------------------------//
//////////////////////////////////////////////////////////
PhongMaterial::PhongMaterial(Color color, float ke, float kd, float ka, float ks, float shininess){
this->color = color;
this->ke = ke;
this->kd = kd;
this->ka = ka;
this->ks = ks;
n = shininess;
}
void PhongMaterial::Preprocess(){
//if(kd+ks > 1.f){
// float d = 1/(kd+ks);
// kd*=d; ks*=d;
//}
}
Color PhongMaterial::Shade(const RenderContext& rc, const Ray& ray, const HitRecord& hrec, int depth) const{
Scene* scene = (Scene*)rc.GetScene();
Point hp = ((Ray&)ray).PointOn(((HitRecord&)hrec).GetT());
Vector normal = ((HitRecord&)hrec).GetPrimitive()->Normal(hp);
Vector v = scene->GetCamera()->GetEye() - hp;
v.Normalize();
hp += 0.0001f * normal;
int numlights = scene->NumLights();
Color finalc(0.f,0.f,0.f);
for(int i=0; i<numlights; i++){
Vector ldir;
Color lcolor;
float ldist = scene->GetLight(i)->GetLight(lcolor, ldir, rc, hp);
HitRecord shadowhr;
Ray shadowray(hp, ldir);
scene->GetObject()->Intersect(shadowhr, rc, shadowray);
if((shadowhr.GetT()>=ldist || shadowhr.GetT()<0.01)){
float dp = Dot(normal, ldir) * kd;
if(!(dp > 0)) dp = 0;
Vector r = 2*(Dot(ldir, normal))*normal - ldir;
r.Normalize();
float spec = Dot(r, v);
if(!(spec > 0)) spec = 0;
else spec = pow(spec,n);
finalc += (dp*kd+spec*ks)*lcolor;
}
}
return color*(finalc + scene->GetAmbient()*ka);
}