Vec3f
ReflectiveEyeLightShader::Shade(Ray& ray)
{
- Vec3f eyeColor = EyeLightShader::Shade(ray);
- Vec3f reflColor;
-
- if(ray.recursionDepth() > 0) {
- m_scene->Intersect(ray);
- // intersection, - Epsilon to avoid numerical problems and getting the
- // reflection on the object's inside ;-)
- Vec3f i = ray.origin() + ray.direction() * (ray.t() - Epsilon);
- Vec3f r = ray.direction();
- Vec3f n = (ray.hit()->GetNormal(ray));
-
- Ray sec(i, r + n * (2 * r.dot(n * -1)));
- sec.setRecursionDepth(ray.recursionDepth() - 1);
- reflColor = m_scene->RayTrace(sec);
- }
- return eyeColor + reflColor * m_reflectivity;
+ Vec3f N = ray.hit()->GetNormal(ray);
+
+ // diffuse color
+ Vec3f color = EyeLightShader::Shade(ray);
+
+ // add reflection
+ if(ray.recursionDepth() < RecursionDepth)
+ {
+ // generate reflected ray
+ // ray origin = hitpoint
+ Vec3f origin = ray.origin() + ray.direction()*ray.t();
+ Vec3f dir = ray.direction()-N*2*N.dot(ray.direction());
+ dir.normalize();
+
+ // spawn new ray
+ Ray reflection_ray(origin, dir, ray.recursionDepth()+1);
+ reflection_ray.setT(Infinity);
+
+ // trace reflection ray
+ Vec3f reflected_color = m_scene->RayTrace(reflection_ray);
+ color += reflected_color * m_reflectivity;
+ }
+
+ color.clamp();
+
+ return color;
}