src/PhongShader.h

Go to the documentation of this file.
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         //const Color cd(0.8f, 0.7f, 0.6f);  //this is right, but the graphic guys want it wrong
00057         const Color cd = ca;
00058         const Color cs(1,1,1);
00059 
00060         Vec3f normal = this->normal(ray);
00061         // turn normal to the front
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         // add Textures
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             // get texture color
00100             const RGBAColor tex = (*it)->texel(ray.hit()->texCoord(ray));
00101 
00102             // combine texture color with the computed result
00103             texes = RGBAColor(lerp(texes.rgb(), tex.rgb(), tex.a()));
00104         }
00105 
00106         // add lighting
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 

Generated on Fri Feb 1 00:01:42 2008 for Grayfall by  doxygen 1.5.1