box overlapping
[MicroTrace.git] / PhongShader.cxx
1 #include <vector>
2
3 #include "PhongShader.hxx"
4 #include "Primitive.hxx"
5 #include "Scene.hxx"
6
7 PhongShader::PhongShader(Scene* scene,
8 const Vec3f& am_c,
9 const Vec3f& di_c,
10 const Vec3f& sp_c,
11 float ka,
12 float kd,
13 float ks,
14 float ke)
15 : Shader(scene),
16 m_ambient_color(am_c),
17 m_diffuse_color(di_c),
18 m_specular_color(sp_c),
19 m_ka(ka),
20 m_kd(kd),
21 m_ks(ks),
22 m_ke(ke)
23 {
24 }
25
26 PhongShader::PhongShader()
27 : Shader(0)
28 {
29 }
30
31 PhongShader::~PhongShader()
32 {
33 }
34
35 Vec3f
36 PhongShader::Shade(Ray& ray)
37 {
38 // surface normal at hit point
39 Vec3f N = ray.hit()->GetNormal(ray);
40 // turn normal to front
41 if(N.dot(ray.direction()) > 0)
42 {
43 N *= -1;
44 }
45
46 // reflection vector
47 Vec3f R = ray.direction() - N*2*N.dot(ray.direction());
48 R.normalize();
49
50 // ambient term
51 Vec3f color = m_ambient_color * 1.0 * m_ka;
52
53 // construct shadow ray
54 Vec3f shadow_org = ray.origin()+ray.direction()*ray.t();
55 Ray shadow_ray;
56 shadow_ray.setOrigin(shadow_org);
57
58
59 int n_area_rays = 1000;
60 std::vector<Light*> lights = m_scene->lights();
61 for(unsigned int i = 0; i < lights.size(); ++i)
62 {
63 Vec3f intensity;
64
65 int max_s = (lights[i]->IsArea()) ? n_area_rays : 1;
66 Vec3f color_l(0.0f,0.0f,0.0f);
67 for(int s = 0; s < max_s; ++s)
68 {
69
70 if(lights[i]->Illuminate(shadow_ray, intensity))
71 {
72 // check for occluders
73 if(m_scene->Occluded(shadow_ray))
74 {
75 continue;
76 }
77
78 float IdotN = shadow_ray.direction().dot(N);
79 if(IdotN > 0)
80 {
81 // diffuse term
82 color_l += m_diffuse_color * intensity * IdotN * m_kd;
83 }
84
85 // specular term
86 float IdotR = shadow_ray.direction().dot(R);
87 if(IdotR > 0)
88 {
89 color_l += m_specular_color * intensity * pow(IdotR,m_ke) * m_ks;
90 }
91 }
92 }
93 color_l /= static_cast<float>(max_s);
94 color += color_l;
95 }
96 color.clamp();
97
98 return color;
99 }
This page took 0.054057 seconds and 5 git commands to generate.