Finally! We have reflections!

This commit is contained in:
Godzil
2020-02-21 17:21:06 +00:00
parent 9fffb68026
commit 7337ae4837
9 changed files with 174 additions and 12 deletions

View File

@@ -16,8 +16,10 @@ class Shape;
struct Computation
{
Computation(Shape *object, double t, Tuple point, Tuple eyev, Tuple normalv, Tuple overHitP, bool inside) :
object(object), t(t), hitPoint(point), eyeVector(eyev), normalVector(normalv), inside(inside), overHitPoint(overHitP) { };
Computation(Shape *object, double t, Tuple point, Tuple eyev, Tuple normalv, Tuple overHitP,
bool inside, Tuple reflectV = Vector(0, 0, 0)) :
object(object), t(t), hitPoint(point), eyeVector(eyev), normalVector(normalv), inside(inside),
overHitPoint(overHitP), reflectVector(reflectV) { };
Shape *object;
double t;
@@ -25,6 +27,7 @@ struct Computation
Tuple overHitPoint;
Tuple eyeVector;
Tuple normalVector;
Tuple reflectVector;
bool inside;
};

View File

@@ -24,11 +24,12 @@ public:
double diffuse;
double specular;
double shininess;
double reflective;
Pattern *pattern;
public:
Material() : colour(Colour(1, 1, 1)), ambient(0.1), diffuse(0.9), specular(0.9), shininess(200), pattern(nullptr) {};
Material() : colour(Colour(1, 1, 1)), ambient(0.1), diffuse(0.9), specular(0.9), shininess(200), reflective(0.0), pattern(nullptr) {};
Colour lighting(Light light, Tuple point, Tuple eyeVector, Tuple normalVector, Shape *hitObject, bool inShadow = false);

View File

@@ -40,11 +40,14 @@ public:
bool objectIsIn(Shape &s);
Shape *getObject(int i) { return this->objectList[i]; };
Light *getLight(int i) { return this->lightList[i]; };
Tuple shadeHit(Computation comps);;
Tuple colourAt(Ray r);
Tuple shadeHit(Computation comps, uint32_t depthCount = 4);
Tuple colourAt(Ray r, uint32_t depthCount = 4);
bool isShadowed(Tuple point);
Colour reflectColour(Computation comps, uint32_t depthCount = 4);
Intersect intersect(Ray r);
};

View File

@@ -23,6 +23,7 @@ Computation Intersection::prepareComputation(Ray r)
}
Tuple overHitP = hitP + normalV * getEpsilon();
Tuple reflectV = r.direction.reflect(normalV);
return Computation(this->object,
this->t,
@@ -30,5 +31,6 @@ Computation Intersection::prepareComputation(Ray r)
eyeV,
normalV,
overHitP,
inside);
inside,
reflectV);
}

View File

@@ -92,17 +92,21 @@ Intersect World::intersect(Ray r)
return ret;
}
Tuple World::shadeHit(Computation comps)
Tuple World::shadeHit(Computation comps, uint32_t depthCount)
{
/* TODO: Add support for more than one light */
bool isThereAnObstacle = this->isShadowed(comps.overHitPoint);
return comps.object->material.lighting(*this->lightList[0], comps.overHitPoint, comps.eyeVector,
Tuple surface = comps.object->material.lighting(*this->lightList[0], comps.overHitPoint, comps.eyeVector,
comps.normalVector, comps.object, isThereAnObstacle);
Tuple reflected = this->reflectColour(comps, depthCount);
return surface + reflected;
}
Tuple World::colourAt(Ray r)
Tuple World::colourAt(Ray r, uint32_t depthCount)
{
Intersection hit = this->intersect(r).hit();
@@ -112,7 +116,7 @@ Tuple World::colourAt(Ray r)
}
else
{
return this->shadeHit(hit.prepareComputation(r));
return this->shadeHit(hit.prepareComputation(r), depthCount);
}
}
@@ -134,3 +138,21 @@ bool World::isShadowed(Tuple point)
return false;
}
Colour World::reflectColour(Computation comps, uint32_t depthCount)
{
if ((depthCount == 0) || (comps.object->material.reflective == 0))
{
return Colour(0, 0, 0);
}
/* So it is reflective, even just a bit. Let'sr reflect the ray! */
Ray reflectedRay = Ray(comps.overHitPoint, comps.reflectVector);
Tuple hitColour = this->colourAt(reflectedRay, depthCount - 1);
hitColour = hitColour * comps.object->material.reflective;
return Colour(hitColour.x, hitColour.y, hitColour.z);
}