~ | BVH optimizing again

This commit is contained in:
TheRedShip
2025-01-19 00:34:35 +01:00
parent 388ad5fc7d
commit 08c0ce1d83
11 changed files with 95 additions and 2836 deletions

2806
fps.txt

File diff suppressed because it is too large Load Diff

View File

@ -11,10 +11,14 @@ Pos=1648,207
Size=266,285
[Window][Fog settings]
Pos=1654,501
Pos=1640,500
Size=247,157
[Window][Debug]
Pos=1642,667
Pos=1642,668
Size=260,143
[Window][Debug BVH]
Pos=60,60
Size=159,127

View File

@ -27,6 +27,11 @@ struct AABB
AABB(glm::vec3 min, glm::vec3 max) : min(min), max(max) {}
};
struct BVHStats {
int min_triangles;
int max_triangles;
float average_triangles;
};
class BVH
{
@ -39,7 +44,9 @@ class BVH
void updateBounds(std::vector <GPUTriangle> &primitives);
void subdivide(std::vector<GPUTriangle> &primitives);
int size();
int getSize();
int getLeaves();
BVHStats analyzeBVHLeaves(BVH* root);
void flatten(std::vector<GPUBvh> &bvhs, int &currentIndex);
GPUBvh toGPUBvh();

View File

@ -23,7 +23,7 @@ pl 0 -2 0 0 1 0 2 // floor
qu -1 1.999 -1 2 0 0 0 0 2 6
# sp 1 1 0 0.5 6
# sp 1 1 0 0.1 6
OBJ obj/Dragon_80K.obj

View File

@ -22,4 +22,4 @@ pl 0 -10 0 0 1 0 2 // floor
qu -20 59 -20 40 0 0 0 0 40 6
OBJ obj/audi.obj
OBJ obj/Model.obj

View File

@ -140,24 +140,23 @@ hitInfo traceBVH(Ray ray, inout Stats stats)
hit.t = 1e30;
hit.obj_index = -1;
int stack[64];
int stack[32];
int stack_ptr = 0;
stack[0] = 0;
while (stack_ptr >= 0)
{
int current_index = stack[stack_ptr--];
GPUBvh node = bvh[current_index];
if (node.is_leaf != 0)
{
for (int i = 0; i < node.primitive_count; i++)
{
{
GPUTriangle obj = triangles[node.first_primitive + i];
hitInfo temp_hit;
if (intersectTriangle(ray, obj, temp_hit) && temp_hit.t > 0.0f && temp_hit.t < hit.t + 0.0001)
if (intersectTriangle(ray, obj, temp_hit) && temp_hit.t < hit.t)
{
hit.t = temp_hit.t;
hit.normal = temp_hit.normal;

View File

@ -66,7 +66,7 @@ hitInfo traceBVH(Ray ray)
hit.t = 1e30;
hit.obj_index = -1;
int stack[64];
int stack[32];
int stack_ptr = 0;
stack[0] = 0;
@ -84,7 +84,7 @@ hitInfo traceBVH(Ray ray)
GPUTriangle obj = triangles[node.first_primitive + i];
hitInfo temp_hit;
if (intersectTriangle(ray, obj, temp_hit) && temp_hit.t > 0.0f && temp_hit.t < hit.t + 0.0001)
if (intersectTriangle(ray, obj, temp_hit) && temp_hit.t < hit.t)
{
hit.t = temp_hit.t;
hit.last_t = temp_hit.last_t;

View File

@ -20,8 +20,8 @@ int main(int argc, char **argv)
return (1);
Window window(&scene, WIDTH, HEIGHT, "RT_GPU", 0);
// Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/compute.glsl");
Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/debug.glsl");
Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/compute.glsl");
// Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/debug.glsl");
GLint max_gpu_size;
glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_gpu_size);
@ -128,7 +128,7 @@ int main(int argc, char **argv)
recorded_fps.push_back((int)window.getFps());
float y_offset = 0.;
float y_offset = 0;
float dist_to_obj = 2;
float speed = 0.5;

View File

@ -145,26 +145,74 @@ void BVH::flatten(std::vector<GPUBvh> &bvhs, int &currentIndex)
bvhs[self_index] = self_bvh;
}
int BVH::size()
{
int count = 0;
if (_is_leaf)
return (0);
count += 1 + _left->size();
count += 1 + _right->size();
return (count);
}
std::vector<GPUBvh> BVH::getGPUBvhs()
{
std::vector<GPUBvh> bvhs(size() + 1);
std::vector<GPUBvh> bvhs(getSize() + 1);
int currentIndex = 0;
flatten(bvhs, currentIndex);
return (bvhs);
}
int BVH::getSize()
{
int count = 0;
if (_is_leaf)
return (0);
count += 1 + _left->getSize();
count += 1 + _right->getSize();
return (count);
}
int BVH::getLeaves()
{
int count = 0;
if (_is_leaf)
return (1);
count += _left->getLeaves();
count += _right->getLeaves();
return (count);
}
//get tri per leaf min max and average
BVHStats BVH::analyzeBVHLeaves(BVH *root)
{
if (!root)
return {0, 0, 0.0f};
// If this is a leaf node, return its stats
if (root->_is_leaf)
return {
root->_primitive_count, // min
root->_primitive_count, // max
(float)root->_primitive_count // average
};
// Get stats from left and right subtrees
BVHStats left = analyzeBVHLeaves(root->_left);
BVHStats right = analyzeBVHLeaves(root->_right);
// Combine the results
int min_count = std::min(left.min_triangles, right.min_triangles);
int max_count = std::max(left.max_triangles, right.max_triangles);
// Calculate weighted average based on number of leaves in each subtree
float left_leaf_count = (left.average_triangles > 0) ? 1.0f : 0.0f;
float right_leaf_count = (right.average_triangles > 0) ? 1.0f : 0.0f;
float total_leaf_count = left_leaf_count + right_leaf_count;
float avg_count = 0.0f;
if (total_leaf_count > 0)
avg_count = (left.average_triangles * left_leaf_count +
right.average_triangles * right_leaf_count) / total_leaf_count;
return {min_count, max_count, avg_count};
}

View File

@ -64,8 +64,15 @@ bool Scene::parseScene(char *name)
BVH *bvh = new BVH(_gpu_triangles, 0, _gpu_triangles.size());
_gpu_bvh = bvh->getGPUBvhs();
std::cout << "BVH Done: " << bvh->size() << std::endl;
std::cout << "BVH Done: " << std::endl;
std::cout << "\tBVH size: " << bvh->getSize() << std::endl;
std::cout << "\tBVH leaves: " << bvh->getLeaves() << std::endl << std::endl;
BVHStats stats = bvh->analyzeBVHLeaves(bvh);
std::cout << "\tMin triangles per leaf: " << stats.min_triangles << std::endl;
std::cout << "\tMax triangles per leaf: " << stats.max_triangles << std::endl;
std::cout << "\tAverage triangles per leaf: " << stats.average_triangles << std::endl << std::endl;
return (true);
}

View File

@ -248,7 +248,7 @@ void Window::imGuiRender()
ImGui::End();
ImGui::Begin("Debug");
ImGui::Begin("Debug BVH");
has_changed |= ImGui::Checkbox("Enable", (bool *)(&_scene->getDebug().enabled));
ImGui::Separator();