00001 #ifndef MIRROR_SHADER_H 00002 #define MIRROR_SHADER_H 00003 00004 00005 #include "Shader.h" 00006 #include "Vec3f.h" 00007 #include "Ray.h" 00008 #include "Scene.h" 00009 00010 00015 class MirrorShader : public Shader 00016 { 00017 public: 00023 MirrorShader( Scene * scene, 00024 const RGBAColor & color) 00025 : Shader(scene), 00026 mMirrorColor(color) 00027 { 00028 } 00029 00033 RGBAColor shade(const Ray & ray) const 00034 { 00035 assert(ray.hit()); 00036 assert(ray.obj()); 00037 00038 // adaptive recursion termination 00039 if (ray.influence() < MIN_INFLUENCE || ray.recDeep() > MAX_RECURSION_DEEP) 00040 { 00041 // let rays with small influence through the mirror 00042 Ray newray; 00043 newray.init(ray.hitPoint(EPSILON), ray.dir()); 00044 newray.updateInfluence(ray); 00045 return RGBAColor(lerp(mScene->rayTrace(newray).rgb(), mMirrorColor.rgb(), mMirrorColor.a())); 00046 } 00047 00048 // get normal of the hit surface 00049 Vec3f normal = this->normal(ray); 00050 00051 // compute reflection vector 00052 Vec3f reflect = ray.dir() - 2*(normal.dot(ray.dir()))*normal; 00053 00054 // change ray direction and position 00055 Ray localRay; 00056 localRay.init(ray.hitPoint(-EPSILON), reflect); 00057 localRay.updateInfluence(ray, 1.0f - mMirrorColor.a()); 00058 00059 // trace the ray back into the scene 00060 return RGBAColor(lerp(mScene->rayTrace(localRay).rgb(), mMirrorColor.rgb(), mMirrorColor.a())); 00061 } 00062 00063 private: 00065 RGBAColor mMirrorColor; 00066 }; 00067 00068 #endif 00069