Refraction seems to work. Still need to do a nice scene.

This commit is contained in:
Godzil
2020-02-21 22:50:12 +00:00
parent df52cb36db
commit 3db0aaaeac
9 changed files with 274 additions and 16 deletions

View File

@@ -18,14 +18,16 @@ 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), double n1 = 1.0, double n2 = 1.0) :
bool inside, Tuple reflectV = Vector(0, 0, 0), double n1 = 1.0, double n2 = 1.0,
Tuple underHitP = Point(0, 0, 0)) :
object(object), t(t), hitPoint(point), eyeVector(eyev), normalVector(normalv), inside(inside),
overHitPoint(overHitP), reflectVector(reflectV), n1(n1), n2(n2) { };
overHitPoint(overHitP), underHitPoint(underHitP), reflectVector(reflectV), n1(n1), n2(n2) { };
Shape *object;
double t;
Tuple hitPoint;
Tuple overHitPoint;
Tuple underHitPoint;
Tuple eyeVector;
Tuple normalVector;
Tuple reflectVector;

View File

@@ -44,13 +44,31 @@ public:
{
ChainList *p = this->head;
if (p == nullptr) { return; }
if ((p->next == nullptr) && (p->shape == s))
{
/* First element */
this->tail = nullptr;
free(this->head);
this->head = nullptr;
this->count = 0;
return;
}
while(p->next != nullptr)
{
if (p->next->shape == s)
{
this->count --;
ChainList *found = p->next;
p->next = p->next->next;
free(p->next);
free(found);
if (p->next == NULL) { this->tail = p; }
this->count --;
return;
}
p = p->next;
@@ -64,10 +82,10 @@ public:
theNew->shape = s;
ChainList *p = this->tail;
tail = theNew;
this->tail = theNew;
if (p != nullptr) { p->next = theNew; }
else { head = theNew; } /* If the tail is empty, it mean the list IS empty. */
else { this->head = theNew; } /* If the tail is empty, it mean the list IS empty. */
this->count ++;
}

View File

@@ -47,6 +47,7 @@ public:
bool isShadowed(Tuple point);
Colour reflectColour(Computation comps, uint32_t depthCount = 4);
Colour refractedColour(Computation comps, uint32_t depthCount = 0);
Intersect intersect(Ray r);

View File

@@ -27,18 +27,18 @@ Computation Intersection::prepareComputation(Ray r, Intersect *xs)
}
Tuple overHitP = hitP + normalV * getEpsilon();
Tuple underHitP = 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 (*this == i)
{
if (!containers.isEmpty())
{
@@ -55,12 +55,11 @@ Computation Intersection::prepareComputation(Ray r, Intersect *xs)
containers.append(i.object);
}
if (hit == i)
if (*this == i)
{
if (!containers.isEmpty())
{
Shape *cur = containers.last();
n2 = cur->material.refractiveIndex;
n2 = containers.last()->material.refractiveIndex;
}
/* End the loop */
@@ -78,5 +77,6 @@ Computation Intersection::prepareComputation(Ray r, Intersect *xs)
inside,
reflectV,
n1,
n2);
n2,
underHitP);
}

View File

@@ -102,8 +102,9 @@ Tuple World::shadeHit(Computation comps, uint32_t depthCount)
comps.normalVector, comps.object, isThereAnObstacle);
Tuple reflected = this->reflectColour(comps, depthCount);
Tuple refracted = this->refractedColour(comps, depthCount);
return surface + reflected;
return surface + reflected + refracted;
}
Tuple World::colourAt(Ray r, uint32_t depthCount)
@@ -156,4 +157,24 @@ Colour World::reflectColour(Computation comps, uint32_t depthCount)
return Colour(hitColour.x, hitColour.y, hitColour.z);
}
Colour World::refractedColour(Computation comps, uint32_t depthCount)
{
double nRatio = comps.n1 / comps.n2;
double cos_i = comps.eyeVector.dot(comps.normalVector);
double sin2_t = (nRatio*nRatio) * (1 - cos_i * cos_i);
if ((sin2_t > 1 ) || (depthCount == 0) || (comps.object->material.transparency == 0))
{
return Colour(0, 0, 0);
}
double cos_t = sqrt(1.0 - sin2_t);
Tuple direction = comps.normalVector * (nRatio * cos_i - cos_t) - comps.eyeVector * nRatio;
Ray refractedRay = Ray(comps.underHitPoint, direction);
Tuple hitColour = this->colourAt(refractedRay, depthCount - 1) * comps.object->material.transparency;
return Colour(hitColour.x, hitColour.y, hitColour.z);
}