Huge speed up by changing how Intersect are shared.

This commit is contained in:
Godzil
2020-03-12 00:11:26 +00:00
parent 0aa949c60b
commit b00bb75189
38 changed files with 116 additions and 153 deletions

View File

@@ -17,7 +17,7 @@
class Cone : public Shape {
protected:
Intersect localIntersect(Ray r);
void localIntersect(Ray r, Intersect &xs);
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);

View File

@@ -28,7 +28,7 @@ protected:
BoundingBox bounds;
protected:
Intersect localIntersect(Ray r);
void localIntersect(Ray r, Intersect &xs);
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
BoundingBox getLocalBounds();
@@ -42,7 +42,7 @@ protected:
public:
CSG(OperationType operation, Shape *left, Shape *right);
Intersect intersect(Ray r);
void intersect(Ray &r, Intersect &xs);
bool includes(Shape *b);

View File

@@ -19,7 +19,7 @@ class Cube : public Shape {
protected:
void checkAxis(double axeOrigin, double axeDirection, double *axeMin, double *axeMax);
Intersect localIntersect(Ray r);
void localIntersect(Ray r, Intersect &xs);
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);

View File

@@ -18,7 +18,7 @@
class Cylinder : public Shape {
protected:
Intersect localIntersect(Ray r);
void localIntersect(Ray r, Intersect &xs);
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);

View File

@@ -28,7 +28,7 @@ private:
char name[32 + 1];
protected:
Intersect localIntersect(Ray r);
void localIntersect(Ray r, Intersect &xs);
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
BoundingBox bounds;
@@ -43,7 +43,7 @@ public:
Shape *getObject(const int p) { return this->objectList[p]; };
Shape *getUnboxable(const int p) { return this->unboxableObjectList[p]; };
Intersect intersect(Ray r);
void intersect(Ray &r, Intersect &xs);
BoundingBox getLocalBounds();
BoundingBox getBounds();
@@ -59,6 +59,8 @@ public:
void lock();
void setBounds(BoundingBox &bb) { this->bounds | bb; };
const char *getName() { return this->name; };
void dumpMe(FILE * fp);

View File

@@ -31,7 +31,7 @@ private:
uint32_t vertexNormalCount;
private:
Intersect localIntersect(Ray r);
void localIntersect(Ray r, Intersect &xs);
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
public:
@@ -59,7 +59,7 @@ public:
Point vertices(uint32_t i) { return *this->vertexList[i - 1]; };
Vector verticesNormal(uint32_t i) { return *this->vertexNormalList[i - 1]; };
Group *groups(const char *groupName);
Intersect intersect(Ray r);
void intersect(Ray &r, Intersect &xs);
BoundingBox getLocalBounds();
BoundingBox getBounds();

View File

@@ -14,7 +14,7 @@
class Plane : public Shape
{
protected:
Intersect localIntersect(Ray r);
void localIntersect(Ray r, Intersect &xs);
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
public:

View File

@@ -44,7 +44,7 @@ protected:
bool locked;
protected:
virtual Intersect localIntersect(Ray r) = 0;
virtual void localIntersect(Ray r, Intersect &xs) = 0;
virtual Tuple localNormalAt(Tuple point, Intersection *hit) = 0;
public:
@@ -62,7 +62,7 @@ public:
ShapeType getType() { return this->type; };
virtual Intersect intersect(Ray r);
virtual void intersect(Ray &r, Intersect &xs);
Tuple normalAt(Tuple point, Intersection *hit = nullptr);
/* Bounding box points are always world value */
@@ -92,8 +92,8 @@ public:
void setTransform(Matrix transform);
void setMaterial(Material material) { this->material = material; this->materialSet = true; };
Ray transform(Ray r) { return Ray(this->transformMatrix * r.origin, this->transformMatrix * r.direction); };
Ray invTransform(Ray r) { return Ray(this->inverseTransform * r.origin, this->inverseTransform * r.direction); };
Ray transform(Ray &r) { return Ray(this->transformMatrix * r.origin, this->transformMatrix * r.direction); };
Ray invTransform(Ray &r) { return Ray(this->inverseTransform * r.origin, this->inverseTransform * r.direction); };
bool operator==(const Shape &b) const { return this->material == b.material &&
this->type == b.type &&

View File

@@ -18,7 +18,7 @@
class Sphere : public Shape
{
protected:
Intersect localIntersect(Ray r);
void localIntersect(Ray r, Intersect &xs);
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
public:

View File

@@ -16,7 +16,7 @@
class TestShape : public Shape
{
private:
Intersect localIntersect(Ray r);
void localIntersect(Ray r, Intersect &xs);
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
public:

View File

@@ -15,7 +15,7 @@
class Triangle : public Shape
{
protected:
Intersect localIntersect(Ray r);
void localIntersect(Ray r, Intersect &xs);
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
public:

View File

@@ -63,7 +63,7 @@ public:
Colour reflectColour(Computation comps, uint32_t depthCount = 4);
Colour refractedColour(Computation comps, uint32_t depthCount = 4);
Intersect intersect(Ray r);
void intersect(Ray &r, Intersect &xs);
void finalise(WorldOptimiser &opt);

View File

@@ -51,10 +51,8 @@ void Cone::intersectCaps(Ray r, Intersect &xs)
}
}
Intersect Cone::localIntersect(Ray r)
void Cone::localIntersect(Ray r, Intersect &xs)
{
Intersect ret;
double A = (r.direction.x * r.direction.x) -
(r.direction.y * r.direction.y) +
(r.direction.z * r.direction.z);
@@ -70,7 +68,7 @@ Intersect Cone::localIntersect(Ray r)
if ((fabs(A) <= getEpsilon()) && (fabs(B) >= getEpsilon()))
{
double t = -C / (2*B);
ret.add(Intersection(t, this));
xs.add(Intersection(t, this));
}
else if (fabs(A) >= getEpsilon())
{
@@ -83,20 +81,18 @@ Intersect Cone::localIntersect(Ray r)
double y0 = r.origin.y + t0 * r.direction.y;
if ((this->minCap < y0) && (y0 < this->maxCap))
{
ret.add(Intersection(t0, this));
xs.add(Intersection(t0, this));
}
double y1 = r.origin.y + t1 * r.direction.y;
if ((this->minCap < y1) && (y1 < this->maxCap))
{
ret.add(Intersection(t1, this));
xs.add(Intersection(t1, this));
}
}
}
this->intersectCaps(r, ret);
return ret;
this->intersectCaps(r, xs);
}
Tuple Cone::localNormalAt(Tuple point, Intersection *hit)

View File

@@ -24,31 +24,24 @@ CSG::CSG(OperationType operation, Shape *left, Shape *right) : Shape(Shape::CSG)
this->bounds | this->right->getBounds();
}
Intersect CSG::localIntersect(Ray r)
void CSG::localIntersect(Ray r, Intersect &xs)
{
return this->intersect(r);
this->intersect(r, xs);
}
Intersect CSG::intersect(Ray r)
void CSG::intersect(Ray &r, Intersect &xs)
{
int i;
Intersect ret = Intersect();
Intersect tmp = Intersect();
if (this->bounds.intesectMe(r))
{
Intersect leftxs = this->left->intersect(r);
Intersect rightxs = this->right->intersect(r);
this->left->intersect(r, tmp);
this->right->intersect(r, tmp);
for (i = 0 ; i < rightxs.count() ; i++)
{
leftxs.add(rightxs[i]);
}
this->filterIntersections(leftxs, ret);
this->filterIntersections(tmp, xs);
}
return ret;
}
Tuple CSG::localNormalAt(Tuple point, Intersection *hit)

View File

@@ -36,10 +36,8 @@ void Cube::checkAxis(double axeOrigin, double axeDirection, double *axeMin, doub
}
}
Intersect Cube::localIntersect(Ray r)
void Cube::localIntersect(Ray r, Intersect &xs)
{
Intersect ret;
double xtMin, xtMax, ytMin, ytMax, ztMin, ztMax;
double tMin, tMax;
@@ -52,11 +50,9 @@ Intersect Cube::localIntersect(Ray r)
if (tMin <= tMax)
{
ret.add(Intersection(tMin, this));
ret.add(Intersection(tMax, this));
xs.add(Intersection(tMin, this));
xs.add(Intersection(tMax, this));
}
return ret;
}
Tuple Cube::localNormalAt(Tuple point, Intersection *hit)

View File

@@ -51,10 +51,8 @@ void Cylinder::intersectCaps(Ray r, Intersect &xs)
}
}
Intersect Cylinder::localIntersect(Ray r)
void Cylinder::localIntersect(Ray r, Intersect &xs)
{
Intersect ret;
double A = r.direction.x * r.direction.x + r.direction.z * r.direction.z;
/* Ray is parallel to the Y axis */
@@ -74,20 +72,18 @@ Intersect Cylinder::localIntersect(Ray r)
double y0 = r.origin.y + t0 * r.direction.y;
if ((this->minCap < y0) && (y0 < this->maxCap))
{
ret.add(Intersection(t0, this));
xs.add(Intersection(t0, this));
}
double y1 = r.origin.y + t1 * r.direction.y;
if ((this->minCap < y1) && (y1 < this->maxCap))
{
ret.add(Intersection(t1, this));
xs.add(Intersection(t1, this));
}
}
}
this->intersectCaps(r, ret);
return ret;
this->intersectCaps(r, xs);
}
Tuple Cylinder::localNormalAt(Tuple point, Intersection *hit)

View File

@@ -36,9 +36,8 @@ Group::Group(const char *name) : Shape(Shape::GROUP)
}
}
Intersect Group::intersect(Ray r)
void Group::intersect(Ray &r, Intersect &xs)
{
Intersect ret;
int i, j;
if (this->objectCount > 0)
{
@@ -46,14 +45,7 @@ Intersect Group::intersect(Ray r)
{
for (i = 0 ; i < this->objectCount ; i++)
{
Intersect xs = this->objectList[i]->intersect(r);
if (xs.count() > 0)
{
for (j = 0 ; j < xs.count() ; j++)
{
ret.add(xs[j]);
}
}
this->objectList[i]->intersect(r, xs);
}
}
}
@@ -63,17 +55,9 @@ Intersect Group::intersect(Ray r)
{
for(i = 0; i < this->unboxableObjectCount; i++)
{
Intersect xs = this->unboxableObjectList[i]->intersect(r);
if (xs.count() > 0)
{
for(j = 0; j < xs.count(); j++)
{
ret.add(xs[j]);
}
}
this->unboxableObjectList[i]->intersect(r, xs);
}
}
return ret;
}
bool Group::includes(Shape *b)
@@ -104,9 +88,9 @@ bool Group::includes(Shape *b)
return false;
}
Intersect Group::localIntersect(Ray r)
void Group::localIntersect(Ray r, Intersect &xs)
{
return Intersect();
this->intersect(r, xs);
}
Tuple Group::localNormalAt(Tuple point, Intersection *hit)

View File

@@ -160,9 +160,9 @@ Group *OBJFile::groups(const char *groupName)
return nullptr;
}
Intersect OBJFile::intersect(Ray r)
void OBJFile::intersect(Ray &r, Intersect &xs)
{
return this->baseGroup->intersect(r);
this->baseGroup->intersect(r, xs);
}
bool OBJFile::includes(Shape *b)
@@ -170,9 +170,9 @@ bool OBJFile::includes(Shape *b)
return this->baseGroup->includes(b);
}
Intersect OBJFile::localIntersect(Ray r)
void OBJFile::localIntersect(Ray r, Intersect &xs)
{
return Intersect();
this->intersect(r, xs);
}
Tuple OBJFile::localNormalAt(Tuple point, Intersection *hit)

View File

@@ -12,22 +12,20 @@
#include <plane.h>
#include <math_helper.h>
Intersect Plane::localIntersect(Ray r)
void Plane::localIntersect(Ray r, Intersect &xs)
{
double t;
Intersect ret = Intersect();
if (fabs(r.direction.y) < getEpsilon())
{
/* With a direction == 0, the ray can't intersect the plane */
return ret;
}
else
{
t = -r.origin.y / r.direction.y;
t = -r.origin.y / r.direction.y;
ret.add(Intersection(t, this));
return ret;
xs.add(Intersection(t, this));
}
}
Tuple Plane::localNormalAt(Tuple point, Intersection *hit)

View File

@@ -25,9 +25,9 @@ Shape::Shape(ShapeType type)
this->updateTransform();
}
Intersect Shape::intersect(Ray r)
void Shape::intersect(Ray &r, Intersect &xs)
{
return this->localIntersect(this->invTransform(r));
this->localIntersect(this->invTransform(r), xs);
};
Tuple Shape::normalToWorld(Tuple normalVector)

View File

@@ -13,9 +13,8 @@
#include <tuple.h>
#include <intersect.h>
Intersect Sphere::localIntersect(Ray r)
void Sphere::localIntersect(Ray r, Intersect &xs)
{
Intersect ret;
double a, b, c, discriminant;
Tuple sphere_to_ray = r.origin - Point(0, 0, 0);
@@ -28,11 +27,9 @@ Intersect Sphere::localIntersect(Ray r)
if (discriminant >= 0)
{
ret.add(Intersection((-b - sqrt(discriminant)) / (2 * a), this));
ret.add(Intersection((-b + sqrt(discriminant)) / (2 * a), this));
xs.add(Intersection((-b - sqrt(discriminant)) / (2 * a), this));
xs.add(Intersection((-b + sqrt(discriminant)) / (2 * a), this));
}
return ret;
}
Tuple Sphere::localNormalAt(Tuple point, Intersection *hit)

View File

@@ -13,10 +13,9 @@ TestShape::TestShape() : localRay(Point(0, 0, 0), Vector(0, 0, 0))
{
}
Intersect TestShape::localIntersect(Ray r)
void TestShape::localIntersect(Ray r, Intersect &xs)
{
this->localRay = r;
return Intersect();
}
Tuple TestShape::localNormalAt(Tuple point, Intersection *hit)

View File

@@ -21,15 +21,13 @@ Triangle::Triangle(Point p1, Point p2, Point p3) : Shape(Shape::TRIANGLE), p1(p1
this->normal = e2.cross(e1).normalise();
}
Intersect Triangle::localIntersect(Ray r)
void Triangle::localIntersect(Ray r, Intersect &xs)
{
Intersect ret;
Tuple dirCrossE2 = r.direction.cross(this->e2);
double determinant = this->e1.dot(dirCrossE2);
if (fabs(determinant) < getEpsilon())
{
return ret;
return;
}
double f = 1.0 / determinant;
@@ -40,18 +38,16 @@ Intersect Triangle::localIntersect(Ray r)
if ((u < 0) || (u > 1))
{
return ret;
return;
}
if ((v < 0) || ((u + v) > 1))
{
return ret;
return;
}
double t = f * this->e2.dot(originCrossE1);
ret.add(Intersection(t, this, u, v));
return ret;
xs.add(Intersection(t, this, u, v));
}
Tuple Triangle::localNormalAt(Tuple point, Intersection *hit)

View File

@@ -75,9 +75,9 @@ bool World::objectIsIn(Shape &s)
return this->worldGroup.includes(&s);
}
Intersect World::intersect(Ray r)
void World::intersect(Ray &r, Intersect &xs)
{
return this->worldGroup.intersect(r);
this->worldGroup.intersect(r, xs);
}
Tuple World::shadeHit(Computation comps, uint32_t depthCount)
@@ -108,7 +108,8 @@ Tuple World::shadeHit(Computation comps, uint32_t depthCount)
Tuple World::colourAt(Ray r, uint32_t depthCount)
{
Intersect allHits = this->intersect(r);
Intersect allHits;
this->intersect(r, allHits);
Intersection hit = allHits.hit();
stats.setMaxDepth(depthCount);
@@ -131,7 +132,8 @@ bool World::isShadowed(Tuple point, Tuple lightPosition)
Ray r = Ray(point, direction);
stats.addLightRay();
Intersect xs = this->intersect(r);
Intersect xs;
this->intersect(r, xs);
int i;
for(i = 0; i < xs.count(); i++)