BVH Cleanup / Changes.

Working on fixing issues with the BVH implementation.
Commiting a working changes version. Code has been cleaned up considerably.
A proper code review is nessacary in the near future.
main
Brett 2022-11-13 13:03:48 -05:00
parent 9e533a86f6
commit 7a09800c40
29 changed files with 275 additions and 262 deletions

View File

@ -2,42 +2,27 @@
374 3235 1668323538168825062 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_tables.cpp.o f6dab204e07e8dcf
2 2022 1668323499583713805 CMakeFiles/Step_3.dir/src/graphics/gl/gl.c.o 30ab06816e8637c1
4 3390 1668323512856096078 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_demo.cpp.o 7798aba97da63e31
3 2621 1668323537552807322 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 6470df278966c4
2 1153 1668323498715688802 CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o d86a254d2bce8f74
2 8763 1668323543696984256 CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o 1c68ba16e6b4d09b
2 871 1668323498431680622 CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o 9493619f74acd06a
2 1840 1668361409895046083 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 6470df278966c4
1 1716 1668360835926339635 CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o d86a254d2bce8f74
1 7565 1668362431984323343 CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o 1c68ba16e6b4d09b
2 1499 1668360835706333174 CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o 9493619f74acd06a
4 605 1668323535536749264 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_x11.cpp.o d1e9a2fcb31e2ec8
0 26 1668323688289146536 build.ninja ccb5de0c063412ab
1 920 1668323498479682005 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o 4ef77d2224f86511
2 1403 1668323536336772303 CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o 39e9f435096d066b
3 2335 1668323537268799144 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o 164394d360c43072
0 26 1668358519550031316 build.ninja ccb5de0c063412ab
1 1621 1668360835826336698 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o 4ef77d2224f86511
1 1405 1668362425824144748 CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o 39e9f435096d066b
2 1712 1668362494026122707 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o 164394d360c43072
3 6633 1668323516100189511 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui.cpp.o 55e7538fd27b47be
8763 8835 1668323543768986328 Step_3 f055ce2b85635598
2268 2354 1668361410407060406 Step_3 f055ce2b85635598
4 521 1668323535452746847 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_glfw.cpp.o 6aef9db88eb3d76d
2 2720 1668323537648810087 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 11f0e227e9fda9ca
605 1795 1668323536728783593 CMakeFiles/Step_3.dir/src/graphics/input.cpp.o 510001b0955ab019
2 2015 1668362494330131524 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 11f0e227e9fda9ca
1499 2524 1668360836734363373 CMakeFiles/Step_3.dir/src/graphics/input.cpp.o 510001b0955ab019
5 4715 1668323514180134213 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_draw.cpp.o f89fa3d7b779872a
521 6249 1668323541180911801 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_widgets.cpp.o 84017388bc7af144
3 2248 1668323537180796610 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
3 2124 1668323537056793038 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
2 1830 1668362494146126186 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
2 1624 1668362426044151124 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
4 374 1668323535308742700 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_opengl3.cpp.o 1b5f0fbe3cf8ce4e
3 2080 1668323537012791771 CMakeFiles/Step_3.dir/src/graphics/gl/shader.cpp.o 2553d57dba16057b
2 3101 1668323538032821145 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
2 1369 1668323498931695025 CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o 1007c86c207ac940
1 1102 1668324071584170088 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
1 1373 1668324071856177907 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
1374 1444 1668324071924179862 Step_3 f055ce2b85635598
1 1083 1668324105033131597 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
1083 1160 1668324105109133783 Step_3 f055ce2b85635598
1 1080 1668324205980033050 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
1 1310 1668324206208039601 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
1310 1378 1668324206276041556 Step_3 f055ce2b85635598
1 1298 1668324222400504969 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
1298 1369 1668324222472507037 Step_3 f055ce2b85635598
1 1075 1668324349212149162 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
1 1305 1668324349440155714 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
1305 1374 1668324349508157669 Step_3 f055ce2b85635598
1 1177 1668326424977049673 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
1 1405 1668326425205056279 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
1 1911 1668326425713070995 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
1912 2024 1668326425821074124 Step_3 f055ce2b85635598
2 1617 1668362426036150892 CMakeFiles/Step_3.dir/src/graphics/gl/shader.cpp.o 2553d57dba16057b
1 2419 1668362494734143245 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
2 2242 1668360836450355031 CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o 1007c86c207ac940
2 1579 1668362569316307713 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 6470df278966c4
1579 1704 1668362569440311315 Step_3 f055ce2b85635598

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 KiB

Binary file not shown.

View File

@ -1,3 +1,3 @@
Start testing: Nov 13 03:00 EST
Start testing: Nov 13 13:02 EST
----------------------------------------------------------
End testing: Nov 13 03:00 EST
End testing: Nov 13 13:02 EST

View File

@ -9,7 +9,7 @@ Size=550,680
Collapsed=1
[Window][Debug Menu]
Pos=28,35
Pos=26,34
Size=339,226
Collapsed=0

View File

@ -10,19 +10,30 @@
#include "engine/types.h"
#include <utility>
#include <cassert>
// A currently pure header implementation of a BVH. TODO: make source file.
// this is also for testing and might not make it into the step 2.
namespace Raytracing {
struct BVHObject {
Object* ptr = nullptr;
AABB aabb;
};
struct BVHPartitionedSpace {
std::vector<BVHObject> left;
std::vector<BVHObject> right;
};
struct BVHNode {
public:
std::vector<Object*> objs;
std::vector<BVHObject> objs;
AABB aabb;
BVHNode* left;
BVHNode* right;
BVHNode(std::vector<Object*> objs, AABB aabb, BVHNode* left, BVHNode* right): objs(std::move(objs)), aabb(std::move(aabb)),
BVHNode(std::vector<BVHObject> objs, AABB aabb, BVHNode* left, BVHNode* right): objs(std::move(objs)), aabb(std::move(aabb)),
left(left), right(right) {}
~BVHNode() {
delete (left);
@ -35,42 +46,30 @@ namespace Raytracing {
const int MAX_TREE_DEPTH = 50;
BVHNode* root = nullptr;
void del() {
// delete copied objects
for (auto* obj : root->objs)
delete(obj);
delete (root);
}
// splits the objs in the vector based on the provided AABBs
static std::pair<std::vector<Object*>, std::vector<Object*>>
partition(const std::pair<AABB, AABB>& aabbs, const std::vector<Object*>& objs) {
std::vector<Object*> a1;
std::vector<Object*> a2;
for (auto* obj: objs) {
static BVHPartitionedSpace partition(const std::pair<AABB, AABB>& aabbs, const std::vector<BVHObject>& objs) {
BVHPartitionedSpace space;
for (const auto& obj: objs) {
// if this object doesn't have an AABB, we cannot use a BVH on it
if (obj->getAABB().isEmpty()) {
throw std::runtime_error("Invalid AABB provided to the BVH! (Your implementation is flawed)");
// If this ever fails we have a problem with the implementation.
assert(obj.aabb.isEmpty());
if (obj.aabb.intersects(aabbs.first)) {
space.left.push_back(obj);
} else if (obj.aabb.intersects(aabbs.second)) {
space.right.push_back(obj);
}
if (obj->getAABB().intersects(aabbs.first)) {
a1.push_back(obj);
} else if (obj->getAABB().intersects(aabbs.second)) {
a2.push_back(obj);
}
//tlog << "OBJ: " << obj->getAABB() << " " << obj->getAABB().intersects(aabbs.first) << " " << obj->getAABB().intersects(aabbs.second) << " " << objs.size() << "\n";
}
//tlog << "we split into two of sizes: " << a1.size() << " " << a2.size() << " orig size: " << (a1.size() + a2.size()) << "\n";
return {a1, a2};
return space;
}
BVHNode* addObjectsRecur(const std::vector<Object*>& objects, unsigned long prevSize) {
BVHNode* addObjectsRecur(const std::vector<BVHObject>& objects, unsigned long prevSize) {
//ilog << "size: " << objects.size() << "\n";
// prevSize was required to solve some really weird bugs
// which are a TODO:
if ((objects.size() <= 2 && !objects.empty()) || prevSize == objects.size()) {
AABB local;
for (const auto& obj: objects)
local = local.expand(obj->getAABB());
local = local.expand(obj.aabb);
return new BVHNode(objects, local, nullptr, nullptr);
} else if (objects.empty()) // should never reach here!!
return nullptr;
@ -81,26 +80,24 @@ namespace Raytracing {
AABB world;
for (const auto& obj: objects) {
//tlog << obj->getAABB();
world = world.expand(obj->getAABB());
world = world.expand(obj.aabb);
}
//tlog << "\n";
// then split and partition the world
auto spltAABB = world.splitByLongestAxis();
//dlog << "We have " << world << " being split into: \n\t" << spltAABB.first << "\n\t" << spltAABB.second << "\n";
auto partitionedObjs = partition(spltAABB, objects);
auto splitAABBs = world.splitByLongestAxis();
auto partitionedObjs = partition(splitAABBs, objects);
BVHNode* left = nullptr;
BVHNode* right = nullptr;
// don't try to explore nodes which don't have anything in them.
if (!partitionedObjs.first.empty())
left = addObjectsRecur(partitionedObjs.first, objects.size());
if (!partitionedObjs.second.empty())
right = addObjectsRecur(partitionedObjs.second, objects.size());
if (!partitionedObjs.left.empty())
left = addObjectsRecur(partitionedObjs.left, objects.size());
if (!partitionedObjs.right.empty())
right = addObjectsRecur(partitionedObjs.right, objects.size());
return new BVHNode(objects, world, left, right);
}
static std::vector<Object*>
traverseFindRayIntersection(BVHNode* node, const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) {
static std::vector<BVHObject> traverseFindRayIntersection(BVHNode* node, const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) {
// check for intersections on both sides of the tree
if (node->left != nullptr) {
if (node->left->aabb.intersects(ray, min, max))
@ -125,30 +122,32 @@ namespace Raytracing {
void addObjects(const std::vector<Object*>& objects) {
if (root != nullptr)
del();
throw std::runtime_error("BVHTree already exists. What are you trying to do?");
// move all the object's aabb's into world position
std::vector<Object*> objs;
std::vector<BVHObject> objs;
for (auto* obj: objects) {
// we don't want to store all the AABBs which don't exist
// ie spheres
if (obj->getAABB().isEmpty()) {
//tlog << "Goodbye\n";
noAABBObjects.push_back(obj);
continue;
}
Object* objCopy = obj->clone();
objCopy->setAABB(obj->getAABB().translate(obj->getPosition()));
objs.push_back(objCopy);
BVHObject bvhObject;
// returns a copy of the AABB object and assigns it in to the tree storage object
bvhObject.aabb = obj->getAABB().translate(obj->getPosition());
// which means we don't have to do memory management, since we are using the pointer without ownership or coping now.
bvhObject.ptr = obj;
objs.push_back(bvhObject);
}
root = addObjectsRecur(objs, -1);
}
std::vector<Object*> rayIntersect(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) {
std::vector<BVHObject> rayIntersect(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) {
return traverseFindRayIntersection(root, ray, min, max);
}
~BVHTree() {
del();
delete (root);
}
};

View File

@ -14,11 +14,8 @@ namespace Raytracing {
protected:
Vec4 min;
Vec4 max;
bool empty = false;
public:
AABB() {
empty = true;
};
AABB(): min({0,0,0}), max({0,0,0}) {};
AABB(PRECISION_TYPE minX, PRECISION_TYPE minY, PRECISION_TYPE minZ, PRECISION_TYPE maxX, PRECISION_TYPE maxY, PRECISION_TYPE maxZ):
min{minX, minY, minZ}, max{maxX, maxY, maxZ} {
@ -100,7 +97,9 @@ namespace Raytracing {
[[nodiscard]] PRECISION_TYPE avgDistanceFromCenter() const;
[[nodiscard]] inline bool isEmpty() const { return empty; }
// Returns true if the min and max are equal, which tells us this AABB wasn't assigned
// or was properly created. Either way it isn't responsible to use the AABB in said case.
[[nodiscard]] inline bool isEmpty() const { return min == max; }
[[nodiscard]] Vec4 getMin() const { return min; }

View File

@ -392,6 +392,10 @@ namespace Raytracing {
return out << "Vec4{" << v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w() << "} ";
}
inline bool operator==(const Vec4& left, const Vec4& right) {
return left.x() == right.x() && left.y() == right.y() && left.z() == right.z() && left.w() == right.w();
}
class Ray {
private:
// the starting point for our ray

View File

@ -25,6 +25,8 @@
#include <algorithm>
#include <limits>
#include <random>
#include <cstdlib>
#include <memory>
/**
* defines
@ -47,33 +49,45 @@ const double EPSILON = 0.0000001;
/**
* classes
*/
static inline double degreeeToRadian(double deg){
return deg * PI/180.0;
static inline double degreeeToRadian(double deg) {
return deg * PI / 180.0;
}
namespace Raytracing {
class AlignedAllocator {
private:
public:
// not sure if this actually provides a performance benefit. Testing is inconclusive
template<typename T>
static T* allocateCacheAligned(int number = 1) {
void* allocatedSpace = aligned_alloc(64, sizeof(T) * number);
return new(allocatedSpace) T[number];
}
};
class Random {
private:
std::random_device rd; // obtain a random number from hardware
std::mt19937 gen;
std::uniform_real_distribution<double> doubleDistr {0, 1};
std::uniform_real_distribution<double> doubleDistr{0, 1};
public:
Random(): gen(std::mt19937(long(rd.entropy() * 691 * 691))) {}
Random(double min, double max): gen(std::mt19937(long(rd.entropy() * 691 * 691))), doubleDistr{min, max} {}
double getDouble(){
double getDouble() {
return doubleDistr(gen);
}
};
class String {
public:
static inline std::string toLowerCase(const std::string& s){
static inline std::string toLowerCase(const std::string& s) {
std::stringstream str;
std::for_each(s.begin(), s.end(), [&str](unsigned char ch) {
str << (char) std::tolower(ch);
});
return str.str();
}
static inline std::string toUpperCase(const std::string& s){
static inline std::string toUpperCase(const std::string& s) {
std::stringstream str;
std::for_each(s.begin(), s.end(), [&str](unsigned char ch) {
str << (char) std::toupper(ch);
@ -82,7 +96,7 @@ namespace Raytracing {
}
// taken from https://stackoverflow.com/questions/14265581/parse-split-a-string-in-c-using-string-delimiter-standard-c
// extended to return a vector
static inline std::vector<std::string> split(std::string s, const std::string& delim){
static inline std::vector<std::string> split(std::string s, const std::string& delim) {
size_t pos = 0;
std::vector<std::string> tokens;
while ((pos = s.find(delim)) != std::string::npos) {
@ -102,7 +116,7 @@ namespace Raytracing {
}));
return s;
}
// trim from end (in place)
static inline std::string& rtrim(std::string& s) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
@ -110,26 +124,26 @@ namespace Raytracing {
}).base(), s.end());
return s;
}
// trim from both ends (in place)
static inline std::string& trim(std::string& s) {
ltrim(s);
rtrim(s);
return s;
}
// trim from start (copying)
static inline std::string ltrim_copy(std::string s) {
ltrim(s);
return s;
}
// trim from end (copying)
static inline std::string rtrim_copy(std::string s) {
rtrim(s);
return s;
}
// trim from both ends (copying)
static inline std::string trim_copy(std::string s) {
trim(s);
@ -138,9 +152,9 @@ namespace Raytracing {
};
}
static Raytracing::Random rnd {};
static Raytracing::Random rnd{};
static inline double getRandomDouble(){
static inline double getRandomDouble() {
return rnd.getDouble();
}

View File

@ -14,6 +14,7 @@
#include <utility>
namespace Raytracing {
class SphereObject : public Object {
@ -114,14 +115,15 @@ namespace Raytracing {
* saving on computation
*/
// TODO: the above todo has been done, now we need to test the performance advantage of the BVH
BVHTree* bvhTree = nullptr;
std::unique_ptr<BVHTree> bvhObjects;
std::unordered_map<std::string, Material*> materials;
public:
World() = default;
World(const World& world) = delete;
World(const World&& world) = delete;
// call this after you've added all the objects to the world. (Called by the raycaster class)
// Called by the raytracer class after all objects have been added to the world
// this allows us to generate a statically unchanging BVH for easy rendering
void generateBVH();
inline void add(Object* object) { objects.push_back(object); }

View File

@ -12,24 +12,167 @@
#include <engine/image/image.h>
#include <config.h>
#include <graphics/gl/shader.h>
#ifndef USE_GLFW
#include <GLES3/gl32.h>
#include <GLES3/gl3.h>
#include <GL/gl.h>
#include "graphics/gl/glext.h"
extern PFNGLCREATEVERTEXARRAYSPROC glCreateVertexArrays;
extern PFNGLCREATEBUFFERSPROC glCreateBuffers;
extern PFNGLNAMEDBUFFERDATAPROC glNamedBufferData;
extern PFNGLNAMEDBUFFERSUBDATAPROC glNamedBufferSubData;
extern PFNGLENABLEVERTEXARRAYATTRIBPROC glEnableVertexArrayAttrib;
extern PFNGLVERTEXARRAYATTRIBBINDINGPROC glVertexArrayAttribBinding;
extern PFNGLVERTEXARRAYATTRIBFORMATPROC glVertexArrayAttribFormat;
extern PFNGLCREATEVERTEXARRAYSPROC glCreateVertexArrays;
extern PFNGLCREATEBUFFERSPROC glCreateBuffers;
extern PFNGLNAMEDBUFFERDATAPROC glNamedBufferData;
extern PFNGLNAMEDBUFFERSUBDATAPROC glNamedBufferSubData;
extern PFNGLENABLEVERTEXARRAYATTRIBPROC glEnableVertexArrayAttrib;
extern PFNGLVERTEXARRAYATTRIBBINDINGPROC glVertexArrayAttribBinding;
extern PFNGLVERTEXARRAYATTRIBFORMATPROC glVertexArrayAttribFormat;
#else
#include <graphics/gl/glad/gl.h>
#endif
class Shapes {
public:
struct cubeVertexBuilder {
std::vector<float> cubeVerticesRaw = {
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
};
std::vector<float> cubeUVs = {
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f
};
static cubeVertexBuilder getCubeExtends(float xRadius, float yRadius, float zRadius) {
cubeVertexBuilder builder {};
builder.cubeVerticesRaw = {
-0.5f, -0.5f, -zRadius,
0.5f, -0.5f, -zRadius,
0.5f, 0.5f, -zRadius,
0.5f, 0.5f, -zRadius,
-0.5f, 0.5f, -zRadius,
-0.5f, -0.5f, -zRadius,
-0.5f, -0.5f, zRadius,
0.5f, -0.5f, zRadius,
0.5f, 0.5f, zRadius,
0.5f, 0.5f, zRadius,
-0.5f, 0.5f, zRadius,
-0.5f, -0.5f, zRadius,
-xRadius, 0.5f, 0.5f,
-xRadius, 0.5f, -0.5f,
-xRadius, -0.5f, -0.5f,
-xRadius, -0.5f, -0.5f,
-xRadius, -0.5f, 0.5f,
-xRadius, 0.5f, 0.5f,
xRadius, 0.5f, 0.5f,
xRadius, 0.5f, -0.5f,
xRadius, -0.5f, -0.5f,
xRadius, -0.5f, -0.5f,
xRadius, -0.5f, 0.5f,
xRadius, 0.5f, 0.5f,
-0.5f, -yRadius, -0.5f,
0.5f, -yRadius, -0.5f,
0.5f, -yRadius, 0.5f,
0.5f, -yRadius, 0.5f,
-0.5f, -yRadius, 0.5f,
-0.5f, -yRadius, -0.5f,
-0.5f, yRadius, -0.5f,
0.5f, yRadius, -0.5f,
0.5f, yRadius, 0.5f,
0.5f, yRadius, 0.5f,
-0.5f, yRadius, 0.5f,
-0.5f, yRadius, -0.5f,
};
return builder;
}
};
};
// since we are doing everything with raytracing
// the purpose of these utility classes are purely for debug
// such as drawing bounding boxes around a BVH
@ -46,8 +189,8 @@ class Texture {
unsigned char* data;
public:
Texture(Texture &&) noexcept = delete; // Disable move constructor.
Texture& operator=(Texture &&) noexcept = delete; // Disable Move Assignment
Texture(Texture&&) noexcept = delete; // Disable move constructor.
Texture& operator=(Texture&&) noexcept = delete; // Disable Move Assignment
Texture();
explicit Texture(const std::string& path);
explicit Texture(Raytracing::Image* image);
@ -66,7 +209,7 @@ class VAO {
// vertex data
unsigned int storeData(int attrNumber, int coordSize, int stride, long offset, int length, const float* data);
// element data (indices)
unsigned int storeData(int length, const unsigned int *data);
unsigned int storeData(int length, const unsigned int* data);
// instance data
unsigned int createInstanceVBO(int count, int bytePerInstance);
// used much in the same way that store data sets an attribute where the data is expected
@ -78,10 +221,10 @@ class VAO {
VAO(const VAO& that); // Disable Copy Constructor
VAO& operator=(const VAO& that); // Disable Copy Assignment
public:
VAO(VAO &&) noexcept = delete; // Disable move constructor.
VAO& operator=(VAO &&) noexcept = delete; // Disable Move Assignment
VAO(VAO&&) noexcept = delete; // Disable move constructor.
VAO& operator=(VAO&&) noexcept = delete; // Disable Move Assignment
explicit VAO(const std::vector<Raytracing::Triangle> &triangles);
explicit VAO(const std::vector<Raytracing::Triangle>& triangles);
VAO(const std::vector<float>& verts, const std::vector<float>& uvs, const std::vector<unsigned int>& indices);
VAO(const std::vector<float>& verts, const std::vector<float>& uvs);

View File

@ -5,11 +5,15 @@ in vec2 outUv;
in vec3 outNormal;
uniform sampler2D tex;
uniform int useWhite;
const vec3 lightDir = vec3(1.0, 1.0, 1.0);
void main() {
vec4 textureColor = texture(tex, outUv);
//FragColor = vec4(textureColor.rgb, 1.0f);
FragColor = vec4(vec3(1.0, 0.0f, 0.0f) * dot(lightDir, outNormal), 1.0f);
if (useWhite == 0)
FragColor = vec4(vec3(1.0, 0.0f, 0.0f) * dot(lightDir, outNormal), 1.0f);
else
FragColor = vec4(1.0);
}

View File

@ -12,7 +12,7 @@ namespace Raytracing {
delete (p);
for (const auto& p: materials)
delete (p.second);
//delete(bvhTree);
//delete(bvhObjects);
}
HitData SphereObject::checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const {
@ -58,25 +58,25 @@ namespace Raytracing {
std::pair<HitData, Object*> World::checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const {
// actually speeds up rendering by about 110,000ms (total across 16 threads)
if (bvhTree != nullptr){
if (bvhObjects != nullptr){
auto hResult = HitData{false, Vec4(), Vec4(), max};
Object* objPtr = nullptr;
auto intersected = bvhTree->rayIntersect(ray, min, max);
auto intersected = bvhObjects->rayIntersect(ray, min, max);
//dlog << "Intersections " << intersected.size() << " " << ray << "\n";
for (auto* ptr : intersected) {
auto cResult = ptr->checkIfHit(ray, min, hResult.length);
for (const auto& ptr : intersected) {
auto cResult = ptr.ptr->checkIfHit(ray, min, hResult.length);
if (cResult.hit) {
hResult = cResult;
objPtr = ptr;
objPtr = ptr.ptr;
}
}
// after we check the BVH, we have to check for other missing objects
// since stuff like spheres currently don't have AABB and AABB isn't a requirement
// for the object class (to be assigned)
for (auto* obj: bvhTree->noAABBObjects) {
for (auto* obj: bvhObjects->noAABBObjects) {
// check up to the point of the last closest hit,
// will give the closest object's hit result
auto cResult = obj->checkIfHit(ray, min, hResult.length);
@ -105,7 +105,7 @@ namespace Raytracing {
}
void World::generateBVH() {
bvhTree = new BVHTree(objects);
bvhObjects = std::make_unique<BVHTree>(objects);
}
ScatterResults DiffuseMaterial::scatter(const Ray& ray, const HitData& hitData) const {

View File

@ -14,143 +14,6 @@ extern bool* haltRaytracing;
namespace Raytracing {
struct cubeVertexBuilder {
std::vector<float> cubeVerticesRaw = {
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
};
static cubeVertexBuilder getCubeExtends(float xRadius, float yRadius, float zRadius) {
cubeVertexBuilder builder;
builder.cubeVerticesRaw = {
-0.5f, -0.5f, -zRadius,
0.5f, -0.5f, -zRadius,
0.5f, 0.5f, -zRadius,
0.5f, 0.5f, -zRadius,
-0.5f, 0.5f, -zRadius,
-0.5f, -0.5f, -zRadius,
-0.5f, -0.5f, zRadius,
0.5f, -0.5f, zRadius,
0.5f, 0.5f, zRadius,
0.5f, 0.5f, zRadius,
-0.5f, 0.5f, zRadius,
-0.5f, -0.5f, zRadius,
-xRadius, 0.5f, 0.5f,
-xRadius, 0.5f, -0.5f,
-xRadius, -0.5f, -0.5f,
-xRadius, -0.5f, -0.5f,
-xRadius, -0.5f, 0.5f,
-xRadius, 0.5f, 0.5f,
xRadius, 0.5f, 0.5f,
xRadius, 0.5f, -0.5f,
xRadius, -0.5f, -0.5f,
xRadius, -0.5f, -0.5f,
xRadius, -0.5f, 0.5f,
xRadius, 0.5f, 0.5f,
-0.5f, -yRadius, -0.5f,
0.5f, -yRadius, -0.5f,
0.5f, -yRadius, 0.5f,
0.5f, -yRadius, 0.5f,
-0.5f, -yRadius, 0.5f,
-0.5f, -yRadius, -0.5f,
-0.5f, yRadius, -0.5f,
0.5f, yRadius, -0.5f,
0.5f, yRadius, 0.5f,
0.5f, yRadius, 0.5f,
-0.5f, yRadius, 0.5f,
-0.5f, yRadius, -0.5f,
};
return builder;
}
};
std::vector<float> cubeUVs = {
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f
};
const std::vector<float> vertices = {
1.0f, 1.0f, 0.0f, // top right
1.0f, -1.0f, 0.0f, // bottom right