code for assignment 3
authorRoland Hieber <rhieber@gaffel.ibr.cs.tu-bs.de>
Mon, 25 Jan 2010 14:43:29 +0000 (15:43 +0100)
committerRoland Hieber <rhieber@gaffel.ibr.cs.tu-bs.de>
Mon, 25 Jan 2010 14:43:29 +0000 (15:43 +0100)
20 files changed:
EyeLightShader.cxx
EyeLightShader.hxx
FlatShader.cxx
Image.cxx
InfinitePlane.cxx
Makefile
MicroTrace.cxx
Primitive.cxx
Primitive.hxx
Ray.cxx
Ray.hxx
ReflectiveEyeLightShader.cxx
Scene.cxx
Scene.hxx
Shader.hxx
Sphere.cxx
Triangle.cxx
Triangle.hxx
Vec3f.cxx
Vec3f.hxx

index 8eae610..4f31b84 100644 (file)
@@ -21,9 +21,8 @@ EyeLightShader::EyeLightShader()
 Vec3f
 EyeLightShader::Shade(Ray& ray)
 {
-  // shade according to cos(theta)
-  Vec3f r = ray.direction();
-  Vec3f n = ray.hit()->GetNormal(ray);
-  float cos_theta = fabs(r.dot(n) / (r.norm() * n.norm()));
-  return m_color * cos_theta;
+  Vec3f N = ray.hit()->GetNormal(ray);
+  float cos_phi = fabs(ray.direction().dot(N));
+  
+  return m_color * cos_phi;
 }
index 9b4777e..2d0bfe5 100644 (file)
@@ -10,11 +10,10 @@ public:
   virtual ~EyeLightShader();
 
   virtual Vec3f Shade(Ray& ray);
-
-protected:
-  Vec3f m_color;
-  
 private:
   EyeLightShader();
+  
+protected:
+  Vec3f m_color;
 };
 #endif
index 3699cd4..210fc6f 100644 (file)
@@ -12,7 +12,7 @@ FlatShader::~FlatShader()
 }
 
 FlatShader::FlatShader()
-  : Shader(0),
+  : Shader(0), 
     m_color(Vec3f())
 {
 }
@@ -20,5 +20,5 @@ FlatShader::FlatShader()
 Vec3f
 FlatShader::Shade(Ray& ray)
 {
-  return m_color;
+  return m_color; 
 }
index 899ac6f..b45cac9 100644 (file)
--- a/Image.cxx
+++ b/Image.cxx
@@ -39,39 +39,31 @@ Image::operator()(int x, int y)
 {
   assert(x >= 0 && x < m_resX);
   assert(y >= 0 && y < m_resY);
-
-  return m_pixel[y*m_resX+x];
+        
+  return m_pixel[y*m_resX+x];   
 }
 
 void Image::WritePPM(const std::string& fileName)
 {
   std::cerr << "(Image): Writing to file " << fileName << std::endl;
   std::ofstream file(fileName.c_str());
-
+  
   if(!file.is_open())
     {
       std::cerr << "(Image): Could not open file " << fileName << std::endl;
       return;
     }
-
+  
   file << "P3" << std::endl;
   file << m_resX << " " << m_resY << " " << 255 << std::endl;
-  for (int y=m_resY-1;y>=0;y--)
+  for (int y=m_resY-1;y>=0;y--) 
     {
       for (int x=0;x<m_resX;x++)
        {
-    Vec3f cur = (*this)(x,y);
-    if(cur[0] < 0) cur[0] = 0;
-    if(cur[1] < 0) cur[1] = 0;
-    if(cur[2] < 0) cur[2] = 0;
-    if(cur[0] > 255) cur[0] = 255;
-    if(cur[1] > 255) cur[1] = 255;
-    if(cur[2] > 255) cur[2] = 255;
-
-         file
-           << (int)(255.99999999 * cur[0]) << " "
-           << (int)(255.99999999 * cur[1]) << " "
-           << (int)(255.99999999 * cur[2]) << " "
+         file 
+           << (int)(255.99999999 * (*this)(x,y)[0]) << " "
+           << (int)(255.99999999 * (*this)(x,y)[1]) << " "
+           << (int)(255.99999999 * (*this)(x,y)[2]) << " "
            << "\t";
        }
       file << std::endl;
index 54c9570..f73d835 100644 (file)
@@ -1,11 +1,11 @@
 #include "InfinitePlane.hxx"
 
 InfinitePlane::InfinitePlane(const Vec3f& a, const Vec3f& n, Shader* shader)
-  : Primitive(shader),
+  : Primitive(shader), 
     m_a(a),
     m_n(n)
 {
-
+  
 }
 
 InfinitePlane::~InfinitePlane()
@@ -17,15 +17,17 @@ InfinitePlane::Intersect(Ray& ray)
 {
   Vec3f diff = m_a - ray.origin();
   float t = diff.dot(m_n) / ray.direction().dot(m_n);
-  if (t < 1e-5 || t > ray.t())
+  if (t < Epsilon || t > ray.t()) 
     return false;
+  
   ray.setT(t);
+  ray.setHit(this);
+
   return true;
 }
 
 Vec3f
 InfinitePlane::GetNormal(Ray& ray)
 {
-  // We already have the surface normal
   return m_n;
 }
index a9276b7..f263909 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 all: MicroTrace
 
 CC = g++ 
-CFLAGS = -O0 -g -Wall 
+CFLAGS = -O3 -Wall
 
 
 OBJ = MicroTrace.o\
@@ -19,6 +19,10 @@ OBJ = MicroTrace.o\
       FlatShader.o\
       EyeLightShader.o\
       ReflectiveEyeLightShader.o\
+      PhongShader.o\
+      Light.o\
+      PointLight.o\
+      SpotLight.o\
       Scene.o\
       Primitive.o
 
index 4689425..e0fd688 100644 (file)
 #include "FlatShader.hxx"
 #include "EyeLightShader.hxx"
 #include "ReflectiveEyeLightShader.hxx"
+#include "PhongShader.hxx"
+#include "PointLight.hxx"
+#include "SpotLight.hxx"
 #include "Scene.hxx"
 
-void RenderFrameFlat(const std::string& fileName)
+
+void RenderFramePhongPointLight(const std::string& fileName)
 {
   /* Scene definition */
-
   Scene scene;
-
+  
   /* Flat shaders */
-  FlatShader shd1(&scene, Vec3f(1,0,0)); // red surface
-  FlatShader shd2(&scene, Vec3f(0,1,0)); // green surface
-  FlatShader shd3(&scene, Vec3f(0,0,1)); // blue surface
-  FlatShader shd4(&scene, Vec3f(1,1,0)); // yellow surface
-  FlatShader shd5(&scene, Vec3f(0,1,1)); // cyan surface
-  FlatShader shd6(&scene, Vec3f(1,1,1)); // white surface
+  PhongShader shd1(&scene, Vec3f(1,0,0),Vec3f(1,0,0),Vec3f(1,1,1), 0.1, 0.5, 0.5, 40); // red surface
+  PhongShader shd2(&scene, Vec3f(0,1,0),Vec3f(0,1,0),Vec3f(1,1,1), 0.1, 0.5, 0.5, 40); // green surface
+  PhongShader shd3(&scene, Vec3f(0,0,1),Vec3f(0,0,1),Vec3f(1,1,1), 0.1, 0.5, 0.5, 40); // blue surface
+  PhongShader shd4(&scene, Vec3f(1,1,0),Vec3f(1,1,0),Vec3f(1,1,1), 0.1, 0.5, 0.5, 40); // yellow surface
+  PhongShader shd5(&scene, Vec3f(0,1,1),Vec3f(0,1,1),Vec3f(1,1,1), 0.1, 0.5, 0.5, 40); // cyan surface
+  PhongShader shd6(&scene, Vec3f(1,1,1),Vec3f(1,1,1),Vec3f(1,1,1), 0.1, 0.5, 0.5, 40); // white surface
 
   /* scene objects */
   Sphere s1(Vec3f(-2,1.7,0), 2, &shd1);
@@ -32,57 +35,61 @@ void RenderFrameFlat(const std::string& fileName)
   Sphere s3(Vec3f(3,0.8,-2), 2, &shd3);
   InfinitePlane p1(Vec3f(0,-1,0),Vec3f(0,1,0), &shd4);
 
-
-  Triangle t1(Vec3f(-2,3,1),Vec3f(1,2,1),Vec3f(3,2.8,3), &shd5);
-
+    
+  Triangle t1(Vec3f(-2,3,1),Vec3f(1,2,1),Vec3f(3,2.8,3), &shd5); 
+  
   /* add to scene */
   scene.Add(&s1);
   scene.Add(&s2);
   scene.Add(&s3);
   scene.Add(&p1);
   scene.Add(&t1);
+  
+  /* light sources */
+  Vec3f lightPosition1(4,5,6);
+  Vec3f lightPosition2(-3,5,4);
+  Vec3f pointLightSourceIntensity(50,50,50);
+  
+  PointLight pointLight1(&scene, lightPosition1, pointLightSourceIntensity);
+  PointLight pointLight2(&scene, lightPosition2, pointLightSourceIntensity);
+  scene.Add(&pointLight1);
+  scene.Add(&pointLight2);
 
 
   Image img(scene.camera()->resX(),scene.camera()->resY()); // image array
   Ray ray;                            // primary ray
-
+  
   for(int y = 0; y < scene.camera()->resY(); y++)
     {
-      for (int x = 0; x < scene.camera()->resX(); x++)
-      {
-
-        /* Initialize your ray here */
-        // shoot four rays for antialiasing
-        scene.camera()->InitRay(x+0.5,y+0.5, ray); // initialize ray
-        Vec3f col1 = scene.RayTrace(ray);
-        scene.camera()->InitRay(x-0.5,y+0.5, ray); // initialize ray
-        Vec3f col2 = scene.RayTrace(ray);
-        scene.camera()->InitRay(x-0.5,y-0.5, ray); // initialize ray
-        Vec3f col3 = scene.RayTrace(ray);
-        scene.camera()->InitRay(x-0.5,y-0.5, ray); // initialize ray
-        Vec3f col4 = scene.RayTrace(ray);
-
-        img(x,y) = (col1 + col2 + col3 + col4) / 4.0; // store pixel color
-        //std::cerr << "Main: Image color = " << img(x,y) << std::endl;
-      }
+      for (int x = 0; x < scene.camera()->resX(); x++) 
+       {
+         
+         /* Initialize your ray here */
+         
+         scene.camera()->InitRay(x+0.5,y+0.5,ray); // initialize ray
+       
+         Vec3f col = scene.RayTrace(ray);
+         
+         img(x,y) = col; // store pixel color
+         //std::cerr << "Main: Image color = " << img(x,y) << std::endl;
+       }
     }
   img.WritePPM(fileName); // write final image
 }
 
-
-void RenderFrameEyeLight(const std::string& fileName)
+void RenderFramePhongSpotLight(const std::string& fileName)
 {
   /* Scene definition */
-
   Scene scene;
-
+  
   /* Flat shaders */
-  EyeLightShader shd1(&scene, Vec3f(1,0,0)); // red surface
-  EyeLightShader shd2(&scene, Vec3f(0,1,0)); // green surface
-  EyeLightShader shd3(&scene, Vec3f(0,0,1)); // blue surface
-  EyeLightShader shd4(&scene, Vec3f(1,1,0)); // yellow surface
-  EyeLightShader shd5(&scene, Vec3f(0,1,1)); // cyan surface
-  EyeLightShader shd6(&scene, Vec3f(1,1,1)); // white surface
+  PhongShader shd1(&scene, Vec3f(1,0,0),Vec3f(1,0,0),Vec3f(1,1,1), 0.1, 0.5, 0.5, 40); // red surface
+  PhongShader shd2(&scene, Vec3f(0,1,0),Vec3f(0,1,0),Vec3f(1,1,1), 0.1, 0.5, 0.5, 40); // green surface
+  PhongShader shd3(&scene, Vec3f(0,0,1),Vec3f(0,0,1),Vec3f(1,1,1), 0.1, 0.5, 0.5, 40); // blue surface
+  PhongShader shd4(&scene, Vec3f(1,1,0),Vec3f(1,1,0),Vec3f(1,1,1), 0.1, 0.5, 0.5, 40); // yellow surface
+  PhongShader shd5(&scene, Vec3f(0,1,1),Vec3f(0,1,1),Vec3f(1,1,1), 0.1, 0.5, 0.5, 40); // cyan surface
+  PhongShader shd6(&scene, Vec3f(1,1,1),Vec3f(1,1,1),Vec3f(1,1,1), 0.1, 0.5, 0.5, 40); // white surface
 
   /* scene objects */
   Sphere s1(Vec3f(-2,1.7,0), 2, &shd1);
@@ -90,105 +97,60 @@ void RenderFrameEyeLight(const std::string& fileName)
   Sphere s3(Vec3f(3,0.8,-2), 2, &shd3);
   InfinitePlane p1(Vec3f(0,-1,0),Vec3f(0,1,0), &shd4);
 
-
-  Triangle t1(Vec3f(-2,3,1),Vec3f(1,2,1),Vec3f(3,2.8,3), &shd5);
-
-  /* add to scene */
-  scene.Add(&s1);
-  scene.Add(&s2);
-  scene.Add(&s3);
-  scene.Add(&p1);
-  scene.Add(&t1);
-
-  Image img(scene.camera()->resX(),scene.camera()->resY()); // image array
-  Ray ray;                            // primary ray
-
-  for(int y = 0; y < scene.camera()->resY(); y++)
-    {
-      for (int x = 0; x < scene.camera()->resX(); x++)
-      {
-
-        /* Initialize your ray here */
-        // shoot four rays for antialiasing
-        scene.camera()->InitRay(x+0.5,y+0.5, ray); // initialize ray
-        Vec3f col1 = scene.RayTrace(ray);
-        scene.camera()->InitRay(x-0.5,y+0.5, ray); // initialize ray
-        Vec3f col2 = scene.RayTrace(ray);
-        scene.camera()->InitRay(x-0.5,y-0.5, ray); // initialize ray
-        Vec3f col3 = scene.RayTrace(ray);
-        scene.camera()->InitRay(x-0.5,y-0.5, ray); // initialize ray
-        Vec3f col4 = scene.RayTrace(ray);
-
-        img(x,y) = (col1 + col2 + col3 + col4) / 4.0; // store pixel color
-      }
-    }
-  img.WritePPM(fileName); // write final image
-}
-
-void RenderFrameReflectiveEyeLight(const std::string& fileName)
-{
-  /* Scene definition */
-
-  Scene scene;
-
-  /* Flat shaders */
-  ReflectiveEyeLightShader shd1(&scene, 1.0, Vec3f(1,0,0)); // red surface
-  ReflectiveEyeLightShader shd2(&scene, 1.0, Vec3f(0.0,1.0,0.0)); // green surface
-  ReflectiveEyeLightShader shd3(&scene, 1.0, Vec3f(0,0,1)); // blue surface
-  ReflectiveEyeLightShader shd4(&scene, 0.8, Vec3f(1,1,0)); // yellow surface
-  ReflectiveEyeLightShader shd5(&scene, 1.0, Vec3f(0,1,1)); // cyan surface
-  ReflectiveEyeLightShader shd6(&scene, 0.0, Vec3f(1,1,1)); // white surface
-
-  /* scene objects */
-  Sphere s1(Vec3f(-2,1.7,0), 2, &shd1);
-  Sphere s2(Vec3f(0.4,-1,1), 2.0, &shd2);
-  Sphere s3(Vec3f(3,0.8,-2), 2, &shd3);
-  InfinitePlane p1(Vec3f(0,-1,0),Vec3f(0,1,0), &shd4);
-
-
-  Triangle t1(Vec3f(-2,3,1),Vec3f(1,2,1),Vec3f(3,2.8,3), &shd5);
-
+    
+  Triangle t1(Vec3f(-2,3,1),Vec3f(1,2,1),Vec3f(3,2.8,3), &shd5); 
+  
   /* add to scene */
   scene.Add(&s1);
   scene.Add(&s2);
   scene.Add(&s3);
   scene.Add(&p1);
   scene.Add(&t1);
+  
+  /* light sources */
+  Vec3f lightPosition1(4,5,6);
+  Vec3f lightPosition2(-3,5,4);
+  Vec3f spotLightSourceIntensity(50,50,50);
+  Vec3f lightDir1 = lightPosition1 * (-1.0f);
+  lightDir1.normalize();
+  Vec3f lightDir2 = lightPosition2 *(-1.0f);
+  lightDir2.normalize();
+  float alpha_min = 15.0f;
+  float alpha_max = 30.0f;
+  
+  SpotLight spotLight1(&scene, lightPosition1, lightDir1, spotLightSourceIntensity, alpha_min, alpha_max);
+  SpotLight spotLight2(&scene, lightPosition2, lightDir2, spotLightSourceIntensity, alpha_min, alpha_max);
+  scene.Add(&spotLight1);
+  scene.Add(&spotLight2);
 
 
   Image img(scene.camera()->resX(),scene.camera()->resY()); // image array
   Ray ray;                            // primary ray
-
+  
   for(int y = 0; y < scene.camera()->resY(); y++)
     {
-      for (int x = 0; x < scene.camera()->resX(); x++)
-      {
-        /* Initialize your ray here */ //int x = 319, y = 59;
-        // shoot four rays for antialiasing
-        scene.camera()->InitRay(x+0.5,y+0.5, ray); // initialize ray
-        Vec3f col1 = scene.RayTrace(ray);
-        scene.camera()->InitRay(x-0.5,y+0.5, ray); // initialize ray
-        Vec3f col2 = scene.RayTrace(ray);
-        scene.camera()->InitRay(x-0.5,y-0.5, ray); // initialize ray
-        Vec3f col3 = scene.RayTrace(ray);
-        scene.camera()->InitRay(x-0.5,y-0.5, ray); // initialize ray
-        Vec3f col4 = scene.RayTrace(ray);
-
-        img(x,y) = (col1 + col2 + col3 + col4) / 4.0; // store pixel color
-        //std::cerr << "Main: Image color = " << img(x,y) << std::endl;
-      }
+      for (int x = 0; x < scene.camera()->resX(); x++) 
+       {
+         
+         /* Initialize your ray here */
+         
+         scene.camera()->InitRay(x+0.5,y+0.5,ray); // initialize ray
+       
+         Vec3f col = scene.RayTrace(ray);
+         
+         img(x,y) = col; // store pixel color
+         //std::cerr << "Main: Image color = " << img(x,y) << std::endl;
+       }
     }
   img.WritePPM(fileName); // write final image
 }
 
-
-
 #define RESX 640 // image x-resolution
 #define RESY 480 // image y-resolution
 
 int main(int, char**)
 {
-  //RenderFrameFlat("flatshaded.ppm");
-  //RenderFrameEyeLight("eyelight.ppm");
-  RenderFrameReflectiveEyeLight("reflective.ppm");
+  RenderFramePhongPointLight("phong_point.ppm");
+  RenderFramePhongSpotLight("phong_spot.ppm");
 }
index 850cb24..4c8cf94 100644 (file)
@@ -16,7 +16,7 @@ Primitive::Occluded(Ray& ray)
 }
 
 Shader*
-Primitive::shader() 
+Primitive::shader()
 {
   return m_shader;
 }
index 04e201f..68dd11c 100644 (file)
@@ -13,8 +13,8 @@ public:
   virtual bool Intersect(Ray &ray) = 0;
   virtual bool Occluded(Ray& ray);
   virtual Vec3f GetNormal(Ray& ray) = 0;
-  
   Shader* shader();
+  
 protected:
   Shader* m_shader;
 };
diff --git a/Ray.cxx b/Ray.cxx
index e0a1ab5..84617d1 100644 (file)
--- a/Ray.cxx
+++ b/Ray.cxx
@@ -2,22 +2,23 @@
 
 #include "Ray.hxx"
 
-#define MAX_RECURSION_DEPTH 10
-
 Ray::Ray()
   : m_org(Vec3f()),
     m_dir(Vec3f()),
-    m_level(MAX_RECURSION_DEPTH),
+    m_level(0),
+    m_density(1.0),
     m_hit(0)
 {
   m_t = std::numeric_limits<float>::max();
 }
 
-Ray::Ray(const Vec3f& org,
-        const Vec3f& dir)
+Ray::Ray(const Vec3f& org, 
+        const Vec3f& dir,
+        unsigned int recursion_level)
   : m_org(org),
     m_dir(dir),
-    m_level(MAX_RECURSION_DEPTH),
+    m_level(recursion_level),
+    m_density(1.0),
     m_hit(0)
 {
   m_t = std::numeric_limits<float>::max();
@@ -34,6 +35,7 @@ Ray::Ray(const Ray& r)
   m_t = r.m_t;
   m_hit = r.m_hit;
   m_level = r.m_level;
+  m_density = r.m_density;
 }
 
 Ray&
@@ -45,6 +47,8 @@ Ray::operator=(const Ray& r)
       m_dir = r.m_dir;
       m_t = r.m_t;
       m_hit = r.m_hit;
+      m_level = r.m_level;
+      m_density = r.m_density;
     }
   return *this;
 }
@@ -85,19 +89,19 @@ Ray::setT(float t)
   m_t = t;
 }
 
-void
-Ray::setHit(Primitive * p)
-{
-   m_hit = p;
-}
-
 Primitive*
 Ray::hit()
 {
   return m_hit;
 }
 
-unsigned int
+void
+Ray::setHit(Primitive* p)
+{
+  m_hit = p;
+}
+
+unsigned int 
 Ray::recursionDepth() const
 {
   return m_level;
@@ -108,3 +112,15 @@ Ray::setRecursionDepth(unsigned int i)
 {
   m_level = i;
 }
+
+float
+Ray::indexOfRefraction() const
+{
+  return m_density;
+}
+
+void
+Ray::setIndexOfRefraction(float d)
+{
+  m_density = d;
+}
diff --git a/Ray.hxx b/Ray.hxx
index 0b4e796..0ec9f76 100644 (file)
--- a/Ray.hxx
+++ b/Ray.hxx
@@ -9,29 +9,32 @@ class Ray
 {
 public:
   Ray();
-  Ray(const Vec3f& org, const Vec3f& dir);
+  Ray(const Vec3f& org, const Vec3f& dir, unsigned int recursion_level = 0);
   ~Ray();
   Ray(const Ray& r);
   Ray& operator=(const Ray& r);
-
+  
   const Vec3f& origin() const;
   const Vec3f& direction() const;
   float t() const;
-  void setHit(Primitive * p);
   Primitive* hit();
   unsigned int recursionDepth() const;
+  float indexOfRefraction() const;
 
   void setOrigin(const Vec3f& o);
   void setDir(const Vec3f& d);
   void setT(float t);
+  void setHit(Primitive* p);
   void setRecursionDepth(unsigned int i);
+  void setIndexOfRefraction(float ior);
 
 private:
   Vec3f m_org; //!< ray origin
   Vec3f m_dir; //!< ray direction
   float m_t;   //!< current/maximum hit distance
-
+   
   unsigned int m_level; //!< level of recursion
+  float m_density; //!< index of refraction
 
   Primitive* m_hit;
 };
index b681e47..0adb174 100644 (file)
@@ -23,20 +23,30 @@ ReflectiveEyeLightShader::ReflectiveEyeLightShader()
 Vec3f
 ReflectiveEyeLightShader::Shade(Ray& ray)
 {
-  Vec3f eyeColor = EyeLightShader::Shade(ray);
-  Vec3f reflColor;
-
-  if(ray.recursionDepth() > 0) {
-    m_scene->Intersect(ray);
-    // intersection, - Epsilon to avoid numerical problems and getting the
-    // reflection on the object's inside ;-)
-    Vec3f i = ray.origin() + ray.direction() * (ray.t() - Epsilon);
-    Vec3f r = ray.direction();
-    Vec3f n = (ray.hit()->GetNormal(ray));
-
-    Ray sec(i, r + n * (2 * r.dot(n * -1)));
-    sec.setRecursionDepth(ray.recursionDepth() - 1);
-    reflColor = m_scene->RayTrace(sec);
-  }
-  return eyeColor + reflColor * m_reflectivity;
+  Vec3f N = ray.hit()->GetNormal(ray);
+  
+  // diffuse color
+  Vec3f color = EyeLightShader::Shade(ray); 
+  // add reflection
+  if(ray.recursionDepth() < RecursionDepth)
+    {
+      // generate reflected ray
+      // ray origin = hitpoint
+      Vec3f origin = ray.origin() + ray.direction()*ray.t();
+      Vec3f dir = ray.direction()-N*2*N.dot(ray.direction());
+      dir.normalize();
+      
+      // spawn new ray
+      Ray reflection_ray(origin, dir, ray.recursionDepth()+1);
+      reflection_ray.setT(Infinity);
+      
+      // trace reflection ray
+      Vec3f reflected_color = m_scene->RayTrace(reflection_ray);
+      color += reflected_color * m_reflectivity;
+    }
+  
+  color.clamp();
+  
+  return color;
 }
index 4998bd1..bbd6785 100644 (file)
--- a/Scene.cxx
+++ b/Scene.cxx
@@ -1,13 +1,12 @@
 #include "Scene.hxx"
 #include "PerspectiveCamera.hxx"
-#include <limits>
 
 Scene::Scene()
-  : m_camera(new PerspectiveCamera(Vec3f(0,0,8),
-                                  Vec3f(0,0,-1),
-                                  Vec3f(0,1,0),
-                                  50,
-                                  640,
+  : m_camera(new PerspectiveCamera(Vec3f(0,0,8), 
+                                  Vec3f(0,0,-1), 
+                                  Vec3f(0,1,0), 
+                                  50, 
+                                  640, 
                                   480)
             ),
     m_bgColor(Vec3f(0,0,0))
@@ -30,29 +29,28 @@ Scene::operator=(const Scene& s)
   return *this;
 }
 
-void
+void 
 Scene::Add(Primitive* p)
 {
   m_primitives.push_back(p);
 }
 
+void
+Scene::Add(Light* l)
+{
+}
 
 bool
 Scene::Intersect(Ray& ray)
 {
-  bool hit = false;
-  float t = std::numeric_limits<float>::max();
-  for (std::vector<Primitive*>::iterator i = m_primitives.begin();
-    i != m_primitives.end(); i++) {
-    // store closest object hit
-    if (hit |= (*i)->Intersect(ray)) {
-      if (ray.t() < t) {
-        ray.setHit(*i);
-        t = ray.t();
-      }
+  bool intersect = false;
+
+  for(unsigned int i = 0; i < m_primitives.size(); ++i)
+    {
+      intersect |= m_primitives[i]->Intersect(ray);
     }
-  }
-  return hit;
+  
+  return intersect;
 }
 
 bool
@@ -64,14 +62,11 @@ Scene::Occluded(Ray& ray)
 Vec3f
 Scene::RayTrace(Ray& ray)
 {
-  if (Intersect(ray)) {
-    return ray.hit()->shader()->Shade(ray);
-  } else {
-    return Vec3f(0,0,0);
-  }
+  bool intersect = this->Intersect(ray);
+  return (intersect) ? ray.hit()->shader()->Shade(ray) : m_bgColor;
 }
 
-const Camera*
+const Camera* 
 Scene::camera() const
 {
   return m_camera;
index 18deb79..b92e9e5 100644 (file)
--- a/Scene.hxx
+++ b/Scene.hxx
@@ -5,6 +5,7 @@
 
 #include "Ray.hxx"
 #include "Camera.hxx"
+#include "Light.hxx"
 #include "Primitive.hxx"
 
 class Scene
@@ -15,7 +16,9 @@ public:
   
   // add another primitive to the scene
   void Add(Primitive* p);
+  // add another light source to the scene
+  void Add(Light* l);
+
   // intersect the ray with all objects in the scene
   virtual bool Intersect(Ray& ray);
   // find occluder
@@ -35,5 +38,7 @@ private:
   
   // primitives
   std::vector<Primitive*> m_primitives;
+  // lights
+  std::vector<Light*> m_lights;
 };
 #endif
index ac6de1d..98e591f 100644 (file)
@@ -7,6 +7,8 @@
 // forward declaration
 class Scene;
 
+#define RecursionDepth 10
+
 class Shader
 {
 public:
index 77d4320..6b8d943 100644 (file)
@@ -1,7 +1,7 @@
 #include "Sphere.hxx"
 
 Sphere::Sphere(const Vec3f& center, float radius, Shader* shader)
-  : Primitive(shader),
+  : Primitive(shader), 
     m_center(center),
     m_radius(radius)
 {
@@ -20,39 +20,31 @@ Sphere::Intersect(Ray& ray)
 
   if( B*B-4*A*C < 0 )
     return false;
-
+  
   float root = sqrtf(B*B-4*A*C);
   float t = (-B-root)/(2.0f*A);
   if(t > ray.t())
     return false;
-
-  if( t < 1e-6 )
+      
+  if( t < Epsilon )
     {
       t = (-B+root)/(2.0f*A);
-      if( t < 1e-6 || t > ray.t())
+      if( t < Epsilon || t > ray.t())
        return false;
     }
+  
   ray.setT(t);
+  ray.setHit(this);
+  
   return true;
 }
 
 Vec3f
 Sphere::GetNormal(Ray& ray)
 {
-  // We don't want to modify the ray (probably this is not needed, but I am
-  // too lazy to think about it now ...)
-  Ray tempRay = ray;
+  Vec3f p = ray.origin()+ray.direction()*ray.t();
+  Vec3f N = (p-m_center);
+  N.normalize();
 
-  // Surface normal is the difference between intersection and center point
-  if(Intersect(tempRay)) {
-    // intersection point
-    Vec3f i = tempRay.origin() + tempRay.direction() * (tempRay.t() - Epsilon);
-    // normal
-    Vec3f n = (i - m_center);
-    n.normalize();
-    return n;
-  } else {
-    // no intersection with ray, so no surface normal
-    return Vec3f(0,0,0);
-  }
+  return N;
 }
index 456c6d8..498757e 100644 (file)
@@ -7,8 +7,10 @@ Triangle::Triangle(const Vec3f& a,
   : Primitive(shader),
     m_a(a),
     m_b(b),
-    m_c(c)
+    m_c(c),
+    m_n( (b-a).cross(c-a) )
 {
+  m_n.normalize();
 }
 
 Triangle::~Triangle()
@@ -20,34 +22,35 @@ Triangle::Intersect(Ray& ray)
 {
   const Vec3f edge1 = m_b-m_a;
   const Vec3f edge2 = m_c-m_a;
-
+  
   const Vec3f pvec = ray.direction().cross(edge2);
-
+  
   const float det = edge1.dot(pvec);
   if (fabs(det) < Epsilon) return false;
-
+  
   const float inv_det = 1.0f / det;
-
+  
   const Vec3f tvec = ray.origin()-m_a;
   float lambda = tvec.dot( pvec );
   lambda *= inv_det;
-
-  if (lambda < 0.0f || lambda > 1.0f)
+    
+  if (lambda < 0.0f || lambda > 1.0f) 
     return false;
 
   const Vec3f qvec = tvec.cross(edge1);
   float mue = ray.direction().dot(qvec);
   mue *= inv_det;
-
-  if (mue < 0.0f || mue+lambda > 1.0f)
+  
+  if (mue < 0.0f || mue+lambda > 1.0f) 
     return false;
 
   float f = edge2.dot(qvec);
   f *= inv_det;
-  if (ray.t() <= f || f <  1e-4  )
+  if (ray.t() <= f || f < Epsilon ) 
     return false;
-
+  
   ray.setT(f);
+  ray.setHit(this);
 
   return true;
 }
@@ -55,8 +58,5 @@ Triangle::Intersect(Ray& ray)
 Vec3f
 Triangle::GetNormal(Ray& ray)
 {
-  // normal is cross product of spanning vectors
-  Vec3f n = (m_c - m_a) % (m_c - m_b);
-  n.normalize();
-  return n;
+  return m_n;
 }
index fbf4e2c..6abbe53 100644 (file)
@@ -13,5 +13,6 @@ public:
   virtual Vec3f GetNormal(Ray& ray);
 private:
   Vec3f m_a, m_b, m_c;
+  Vec3f m_n;
 };
 #endif
index f656d29..7c39435 100644 (file)
--- a/Vec3f.cxx
+++ b/Vec3f.cxx
@@ -211,3 +211,15 @@ Vec3f::operator[](unsigned int i)
   assert(i < 3);
   return m_values[i];
 }
+
+void
+Vec3f::clamp()
+{
+  for(unsigned int i = 0; i < 3; ++i)
+    {
+      if(m_values[i] < 0.0)
+       m_values[i] = 0.0;
+      if(m_values[i] > 1.0)
+       m_values[i] = 1.0;
+    }
+}
index 6b67d5b..81c0c8b 100644 (file)
--- a/Vec3f.hxx
+++ b/Vec3f.hxx
@@ -11,7 +11,7 @@
 #endif
 
 
-#define Epsilon 1E-4
+#define Epsilon 1E-3
 #define Infinity HUGE_VAL
 
 //! Standard operators and useful methods for 3d vectors
@@ -68,6 +68,8 @@ public:
   float operator[](unsigned int i) const;
   float& operator[](unsigned int i);
  
+  //! clamp each element to [0,1]
+  void clamp();
 private:
   float m_values[3];
 };
This page took 0.051366 seconds and 4 git commands to generate.