00001 #ifndef PHONGSHADER_H
00002 #define PHONGSHADER_H
00003
00004
00005 #include <cassert>
00006
00007 #include "Shader.h"
00008 #include "Vec3f.h"
00009 #include "Ray.h"
00010 #include "Scene.h"
00011
00012
00018 class PhongShader : public Shader
00019 {
00020 public:
00030 PhongShader(Scene * scene,
00031 RGBAColor color,
00032 float ka,
00033 float kd,
00034 float ks,
00035 float ke)
00036 : Shader(scene),
00037 mColor(color),
00038 mKa(ka),
00039 mKd(kd),
00040 mKs(ks),
00041 mKe(ke)
00042 {
00043 }
00044
00047 virtual RGBAColor shade(const Ray & ray) const
00048 {
00049 assert(ray.hit());
00050 assert(ray.obj());
00051
00052 typedef Vec3f Color;
00053
00054 const Color La(1,1,1);
00055 const Color ca = mColor.rgb();
00056
00057 const Color cd = ca;
00058 const Color cs(1,1,1);
00059
00060 Vec3f normal = this->normal(ray);
00061
00062 if (ray.dir().dot(normal) > 0.0f)
00063 normal = -normal;
00064 const Vec3f reflectdir = ray.dir() - 2* ( normal.dot(ray.dir()) * normal );
00065
00066 Color firstterm = mKa*ca.scaled(La);
00067
00068 Color secondterm(0,0,0);
00069 Color thirdterm(0,0,0);
00070 for(unsigned int i = 0; i < mScene->lightsCount(); i++)
00071 {
00072 Vec3f dir;
00073 for (unsigned int j = 0; j < mScene->getLight(i)->numberOfRays(); j++)
00074 {
00075 RGBAColor intensity = mScene->getLight(i)->illuminate(dir, ray.hitPoint(-EPSILON), j);
00076 float cosLightNormal = dir.dot( normal );
00077 if (cosLightNormal <= 0)
00078 continue;
00079 secondterm += intensity.rgb() * cosLightNormal;
00080 float cosLightReflect = dir.dot( reflectdir );
00081 if (cosLightReflect <= 0)
00082 continue;
00083 thirdterm += intensity.rgb() * powf( cosLightReflect, mKe );
00084 }
00085 }
00086 secondterm.scale(mKd * cd);
00087 thirdterm.scale(mKs * cs);
00088 RGBAColor result = RGBAColor(firstterm + secondterm + thirdterm, 1.0f);
00089
00090
00091 if (textureCount() <= 0)
00092 return result;
00093
00094 std::vector<Texture*>::const_iterator it = mTextures.begin();
00095 RGBAColor texes = (*it)->texel(ray.hit()->texCoord(ray));
00096 ++it;
00097 for(; it!=mTextures.end(); ++it)
00098 {
00099
00100 const RGBAColor tex = (*it)->texel(ray.hit()->texCoord(ray));
00101
00102
00103 texes = RGBAColor(lerp(texes.rgb(), tex.rgb(), tex.a()));
00104 }
00105
00106
00107 return result.scaled(texes);
00108 }
00109
00110 private:
00112 RGBAColor mColor;
00113
00115 float mKa;
00116
00118 float mKd;
00119
00121 float mKs;
00122
00124 float mKe;
00125 };
00126
00127 #endif
00128