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