BVH performance results in ods file

main
Brett 2022-11-16 17:34:17 -05:00
parent e72fc15007
commit 7aea5ee8c4
23 changed files with 104 additions and 103 deletions

View File

@ -2,63 +2,33 @@
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
2 1991 1668626445150369433 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 6470df278966c4
3 2012 1668635891935220716 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 6470df278966c4
2 1641 1668366223598629532 CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o d86a254d2bce8f74
1 6863 1668489146695541389 CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o 1c68ba16e6b4d09b
2 1301 1668366223258619732 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 1668626511144238740 build.ninja ccb5de0c063412ab
1 1437 1668553279255395930 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o 4ef77d2224f86511
1 894 1668624669410339888 CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o 39e9f435096d066b
2 1674 1668626444830360386 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o 164394d360c43072
1 1106 1668635163369936484 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o 4ef77d2224f86511
1 1204 1668634560852374884 CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o 39e9f435096d066b
3 2024 1668635891947221067 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
2741 2809 1668626445966392496 Step_3 f055ce2b85635598
2052 2137 1668635966781408392 Step_3 9d5d6ad8db7a0552
4 521 1668323535452746847 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_glfw.cpp.o 6aef9db88eb3d76d
1 2086 1668626445246372145 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 11f0e227e9fda9ca
2 2328 1668635892251229953 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 11f0e227e9fda9ca
1 827 1668366742693637470 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
1 1446 1668635966093388282 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
521 6249 1668323541180911801 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_widgets.cpp.o 84017388bc7af144
2 1815 1668626444974364458 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
1 1651 1668553279471402444 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
2 1533 1668634561180384420 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
2 1655 1668489141487439674 CMakeFiles/Step_3.dir/src/graphics/gl/shader.cpp.o 2553d57dba16057b
1 2741 1668626445898390573 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
2 1769 1668635891691213584 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 7d05e3e63b85d471
1 2052 1668635966697405936 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
2 2095 1668366224050642556 CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o 1007c86c207ac940
1 1042 1668626620015338709 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 7d05e3e63b85d471
1 1549 1668626620523353215 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o 164394d360c43072
2 1681 1668626620655356986 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
1 1965 1668626620939365097 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 11f0e227e9fda9ca
1 2240 1668626621211372864 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 6470df278966c4
1 2932 1668626621903392627 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
2932 3003 1668626621975394684 Step_3 9d5d6ad8db7a0552
2 1428 1668628077489660064 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 7d05e3e63b85d471
2 1839 1668628077901672111 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o 164394d360c43072
2 1862 1668628077925672810 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
2 2040 1668628078101677955 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 6470df278966c4
2 2509 1668628078569691639 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 11f0e227e9fda9ca
1 3191 1668628079253711634 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
3191 3330 1668628079389715610 Step_3 9d5d6ad8db7a0552
1 1126 1668628304228306826 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 7d05e3e63b85d471
1126 1200 1668628304300309045 Step_3 9d5d6ad8db7a0552
1 1390 1668628319148766801 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
1390 1463 1668628319220769019 Step_3 9d5d6ad8db7a0552
1 1069 1668628428808130406 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 7d05e3e63b85d471
1069 1150 1668628428888132849 Step_3 9d5d6ad8db7a0552
1 1145 1668628493142091376 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 7d05e3e63b85d471
1145 1230 1668628493226093931 Step_3 9d5d6ad8db7a0552
1 1292 1668628542051576911 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 7d05e3e63b85d471
1293 1371 1668628542127579215 Step_3 9d5d6ad8db7a0552
1 1142 1668628564072244382 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 7d05e3e63b85d471
1142 1242 1668628564172247411 Step_3 9d5d6ad8db7a0552
1 1337 1668632607895588360 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 7d05e3e63b85d471
1337 1457 1668632608015591790 Step_3 9d5d6ad8db7a0552
2 1291 1668633243861949710 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o 4ef77d2224f86511
3 1424 1668633243993953547 CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o 39e9f435096d066b
3 1577 1668633244145957965 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
2 1588 1668633244157958315 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 7d05e3e63b85d471
3 1697 1668633244265961453 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o 164394d360c43072
2 1895 1668633269338690359 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 6470df278966c4
1 2359 1668633269802703851 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
1 2386 1668633269830704665 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 11f0e227e9fda9ca
1 1382 1668633279558987547 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
1382 1513 1668633279690991384 Step_3 9d5d6ad8db7a0552
1 1061 1668636253817799066 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o 4ef77d2224f86511
2 1114 1668636253869800588 CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o d86a254d2bce8f74
1 1946 1668636254701824910 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 11f0e227e9fda9ca
1 2024 1668636254781827250 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
2024 2092 1668636254845829121 Step_3 9d5d6ad8db7a0552
1 2159 1668636510057295808 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
2159 2281 1668636510177299347 Step_3 9d5d6ad8db7a0552

Binary file not shown.

View File

@ -1,3 +1,3 @@
Start testing: Nov 16 16:14 EST
Start testing: Nov 16 17:11 EST
----------------------------------------------------------
End testing: Nov 16 16:14 EST
End testing: Nov 16 17:11 EST

View File

@ -9,7 +9,7 @@ Size=550,680
Collapsed=1
[Window][Debug Menu]
Pos=36,38
Pos=33,27
Size=339,226
Collapsed=0

View File

@ -37,6 +37,20 @@ namespace Raytracing {
std::vector<BVHObject> right;
};
inline bool operator==(const BVHPartitionedSpace& left, const BVHPartitionedSpace& right) {
if (left.left.size() != right.left.size() || left.right.size() != right.right.size())
return false;
for (int i = 0; i < left.left.size(); i++){
if (left.left[i].aabb != right.left[i].aabb)
return false;
}
for (int i = 0; i < left.right.size(); i++){
if (left.right[i].aabb != right.right[i].aabb)
return false;
}
return true;
}
struct BVHNode {
public:
struct BVHHitData {
@ -65,10 +79,8 @@ namespace Raytracing {
private:
BVHNode* root = nullptr;
// splits the objs in the vector based on the provided AABBs
static BVHPartitionedSpace partition(const std::pair<AABB, AABB>& aabbs, const std::vector<BVHObject>& objs);
static bool vectorEquals(const BVHPartitionedSpace& oldSpace, const BVHPartitionedSpace& newSpace);
BVHNode* addObjectsRecur(const std::vector<BVHObject>& objects, const BVHPartitionedSpace& prevSpace);
BVHNode* addObjectsRecursively(const std::vector<BVHObject>& objects, const BVHPartitionedSpace& prevSpace);
public:
std::vector<Object*> noAABBObjects;
explicit BVHTree(const std::vector<Object*>& objectsInWorld) {

View File

@ -15,6 +15,10 @@ namespace Raytracing {
PRECISION_TYPE tMin, tMax;
};
enum AABBAxis {
X = 0, Y = 1, Z = 2
};
class AABB {
protected:
Vec4 min;
@ -105,7 +109,7 @@ namespace Raytracing {
[[nodiscard]] int longestAxis() const;
[[nodiscard]] PRECISION_TYPE longestAxisLength() const;
[[nodiscard]] std::pair<AABB, AABB> splitByLongestAxis();
[[nodiscard]] std::pair<AABB, AABB> splitAlongAxis();
[[nodiscard]] std::pair<AABB, AABB> splitAlongAxis(AABBAxis axis);
[[nodiscard]] PRECISION_TYPE avgDistanceFromCenter() const;

View File

@ -14,6 +14,7 @@
#include "std.h"
#include <config.h>
#include <mutex>
#ifdef COMPILE_GUI
#include <graphics/debug_gui.h>
#endif
@ -37,12 +38,15 @@ namespace Raytracing {
long _start = 0;
long _end = 0;
std::unordered_map<std::string, std::pair<long, long>> timings;
std::mutex timerLock {};
public:
explicit profiler(std::string name);
void start();
void start(const std::string& name);
static void start(const std::string& name, const std::string& tabName) {
static std::mutex staticLock{};
std::scoped_lock lock(staticLock);
if (profiles.contains(name)) {
auto p = profiles.at(name);
p->start(tabName);
@ -56,6 +60,8 @@ namespace Raytracing {
void end();
void end(const std::string& name);
static void end(const std::string& name, const std::string& tabName){
static std::mutex staticLock{};
std::scoped_lock lock(staticLock);
try {
profiles.at(name)->end(tabName);
} catch (std::exception& e){}
@ -63,6 +69,8 @@ namespace Raytracing {
void print();
static void print(const std::string& name){
static std::mutex staticLock{};
std::scoped_lock lock(staticLock);
try {
profiles.at(name)->print();
} catch (std::exception& e){}

View File

@ -23,7 +23,7 @@ namespace Raytracing {
PRECISION_TYPE radius;
public:
SphereObject(const Vec4& position, PRECISION_TYPE radius, Material* material): radius(radius), Object(material, position) {
// aabb = AABB(position.x(), position.y(), position.z(), radius);
//aabb = AABB(position.x(), position.y(), position.z(), radius);
}
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const;
@ -107,6 +107,11 @@ namespace Raytracing {
}
};
struct WorldConfig {
bool useBVH = true;
bool padding[7];
};
class World {
private:
// store all the objects in the world,
@ -118,8 +123,9 @@ namespace Raytracing {
// TODO: the above todo has been done, now we need to test the performance advantage of the BVH
std::unique_ptr<BVHTree> bvhObjects;
std::unordered_map<std::string, Material*> materials;
WorldConfig m_config;
public:
World() = default;
explicit World(WorldConfig config): m_config(config) {};
World(const World& world) = delete;
World(const World&& world) = delete;

View File

@ -4,6 +4,8 @@
*/
// Yes, globals are bad.
#include "engine/util/debug.h"
#include <config.h>
#ifdef COMPILE_GUI
#include <graphics/gl/gl.h>

View File

@ -105,7 +105,10 @@ int main(int argc, char** args) {
camera.setPosition({6, 5, 6});
camera.lookAt({0, 0, 0});
Raytracing::World world;
WorldConfig worldConfig;
worldConfig.useBVH = true;
Raytracing::World world {worldConfig};
Raytracing::OBJLoader loader;
// assumes you are running it from a subdirectory, "build" or "cmake-build-release", etc.
@ -133,10 +136,10 @@ int main(int argc, char** args) {
world.add(new Raytracing::ModelObject({0, 0, 5}, house, world.getMaterial("blueDiffuse")));*/
world.add(new Raytracing::ModelObject({0, 1, 0}, spider, world.getMaterial("redDiffuse")));
world.add(new Raytracing::ModelObject({-15, 0.5, 0}, plane, world.getMaterial("greenMetal")));
world.add(new Raytracing::ModelObject({15, 1, 0}, house, world.getMaterial("redDiffuse")));
world.add(new Raytracing::ModelObject({0, 0, -15}, house, world.getMaterial("blueDiffuse")));
world.add(new Raytracing::ModelObject({0, 0, 15}, house, world.getMaterial("blueDiffuse")));
world.add(new Raytracing::ModelObject({-5, 0.5, 0}, plane, world.getMaterial("greenMetal")));
world.add(new Raytracing::ModelObject({5, 1, 0}, house, world.getMaterial("redDiffuse")));
world.add(new Raytracing::ModelObject({0, 0, -5}, house, world.getMaterial("blueDiffuse")));
world.add(new Raytracing::ModelObject({0, 0, 5}, house, world.getMaterial("blueDiffuse")));
if (parser.hasOption("--gui") || parser.hasOption("-g")) {
#ifdef COMPILE_GUI

View File

@ -84,7 +84,7 @@ namespace Raytracing {
bvhObject.ptr = obj;
objs.push_back(bvhObject);
}
root = addObjectsRecur(objs, {});
root = addObjectsRecursively(objs, {});
}
/**
@ -152,52 +152,57 @@ namespace Raytracing {
}
return objects;
}
BVHNode* BVHTree::addObjectsRecur(const std::vector<BVHObject>& objects, const BVHPartitionedSpace& prevSpace) {
BVHNode* BVHTree::addObjectsRecursively(const std::vector<BVHObject>& objects, const BVHPartitionedSpace& prevSpace) {
// create a volume for the entire world.
// yes, we could use a recursion provided AABB, but that wouldn't be minimum, only half. this ensures that we have a minimum AABB.
AABB world;
for (const auto& obj: objects)
world = world.expand(obj.aabb);
// then split and partition the world
auto splitAABBs = world.splitByLongestAxis();
auto partitionedObjs = partition(splitAABBs, objects);
if (vectorEquals(prevSpace, partitionedObjs)){
splitAABBs = world.splitAlongAxis();
partitionedObjs = partition(splitAABBs, objects);
}
// if we have a single object then we can create a leaf.
if ((objects.size() <= 1 && !objects.empty())) {
return new BVHNode(objects, world, nullptr, nullptr);
} else if (objects.empty()) // should never reach here!!
return nullptr;
// then split and partition the world
auto splitAABBs = world.splitByLongestAxis();
auto partitionedObjs = partition(splitAABBs, objects);
if (prevSpace == partitionedObjs) {
// if we haven't made progress in splitting the world, try inverting the order we add objects first
partitionedObjs = partition({splitAABBs.second, splitAABBs.first}, objects);
// if we fail then try splitting on another axis
if (prevSpace == partitionedObjs) {
// try all axis
for (int i = 0; i < 3; i++){
splitAABBs = world.splitAlongAxis(i == 0 ? X : i == 1 ? Y : Z);
partitionedObjs = partition(splitAABBs, objects);
// and once we have an axis that works we can break.
if (prevSpace != partitionedObjs)
break;
}
}
}
// if we were unable to find a partition that isn't the same as our last, we should create a leaf here
// otherwise we'll get infinite recursion
if (prevSpace == partitionedObjs) {
return new BVHNode(objects, world, nullptr, nullptr);
}
BVHNode* left = nullptr;
BVHNode* right = nullptr;
// don't try to explore nodes which don't have anything in them.
if (!partitionedObjs.left.empty())
left = addObjectsRecur(partitionedObjs.left, partitionedObjs);
left = addObjectsRecursively(partitionedObjs.left, partitionedObjs);
if (!partitionedObjs.right.empty())
right = addObjectsRecur(partitionedObjs.right, partitionedObjs);
right = addObjectsRecursively(partitionedObjs.right, partitionedObjs);
if (left == nullptr && right == nullptr)
return new BVHNode(objects, world, left, right);
else
return new BVHNode({}, world, left, right);
}
bool BVHTree::vectorEquals(const BVHPartitionedSpace& oldSpace, const BVHPartitionedSpace& newSpace) {
if (oldSpace.left.size() != newSpace.left.size() || oldSpace.right.size() != newSpace.right.size())
return false;
for (int i = 0; i < oldSpace.left.size(); i++){
if (oldSpace.left[i].aabb != newSpace.left[i].aabb)
return false;
}
for (int i = 0; i < oldSpace.right.size(); i++){
if (oldSpace.right[i].aabb != newSpace.right[i].aabb)
return false;
}
return true;
}
}
/**

View File

@ -114,27 +114,16 @@ namespace Raytracing {
return simpleSlabRayAABBMethod(ray, tmin, tmax);
}
// I want this function to be somewhat deterministic
// Yet if this is being called divide and conquer isn't working.
// so we need a way of splitting the AABB to get different results
// preventing the plague of infinite recursion.
// this alternating of axis is like K-Trees? Pretty sure the algorithms book I read said to split in alternating order.
// Might have been for red-black trees. Either way we are going to take a page from that book.
int lastAxis = 2;
std::pair<AABB, AABB> AABB::splitAlongAxis() {
lastAxis %= 3;
lastAxis += 1;
std::pair<AABB, AABB> AABB::splitAlongAxis(AABBAxis axis) {
// return the new split AABBs based on the calculated max lengths, but only in their respective axis.
if (lastAxis == 1){
if (axis == X){
PRECISION_TYPE X = std::abs(max.x() - min.x());
PRECISION_TYPE X2 = X/2;
// end the first at half the parent.
return {{min.x(), min.y(), min.z(), max.x()-X2, max.y(), max.z()},
// start the second AABB at the end of the first AABB.
{min.x()+X2, min.y(), min.z(), max.x(), max.y(), max.z()}};
} else if (lastAxis == 2) {
} else if (axis == Y) {
PRECISION_TYPE Y = std::abs(max.y() - min.y());
PRECISION_TYPE Y2 = Y/2;
return {{min.x(), min.y(), min.z(), max.x(), max.y()-Y2, max.z()}, {min.x(), min.y()+Y2, min.z(), max.x(), max.y(), max.z()}};

View File

@ -16,6 +16,7 @@ namespace Raytracing {
start("Unnamed");
}
void profiler::start(const std::string& name) {
std::scoped_lock lock(timerLock);
auto p1 = std::chrono::high_resolution_clock::now();
_start = std::chrono::duration_cast<std::chrono::nanoseconds>(p1.time_since_epoch()).count();
timings[name] = std::pair<long, long>(_start, 0);
@ -25,6 +26,7 @@ namespace Raytracing {
end("Unnamed");
}
void profiler::end(const std::string& name) {
std::scoped_lock lock(timerLock);
auto p1 = std::chrono::high_resolution_clock::now();
_end = std::chrono::duration_cast<std::chrono::nanoseconds>(p1.time_since_epoch()).count();
timings[name] = std::pair<long, long>(timings[name].first, _end);

View File

@ -58,7 +58,7 @@ 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 (bvhObjects != nullptr){
if (bvhObjects != nullptr && m_config.useBVH){
auto hResult = HitData{false, Vec4(), Vec4(), max};
Object* objPtr = nullptr;

View File

@ -581,9 +581,9 @@ namespace Raytracing {
m_spiderVAO->bind();
m_spiderVAO->draw(m_worldShader, {{0, 1, 0}});
m_houseVAO->bind();
m_houseVAO->draw(m_worldShader, {{15, 1, 0}, {0, 0, -15}, {0, 0, 15}});
m_houseVAO->draw(m_worldShader, {{5, 1, 0}, {0, 0, -5}, {0, 0, 5}});
m_planeVAO->bind();
m_planeVAO->draw(m_worldShader, {{-15, 0.5, 0}});
m_planeVAO->draw(m_worldShader, {{-5, 0.5, 0}});
} else {
m_imageShader.use();
m_mainImage.updateImage();

BIN
WorldBVHTests.ods Normal file

Binary file not shown.