diff --git a/imgui.ini b/imgui.ini index 3af6cd7..93ca36f 100644 --- a/imgui.ini +++ b/imgui.ini @@ -3,14 +3,14 @@ Pos=60,60 Size=400,400 [Window][Camera] -Pos=651,101 +Pos=1682,11 Size=229,184 [Window][Material] -Pos=1136,164 +Pos=1650,202 Size=266,285 [Window][Fog settings] -Pos=884,462 +Pos=1679,495 Size=247,157 diff --git a/includes/RT/BVH.hpp b/includes/RT/BVH.hpp index 9a2af8c..c7f8455 100644 --- a/includes/RT/BVH.hpp +++ b/includes/RT/BVH.hpp @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* BVH.hpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: TheRed +#+ +:+ +#+ */ +/* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/16 21:36:19 by TheRed #+# #+# */ -/* Updated: 2025/01/16 21:36:19 by TheRed ### ########.fr */ +/* Updated: 2025/01/17 18:59:28 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -30,13 +30,13 @@ struct AABB class BVH { public: - BVH(std::vector primitives, int first_primitive, int primitive_count); + BVH(std::vector &primitives, int first_primitive, int primitive_count); void showAABB(Scene *scene); - void updateBounds(std::vector primitives); - void subdivide(std::vector primitives); + void updateBounds(std::vector &primitives); + void subdivide(std::vector &primitives); int size(); diff --git a/includes/RT/objects/Triangle.hpp b/includes/RT/objects/Triangle.hpp index a90b999..165da9a 100644 --- a/includes/RT/objects/Triangle.hpp +++ b/includes/RT/objects/Triangle.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/23 19:12:51 by ycontre #+# #+# */ -/* Updated: 2025/01/13 18:43:18 by ycontre ### ########.fr */ +/* Updated: 2025/01/17 18:17:30 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,8 +53,8 @@ class Triangle : public Object : Object(position, mat_index), _vertex2(vertex2), _vertex3(vertex3) { // _vertex2 -= _position; //optimization // _vertex3 -= _position; //optimization - - _normal = glm::normalize(glm::cross(_vertex2, _vertex3)); //optimization + + _normal = glm::normalize(glm::cross(_vertex2 - _position, _vertex3 - _position)); //optimization } const glm::vec3 &getVertex2() const { return (_vertex2); } diff --git a/obj/10517_Motorcycle_Helmet_v01_L3.obj b/obj/10517_Motorcycle_Helmet_v01_L3.obj index 1cfd832..6ebf2ca 100644 --- a/obj/10517_Motorcycle_Helmet_v01_L3.obj +++ b/obj/10517_Motorcycle_Helmet_v01_L3.obj @@ -19138,7 +19138,7 @@ vt 0.0798 0.4469 0.0000 # 6409 texture coords g 10517_Motorcycle_Helmet_v01 -usemtl 10517_Motorcycle_Helmet_v01 +###usemtl 10517_Motorcycle_Helmet_v01 s 3 f 1 2 3 4 f 2 5 6 3 @@ -23841,7 +23841,7 @@ f 4267 4008 4591 4614 f 4614 4591 4587 4608 f 4269 4267 4614 4613 f 4613 4614 4608 4609 -usemtl 10517_Motorcycle_Helmet_v01_glass +##usemtl 10517_Motorcycle_Helmet_v01_glass s 2 f 4615 4616 4617 4618 f 4616 4619 4620 4617 @@ -25254,7 +25254,7 @@ f 6008 5106 5105 6024 f 6024 5105 5100 6018 f 6010 6008 6024 6023 f 6023 6024 6018 6019 -usemtl 10517_Motorcycle_Helmet_v01 +#usemtl 10517_Motorcycle_Helmet_v01 s 1 f 1315 1643 6025 1316 f 1643 1647 6026 6025 diff --git a/scenes/test.rt b/scenes/test.rt index 7598a7a..1f2179b 100644 --- a/scenes/test.rt +++ b/scenes/test.rt @@ -1,4 +1,4 @@ -CAM 10.2849 6.27579 9.45482 -0.600081 -128.999 0 4 90 5 +CAM 0.582504 9.47921 50.0705 -20.6001 -87.3991 0 4 90 5 MAT 200 200 200 0.0 0.0 0.0 //white MAT 255 50 50 0.0 1.0 0.05 //red @@ -13,16 +13,16 @@ MAT 255 255 255 0.0 0.0 0.0 TRN // glass # sp 0 -25 0 50 1 -tr -4 5 0 -3 5 0 -4 5 1 0 -tr 0 7 2 1 4 2 0 5 3 0 -tr 3 7 2 4 5 1 2 6 3 0 +# tr -4 5 0 -3 5 0 -4 5 1 0 +# tr 0 7 2 1 4 2 0 5 3 0 +# tr 3 7 2 4 5 1 2 6 3 0 -tr 7 5 0 8 5 0 7 5 1 0 -tr 7 7 2 8 4 2 7 5 3 0 -tr 10 7 2 11 5 1 8 6 3 0 -tr 15 -2 4 11 5 1 8 6 3 0 -tr 15 -2 4 11 5 1 7 5 9 0 -tr 12 4 4 4 3 1 7 5 9 0 +# tr 7 5 0 8 5 0 7 5 1 0 +# tr 7 7 2 8 4 2 7 5 3 0 +# tr 10 7 2 11 5 1 8 6 3 0 +# tr 15 -2 4 11 5 1 8 6 3 0 +# tr 15 -2 4 11 5 1 7 5 9 0 +# tr 12 4 4 4 3 1 7 5 9 0 -# OBJ obj/Lowpoly_tree_sample.obj +OBJ obj/10517_Motorcycle_Helmet_v01_L3.obj diff --git a/shaders/bvh.glsl b/shaders/bvh.glsl deleted file mode 100644 index c18e5e5..0000000 --- a/shaders/bvh.glsl +++ /dev/null @@ -1,17 +0,0 @@ - - -bool intersectRayBVH(Ray ray, GPUBvh node) -{ - vec3 invDir = 1.0 / ray.direction; - - vec3 t1 = (node.min - ray.origin) * invDir; - vec3 t2 = (node.max - ray.origin) * invDir; - - vec3 tMin = min(t1, t2); - vec3 tMax = max(t1, t2); - - float tEnter = max(max(tMin.x, tMin.y), tMin.z); - float tExit = min(min(tMax.x, tMax.y), tMax.z); - - return tEnter <= tExit && tExit >= 0.0; -} \ No newline at end of file diff --git a/shaders/compute.glsl b/shaders/compute.glsl index 74806f7..c66990a 100644 --- a/shaders/compute.glsl +++ b/shaders/compute.glsl @@ -66,6 +66,24 @@ layout(std430, binding = 3) buffer LightsBuffer int lightsIndex[]; }; +struct GPUBvh +{ + vec3 min; + vec3 max; + + int left_index; + int right_index; + + int is_leaf; + + int first_primitive; + int primitive_count; +}; +layout(std430, binding = 4) buffer BvhBuffer +{ + GPUBvh bvh[]; +}; + layout(std140, binding = 0) uniform CameraData { @@ -105,64 +123,8 @@ struct hitInfo #include "shaders/scatter.glsl" #include "shaders/light.glsl" #include "shaders/volumetric.glsl" +#include "shaders/trace.glsl" -Ray portalRay(Ray ray, hitInfo hit) -{ - GPUObject portal_1; - GPUObject portal_2; - vec3 relative; - - portal_1 = objects[hit.obj_index]; - portal_2 = objects[int(portal_1.radius)]; // saving memory radius = portal_index - - relative = hit.position - portal_1.position; - - mat3 rotation = mat3(portal_2.rotation) * transpose(mat3(portal_1.rotation)); - - if (dot(portal_1.normal, portal_2.normal) > 0.0) - { - mat3 reflection = mat3(1.0) - 2.0 * outerProduct(portal_2.normal, portal_2.normal); - rotation *= reflection; - } - - ray.origin = portal_2.position + rotation * relative; - ray.direction = normalize(rotation * ray.direction); - - ray.origin += ray.direction * 0.01f; - - return (ray); -} - -hitInfo traceRay(Ray ray) -{ - hitInfo hit; - - for (int p = 0; p < 25; p++) //portals - { - hit.t = 1e30; - hit.obj_index = -1; - - for (int i = 0; i < u_objectsNum; i++) - { - GPUObject obj = objects[i]; - - hitInfo temp_hit; - if (intersect(ray, obj, temp_hit) && temp_hit.t > 0.0f && temp_hit.t < hit.t + 0.0001) - { - hit.t = temp_hit.t; - hit.last_t = temp_hit.last_t; - hit.obj_index = i; - hit.position = temp_hit.position; - hit.normal = temp_hit.normal; - } - } - if (hit.obj_index == -1 || objects[hit.obj_index].type != 5) - break ; - ray = portalRay(ray, hit); - } - - return (hit); -} vec3 pathtrace(Ray ray, inout uint rng_state) { diff --git a/shaders/debug.glsl b/shaders/debug.glsl index 2d33522..e3c7a1a 100644 --- a/shaders/debug.glsl +++ b/shaders/debug.glsl @@ -100,33 +100,6 @@ int traceRay(Ray ray) return (num_hit); } - -int traceBVHBad(Ray ray) -{ - int num_hit; - - num_hit = 0; - for (int i = 0; i < u_bvhNum; i++) - { - GPUBvh node = bvh[i]; - - if (intersectRayBVH(ray, node)) - { - // num_hit++; - for (int i = 0; i < node.primitive_count; i++) - { - GPUObject obj = objects[node.first_primitive + i]; - - hitInfo tmp; - if (intersect(ray, obj, tmp)) - num_hit++; - } - } - } - - return (num_hit); -} - int traceBVH(Ray ray) { int num_hit = 0; @@ -157,7 +130,7 @@ int traceBVH(Ray ray) hitInfo tmp; if (intersect(ray, obj, tmp)) - num_hit++; + num_hit; } } @@ -199,6 +172,6 @@ void main() Ray ray = initRay(uv); int hits = traceBVH(ray); - vec3 color = vec3(float(hits) / float(10)); + vec3 color = vec3(float(hits) / float(u_bvhNum / 4)); imageStore(output_image, pixel_coords, vec4(color, 1.)); } \ No newline at end of file diff --git a/shaders/intersect.glsl b/shaders/intersect.glsl index cfdf23a..c499810 100644 --- a/shaders/intersect.glsl +++ b/shaders/intersect.glsl @@ -225,4 +225,23 @@ bool intersect(Ray ray, GPUObject obj, out hitInfo hit) if (obj.type == 6) return (intersectCylinder(ray, obj, hit)); return (false); -} \ No newline at end of file +} + + +bool intersectRayBVH(Ray ray, GPUBvh node) +{ + vec3 invDir = 1.0 / ray.direction; + + vec3 t1 = (node.min - ray.origin) * invDir; + vec3 t2 = (node.max - ray.origin) * invDir; + + vec3 tMin = min(t1, t2); + vec3 tMax = max(t1, t2); + + float tEnter = max(max(tMin.x, tMin.y), tMin.z); + float tExit = min(min(tMax.x, tMax.y), tMax.z); + + return tEnter <= tExit && tExit >= 0.0; +} + + diff --git a/shaders/trace.glsl b/shaders/trace.glsl new file mode 100644 index 0000000..c3cb035 --- /dev/null +++ b/shaders/trace.glsl @@ -0,0 +1,118 @@ + + +Ray portalRay(Ray ray, hitInfo hit) +{ + GPUObject portal_1; + GPUObject portal_2; + vec3 relative; + + portal_1 = objects[hit.obj_index]; + portal_2 = objects[int(portal_1.radius)]; // saving memory radius = portal_index + + relative = hit.position - portal_1.position; + + mat3 rotation = mat3(portal_2.rotation) * transpose(mat3(portal_1.rotation)); + + if (dot(portal_1.normal, portal_2.normal) > 0.0) + { + mat3 reflection = mat3(1.0) - 2.0 * outerProduct(portal_2.normal, portal_2.normal); + rotation *= reflection; + } + + ray.origin = portal_2.position + rotation * relative; + ray.direction = normalize(rotation * ray.direction); + + ray.origin += ray.direction * 0.01f; + + return (ray); +} + +hitInfo traceScene(Ray ray) +{ + hitInfo hit; + + for (int p = 0; p < 25; p++) //portals + { + hit.t = 1e30; + hit.obj_index = -1; + + for (int i = 0; i < u_objectsNum; i++) + { + GPUObject obj = objects[i]; + + hitInfo temp_hit; + if (intersect(ray, obj, temp_hit) && temp_hit.t > 0.0f && temp_hit.t < hit.t + 0.0001) + { + hit.t = temp_hit.t; + hit.last_t = temp_hit.last_t; + hit.obj_index = i; + hit.position = temp_hit.position; + hit.normal = temp_hit.normal; + } + } + if (hit.obj_index == -1 || objects[hit.obj_index].type != 5) + break ; + ray = portalRay(ray, hit); + } + + return (hit); +} + +hitInfo traceBVH(Ray ray) +{ + hitInfo hit; + + hit.t = 1e30; + hit.obj_index = -1; + + const int MAX_STACK_SIZE = 64; + int stack[MAX_STACK_SIZE]; + int stack_ptr = 0; + + stack[0] = 0; + + while (stack_ptr >= 0) + { + int current_index = stack[stack_ptr--]; + + GPUBvh node = bvh[current_index]; + + if (intersectRayBVH(ray, node)) + { + if (node.is_leaf != 0) + { + for (int i = 0; i < node.primitive_count; i++) + { + GPUObject obj = objects[node.first_primitive + i]; + + hitInfo temp_hit; + if (intersect(ray, obj, temp_hit) && temp_hit.t > 0.0f && temp_hit.t < hit.t + 0.0001) + { + hit.t = temp_hit.t; + hit.last_t = temp_hit.last_t; + hit.obj_index = node.first_primitive + i; + hit.position = temp_hit.position; + hit.normal = temp_hit.normal; + } + } + } + + if (node.is_leaf == 0 && stack_ptr < MAX_STACK_SIZE - 2) + { + stack_ptr++; + stack[stack_ptr] = node.left_index; + stack_ptr++; + stack[stack_ptr] = node.right_index; + } + } + } + + return (hit); +} + +hitInfo traceRay(Ray ray) +{ + if (true) + return (traceBVH(ray)); + return (traceScene(ray)); +} \ No newline at end of file diff --git a/srcs/RT.cpp b/srcs/RT.cpp index c5891ac..c933002 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/27 14:51:49 by TheRed #+# #+# */ -/* Updated: 2025/01/13 17:40:45 by tomoron ### ########.fr */ +/* Updated: 2025/01/17 19:25:14 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -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); diff --git a/srcs/class/BVH.cpp b/srcs/class/BVH.cpp index 160fb3b..1924fcf 100644 --- a/srcs/class/BVH.cpp +++ b/srcs/class/BVH.cpp @@ -3,16 +3,16 @@ /* ::: :::::::: */ /* BVH.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: TheRed +#+ +:+ +#+ */ +/* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/16 21:48:48 by TheRed #+# #+# */ -/* Updated: 2025/01/16 21:48:48 by TheRed ### ########.fr */ +/* Updated: 2025/01/17 19:25:08 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ #include "BVH.hpp" -BVH::BVH(std::vector primitives, int first_primitive, int primitive_count) : _aabb(AABB(glm::vec3(1e30f), glm::vec3(-1e30f))) +BVH::BVH(std::vector &primitives, int first_primitive, int primitive_count) : _aabb(AABB(glm::vec3(1e30f), glm::vec3(-1e30f))) { _left = nullptr; _right = nullptr; @@ -26,7 +26,7 @@ BVH::BVH(std::vector primitives, int first_primitive, int primitive_c subdivide(primitives); } -void BVH::updateBounds(std::vector primitives) +void BVH::updateBounds(std::vector &primitives) { for (int i = 0; i < _primitive_count; i++) { @@ -44,13 +44,11 @@ void BVH::updateBounds(std::vector primitives) } } -void BVH::subdivide(std::vector primitives) +void BVH::subdivide(std::vector &primitives) { - if (_primitive_count <= 2) + if (_primitive_count <= 100) return ; - std::cout << "subdivide" << std::endl; - glm::vec3 extent = _aabb.max - _aabb.min; int axis = 0; @@ -78,9 +76,6 @@ void BVH::subdivide(std::vector primitives) int left_count = i - _first_primitive; - std::cout << "left bvh starts from " << _first_primitive << " and has " << left_count << " primitives" << std::endl; - std::cout << "right bvh starts from " << i << " and has " << _primitive_count - left_count << " primitives" << std::endl; - if (left_count == 0 || left_count == _primitive_count) return ; @@ -88,14 +83,14 @@ void BVH::subdivide(std::vector primitives) _is_leaf = false; _left = new BVH(primitives, _first_primitive, left_count); - _right = new BVH(primitives, i, _primitive_count - left_count); + _right = new BVH(primitives, i , _primitive_count - left_count); _primitive_count = 0; } void BVH::showAABB(Scene *scene) { - if (_is_leaf) + if (!_is_leaf) { scene->addObject(new Sphere(_aabb.min, 0.5f, 6)); scene->addObject(new Sphere(_aabb.max, 0.5f, 6)); @@ -108,8 +103,8 @@ void BVH::showAABB(Scene *scene) } else { - _left->showAABB(scene); - _right->showAABB(scene); + // _left->showAABB(scene); + // _right->showAABB(scene); } } @@ -171,5 +166,7 @@ std::vector BVH::getGPUBvhs() int currentIndex = 0; flatten(bvhs, currentIndex); + std::cout << "BVH Done: " << bvhs.size() << std::endl; + return (bvhs); } \ No newline at end of file diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index 1b8a099..a153245 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/23 18:29:41 by ycontre #+# #+# */ -/* Updated: 2025/01/15 19:34:49 by ycontre ### ########.fr */ +/* Updated: 2025/01/17 19:05:53 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -56,9 +56,6 @@ bool Scene::parseScene(char *name) BVH *bvh = new BVH(_gpu_objects, 0, _gpu_objects.size()); _gpu_bvh = bvh->getGPUBvhs(); - // bvh->showAABB(this); - - return (true); } diff --git a/srcs/class/Shader.cpp b/srcs/class/Shader.cpp index 1ed80a9..d06e680 100644 --- a/srcs/class/Shader.cpp +++ b/srcs/class/Shader.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 20:21:13 by ycontre #+# #+# */ -/* Updated: 2025/01/10 18:53:39 by ycontre ### ########.fr */ +/* Updated: 2025/01/17 19:05:41 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */