Skip to content

Commit

Permalink
Working on refraction & transparency.
Browse files Browse the repository at this point in the history
Lots of work left to do!
  • Loading branch information
Godzil committed Feb 21, 2020
1 parent 89dd74f commit df52cb3
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 9 deletions.
10 changes: 7 additions & 3 deletions source/include/intersection.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
#include <ray.h>

class Shape;
class Intersect;

struct Computation
{
Computation(Shape *object, double t, Tuple point, Tuple eyev, Tuple normalv, Tuple overHitP,
bool inside, Tuple reflectV = Vector(0, 0, 0)) :
bool inside, Tuple reflectV = Vector(0, 0, 0), double n1 = 1.0, double n2 = 1.0) :
object(object), t(t), hitPoint(point), eyeVector(eyev), normalVector(normalv), inside(inside),
overHitPoint(overHitP), reflectVector(reflectV) { };
overHitPoint(overHitP), reflectVector(reflectV), n1(n1), n2(n2) { };

Shape *object;
double t;
Expand All @@ -29,6 +30,9 @@ struct Computation
Tuple normalVector;
Tuple reflectVector;

double n1;
double n2;

bool inside;
};

Expand All @@ -42,7 +46,7 @@ class Intersection
Intersection(double t, Shape *object) : t(t), object(object) { };
bool nothing() { return (this->object == nullptr); };

Computation prepareComputation(Ray r);
Computation prepareComputation(Ray r, Intersect *xs = nullptr);

bool operator==(const Intersection &b) const { return ((this->t == b.t) && (this->object == b.object)); };
};
Expand Down
94 changes: 94 additions & 0 deletions source/include/list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* DoRayMe - a quick and dirty Raytracer
* List header
*
* Created by Manoël Trapier
* Copyright (c) 2020 986-Studio.
*
*/
#ifndef DORAYME_LIST_H
#define DORAYME_LIST_H

#include <shape.h>

struct ChainList
{
Shape *shape;
ChainList *next;
};

class List
{
private:
ChainList *head;
ChainList *tail;
uint32_t count;
public:
List() : head(nullptr), tail(nullptr), count(0) { };
~List()
{
ChainList *p = this->head;
if (p == nullptr) { return; }

/* clear up the list */
}

Shape *last()
{
ChainList *p = this->tail;
if (p == nullptr) { return nullptr; }
return p->shape;
}

void remove(Shape *s)
{
ChainList *p = this->head;
if (p == nullptr) { return; }
while(p->next != nullptr)
{
if (p->next->shape == s)
{
this->count --;
p->next = p->next->next;
free(p->next);
return;
}
p = p->next;
}
}

void append(Shape *s)
{
ChainList *theNew = (ChainList *)calloc(1, sizeof(ChainList));

theNew->shape = s;

ChainList *p = this->tail;
tail = theNew;

if (p != nullptr) { p->next = theNew; }
else { head = theNew; } /* If the tail is empty, it mean the list IS empty. */

this->count ++;
}

bool isEmpty()
{
return (this->count == 0);
}

bool doesInclude(Shape *s)
{
ChainList *p = this->head;

while(p != nullptr)
{
if (p->shape == s) { return true; }
p = p->next;
}

return false;
}
};

#endif //DORAYME_LIST_H
6 changes: 5 additions & 1 deletion source/include/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ class Material
double specular;
double shininess;
double reflective;
double transparency;
double refractiveIndex;

Pattern *pattern;

public:
Material() : colour(Colour(1, 1, 1)), ambient(0.1), diffuse(0.9), specular(0.9), shininess(200), reflective(0.0), pattern(nullptr) {};
Material() : colour(Colour(1, 1, 1)), ambient(0.1), diffuse(0.9), specular(0.9), shininess(200),
reflective(0.0), transparency(0.0), refractiveIndex(1.0), pattern(nullptr) {};

Colour lighting(Light light, Tuple point, Tuple eyeVector, Tuple normalVector, Shape *hitObject, bool inShadow = false);

Expand All @@ -40,4 +43,5 @@ class Material
(this->colour == b.colour); };
};


#endif /* DORAYME_MATERIAL_H */
7 changes: 7 additions & 0 deletions source/include/sphere.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,11 @@ class Sphere : public Shape
/* All sphere are at (0, 0, 0) and radius 1 in the object space */
};

/* Mostly for test purposes */
class GlassSphere : public Sphere
{
public:
GlassSphere() : Sphere() { this->material.transparency = 1.0; this->material.refractiveIndex = 1.5; };
};

#endif /* DORAYME_SPHERE_H */
50 changes: 48 additions & 2 deletions source/intersection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
*/
#include <intersection.h>
#include <shape.h>
#include <list.h>

Computation Intersection::prepareComputation(Ray r)
Computation Intersection::prepareComputation(Ray r, Intersect *xs)
{
double n1 = 1.0;
double n2 = 1.0;

Tuple hitP = r.position(this->t);
Tuple normalV = this->object->normalAt(hitP);
Tuple eyeV = -r.direction;
Expand All @@ -25,12 +29,54 @@ Computation Intersection::prepareComputation(Ray r)
Tuple overHitP = hitP + normalV * getEpsilon();
Tuple reflectV = r.direction.reflect(normalV);

if (xs != nullptr)
{
List containers;
int j, k;
Intersection hit = xs->hit();

for(j = 0; j < xs->count(); j++)
{
Intersection i = (*xs)[j];
if (hit == i)
{
if (!containers.isEmpty())
{
n1 = containers.last()->material.refractiveIndex;
}
}

if (containers.doesInclude(i.object))
{
containers.remove(i.object);
}
else
{
containers.append(i.object);
}

if (hit == i)
{
if (!containers.isEmpty())
{
Shape *cur = containers.last();
n2 = cur->material.refractiveIndex;
}

/* End the loop */
break;
}
}
}

return Computation(this->object,
this->t,
hitP,
eyeV,
normalV,
overHitP,
inside,
reflectV);
reflectV,
n1,
n2);
}
5 changes: 3 additions & 2 deletions source/world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,16 @@ Tuple World::shadeHit(Computation comps, uint32_t depthCount)

Tuple World::colourAt(Ray r, uint32_t depthCount)
{
Intersection hit = this->intersect(r).hit();
Intersect allHits = this->intersect(r);
Intersection hit = allHits.hit();

if (hit.nothing())
{
return Colour(0, 0, 0);
}
else
{
return this->shadeHit(hit.prepareComputation(r), depthCount);
return this->shadeHit(hit.prepareComputation(r, &allHits), depthCount);
}
}

Expand Down
39 changes: 38 additions & 1 deletion tests/intersect_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,41 @@ TEST(IntersectTest, Precomputing_the_reflection_vector)
Computation comps = i.prepareComputation(r);

ASSERT_EQ(comps.reflectVector, Vector(0, sqrt(2) / 2, sqrt(2) / 2));
}
}

TEST(IntersectTest, Finding_n1_and_n2_at_various_intersections)
{
#if 0
int i;
double n1_res[6] = { 1.0, 1.5, 2.0, 2.5, 2.5, 1.5 };
double n2_res[6] = { 1.5, 2.0, 2.5, 2.5, 1.5, 1.0 };

GlassSphere A = GlassSphere();
A.setTransform(scaling(2, 2, 2));
A.material.refractiveIndex = 1.5;

GlassSphere B = GlassSphere();
B.setTransform(translation(0, 0, -0.25));
B.material.refractiveIndex = 2.0;

GlassSphere C = GlassSphere();
C.setTransform(translation(0, 0, 0.25));
C.material.refractiveIndex = 2.5;

Ray r = Ray(Point(0, 0, -4), Vector(0, 0, 1));
Intersect xs = Intersect();
xs.add(Intersection(2.0, &A));
xs.add(Intersection(2.75, &B));
xs.add(Intersection(3.25, &C));
xs.add(Intersection(4.75, &B));
xs.add(Intersection(5.25, &C));
xs.add(Intersection(6, &A));

for(i = 0; i < xs.count(); i++)
{
Computation comps = xs[i].prepareComputation(r, &xs);
ASSERT_EQ(comps.n1, n1_res[i]);
ASSERT_EQ(comps.n2, n2_res[i]);
}
#endif
}
8 changes: 8 additions & 0 deletions tests/material_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,11 @@ TEST(MaterialTest, Reflectivity_for_the_default_material)

ASSERT_EQ(m.reflective, 0);
}

TEST(MaterialTest, Transparency_and_refractive_index_for_the_default_material)
{
Material m = Material();

ASSERT_EQ(m.transparency, 0.0);
ASSERT_EQ(m.refractiveIndex, 1.0);
}
9 changes: 9 additions & 0 deletions tests/sphere_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,13 @@ TEST(SphereTest, A_sphere_may_be_assigned_a_material)
s.setMaterial(m);

ASSERT_EQ(s.material, m);
}

TEST(SphereTest, A_helper_for_producing_a_sphere_with_a_glassy_material)
{
GlassSphere s = GlassSphere();

ASSERT_EQ(s.transformMatrix, Matrix4().identity());
ASSERT_EQ(s.material.transparency, 1.0);
ASSERT_EQ(s.material.refractiveIndex, 1.5);
}

0 comments on commit df52cb3

Please sign in to comment.