mirror of
https://github.com/TheRedShip/RT_GPU.git
synced 2025-09-27 18:48:36 +02:00
~ | BVH optimizing again
This commit is contained in:
@ -11,10 +11,14 @@ Pos=1648,207
|
|||||||
Size=266,285
|
Size=266,285
|
||||||
|
|
||||||
[Window][Fog settings]
|
[Window][Fog settings]
|
||||||
Pos=1654,501
|
Pos=1640,500
|
||||||
Size=247,157
|
Size=247,157
|
||||||
|
|
||||||
[Window][Debug]
|
[Window][Debug]
|
||||||
Pos=1642,667
|
Pos=1642,668
|
||||||
Size=260,143
|
Size=260,143
|
||||||
|
|
||||||
|
[Window][Debug BVH]
|
||||||
|
Pos=60,60
|
||||||
|
Size=159,127
|
||||||
|
|
||||||
|
@ -27,6 +27,11 @@ struct AABB
|
|||||||
AABB(glm::vec3 min, glm::vec3 max) : min(min), max(max) {}
|
AABB(glm::vec3 min, glm::vec3 max) : min(min), max(max) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BVHStats {
|
||||||
|
int min_triangles;
|
||||||
|
int max_triangles;
|
||||||
|
float average_triangles;
|
||||||
|
};
|
||||||
|
|
||||||
class BVH
|
class BVH
|
||||||
{
|
{
|
||||||
@ -39,7 +44,9 @@ class BVH
|
|||||||
void updateBounds(std::vector <GPUTriangle> &primitives);
|
void updateBounds(std::vector <GPUTriangle> &primitives);
|
||||||
void subdivide(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 ¤tIndex);
|
void flatten(std::vector<GPUBvh> &bvhs, int ¤tIndex);
|
||||||
GPUBvh toGPUBvh();
|
GPUBvh toGPUBvh();
|
||||||
|
@ -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
|
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
|
OBJ obj/Dragon_80K.obj
|
||||||
|
|
||||||
|
@ -22,4 +22,4 @@ pl 0 -10 0 0 1 0 2 // floor
|
|||||||
|
|
||||||
qu -20 59 -20 40 0 0 0 0 40 6
|
qu -20 59 -20 40 0 0 0 0 40 6
|
||||||
|
|
||||||
OBJ obj/audi.obj
|
OBJ obj/Model.obj
|
||||||
|
@ -140,24 +140,23 @@ hitInfo traceBVH(Ray ray, inout Stats stats)
|
|||||||
hit.t = 1e30;
|
hit.t = 1e30;
|
||||||
hit.obj_index = -1;
|
hit.obj_index = -1;
|
||||||
|
|
||||||
int stack[64];
|
int stack[32];
|
||||||
int stack_ptr = 0;
|
int stack_ptr = 0;
|
||||||
stack[0] = 0;
|
stack[0] = 0;
|
||||||
|
|
||||||
while (stack_ptr >= 0)
|
while (stack_ptr >= 0)
|
||||||
{
|
{
|
||||||
int current_index = stack[stack_ptr--];
|
int current_index = stack[stack_ptr--];
|
||||||
|
|
||||||
GPUBvh node = bvh[current_index];
|
GPUBvh node = bvh[current_index];
|
||||||
|
|
||||||
if (node.is_leaf != 0)
|
if (node.is_leaf != 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < node.primitive_count; i++)
|
for (int i = 0; i < node.primitive_count; i++)
|
||||||
{
|
{
|
||||||
GPUTriangle obj = triangles[node.first_primitive + i];
|
GPUTriangle obj = triangles[node.first_primitive + i];
|
||||||
|
|
||||||
hitInfo temp_hit;
|
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.t = temp_hit.t;
|
||||||
hit.normal = temp_hit.normal;
|
hit.normal = temp_hit.normal;
|
||||||
|
@ -66,7 +66,7 @@ hitInfo traceBVH(Ray ray)
|
|||||||
hit.t = 1e30;
|
hit.t = 1e30;
|
||||||
hit.obj_index = -1;
|
hit.obj_index = -1;
|
||||||
|
|
||||||
int stack[64];
|
int stack[32];
|
||||||
int stack_ptr = 0;
|
int stack_ptr = 0;
|
||||||
stack[0] = 0;
|
stack[0] = 0;
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ hitInfo traceBVH(Ray ray)
|
|||||||
GPUTriangle obj = triangles[node.first_primitive + i];
|
GPUTriangle obj = triangles[node.first_primitive + i];
|
||||||
|
|
||||||
hitInfo temp_hit;
|
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.t = temp_hit.t;
|
||||||
hit.last_t = temp_hit.last_t;
|
hit.last_t = temp_hit.last_t;
|
||||||
|
@ -20,8 +20,8 @@ int main(int argc, char **argv)
|
|||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
Window window(&scene, WIDTH, HEIGHT, "RT_GPU", 0);
|
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/compute.glsl");
|
||||||
Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/debug.glsl");
|
// Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/debug.glsl");
|
||||||
|
|
||||||
GLint max_gpu_size;
|
GLint max_gpu_size;
|
||||||
glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &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());
|
recorded_fps.push_back((int)window.getFps());
|
||||||
|
|
||||||
float y_offset = 0.;
|
float y_offset = 0;
|
||||||
float dist_to_obj = 2;
|
float dist_to_obj = 2;
|
||||||
float speed = 0.5;
|
float speed = 0.5;
|
||||||
|
|
||||||
|
@ -145,26 +145,74 @@ void BVH::flatten(std::vector<GPUBvh> &bvhs, int ¤tIndex)
|
|||||||
bvhs[self_index] = self_bvh;
|
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> BVH::getGPUBvhs()
|
||||||
{
|
{
|
||||||
std::vector<GPUBvh> bvhs(size() + 1);
|
std::vector<GPUBvh> bvhs(getSize() + 1);
|
||||||
|
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
flatten(bvhs, currentIndex);
|
flatten(bvhs, currentIndex);
|
||||||
|
|
||||||
|
|
||||||
return (bvhs);
|
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};
|
||||||
}
|
}
|
@ -64,8 +64,15 @@ bool Scene::parseScene(char *name)
|
|||||||
BVH *bvh = new BVH(_gpu_triangles, 0, _gpu_triangles.size());
|
BVH *bvh = new BVH(_gpu_triangles, 0, _gpu_triangles.size());
|
||||||
_gpu_bvh = bvh->getGPUBvhs();
|
_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);
|
return (true);
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ void Window::imGuiRender()
|
|||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
ImGui::Begin("Debug");
|
ImGui::Begin("Debug BVH");
|
||||||
|
|
||||||
has_changed |= ImGui::Checkbox("Enable", (bool *)(&_scene->getDebug().enabled));
|
has_changed |= ImGui::Checkbox("Enable", (bool *)(&_scene->getDebug().enabled));
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
Reference in New Issue
Block a user