Browse files

Added Refractions

  • Loading branch information...
1 parent a65eecb commit e01d8affb12b8073704007d87f8da1862260305f Alejandro committed May 9, 2009
Showing with 96 additions and 30 deletions.
  1. +76 −29 main.cpp
  2. BIN main.o
  3. +1 −1 math/Vector3.h
  4. +1 −0 objects/Object.h
  5. +6 −0 objects/Sphere.cpp
  6. +3 −0 objects/Sphere.h
  7. BIN objects/Sphere.o
  8. +6 −0 objects/Wall.cpp
  9. +3 −0 objects/Wall.h
  10. BIN objects/Wall.o
View
105 main.cpp
@@ -38,6 +38,9 @@ const int MAX_RECURSION = 4;
//Window dimensions
int width = 800, height = 600;
+//Scene needs to be redrawn
+bool redraw = true;
+
//Scene objects
vector<Object*> objects;
@@ -56,7 +59,7 @@ Color gAmbient;
//Camera, corners of the plane, and camera pos
Vector3 minv;
Vector3 maxv;
-Vector3 posv;
+Vector3 posv;
//Keyboard functions
void keyDown(unsigned char key, int x, int y)
@@ -88,10 +91,8 @@ void keyboard()
/*
Cast a ray and return the color of the intersected object
*/
-Color castRay(Ray ray, int recursive)
+Color castRay(Ray ray, int recursive, double &dst)
{
- //ii indicates the index of the current object
- int ii = 0;
//Was there an intersection?
bool intersect = false;
//Is this object receiving light?
@@ -102,6 +103,9 @@ Color castRay(Ray ray, int recursive)
//Pointer to the interseted object
Object *o;
+
+ //Variable use to calculate the beers law;
+ double dist;
//Gets the minimum intersection
//T2 is used in shadow calculation
@@ -116,21 +120,20 @@ Color castRay(Ray ray, int recursive)
{
mint = t;
intersect = true;
- ii = i;
+ o = objects[i];
}
}
//There wasn´t any intersection, we return the background color
if(!intersect)
return c;
-
- //Intersected object
- o = objects[ii];
//Point of intersection
Vector3 p = ray.getPoint(mint);
+ //Distance of intersection
+ dst = mint;
//Normal of the object at the specified point (used in upcoming calculations)
- Vector3 n = o->getNorm(p);
+ Vector3 norm = o->getNorm(p);
//Global ambient calculation, ga = Global ambient, oa = Object ambient
Color ga = gAmbient;
@@ -140,14 +143,15 @@ Color castRay(Ray ray, int recursive)
//Local ilumination model, for each light source
for(int i = 0; i < lights.size(); ++i, shadow = false)
{
+ Vector3 d = (lights[i].pos - p).normalize();
//Ray from the intersection point towards the light source
- Ray ray2(p, lights[i].pos);
+ Ray ray2(p + d*eps, lights[i].pos);
//Now check if this object is receiving light
//t value where the light source is
double tt = ray2.getT(lights[i].pos);
for(int j = 0; !shadow && j < objects.size(); ++j)
{
- if(ii != j)t2 = objects[j]->rayIntersection(ray2);
+ t2 = objects[j]->rayIntersection(ray2);
//The object is in shadows
if(t2 > 0 && t2 <= tt)
shadow = true;
@@ -163,7 +167,7 @@ Color castRay(Ray ray, int recursive)
Color od = (o->hasTex())?o->getColor(p):o->getMat().color*o->getMat().diff;
//dot is the dot product between the normal and the ray
- double dot = n.dot(ray2.getDir());
+ double dot = norm.dot(ray2.getDir());
//double att = 100/(light.pos - p).magnitudeSquared();
double att = 1.0;
if(dot > 0)
@@ -173,7 +177,7 @@ Color castRay(Ray ray, int recursive)
Color ls = lights[i].specular;
Vector3 v = ray.getDir();
Vector3 l = ray2.getDir();
- Vector3 r = l - n*2*l.dot(n);
+ Vector3 r = l - norm*2*l.dot(norm);
double k = v.dot(r);
if(k > 0)
c = c + ls*pow(k, 20.0)*o->getMat().spec;
@@ -185,30 +189,68 @@ Color castRay(Ray ray, int recursive)
double refl = o->getMat().refl;
if(recursive < MAX_RECURSION && refl > 0.01)
{
- Vector3 dir2 = ray.getDir() - n*2*(ray.getDir().dot(n));
+ Vector3 dir2 = (ray.getDir() - norm*2*(ray.getDir().dot(norm))).normalize();
Vector3 dest = p+dir2;
- Ray ray3(p, dest);
- c2 = castRay(ray3, recursive+1);
+ Ray ray3(p + dir2*eps, dest);
+ c2 = castRay(ray3, recursive+1, dist);
}
//Calculates the refraction color
double refr = o->getMat().refr;
if(recursive < MAX_RECURSION && refr > 0.01)
{
+ double index = 1.0;
+ bool internal = false;
+ //Check if the ray is inside the object
+ if(o->isInside(ray.getOrigin()))internal = true;
+
+ double rIndex = o->getMat().rIndex;
+ double n = index/rIndex;
+ if(internal)n = 1.0/n;
+
+ double cosI;
+ if(internal)cosI = (-norm).dot(ray.getDir());
+ else cosI = (norm).dot(ray.getDir());
+ double sinT2 = n*n*(1.0 - cosI * cosI);
+
+ Vector3 dir3;
+ //Total internal reflection
+ if(sinT2 > 1.0)
+ {
+ dir3 = ray.getDir() - (-norm)*2*cosI;
+ }
+ else
+ {
+ if(internal)
+ dir3 = ray.getDir()*n - (-norm)*(n*cosI + sqrt(1.0 - sinT2));
+ else
+ dir3 = ray.getDir()*n - norm*(n*cosI + sqrt(1.0 - sinT2));
+ }
+
+ Vector3 dest2 = p+dir3;
+ Ray ray4(p+dir3*eps, dest2);
+ c3 = castRay(ray4, recursive+1, dist);
+ //Apply beer's law
+ if(!internal)
+ c3 = c3*exp(-dist*0.075);
+
}
//Adds the three colors together
- c = c+c2*refl;
+ c = c+c2*refl+c3*refr;
return c;
}
void draw()
{
+ //The scene doesn't need to be redrawn
+ if(!redraw)return;
+
glClear(GL_COLOR_BUFFER_BIT);
//Camera calculation
posv = Vector3(0.0, 0.0, 10.0);
double h = 10*tan(3.1415926536/8);
- double w = h*800/600;
+ double w = h*width/height;
minv = Vector3(-w, -h, 0);
maxv = Vector3(w, h, 0);
@@ -219,7 +261,8 @@ void draw()
for(int j = 0; j < width; ++j)
{
Ray ray(posv, minv + Vector3(2*w*j/width, 2*h*i/height, 0));
- pixels[i*800 + j] = castRay(ray, 1);
+ double dist;
+ pixels[i*width + j] = castRay(ray, 1, dist);
//Slow but cooler method
/*Color c = castRay(ray, 1);;
float as[3] = {c.r, c.g, c.b};
@@ -229,6 +272,8 @@ void draw()
}
glDrawPixels(width,height,GL_RGB,GL_FLOAT,pixels);
glutSwapBuffers();
+
+ redraw = false;
}
/*
@@ -252,6 +297,8 @@ void resize(int w, int h)
gluOrtho2D(0.0,(GLfloat)width, 0.0,(GLfloat)height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
+
+ redraw = true;
}
/*
@@ -266,15 +313,13 @@ void init()
//SET 1
//Add some spheres
objects.push_back(new Sphere(1, Vector3(-3, -4, -11),
- Material(Color(1.0,0,0), 0.8, 0.8, 0.2, 0.5, 1.2)));
- objects.push_back(new Sphere(1.3, Vector3(5, -3, -13),
- Material(Color(0,0,1.0), 0.7, 0.75, 0.4, 0.5, 1.2)));
- objects.push_back(new Sphere(0.7, Vector3(0, -4.2, -7),
- Material(Color(0,1.0,0.0), 0.5, 0.6, 0.7, 0.5, 1.2)));
+ Material(Color(1.0,0,0), 0.95, 0.8, 0.05, 0.0, 1.2)));
+ objects.push_back(new Sphere(1.1, Vector3(-1.2, -3.5, -7),
+ Material(Color(0,0,1.0), 0.0, 0.3x, 0.0, 1.0, 1.51714)));
objects.push_back(new Sphere(0.8, Vector3(0, -1, -9),
- Material(Color(1.0,1.0,0.0), 0.4, 0.7, 0.8, 0.5, 1.2)));
+ Material(Color(1.0,1.0,0.0), 0.4, 0.7, 0.8, 0.0, 1.2)));
objects.push_back(new Sphere(0.8, Vector3(2, -4.2, -11),
- Material(Color(1.0,1.0,1.0), 0.0, 0.1, 1, 0.5, 1.2)));
+ Material(Color(1.0,1.0,1.0), 0.0, 0.1, 1, 0.0, 1.2)));
//Add a wall
@@ -289,6 +334,7 @@ void init()
objects.push_back(new Wall(Vector3(-7.5f, -5.0f, -18.0f), Vector3(-7.5f, 5.0f, -5.0f),
Vector3(-7.5f, 5.0f, -18.0f),
Material(Color(0.3,0.3,0.7), 0.7, 0.4, 0.6, 0.5, 1.2)));
+
//Lights, and global ambient
lights.push_back(Light(Vector3(-5, 3.0, 2.0), Color(0.0, 0.0, 0.0), Color(0.6f, 0.6f, 0.6f), Color(0.7f, 0.7f, 0.7f), GLOBAL));
@@ -322,10 +368,10 @@ int main(int argc, char *argv[])
glutCreateWindow("Ray Tracer");
- //Reshape not working
- //glutReshapeFunc(resize);
-
+ //Reshape and draw
+ glutReshapeFunc(resize);
glutDisplayFunc(draw);
+
//Keyboard Functions
glutKeyboardFunc(keyDown);
glutSpecialFunc(keySDown);
@@ -335,6 +381,7 @@ int main(int argc, char *argv[])
//glutIdleFunc(idle);
initGl();
init();
+
glutMainLoop();
return 0;
View
BIN main.o
Binary file not shown.
View
2 math/Vector3.h
@@ -4,7 +4,7 @@
#include <iostream>
#include <math.h>
-const double eps = 1e-7;
+const double eps = 1e-9;
class Vector3
{
View
1 objects/Object.h
@@ -39,6 +39,7 @@ class Object
Object(Vector3 pos, Material mat, Texture tex, bool emmit=false);
virtual double rayIntersection(Ray ray)=0;
virtual Vector3 getNorm(Vector3 p)=0;
+ virtual bool isInside(Vector3 point)=0;
//texture
Texture getTex(void);
View
6 objects/Sphere.cpp
@@ -40,6 +40,12 @@ double Sphere::rayIntersection(Ray ray)
return (t1 < t2)?t1:t2;
}
+bool Sphere::isInside(Vector3 point)
+{
+ double dist = (point - pos).magnitudeSquared();
+ return (dist <= r*r);
+}
+
/* Getters */
Vector3 Sphere::getNorm(Vector3 p)
{
View
3 objects/Sphere.h
@@ -18,6 +18,9 @@ class Sphere :public Object
//Ray intersection
double rayIntersection(Ray ray);
+ //Is the point inside
+ bool isInside(Vector3 point);
+
//Getters
Vector3 getNorm(Vector3 p);
double getR(void);
View
BIN objects/Sphere.o
Binary file not shown.
View
6 objects/Wall.cpp
@@ -48,6 +48,12 @@ Vector3 Wall::getNorm(Vector3 p)
return n;
}
+//Is the point inside
+bool Wall::isInside(Vector3 point)
+{
+ return false;
+}
+
/* Gets the color in the specified object point
* Used for textures only
*/
View
3 objects/Wall.h
@@ -17,6 +17,9 @@ class Wall :public Object
Wall(Vector3 min, Vector3 max, Vector3 other, Material mat, bool emmit=false);
Wall(Vector3 min, Vector3 max, Vector3 other, Material mat, Texture tex, bool emit=false);
+ //Is the point inside
+ bool isInside(Vector3 point);
+
//Getters
Vector3 getNorm(Vector3 p);
Vector3 getMin(void);
View
BIN objects/Wall.o
Binary file not shown.

0 comments on commit e01d8af

Please sign in to comment.