00001 #ifndef BUMPMAPPEDPHONGSHADER_H
00002 #define BUMPMAPPEDPHONGSHADER_H BUMPMAPPEDPHONGSHADER_H
00003
00004 #include "Shader.h"
00005
00006 class BumpMappedPhongShader : public Shader
00007 {
00008 public:
00009 ColorRGBA color;
00010 float ka;
00011 float kd;
00012 float ks;
00013 float ke;
00014
00015 Texture* bumpmap;
00016 float bumpfactor;
00017
00018 BumpMappedPhongShader(Scene *scene,
00019 ColorRGBA color, float ka,float kd, float ks, float ke, Texture* bumpmap, float bumpfactor)
00020 : Shader(scene),color(color),ka(ka),kd(kd),ks(ks),ke(ke),bumpmap(bumpmap),bumpfactor(bumpfactor)
00021 {};
00022
00023 virtual ColorRGBA Shade(Ray &ray)
00024 {
00025
00026 Vector3D normal = ray.hit->GetNormal(ray);
00027
00028
00029 if (Dot(normal,ray.dir) > 0)
00030 normal = -normal;
00031
00032
00033 float bump = bumpmap->GetTexel(ray.hit->GetUV(ray)).average();
00034
00035
00036
00037 Vector3D p = ray.org + ray.t * ray.dir;
00038 Vector3D du = p + Cross(normal, normal + Vector3D(0,0,1)).Normalized();
00039 Vector3D dv = p + Cross(normal, du).Normalized();
00040 p += bumpfactor * bump * normal;
00041 du = p - du;
00042 dv = p - dv;
00043 normal = Cross(du, dv).Normalized();
00044
00045
00046 if (Dot(normal,ray.dir) > 0)
00047 normal = -normal;
00048
00049
00050 Vector3D reflect = ray.dir - 2*Dot(normal,ray.dir)*normal;
00051
00052
00053 ColorRGBA ambientColor = ka * color;
00054 ColorRGBA result = ambientColor;
00055
00056
00057 Ray shadow;
00058 shadow.org = ray.org + ray.t * ray.dir;
00059
00060
00061 for (unsigned int l=0; l < scene->mLights.size(); l++)
00062 {
00063
00064 ColorRGBA lightIntensity;
00065 ColorRGBA result_local = ColorRGBA(0.0);
00066
00067
00068 for(unsigned int s = 0; s < scene->mLights[l]->GetNumberOfRays(); s++)
00069 {
00070
00071 if (scene->mLights[l]->Illuminate(shadow, lightIntensity, s))
00072 {
00073
00074 float distance = shadow.t;
00075
00076
00077 float cosLightNormal = Dot(shadow.dir,normal);
00078 if (cosLightNormal > 0)
00079 {
00080
00081
00082 if (scene->castShadows && scene->Intersect(shadow) && shadow.hit->castShadows())
00083 {
00084
00085
00086 if (shadow.t < distance)
00087 continue;
00088 }
00089
00090
00091 ColorRGBA diffuseColor = kd * color;
00092 result_local = result_local + (diffuseColor * cosLightNormal) * lightIntensity;
00093
00094
00095 float cosLightReflect = Dot(shadow.dir,reflect);
00096 if (cosLightReflect > 0)
00097 {
00098 ColorRGBA specularColor = ks * ColorRGBA(1,1,1);
00099 result_local = result_local + (specularColor * powf(cosLightReflect,ke)) * lightIntensity;
00100 }
00101 }
00102 }
00103 }
00104
00105 result_local.red() /= float(scene->mLights[l]->GetNumberOfRays());
00106 result_local.green() /= float(scene->mLights[l]->GetNumberOfRays());
00107 result_local.blue() /= float(scene->mLights[l]->GetNumberOfRays());
00108 result += result_local;
00109 }
00110
00111
00112 for (unsigned int i=0; i < getTextureCount(); i++)
00113 {
00114
00115 const ColorRGBA & tex = getTexture(i)->GetTexel(ray.hit->GetUV(ray));
00116
00117
00118 result = result * tex;
00119 }
00120
00121 return result;
00122 };
00123 };
00124
00125 #endif