00001 #ifndef BUMPMAPPEDMARBLEPHONGSHADER_H
00002 #define BUMPMAPPEDMARBLEPHONGSHADER_H BUMPMAPPEDMARBLEPHONGSHADER_H
00003
00004 #include "Shader.h"
00005 #include "MarbleShader.h"
00006
00007 class BumpMappedMarblePhongShader : 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* marble;
00020
00021 BumpMappedMarblePhongShader(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 marble = new MarbleShader(scene, center, 0.7);
00026 };
00027
00028 ~BumpMappedMarblePhongShader () {
00029 delete marble;
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 float bump = bumpmap->GetTexel(ray.hit->GetUV(ray)).average();
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 * 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 *= marble->Shade(ray);
00123
00124 return result;
00125 };
00126 };
00127
00128 #endif