From c426b8078bd85132e3c64d1f4a079c3b56887722 Mon Sep 17 00:00:00 2001 From: RedShip Date: Sun, 2 Feb 2025 19:45:26 +0100 Subject: [PATCH 01/21] + | Denoising texture --- includes/RT/Shader.hpp | 3 ++- srcs/RT.cpp | 2 +- srcs/class/Shader.cpp | 11 ++++++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/includes/RT/Shader.hpp b/includes/RT/Shader.hpp index 2f37aff..2f4db93 100644 --- a/includes/RT/Shader.hpp +++ b/includes/RT/Shader.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 18:10:10 by TheRed #+# #+# */ -/* Updated: 2025/01/30 22:27:43 by tomoron ### ########.fr */ +/* Updated: 2025/02/02 19:42:13 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -49,6 +49,7 @@ class Shader GLuint _output_texture; GLuint _accumulation_texture; + GLuint _denoising_texture; GLuint _vertex; GLuint _fragment; diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 964f009..96a41e7 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/30 22:29:00 by tomoron ### ########.fr */ +/* Updated: 2025/02/02 19:44:53 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/srcs/class/Shader.cpp b/srcs/class/Shader.cpp index 5c00257..9992b8d 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/30 22:29:39 by tomoron ### ########.fr */ +/* Updated: 2025/02/02 19:44:13 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -136,6 +136,15 @@ void Shader::attach(void) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); glBindImageTexture(1, _accumulation_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + + glGenTextures(1, &_denoising_texture); + glBindTexture(GL_TEXTURE_2D, _denoising_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); + glBindImageTexture(2, _denoising_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); } void Shader::checkCompileErrors(GLuint shader) From e332161e7a793f77e00003dcedd2d62f85c8e641 Mon Sep 17 00:00:00 2001 From: tomoron Date: Mon, 3 Feb 2025 16:53:25 +0100 Subject: [PATCH 02/21] add alias to shell.nix to make a dummy x11 session --- shell.nix | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/shell.nix b/shell.nix index 016fa2c..4b3d7ae 100644 --- a/shell.nix +++ b/shell.nix @@ -1,6 +1,10 @@ { pkgs ? import {} }: pkgs.mkShell { - nativeBuildInputs = with pkgs; [ libGL xorg.libX11 libGLU glfw ffmpeg]; - shellHook="make -j"; + nativeBuildInputs = with pkgs; [ libGL xorg.libX11 libGLU glfw ffmpeg xorg.xvfb]; + shellHook='' + alias xdum="Xvfb :99 -screen 0 1920x1080x24 +extension GLX +render -noreset & export DISPLAY=:99"; + alias xdumstop='pkill Xvfb' + make -j; + ''; } From 7ffc43b7cb4e5e05eb0fa3d996de9fef55712e2b Mon Sep 17 00:00:00 2001 From: RedShip Date: Mon, 3 Feb 2025 18:40:40 +0100 Subject: [PATCH 03/21] ~ | Fixing multiple loading same texture --- includes/RT.hpp | 3 ++- srcs/class/ObjParser.cpp | 37 ++++++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/includes/RT.hpp b/includes/RT.hpp index b9a2dfa..84e906f 100644 --- a/includes/RT.hpp +++ b/includes/RT.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/27 14:52:10 by TheRed #+# #+# */ -/* Updated: 2025/01/22 16:37:32 by tomoron ### ########.fr */ +/* Updated: 2025/02/03 18:17:48 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -31,6 +31,7 @@ # include "imgui/imgui_impl_glfw.h" # include "imgui/imgui_impl_opengl3.h" +# include # include # include # include diff --git a/srcs/class/ObjParser.cpp b/srcs/class/ObjParser.cpp index 04b3bf7..42fe4df 100644 --- a/srcs/class/ObjParser.cpp +++ b/srcs/class/ObjParser.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/16 15:00:33 by tomoron #+# #+# */ -/* Updated: 2025/01/31 19:53:44 by ycontre ### ########.fr */ +/* Updated: 2025/02/03 18:40:04 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -322,18 +322,38 @@ void ObjParser::parseMtl(std::stringstream &input_line, Scene &scene) if (!(lineStream >> path)) throw std::runtime_error("OBJ: syntax error while getting material texture"); - mat->texture_index = scene.getTextures().size(); - scene.addTexture(getFilePath(_filename) + path); + path = getFilePath(_filename) + path; + + std::vector previous_textures = scene.getTextures(); + std::vector::iterator it = std::find(previous_textures.begin(), previous_textures.end(), path); + + if (it != previous_textures.end()) + mat->texture_index = std::distance(previous_textures.begin(), it); + else + { + mat->texture_index = previous_textures.size();; + scene.addTexture(path); + } } else if (identifier == "map_Ke") { std::string path; if (!(lineStream >> path)) - throw std::runtime_error("OBJ: syntax error while getting material texture"); + throw std::runtime_error("OBJ: syntax error while getting emissive texture"); - mat->emission_texture_index = scene.getEmissionTextures().size(); - scene.addEmissionTexture(getFilePath(_filename) + path); + path = getFilePath(_filename) + path; + + std::vector previous_textures = scene.getEmissionTextures(); + std::vector::iterator it = std::find(previous_textures.begin(), previous_textures.end(), path); + + if (it != previous_textures.end()) + mat->texture_index = std::distance(previous_textures.begin(), it); + else + { + mat->texture_index = previous_textures.size();; + scene.addEmissionTexture(path); + } if (mat->emission == 0) mat->emission = 1; @@ -347,11 +367,6 @@ void ObjParser::parseMtl(std::stringstream &input_line, Scene &scene) _matNames[matName] = scene.getMaterialData().size() - 1; } file.close(); - for(auto i = _matNames.begin(); i != _matNames.end(); i++) - { - std::cout << "key : " << i->first << std::endl; - std::cout << "value :" << i->second << std::endl; - } } void ObjParser::parse(Scene &scene, glm::vec3 offset, float scale, glm::mat4 transform) From b425f1e7b80f0b95cb9090e60e39d142e08b3707 Mon Sep 17 00:00:00 2001 From: RedShip Date: Mon, 3 Feb 2025 20:25:19 +0100 Subject: [PATCH 04/21] ~ | chepa --- shaders/trace.glsl | 2 +- srcs/class/ObjParser.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shaders/trace.glsl b/shaders/trace.glsl index 50067f2..57ef4d8 100644 --- a/shaders/trace.glsl +++ b/shaders/trace.glsl @@ -171,7 +171,7 @@ hitInfo traceRay(Ray ray) hitInfo hitScene; hitInfo hit; - #if 1 + #if 0 for (int i = 0; i < 10; i++) // portal ray { hitBVH = traverseBVHs(ray); diff --git a/srcs/class/ObjParser.cpp b/srcs/class/ObjParser.cpp index 42fe4df..25a882e 100644 --- a/srcs/class/ObjParser.cpp +++ b/srcs/class/ObjParser.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/16 15:00:33 by tomoron #+# #+# */ -/* Updated: 2025/02/03 18:40:04 by ycontre ### ########.fr */ +/* Updated: 2025/02/03 19:01:06 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -257,7 +257,7 @@ void ObjParser::parseMtl(std::stringstream &input_line, Scene &scene) continue; } if(!mat) - throw std::runtime_error("OBJ: error in material file, material name not defined"); + throw std::runtime_error("OBJ: error in material file, material name not defined "); if(identifier == "Kd") { if(!(lineStream >> mat->color.x >> mat->color.y >> mat->color.z)) From e1c5c22419863e718f8a7e4ea8f03a5fcdb0915f Mon Sep 17 00:00:00 2001 From: tomoron Date: Mon, 3 Feb 2025 21:12:05 +0100 Subject: [PATCH 05/21] add .gitignore and add a flags rule to makefile to create compile_flags.txt --- .gitignore | 5 +++++ Makefile | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2a0ef9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.vscode +.objs +RT +compile_flags.txt +imgui.ini diff --git a/Makefile b/Makefile index 4193dae..7635c57 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,8 @@ $(NAME): $(OBJS) $(HEADERS) @printf "$(LINE_CLR)$(WHITE) $(NAME): PROJECT COMPILED !$(RESET)\n\n" endif - +flags: + echo $(CFLAGS) $(IFLAGS) | tr " " "\n" > compile_flags.txt $(OBJS_DIR)/%.o: %.cpp @$(DIR_DUP) From 7520515e03d3da6e05a18e07e60f441989d670a0 Mon Sep 17 00:00:00 2001 From: tomoron Date: Mon, 3 Feb 2025 21:27:17 +0100 Subject: [PATCH 06/21] fix gitignore, it ignored the RT directory in the includes files (why is it named like that ?) --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c2a0ef9..7a0338c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .vscode .objs -RT +/RT compile_flags.txt imgui.ini From e10e8e4cfc93b24cf9f94d3e1d5bddfc5904beb9 Mon Sep 17 00:00:00 2001 From: TheRedShip Date: Tue, 4 Feb 2025 00:07:32 +0100 Subject: [PATCH 07/21] + | Backface culling choosing on quad so euclidian map + portal --- includes/RT/objects/Portal.hpp | 33 ++++++++++++++++++++------------- includes/RT/objects/Quad.hpp | 15 +++++++++++++-- scenes/lambo.rt | 2 +- scenes/noneuclidian.rt | 20 ++++++++++++++++++++ scenes/pillard.rt | 2 +- scenes/portalcornell.rt | 8 ++++---- scenes/portalrotation.rt | 4 ++-- scenes/roughness.rt | 2 +- scenes/stairs.rt | 2 +- scenes/test.rt | 20 ++++++++++++++++---- shaders/intersect.glsl | 5 +++-- shaders/trace.glsl | 2 +- srcs/class/Scene.cpp | 2 ++ srcs/class/SceneParser.cpp | 2 +- 14 files changed, 86 insertions(+), 33 deletions(-) create mode 100644 scenes/noneuclidian.rt diff --git a/includes/RT/objects/Portal.hpp b/includes/RT/objects/Portal.hpp index dd5561b..e1ab03f 100644 --- a/includes/RT/objects/Portal.hpp +++ b/includes/RT/objects/Portal.hpp @@ -24,8 +24,6 @@ class Portal : public Object float x1, y1, z1; float x2, y2, z2; - bool invert_normal; - int mat_index; if (!(line >> x >> y >> z)) @@ -37,7 +35,7 @@ class Portal : public Object if (!(line >> x2 >> y2 >> z2)) throw std::runtime_error("Missing Portal's second edge"); - if (!(line >> invert_normal)) + if (!(line >> _invert_normal)) throw std::runtime_error("Missing invert_normal"); if (!(line >> mat_index)) @@ -47,14 +45,18 @@ class Portal : public Object _up = glm::vec3(x1, y1, z1); _right = glm::vec3(x2, y2, z2); - glm::vec3 up = glm::normalize(_up); + // glm::vec3 temp_right = _right; + // _right = _invert_normal ? _up : _right; + // _up = _invert_normal ? temp_right : _up; + glm::vec3 right = glm::normalize(_right); + glm::vec3 up = glm::normalize(_up); glm::vec3 forward = glm::normalize(glm::cross(right, up)); - up = normalize(glm::cross(forward, right)); + // up = normalize(glm::cross(forward, right)); _rotation = glm::mat3(right, up, forward); - _normal = forward * (invert_normal ? -1.0f : 1.0f); + _normal = forward * (_invert_normal ? -1.0f : 1.0f); _linked_portal = -1; @@ -67,19 +69,23 @@ class Portal : public Object { float extension = 0.2f; - glm::vec3 right_dir = glm::normalize(_up); - glm::vec3 up_dir = glm::normalize(_right); + glm::vec3 right_dir = glm::normalize(_right); + glm::vec3 up_dir = glm::normalize(_up); - float right_length = glm::length(_up) + extension; - float up_length = glm::length(_right) + extension; + // glm::vec3 temp_right = right_dir; + // right_dir = _invert_normal ? right_dir : up_dir; + // up_dir = _invert_normal ? up_dir : temp_right; + + float right_length = glm::length(_right) + extension; + float up_length = glm::length(_up) + extension; glm::vec3 center_offset = -(right_dir * (extension / 2.0f) + up_dir * (extension / 2.0f)); - glm::vec3 position = _position + _normal * -0.001f + center_offset; + glm::vec3 position = _position + _normal * 0.001f + center_offset; glm::vec3 right = right_dir * right_length; glm::vec3 up = up_dir * up_length; - - return (new Quad(position, right, up, _mat_index)); + // position += 10; + return (new Quad(position, right, up, _normal, 1, _mat_index)); } glm::vec3 getUp() const { return (_up); } @@ -101,6 +107,7 @@ class Portal : public Object glm::mat3 _rotation; int _linked_portal; + int _invert_normal; }; #endif \ No newline at end of file diff --git a/includes/RT/objects/Quad.hpp b/includes/RT/objects/Quad.hpp index 3df3ff1..e1f17f9 100644 --- a/includes/RT/objects/Quad.hpp +++ b/includes/RT/objects/Quad.hpp @@ -23,6 +23,7 @@ class Quad : public Object float x, y, z; float x1, y1, z1; float x2, y2, z2; + bool double_face; int mat_index; if (!(line >> x >> y >> z)) @@ -33,6 +34,9 @@ class Quad : public Object if (!(line >> x2 >> y2 >> z2)) throw std::runtime_error("Missing quad's second edge"); + + if (!(line >> _single_sided)) + throw std::runtime_error("Missing double_face"); if (!(line >> mat_index)) throw std::runtime_error("Missing material properties"); @@ -41,18 +45,25 @@ class Quad : public Object _up = glm::vec3(x1, y1, z1); _right = glm::vec3(x2, y2, z2); + _normal = glm::normalize(glm::cross(_up, _right)); + _mat_index = mat_index; } - Quad(const glm::vec3 &position, const glm::vec3 &edge1, const glm::vec3 &edge2, const int mat_index) - : Object(position, mat_index), _up(edge1), _right(edge2) {} + Quad(const glm::vec3 &position, const glm::vec3 &edge1, const glm::vec3 &edge2, const glm::vec3 &normal, const int single_sided, const int mat_index) + : Object(position, mat_index), _up(edge1), _right(edge2), _normal(normal), _single_sided(single_sided) {} glm::vec3 getUp() const { return (_up); } glm::vec3 getRight() const { return (_right); } + glm::vec3 getNormal() const { return (_normal); } + int getSingleSided() const { return (_single_sided); } Type getType() const override { return Type::QUAD; } + private: glm::vec3 _up; glm::vec3 _right; + glm::vec3 _normal; + int _single_sided; }; #endif \ No newline at end of file diff --git a/scenes/lambo.rt b/scenes/lambo.rt index bc083a1..f29e63b 100644 --- a/scenes/lambo.rt +++ b/scenes/lambo.rt @@ -2,7 +2,7 @@ CAM -2.41462 2.57199 4.09049 -1.80012 -50.2012 0.02 2.973 45.75 MAT 20 20 20 0. 0.9 0.5 // 0 gray # pl 0 5.2 0 0 -1 0 0 // floor -qu -5 5 -5 10 0 0 0 0 10 0 +qu -5 5 -5 0 0 10 10 0 0 0 MAT 255 100 100 1.0 0.0 0.0 //1 red diff --git a/scenes/noneuclidian.rt b/scenes/noneuclidian.rt new file mode 100644 index 0000000..4a75efa --- /dev/null +++ b/scenes/noneuclidian.rt @@ -0,0 +1,20 @@ +CAM 0 2.59881 7 -4.8 -89.9996 0 1 90 5 + +MAT 100 200 100 0.0 0.0 0.0 // 0 +MAT 200 200 200 0.0 0.0 0.0 // 1 + +MAT 200 200 200 0 0 0 // 2 portal + +pl 0 0 0 0 1 0 0 + +po -1.5 0 4.5 3 0 0 0 3 0 0 2 +po -1.5 0 -4.5 3 0 0 0 3 0 1 2 + +qu -1.5 0 -5 0 3 0 0 0 10 0 1 +qu 1.5 0 -5 0 3 0 0 0 10 0 1 + +qu -1.5 3 -5 3 0 0 0 0 10 0 1 + + + +cu 10 1.5 0 3 3 5 1 diff --git a/scenes/pillard.rt b/scenes/pillard.rt index 6a586e4..a84ba6d 100644 --- a/scenes/pillard.rt +++ b/scenes/pillard.rt @@ -8,7 +8,7 @@ sp +0.000 +17.00 +20.00 4.0 0 sp +0.000 +17.00 +0.000 4.0 1 sp +0.000 +17.00 -20.00 4.0 2 -MAT 250 250 250 0.0 1.5 0.0 DIE -1 // 3 white 0 0 1 +MAT 250 250 250 0.0 1.2 0.0 DIE -1 // 3 white 0 0 1 MAT 250 250 250 0.0 1.0 1.0 // 4 white 0 1 0 MAT 200 200 200 0.0 0.0 0.0 // 5 white 1 0 0 diff --git a/scenes/portalcornell.rt b/scenes/portalcornell.rt index 5f16f4e..15146bc 100644 --- a/scenes/portalcornell.rt +++ b/scenes/portalcornell.rt @@ -22,8 +22,8 @@ qu -1 4 -1 2 0 0 0 0 2 2 cu 0 2.5 0 5 5 5 1 -po -1 1 -1.5 0 2 0 2 0 0 0 3 -po -1 1 1.5 0 2 0 2 0 0 1 4 +po -1 1 -1.5 0 2 0 2 0 0 1 3 +po -1 1 1.5 0 2 0 2 0 0 0 4 -po -1.5 1 -1 0 2 0 0 0 2 1 5 -po 1.5 1 -1 0 2 0 0 0 2 0 6 +po -1.5 1 -1 0 2 0 0 0 2 0 5 +po 1.5 1 -1 0 2 0 0 0 2 1 6 diff --git a/scenes/portalrotation.rt b/scenes/portalrotation.rt index 3278d2e..d765ace 100644 --- a/scenes/portalrotation.rt +++ b/scenes/portalrotation.rt @@ -18,5 +18,5 @@ pl -3 0 0 1 0 0 3 pl 0 0 -3 0 0 1 4 pl 0 0 3 0 0 -1 2 -po -0.33 -0.66 -1 0 1 0 0.5 0.5 -0.5 0 2 -po -0.5 -0.5 1 0 1 0 1 0 0 1 4 \ No newline at end of file +po -0.5 -0.5 -1 0 1 0 1 0.5 0.5 1 2 +po -0.5 -0.5 1 0 1 0 1 0 0 0 4 \ No newline at end of file diff --git a/scenes/roughness.rt b/scenes/roughness.rt index 5e475c7..2eb97be 100644 --- a/scenes/roughness.rt +++ b/scenes/roughness.rt @@ -40,5 +40,5 @@ sp 2.4 1.5 -1 1.5 14 // light quad -qu -1 2.999 -1 2 0 0 0 0 2 0 +qu -1 2.999 -1 0 0 2 2 0 0 0 diff --git a/scenes/stairs.rt b/scenes/stairs.rt index 91b2b84..d3d58a3 100644 --- a/scenes/stairs.rt +++ b/scenes/stairs.rt @@ -65,7 +65,7 @@ cu -9 0.98 3 3 3 3 28 MAT 244 95 28 0.0 0.5 1.0 cu -9 1.23 -6 3 3 3 29 -MAT 200 20 20 0.0 1.0 0.05 LAM 0 +MAT 200 20 20 0.0 1.0 0.05 LAM -1 MAT 255 255 255 0.0 1.8 0.0 DIE -1 MAT 255 255 255 0.0 1.0 1.0 diff --git a/scenes/test.rt b/scenes/test.rt index 0f4cd70..dd47a1b 100644 --- a/scenes/test.rt +++ b/scenes/test.rt @@ -1,6 +1,18 @@ -CAM -0.181956 1.3733 2.83437 -16 -87.8001 0 1 90 5 +CAM 0 1.3733 2.83437 -16 -87.8001 0 1 90 5 -MAT 255 255 255 10.0 1.0 0.0 //white -# sp 0 0 0 1 0 +# MAT 255 255 255 0.0 1.5 0.0 DIE -1 // 0 +# sp 0 0 0 12.5 0 + +TEX skymap.hdr +MAT 255 255 255 1.0 0.0 0.0 LAM 0 // 0 + +MAT 255 255 255 0.0 0.0 0.0 // 1 + + +sp 0 2 0 150 0 + +OBJ scenes/obj/jinx.obj -10 0 0 1.25 0 0 0 +# OBJ scenes/obj/Dragon_800K.obj 0 0 0 35 0 0 0 1 + +OBJ scenes/obj/whitedragon.obj 0 0 0 1 0 0 0 -OBJ scenes/obj/jinx.obj 0 0 0 1 diff --git a/shaders/intersect.glsl b/shaders/intersect.glsl index 543ca42..ddc1fea 100644 --- a/shaders/intersect.glsl +++ b/shaders/intersect.glsl @@ -42,10 +42,10 @@ bool intersectPlane(Ray ray, GPUObject obj, out hitInfo hit) bool intersectQuad(Ray ray, GPUObject obj, out hitInfo hit) { - vec3 normal = normalize(cross(obj.vertex1, obj.vertex2)); + vec3 normal = obj.normal; float d = dot(normal, ray.direction); - if (d == 0.0) return (false); + if (d == 0.0 || (obj.radius != 0.0 && d <= 0)) return (false); // double sided or not float t = dot(obj.position - ray.origin, normal) / d; @@ -64,6 +64,7 @@ bool intersectQuad(Ray ray, GPUObject obj, out hitInfo hit) hit.t = t; hit.position = p + obj.position; hit.normal = normal * -sign(d); + // hit.normal = normal; return (inside); } diff --git a/shaders/trace.glsl b/shaders/trace.glsl index 57ef4d8..50067f2 100644 --- a/shaders/trace.glsl +++ b/shaders/trace.glsl @@ -171,7 +171,7 @@ hitInfo traceRay(Ray ray) hitInfo hitScene; hitInfo hit; - #if 0 + #if 1 for (int i = 0; i < 10; i++) // portal ray { hitBVH = traverseBVHs(ray); diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index 7e6ab5d..7c50bc5 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -91,6 +91,8 @@ void Scene::addObject(Object *obj) auto quad = static_cast(obj); gpu_obj.vertex1 = quad->getUp(); gpu_obj.vertex2 = quad->getRight(); + gpu_obj.normal = quad->getNormal(); + gpu_obj.radius = quad->getSingleSided(); } else if (obj->getType() == Object::Type::CUBE) { diff --git a/srcs/class/SceneParser.cpp b/srcs/class/SceneParser.cpp index b499c3b..cc20dfa 100644 --- a/srcs/class/SceneParser.cpp +++ b/srcs/class/SceneParser.cpp @@ -132,7 +132,7 @@ void SceneParser::parseObj(std::stringstream &line) void SceneParser::parseTexture(std::stringstream &line) { std::string path; - + if (!(line >> path)) throw std::runtime_error("Texture: Missing texture's path"); From 3b3813793fda539d27a1d7caeaf8d82acd7c12de Mon Sep 17 00:00:00 2001 From: RedShip Date: Tue, 4 Feb 2025 18:56:10 +0100 Subject: [PATCH 08/21] + | Map changing --- includes/RT/objects/Quad.hpp | 1 - scenes/lambo.rt | 8 ++++---- scenes/noneuclidian.rt | 14 ++++++++++++-- scenes/portalcornell.rt | 2 +- scenes/portalrotation.rt | 2 +- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/includes/RT/objects/Quad.hpp b/includes/RT/objects/Quad.hpp index e1f17f9..d0b1584 100644 --- a/includes/RT/objects/Quad.hpp +++ b/includes/RT/objects/Quad.hpp @@ -23,7 +23,6 @@ class Quad : public Object float x, y, z; float x1, y1, z1; float x2, y2, z2; - bool double_face; int mat_index; if (!(line >> x >> y >> z)) diff --git a/scenes/lambo.rt b/scenes/lambo.rt index f29e63b..19c8f89 100644 --- a/scenes/lambo.rt +++ b/scenes/lambo.rt @@ -2,14 +2,14 @@ CAM -2.41462 2.57199 4.09049 -1.80012 -50.2012 0.02 2.973 45.75 MAT 20 20 20 0. 0.9 0.5 // 0 gray # pl 0 5.2 0 0 -1 0 0 // floor -qu -5 5 -5 0 0 10 10 0 0 0 +qu -5 5 -5 0 0 10 10 0 0 0 0 MAT 255 100 100 1.0 0.0 0.0 //1 red MAT 100 100 255 1.0 0.0 0.0 //2 blue -po -0.75 1.5 5 0 1.5 0 1.5 0 0 1 2 -po -0.75 10 2.4 0 1.5 0 1.5 0 0 1 1 +po -0.75 1.5 5 0 1.5 0 1.5 0 0 0 2 +po -0.75 10 2.4 0 1.5 0 1.5 0 0 0 1 MAT 200 200 200 0. 0. 0. // 3 white @@ -19,7 +19,7 @@ cu 0 10 0 5 5 5 3 sp 0 10 0 1 4 -OBJ scenes/obj/lambo.obj 0 1.5 0 1 0 0 0 +OBJ obj/lambo.obj 0 1.5 0 1 0 0 0 diff --git a/scenes/noneuclidian.rt b/scenes/noneuclidian.rt index 4a75efa..c47f2c5 100644 --- a/scenes/noneuclidian.rt +++ b/scenes/noneuclidian.rt @@ -7,14 +7,24 @@ MAT 200 200 200 0 0 0 // 2 portal pl 0 0 0 0 1 0 0 +# long tunnel po -1.5 0 4.5 3 0 0 0 3 0 0 2 po -1.5 0 -4.5 3 0 0 0 3 0 1 2 qu -1.5 0 -5 0 3 0 0 0 10 0 1 qu 1.5 0 -5 0 3 0 0 0 10 0 1 - qu -1.5 3 -5 3 0 0 0 0 10 0 1 +# small tunnel +qu 9.5 0 -1 0 3 0 0 0 2 0 1 +qu 12.5 0 -1 0 3 0 0 0 2 0 1 +qu 9.5 3 -1 3 0 0 0 0 2 0 1 -cu 10 1.5 0 3 3 5 1 +# small tunnel entrance +po 9.5 0 1 3 0 0 0 3 0 0 2 +po -1.5 0 4.49 3 0 0 0 3 0 1 2 + +#small tunnel entrace behind +po 9.5 0 -1 3 0 0 0 3 0 1 2 +po -1.5 0 -4.49 3 0 0 0 3 0 0 2 \ No newline at end of file diff --git a/scenes/portalcornell.rt b/scenes/portalcornell.rt index 15146bc..fa2fe75 100644 --- a/scenes/portalcornell.rt +++ b/scenes/portalcornell.rt @@ -18,7 +18,7 @@ pl 0 0 0 0 1 0 0 cu 0 0.5 0 1 1 1 1 sp 0 1.5 0 1 1 -qu -1 4 -1 2 0 0 0 0 2 2 +qu -1 4 -1 2 0 0 0 0 2 1 2 cu 0 2.5 0 5 5 5 1 diff --git a/scenes/portalrotation.rt b/scenes/portalrotation.rt index d765ace..34f5369 100644 --- a/scenes/portalrotation.rt +++ b/scenes/portalrotation.rt @@ -9,7 +9,7 @@ MAT 255 255 100 0.0 0.0 0.0 //yellow MAT 50 50 50 0.0 0.0 0.0 //gray -qu -1 2.5 -1 2 0 0 0 0 2 0 +qu -1 2.5 -1 2 0 0 0 0 2 0 0 pl 0 3 0 0 -1 0 1 pl 0 -3 0 0 1 0 6 From 635cadf52719b96e9c8f69700a2a9688ae6cac75 Mon Sep 17 00:00:00 2001 From: TheRedShip Date: Tue, 4 Feb 2025 22:36:10 +0100 Subject: [PATCH 09/21] + | Portal teleportation --- includes/RT/Camera.hpp | 6 +++++- scenes/dragon.rt | 6 +++--- scenes/lambo.rt | 2 +- scenes/noneuclidian.rt | 27 ++++++++++++++++++--------- srcs/class/Camera.cpp | 40 +++++++++++++++++++++++++++++++++++++++- srcs/class/Window.cpp | 2 +- 6 files changed, 67 insertions(+), 16 deletions(-) diff --git a/includes/RT/Camera.hpp b/includes/RT/Camera.hpp index 32886fb..757680f 100644 --- a/includes/RT/Camera.hpp +++ b/includes/RT/Camera.hpp @@ -26,6 +26,8 @@ struct GPUCamera int bounce; }; +class Scene; + class Camera { public: @@ -34,12 +36,14 @@ class Camera ~Camera(void); - void update(float deltaTime); + void update(Scene *scene, float deltaTime); void processMouse(float xoffset, float yoffset, bool constrainPitch); void processKeyboard(bool forward, bool backward, bool left, bool right, bool up, bool down); void updateCameraVectors(); + void portalTeleport(Scene *scene); + glm::vec3 getPosition(); glm::vec2 getDirection(); glm::mat4 getViewMatrix(); diff --git a/scenes/dragon.rt b/scenes/dragon.rt index 93963d9..fd53608 100644 --- a/scenes/dragon.rt +++ b/scenes/dragon.rt @@ -22,10 +22,10 @@ pl 0 2 0 0 -1 0 0 // ceiling 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 0 0 2 2 0 0 1 6 OBJ scenes/obj/Dragon_800K.obj -0.5 0 0.55 5 0 90 0 OBJ scenes/obj/Dragon_800K.obj 0.5 0 -0.55 5 0 -90 0 -po -1.99 -0.5 -0.5 0 1 0 0 0 1 1 4 -po 1.99 -0.5 -0.5 0 1 0 0 0 1 0 4 +po -1.99 -0.5 -0.5 0 1 0 0 0 1 0 4 +po 1.99 -0.5 -0.5 0 1 0 0 0 1 1 4 diff --git a/scenes/lambo.rt b/scenes/lambo.rt index 19c8f89..eb4dc9a 100644 --- a/scenes/lambo.rt +++ b/scenes/lambo.rt @@ -19,7 +19,7 @@ cu 0 10 0 5 5 5 3 sp 0 10 0 1 4 -OBJ obj/lambo.obj 0 1.5 0 1 0 0 0 +OBJ scenes/obj/lambo.obj 0 1.5 0 1 0 0 0 diff --git a/scenes/noneuclidian.rt b/scenes/noneuclidian.rt index c47f2c5..c9af13c 100644 --- a/scenes/noneuclidian.rt +++ b/scenes/noneuclidian.rt @@ -3,18 +3,27 @@ CAM 0 2.59881 7 -4.8 -89.9996 0 1 90 5 MAT 100 200 100 0.0 0.0 0.0 // 0 MAT 200 200 200 0.0 0.0 0.0 // 1 -MAT 200 200 200 0 0 0 // 2 portal +MAT 200 100 100 0 0 0 // 2 portal +MAT 100 100 200 0 0 0 // 3 portal + +MAT 100 200 100 0 0 0 // 4 portal +MAT 200 100 200 0 0 0 // 5 portal pl 0 0 0 0 1 0 0 # long tunnel -po -1.5 0 4.5 3 0 0 0 3 0 0 2 -po -1.5 0 -4.5 3 0 0 0 3 0 1 2 - qu -1.5 0 -5 0 3 0 0 0 10 0 1 qu 1.5 0 -5 0 3 0 0 0 10 0 1 qu -1.5 3 -5 3 0 0 0 0 10 0 1 +# long tunnel entrance +po -1.5 0 5 3 0 0 0 3 0 0 2 +po 9.5 0 0.95 3 0 0 0 3 0 1 2 + +# long tunnel entrance behind +po -1.5 0 -5 3 0 0 0 3 0 1 3 +po 9.5 0 -0.95 3 0 0 0 3 0 0 3 + # small tunnel qu 9.5 0 -1 0 3 0 0 0 2 0 1 @@ -22,9 +31,9 @@ qu 12.5 0 -1 0 3 0 0 0 2 0 1 qu 9.5 3 -1 3 0 0 0 0 2 0 1 # small tunnel entrance -po 9.5 0 1 3 0 0 0 3 0 0 2 -po -1.5 0 4.49 3 0 0 0 3 0 1 2 +# po 9.5 0 1 3 0 0 0 3 0 0 4 +# po -1.5 0 4.99 3 0 0 0 3 0 1 4 -#small tunnel entrace behind -po 9.5 0 -1 3 0 0 0 3 0 1 2 -po -1.5 0 -4.49 3 0 0 0 3 0 0 2 \ No newline at end of file +# #small tunnel entrace behind +# po 9.5 0 -1 3 0 0 0 3 0 1 5 +# po -1.5 0 -4.99 3 0 0 0 3 0 0 5 \ No newline at end of file diff --git a/srcs/class/Camera.cpp b/srcs/class/Camera.cpp index aaab1b0..450f5ac 100644 --- a/srcs/class/Camera.cpp +++ b/srcs/class/Camera.cpp @@ -36,7 +36,7 @@ void Camera::updateCameraVectors() _up = glm::normalize(glm::cross(_right, _forward)); } -void Camera::update(float delta_time) +void Camera::update(Scene *scene, float delta_time) { // delta_time = std::min(delta_time, 0.01f); @@ -51,8 +51,46 @@ void Camera::update(float delta_time) _position += _velocity * delta_time; _acceleration = glm::vec3(0.0f); + + this->portalTeleport(scene); } +void Camera::portalTeleport(Scene *scene) +{ + for (const GPUObject &obj : scene->getObjectData()) + { + if (obj.type != (int)Object::Type::PORTAL) + continue; + + glm::vec3 portal_to_camera = _position - obj.position; + float distance_plane = glm::dot(portal_to_camera, obj.normal); + glm::vec3 point_projected = _position - distance_plane * obj.normal; + + glm::mat2 A = glm::mat2( + glm::dot(obj.vertex1, obj.vertex1), glm::dot(obj.vertex1, obj.vertex2), + glm::dot(obj.vertex1, obj.vertex2), glm::dot(obj.vertex2, obj.vertex2) + ); + glm::vec2 b = glm::vec2( + glm::dot(point_projected - obj.position, obj.vertex1), + glm::dot(point_projected - obj.position, obj.vertex2) + ); + glm::vec2 alphaBeta = glm::inverse(A) * b; + + if (alphaBeta.x >= 0.0f && alphaBeta.x <= 1.0f && alphaBeta.y >= 0.0f && alphaBeta.y <= 1.0f) + { + float distance = glm::length(point_projected - _position); + if (distance < 0.1f) + { + GPUObject linked_portal = scene->getObjectData()[obj.radius]; + std::cout << glm::to_string(point_projected) << std::endl; + _position = linked_portal.position + (_position - obj.position) - linked_portal.normal * 0.1f; + std::cout << "Teleporting to " << glm::to_string(_position) << std::endl; + + break ; + } + } + } +} void Camera::processMouse(float xoffset, float yoffset, bool constraint_pitch = true) { diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index bfc3fa1..d440611 100644 --- a/srcs/class/Window.cpp +++ b/srcs/class/Window.cpp @@ -155,7 +155,7 @@ void Window::display() void Window::pollEvents() { this->process_input(); - _scene->getCamera()->update(_delta); + _scene->getCamera()->update(_scene, _delta); glfwPollEvents(); } From cb7eb9346cdc7f246e4cf09f01464e2a36ce1c01 Mon Sep 17 00:00:00 2001 From: tomoron Date: Thu, 6 Feb 2025 16:31:28 +0100 Subject: [PATCH 10/21] start changing parsing of arguments to add settings and start a render with no input --- .vscode/settings.json | 86 ------------------- Makefile | 1 + imgui.ini | 4 +- includes/RT.hpp | 3 +- includes/RT/Arguments.hpp | 50 +++++++++++ includes/RT/Renderer.hpp | 17 +++- includes/RT/Scene.hpp | 10 ++- includes/RT/SceneParser.hpp | 4 +- scenes/lambo.rt | 2 +- scenes/test.rt | 1 - srcs/RT.cpp | 15 ++-- srcs/class/Arguments.cpp | 141 +++++++++++++++++++++++++++++++ srcs/class/Renderer.cpp | 161 ++++++++++++++++++++++++++++++++---- srcs/class/Scene.cpp | 40 ++++----- srcs/class/SceneParser.cpp | 4 +- srcs/class/Window.cpp | 4 +- 16 files changed, 395 insertions(+), 148 deletions(-) delete mode 100644 .vscode/settings.json create mode 100644 includes/RT/Arguments.hpp create mode 100644 srcs/class/Arguments.cpp diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index abe297a..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "files.associations": { - "*.cs": "csharp", - "atomic": "cpp", - "bit": "cpp", - "cctype": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "compare": "cpp", - "concepts": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "exception": "cpp", - "initializer_list": "cpp", - "ios": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "iterator": "cpp", - "limits": "cpp", - "memory": "cpp", - "new": "cpp", - "ostream": "cpp", - "stdexcept": "cpp", - "streambuf": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "typeinfo": "cpp", - "utility": "cpp", - "xfacet": "cpp", - "xiosbase": "cpp", - "xlocale": "cpp", - "xlocinfo": "cpp", - "xlocnum": "cpp", - "xmemory": "cpp", - "xstddef": "cpp", - "xstring": "cpp", - "xtr1common": "cpp", - "xutility": "cpp", - "array": "cpp", - "vector": "cpp", - "deque": "cpp", - "string_view": "cpp", - "span": "cpp", - "*.tcc": "cpp", - "chrono": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "unordered_set": "cpp", - "memory_resource": "cpp", - "optional": "cpp", - "format": "cpp", - "functional": "cpp", - "sstream": "cpp", - "variant": "cpp", - "charconv": "cpp", - "cstdarg": "cpp", - "cwctype": "cpp", - "map": "cpp", - "set": "cpp", - "algorithm": "cpp", - "numeric": "cpp", - "random": "cpp", - "ratio": "cpp", - "iomanip": "cpp", - "numbers": "cpp", - "cinttypes": "cpp", - "fstream": "cpp", - "list": "cpp", - "locale": "cpp", - "xhash": "cpp", - "xlocbuf": "cpp", - "xlocmes": "cpp", - "xlocmon": "cpp", - "xloctime": "cpp", - "xtree": "cpp", - "forward_list": "cpp" - }, - "cmake.ignoreCMakeListsMissing": true -} \ No newline at end of file diff --git a/Makefile b/Makefile index 7635c57..4cb0d8d 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,7 @@ ALL_SRCS := $(IMGUI_SRCS) \ class/ObjParser.cpp \ class/BVH.cpp \ class/Renderer.cpp \ + class/Arguments.cpp SRCS := $(ALL_SRCS:%=$(SRCS_DIR)/%) OBJS := $(addprefix $(OBJS_DIR)/, $(SRCS:%.cpp=%.o)) diff --git a/imgui.ini b/imgui.ini index 633cc90..8ac2eb7 100644 --- a/imgui.ini +++ b/imgui.ini @@ -29,6 +29,6 @@ Pos=1556,610 Size=284,382 [Window][Settings] -Pos=1568,11 -Size=336,975 +Pos=532,13 +Size=336,287 diff --git a/includes/RT.hpp b/includes/RT.hpp index 84e906f..9e5aebe 100644 --- a/includes/RT.hpp +++ b/includes/RT.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/27 14:52:10 by TheRed #+# #+# */ -/* Updated: 2025/02/03 18:17:48 by ycontre ### ########.fr */ +/* Updated: 2025/02/04 01:10:20 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -57,6 +57,7 @@ struct Vertex { # include "objects/Portal.hpp" # include "objects/Cylinder.hpp" +# include "Arguments.hpp" # include "Camera.hpp" # include "Renderer.hpp" # include "Window.hpp" diff --git a/includes/RT/Arguments.hpp b/includes/RT/Arguments.hpp new file mode 100644 index 0000000..f0a41a6 --- /dev/null +++ b/includes/RT/Arguments.hpp @@ -0,0 +1,50 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Arguments.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/04 01:07:08 by tomoron #+# #+# */ +/* Updated: 2025/02/04 03:10:58 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ARGUMENTS_HPP +# define ARGUMENTS_HPP + +#include "RT.hpp" + +typedef struct s_arg +{ + char shortName; + std::string longName; + int isFlag; +} t_arg; + +class Arguments +{ + public : + Arguments(int argc, char **argv); + bool getHeadless(void) const; + std::string &getSceneName(void); + std::string getRenderPathName(void); + bool error(void) const; + + private: + void printUsage(); + + int handleArg(char **argv, int argc, int *i); + void initArguments(void); + void addArgument(char shortName, std::string longName, int isFlag); + + void parseRenderPathName(char * path); + + bool _headless; + bool _err; + + std::vector _args; + std::map _values; +}; + +#endif diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index e180dc3..6eb54db 100644 --- a/includes/RT/Renderer.hpp +++ b/includes/RT/Renderer.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:29:26 by tomoron #+# #+# */ -/* Updated: 2025/01/30 22:15:55 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 00:41:10 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,21 +37,28 @@ class Renderer { public: Renderer(Scene *scene, Window *win); + Renderer(Scene *scene, Window *win, std::string filename); void renderImgui(void); void update(Shader &shader); int rendering(void) const; + bool shouldClose(void) const; private: void addPoint(float time); + void init(Scene *scene, Window *win); + void savePath(void); + void rawRead(std::ifstream &file, void *buf, size_t len); + void loadPath(std::string filename); void makeMovement(float timeFromStart, float curSplitTimeReset); void initRender(); void addImageToRender(Shader &shader); void endRender(void); void imguiPathCreation(void); void imguiRenderInfo(void); - std::string floatToTime(float timef); + void imguiRenderSettings(void); + std::string floatToTime(double timef); glm::vec2 bezierSphereInterpolate(glm::vec4 control, glm::vec2 from, glm::vec2 to, float time); - void updateAvailableCodecs(void); + void updateAvailableCodecs(int mode, AVCodecID id); void fillGoodCodecList(std::vector &lst); glm::vec3 hermiteInterpolate(glm::vec3 points[4], double alpha); @@ -69,6 +76,10 @@ class Renderer std::vector _codecList; std::vector _codecListStr; int _codecIndex; + bool _renderSettings; + bool _ignoreUnavailableCodec; + bool _headless; + bool _shouldClose; int _curPathIndex; int _destPathIndex; diff --git a/includes/RT/Scene.hpp b/includes/RT/Scene.hpp index 7e78db4..700399c 100644 --- a/includes/RT/Scene.hpp +++ b/includes/RT/Scene.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/23 18:30:18 by ycontre #+# #+# */ -/* Updated: 2025/01/28 19:05:16 by ycontre ### ########.fr */ +/* Updated: 2025/02/04 03:11:36 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -105,11 +105,9 @@ class Camera; class Scene { public: - Scene(); + Scene(std::string &name); ~Scene(); - bool parseScene(char *name); - void addObject(Object *object); void addMaterial(Material *material); void addTexture(std::string path); @@ -141,7 +139,11 @@ class Scene Camera *getCamera(void) const; GPUMaterial getMaterial(int material_index); + bool fail(void) const; + private: + + bool _fail; std::vector _gpu_bvh_data; std::vector _gpu_bvh; diff --git a/includes/RT/SceneParser.hpp b/includes/RT/SceneParser.hpp index 59cdc0a..d5932e6 100644 --- a/includes/RT/SceneParser.hpp +++ b/includes/RT/SceneParser.hpp @@ -6,7 +6,7 @@ /* By: TheRed +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/26 21:37:37 by TheRed #+# #+# */ -/* Updated: 2025/01/21 15:15:13 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 01:21:28 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,7 +18,7 @@ class SceneParser { public: - SceneParser(Scene *scene, char *filename); + SceneParser(Scene *scene, std::string filename); bool parseLine(const std::string &line); diff --git a/scenes/lambo.rt b/scenes/lambo.rt index eb4dc9a..19c8f89 100644 --- a/scenes/lambo.rt +++ b/scenes/lambo.rt @@ -19,7 +19,7 @@ cu 0 10 0 5 5 5 3 sp 0 10 0 1 4 -OBJ scenes/obj/lambo.obj 0 1.5 0 1 0 0 0 +OBJ obj/lambo.obj 0 1.5 0 1 0 0 0 diff --git a/scenes/test.rt b/scenes/test.rt index dd47a1b..400725e 100644 --- a/scenes/test.rt +++ b/scenes/test.rt @@ -15,4 +15,3 @@ OBJ scenes/obj/jinx.obj -10 0 0 1.25 0 0 0 # OBJ scenes/obj/Dragon_800K.obj 0 0 0 35 0 0 0 1 OBJ scenes/obj/whitedragon.obj 0 0 0 1 0 0 0 - diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 96a41e7..10c0e60 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/02/02 19:44:53 by ycontre ### ########.fr */ +/* Updated: 2025/02/06 16:30:58 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,15 +14,16 @@ int main(int argc, char **argv) { - Scene scene; - - if (argc <= 1 || !scene.parseScene(argv[1])) - return (1); - + Arguments args(argc, argv); + if(args.error()) + return(1); + Scene scene(args.getSceneName()); + if(scene.fail()) + 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"); - + GLint max_gpu_size; glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_gpu_size); diff --git a/srcs/class/Arguments.cpp b/srcs/class/Arguments.cpp new file mode 100644 index 0000000..3a6fbe1 --- /dev/null +++ b/srcs/class/Arguments.cpp @@ -0,0 +1,141 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Arguments.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/04 01:05:44 by tomoron #+# #+# */ +/* Updated: 2025/02/04 03:16:25 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "RT.hpp" + +Arguments::Arguments(int argc, char **argv) +{ + initArguments(); + _headless = 0; + _err = 0; + + if(argc <= 1) + { + _err = 1; + printUsage(); + return ; + } + + for(int i = 1; i < argc; i++) + { + if(!handleArg(argv, argc, &i)) + { + _err = 1; + return ; + } + } + if(_values.find("sceneName") == _values.end()) + { + std::cerr << "missing scene name" << std::endl; + _err = 1; + } +} + +void Arguments::printUsage(void) +{ + std::cerr << "usage : [options] [options]" << std::endl; + std::cerr << R""""(options : + -r | --renderpath : filename for the renderer path + -h | --headless : does the program need to start rendering as soon as it starts(and close automatically) +)""""; +} + +bool Arguments::error(void) const +{ + return(_err); +} + +std::string &Arguments::getSceneName(void) +{ + return(_values["sceneName"]); +} + +void Arguments::addArgument(char shortName, std::string longName, int isFlag) +{ + t_arg arg; + + arg.shortName = shortName; + arg.longName = longName; + arg.isFlag = isFlag; + _args.push_back(arg); +} + +void Arguments::initArguments() +{ + addArgument('r', "renderPath", 0); + addArgument('h', "headless", 1); +} + +int Arguments::handleArg(char **argv, int argc, int *i) +{ + std::string arg(argv[*i]); + + (void)i; + if(!arg.size()) + return(1); + if(arg.size() >= 2 && arg[0] == '-' && arg[1] == '-') + { + for(std::vector::iterator it = _args.begin(); it != _args.end(); it++) + { + if((*it).longName == arg.substr(2)) + { + if((*it).isFlag) + _values[(*it).longName] = "yes"; + else if(*i == argc - 1) + { + std::cerr << "missing option" << std::endl; + return(0); + } + else + _values[(*it).longName] = argv[++(*i)]; + return(1); + } + } + std::cerr<< "unrecognized option : " << arg << std::endl; + return(0); + } + else if(arg[0] == '-') + { + for(size_t j = 1; j < arg.size(); j++) + { + for(std::vector::iterator it = _args.begin(); it != _args.end(); it++) + { + if((*it).shortName == arg[j]) + { + if((*it).isFlag) + _values[(*it).longName] = "yes"; + else if(*i == argc - 1) + { + std::cerr << "missing option" << std::endl; + return(0); + } + else + _values[(*it).longName] = argv[++(*i)]; + return(1); + } + } + std::cerr << "unrecognized option : -" << arg[j] << std::endl; + return(0); + } + } + else + { + if(_values.find("sceneName") == _values.end()) + _values["sceneName"] = arg; + else + { + std::cerr << "unrecognized option : " << arg << std::endl; + return(0); + } + } + return(1); +} diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index d90692e..65e0a2e 100644 --- a/srcs/class/Renderer.cpp +++ b/srcs/class/Renderer.cpp @@ -6,25 +6,41 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ -/* Updated: 2025/01/30 22:22:07 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 00:43:18 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "RT.hpp" Renderer::Renderer(Scene *scene, Window *win) +{ + init(scene, win); + _headless = 0; +} + +Renderer::Renderer(Scene *scene, Window *win, std::string filename) +{ + init(scene, win); + _headless = 1; + loadPath(filename); + initRender(); +} + +void Renderer::init(Scene *scene, Window *win) { _scene = scene; _win = win; _min = 0; _sec = 0; _fps = 30; + _shouldClose = 0; _autoTime = 0; _samples = 1; _testSamples = 1; _curSamples = 0; _destPathIndex = 0; _frameCount = 0; + _renderSettings = 0; _outputFilename = "output.avi"; memcpy(_filenameBuffer, _outputFilename.c_str(), _outputFilename.length()); _filenameBuffer[_outputFilename.length()] = 0; @@ -33,7 +49,87 @@ Renderer::Renderer(Scene *scene, Window *win) _yuv_frame = 0; _format = 0; _codec_context = 0; - updateAvailableCodecs(); + _ignoreUnavailableCodec = 0; + updateAvailableCodecs(_ignoreUnavailableCodec, (AVCodecID)0); +} + +void Renderer::rawRead(std::ifstream &file, void *buf, size_t len) +{ + file.read((char *)buf, len); + if(file.fail()) + throw std::runtime_error("syntax error in path file"); +} + +/* path file format (bytes): + * - output file name (terminated by a \0) + * - codec id + * - samples per image + * - fps + * - path nodes (until the end) + */ +void Renderer::savePath(void) +{ + std::ofstream outputFile; + const AVCodec *codec; + + codec = _codecList[_codecIndex]; + outputFile.open("output.path", std::ios::binary); + outputFile.write(_outputFilename.c_str(), _outputFilename.length() + 1); + outputFile.write((char *)&codec->id, sizeof(codec->id)); + outputFile.write((char *)&_samples, sizeof(_samples)); + outputFile.write((char *)&_fps, sizeof(_fps)); + for(std::vector::iterator it = _path.begin(); it != _path.end(); it++) + outputFile.write((char *)&(*it), sizeof(t_pathPoint)); + outputFile.close(); +} + + +void Renderer::loadPath(std::string filename) +{ + std::ifstream file; + AVCodecID codecId; + t_pathPoint pathPoint; + std::vector::iterator pos; + char c; + + _outputFilename = ""; + _filenameBuffer[0] = 0; + file.open(filename); + c = 1; + while(c) + { + rawRead(file, &c, 1); + if(c && c < 32 && c > 126) + throw std::runtime_error("invalid char in filename"); + if(c) + _outputFilename += c; + } + rawRead(file, &codecId, sizeof(codecId)); + updateAvailableCodecs(2, codecId); + if(_codecList.size() == 0) + throw std::runtime_error("codec not available"); + rawRead(file, &_samples, sizeof(_samples)); + rawRead(file, &_fps, sizeof(_fps)); + if(_samples < 1 || _fps < 1) + throw std::runtime_error("invalid value provided in fps or samples"); + while(!file.eof()) + { + rawRead(file, &pathPoint, sizeof(t_pathPoint)); + if(pathPoint.time < .0f) + throw std::runtime_error("invalid time provided in path"); + pos = _path.begin(); + while(pos != _path.end() && pos->time <= pathPoint.time) + pos++; + _path.insert(pos, pathPoint); + } + if(_path.size() < 2) + throw std::runtime_error("not enough path points provided in the path"); + file.close(); +} + +bool Renderer::shouldClose(void) const +{ + return(_shouldClose); } void Renderer::fillGoodCodecList(std::vector &lst) @@ -46,7 +142,12 @@ void Renderer::fillGoodCodecList(std::vector &lst) lst.push_back(AV_CODEC_ID_V210); } -void Renderer::updateAvailableCodecs(void) +/* modes : + * 0 : adds only supported codecs are showed + * 1 : adds all codecs + * 2 : adds only codec + */ +void Renderer::updateAvailableCodecs(int mode, AVCodecID id) { const AVCodec *codec; AVCodecContext *ctx; @@ -69,6 +170,11 @@ void Renderer::updateAvailableCodecs(void) codec = avcodec_find_encoder(*it); if(!codec) continue; + if (mode == 1 || (mode == 2 && codec->id == id)) + { + _codecList.push_back(codec); + continue; + } ctx = avcodec_alloc_context3(codec); if(ctx) { @@ -226,6 +332,8 @@ void Renderer::endRender(void) _rgb_frame = 0; _yuv_frame = 0; _codec_context = 0; + if(_headless) + _shouldClose = 1; } void Renderer::addPoint(float time) @@ -442,15 +550,9 @@ void Renderer::imguiPathCreation(void) prevSpeed = 0; ImGui::SliderInt("test spi", &_testSamples, 1, 10); - ImGui::SliderInt("render spi", &_samples, 1, 1000); - ImGui::SliderInt("render fps", &_fps, 30, 120); - ImGui::Combo("codec", &_codecIndex, _codecListStr.data(), _codecListStr.size()); - if(ImGui::InputText("file name", _filenameBuffer, 512)) - { - _outputFilename = _filenameBuffer; - updateAvailableCodecs(); - } + if(ImGui::Button("render settings")) + _renderSettings = 1; if(_path.size() > 1 && ImGui::Button("try full path")) { _scene->getCamera()->setPosition(_path[0].pos); @@ -461,8 +563,6 @@ void Renderer::imguiPathCreation(void) _destPathIndex = _path.size() - 1; _testMode = 1; } - if(_path.size() > 1 && _codecList.size() && ImGui::Button("start render")) - initRender(); ImGui::Separator(); @@ -485,6 +585,7 @@ void Renderer::imguiPathCreation(void) if(ImGui::Button("add step")) addPoint(time); + ImGui::Separator(); for(unsigned long i = 0; i < _path.size(); i++) @@ -529,7 +630,7 @@ void Renderer::imguiPathCreation(void) } } -std::string Renderer::floatToTime(float timef) +std::string Renderer::floatToTime(double timef) { std::string res; uint64_t time; @@ -537,13 +638,13 @@ std::string Renderer::floatToTime(float timef) int firstValue; time = timef; - values[0] = time / 3600 * 24 * 365; + values[0] = time / (3600 * 24 * 365); time = time % (3600 * 24 * 365); - values[1] = time / 3600 * 24 * 30; + values[1] = time / (3600 * 24 * 30); time = time % (3600 * 24 * 30); - values[2] = time / 3600 * 24 * 7; + values[2] = time / (3600 * 24 * 7); time = time % (3600 * 24 * 7); - values[3] = time / 3600 * 24; + values[3] = time / (3600 * 24); time = time % (3600 * 24); values[4] = time / 3600; time = time % 3600; @@ -619,6 +720,28 @@ void Renderer::imguiRenderInfo(void) } } +void Renderer::imguiRenderSettings(void) +{ + ImGui::SliderInt("render spi", &_samples, 1, 1000); + ImGui::SliderInt("render fps", &_fps, 30, 120); + ImGui::Combo("codec", &_codecIndex, _codecListStr.data(), _codecListStr.size()); + if(ImGui::InputText("file name", _filenameBuffer, 512)) + { + _outputFilename = _filenameBuffer; + updateAvailableCodecs(_ignoreUnavailableCodec, (AVCodecID)0); + } + if(_path.size() > 1 && _codecList.size()) + { + if(ImGui::Button("start render")) + initRender(); + ImGui::SameLine(); + if(ImGui::Button("save path")) + savePath(); + } + if(ImGui::Button("go back")) + _renderSettings = 0; +} + void Renderer::renderImgui(void) { // ImGui::Begin("Renderer"); @@ -626,6 +749,8 @@ void Renderer::renderImgui(void) { if(rendering()) imguiRenderInfo(); + else if(_renderSettings) + imguiRenderSettings(); else imguiPathCreation(); } diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index 7c50bc5..68e7c77 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/28 19:17:39 by ycontre ### ########.fr */ +/* Updated: 2025/02/04 03:11:24 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,11 +15,15 @@ #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" -Scene::Scene() +Scene::Scene(std::string &name) { + std::cout << "name : " << name << std::endl; + std::ifstream file(name); + std::string line; _camera = new Camera(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), -90.0f, 0.0f); _gpu_volume.enabled = 0; + _fail = 0; _gpu_volume.sigma_a = glm::vec3(0.0000f); _gpu_volume.sigma_s = glm::vec3(0.0800f); _gpu_volume.sigma_t = _gpu_volume.sigma_a + _gpu_volume.sigma_s; @@ -29,23 +33,13 @@ Scene::Scene() _gpu_debug.mode = 0; _gpu_debug.triangle_treshold = 1; _gpu_debug.box_treshold = 1; -} -Scene::~Scene() -{ - delete (_camera); -} - -bool Scene::parseScene(char *name) -{ - std::ifstream file(name); - std::string line; if (!file.is_open()) { - std::cout << "Error opening the file" << std::endl; - file.close(); - return (false); + std::cerr << "Can't open scene file" << std::endl; + _fail = 1; + return ; } SceneParser scene_parser(this, name); @@ -54,19 +48,22 @@ bool Scene::parseScene(char *name) { if (!scene_parser.parseLine(line)) { - std::cerr << line << std::endl; file.close(); - return (false); + std::cerr << line << std::endl; + _fail = 1; + return ; } } file.close(); std::cout << "Parsing done" << std::endl; - - return (true); } +Scene::~Scene() +{ + delete (_camera); +} void Scene::addObject(Object *obj) { @@ -313,6 +310,11 @@ void Scene::updateLightAndObjects(int mat_id) } } +bool Scene::fail(void) const +{ + return(_fail); +} + std::set Scene::getGPULights() { return (_gpu_lights); diff --git a/srcs/class/SceneParser.cpp b/srcs/class/SceneParser.cpp index cc20dfa..bef35fb 100644 --- a/srcs/class/SceneParser.cpp +++ b/srcs/class/SceneParser.cpp @@ -6,13 +6,13 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/26 21:43:51 by TheRed #+# #+# */ -/* Updated: 2025/01/30 22:29:15 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 01:21:11 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "SceneParser.hpp" -SceneParser::SceneParser(Scene *scene, char *filename) : _scene(scene), _filename(filename) +SceneParser::SceneParser(Scene *scene, std::string filename) : _scene(scene), _filename(filename) { object_parsers["sp"] = [](std::stringstream &ss) -> Object * { return (new Sphere(ss)); }; object_parsers["pl"] = [](std::stringstream &ss) -> Object * { return (new Plane(ss)); }; diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index d440611..5e844fb 100644 --- a/srcs/class/Window.cpp +++ b/srcs/class/Window.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 16:16:24 by TheRed #+# #+# */ -/* Updated: 2025/01/28 15:15:53 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 00:42:01 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -161,7 +161,7 @@ void Window::pollEvents() } bool Window::shouldClose() { - return glfwWindowShouldClose(_window); + return glfwWindowShouldClose(_window) || _renderer->shouldClose(); } void Window::rendererUpdate(Shader &shader) From 7778127a8b84aa71237dc416d36225f8f968d746 Mon Sep 17 00:00:00 2001 From: tomoron Date: Thu, 6 Feb 2025 16:32:44 +0100 Subject: [PATCH 11/21] renderer can now load a path --- Makefile | 2 +- imgui.ini | 2 +- includes/RT/Arguments.hpp | 14 ++++++++----- includes/RT/Renderer.hpp | 5 ++--- includes/RT/Window.hpp | 4 ++-- srcs/RT.cpp | 5 +++-- srcs/class/Arguments.cpp | 40 +++++++++++++++++++++++++++-------- srcs/class/Renderer.cpp | 44 +++++++++++++++++++++++++++------------ srcs/class/Scene.cpp | 3 +-- srcs/class/Window.cpp | 6 +++--- 10 files changed, 84 insertions(+), 41 deletions(-) diff --git a/Makefile b/Makefile index 4cb0d8d..1a789cb 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ else RM := rm -rf DIR_DUP = mkdir -p $(@D) CC := clang++ - CFLAGS := -Wall -Wextra -Werror -g -O3 + CFLAGS := -Wall -Wextra -Werror -g #-O3 IFLAGS := -I./includes -I./includes/RT -I./includes/imgui LDFLAGS += -lglfw -lGL -lGLU -lX11 -lpthread -ldl -lavformat -lavcodec -lavutil -lswscale -lswresample FILE = $(shell ls -lR srcs/ | grep -F .c | wc -l) diff --git a/imgui.ini b/imgui.ini index 8ac2eb7..1a5d442 100644 --- a/imgui.ini +++ b/imgui.ini @@ -29,6 +29,6 @@ Pos=1556,610 Size=284,382 [Window][Settings] -Pos=532,13 +Pos=478,75 Size=336,287 diff --git a/includes/RT/Arguments.hpp b/includes/RT/Arguments.hpp index f0a41a6..62c5b12 100644 --- a/includes/RT/Arguments.hpp +++ b/includes/RT/Arguments.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/04 01:07:08 by tomoron #+# #+# */ -/* Updated: 2025/02/04 03:10:58 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 17:04:59 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,10 +26,14 @@ class Arguments { public : Arguments(int argc, char **argv); - bool getHeadless(void) const; - std::string &getSceneName(void); - std::string getRenderPathName(void); - bool error(void) const; + + bool getHeadless(void) const; + bool error(void) const; + void show(void); + + std::string &getSceneName(void); + std::string *getRenderPath(void); + bool getHeadless(void); private: void printUsage(); diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index 6eb54db..b26038e 100644 --- a/includes/RT/Renderer.hpp +++ b/includes/RT/Renderer.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:29:26 by tomoron #+# #+# */ -/* Updated: 2025/02/04 00:41:10 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 18:46:22 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -36,8 +36,7 @@ typedef struct s_pathPoint class Renderer { public: - Renderer(Scene *scene, Window *win); - Renderer(Scene *scene, Window *win, std::string filename); + Renderer(Scene *scene, Window *win, Arguments &args); void renderImgui(void); void update(Shader &shader); int rendering(void) const; diff --git a/includes/RT/Window.hpp b/includes/RT/Window.hpp index 72cbb6a..4c654d1 100644 --- a/includes/RT/Window.hpp +++ b/includes/RT/Window.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 16:15:41 by TheRed #+# #+# */ -/* Updated: 2025/01/25 03:09:23 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 16:46:37 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,7 +20,7 @@ class Scene; class Window { public: - Window(Scene *scene, int width, int height, const char *title, int sleep); + Window(Scene *scene, int width, int height, const char *title, int sleep, Arguments &args); ~Window(void); void display(); diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 10c0e60..74b3eb7 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/02/06 16:30:58 by tomoron ### ########.fr */ +/* Updated: 2025/02/06 16:32:04 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,12 +15,13 @@ int main(int argc, char **argv) { Arguments args(argc, argv); + args.show(); if(args.error()) return(1); Scene scene(args.getSceneName()); if(scene.fail()) return(1); - Window window(&scene, WIDTH, HEIGHT, "RT_GPU", 0); + Window window(&scene, WIDTH, HEIGHT, "RT_GPU", 0, args); Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/compute.glsl"); // Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/debug.glsl"); diff --git a/srcs/class/Arguments.cpp b/srcs/class/Arguments.cpp index 3a6fbe1..9c25399 100644 --- a/srcs/class/Arguments.cpp +++ b/srcs/class/Arguments.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/04 01:05:44 by tomoron #+# #+# */ -/* Updated: 2025/02/04 03:16:25 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 17:10:24 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -40,25 +40,52 @@ Arguments::Arguments(int argc, char **argv) } } +void Arguments::initArguments() +{ + addArgument('r', "renderpath", 0); + addArgument('h', "headless", 1); +} + void Arguments::printUsage(void) { std::cerr << "usage : [options] [options]" << std::endl; std::cerr << R""""(options : - -r | --renderpath : filename for the renderer path + -r | --renderpath : filename for the renderer path -h | --headless : does the program need to start rendering as soon as it starts(and close automatically) )""""; } +void Arguments::show(void) +{ + for(std::map::iterator it = _values.begin();it != _values.end(); it++) + std::cout << (*it).first << ": " << (*it).second << std::endl; +} + bool Arguments::error(void) const { return(_err); } + std::string &Arguments::getSceneName(void) { return(_values["sceneName"]); } +std::string *Arguments::getRenderPath(void) +{ + if(_values.find("renderpath") != _values.end()) + return(&_values["renderpath"]); + else + return(0); +} + +bool Arguments::getHeadless(void) +{ + return(_values.find("headless") != _values.end()); +} + + void Arguments::addArgument(char shortName, std::string longName, int isFlag) { t_arg arg; @@ -69,11 +96,6 @@ void Arguments::addArgument(char shortName, std::string longName, int isFlag) _args.push_back(arg); } -void Arguments::initArguments() -{ - addArgument('r', "renderPath", 0); - addArgument('h', "headless", 1); -} int Arguments::handleArg(char **argv, int argc, int *i) { @@ -92,7 +114,7 @@ int Arguments::handleArg(char **argv, int argc, int *i) _values[(*it).longName] = "yes"; else if(*i == argc - 1) { - std::cerr << "missing option" << std::endl; + std::cerr << "missing option for --" << (*it).longName << std::endl; return(0); } else @@ -115,7 +137,7 @@ int Arguments::handleArg(char **argv, int argc, int *i) _values[(*it).longName] = "yes"; else if(*i == argc - 1) { - std::cerr << "missing option" << std::endl; + std::cerr << "missing option for --" << (*it).longName << std::endl; return(0); } else diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index 65e0a2e..cc24d00 100644 --- a/srcs/class/Renderer.cpp +++ b/srcs/class/Renderer.cpp @@ -6,24 +6,33 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ -/* Updated: 2025/02/04 00:43:18 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 19:06:00 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "RT.hpp" -Renderer::Renderer(Scene *scene, Window *win) +Renderer::Renderer(Scene *scene, Window *win, Arguments &args) { - init(scene, win); - _headless = 0; -} + std::string *renderPath; -Renderer::Renderer(Scene *scene, Window *win, std::string filename) -{ init(scene, win); - _headless = 1; - loadPath(filename); - initRender(); + _headless = args.getHeadless(); + renderPath = args.getRenderPath(); + if(renderPath) + { + try + { + loadPath(*renderPath); + } + catch (std::exception &e) + { + std::cout << e.what() << std::endl; + _shouldClose = 1; + } + } + if(_headless) + initRender(); } void Renderer::init(Scene *scene, Window *win) @@ -71,15 +80,20 @@ void Renderer::savePath(void) { std::ofstream outputFile; const AVCodec *codec; + (void)codec; codec = _codecList[_codecIndex]; outputFile.open("output.path", std::ios::binary); + if(!outputFile.is_open()) + std::cerr << "could open output.path for writing" << std::endl; outputFile.write(_outputFilename.c_str(), _outputFilename.length() + 1); outputFile.write((char *)&codec->id, sizeof(codec->id)); outputFile.write((char *)&_samples, sizeof(_samples)); outputFile.write((char *)&_fps, sizeof(_fps)); for(std::vector::iterator it = _path.begin(); it != _path.end(); it++) + { outputFile.write((char *)&(*it), sizeof(t_pathPoint)); + } outputFile.close(); } @@ -95,6 +109,8 @@ void Renderer::loadPath(std::string filename) _outputFilename = ""; _filenameBuffer[0] = 0; file.open(filename); + if(!file.is_open()) + std::cerr << "failed to open " << filename << std::endl; c = 1; while(c) { @@ -104,15 +120,17 @@ void Renderer::loadPath(std::string filename) if(c) _outputFilename += c; } + memcpy(_filenameBuffer, _outputFilename.c_str(), _outputFilename.length()); + _filenameBuffer[_outputFilename.length()] = 0; rawRead(file, &codecId, sizeof(codecId)); updateAvailableCodecs(2, codecId); if(_codecList.size() == 0) throw std::runtime_error("codec not available"); rawRead(file, &_samples, sizeof(_samples)); rawRead(file, &_fps, sizeof(_fps)); - if(_samples < 1 || _fps < 1) + if(_samples < 1 || _fps < 1 || _samples >= 1000 || _fps >= 120) throw std::runtime_error("invalid value provided in fps or samples"); - while(!file.eof()) + while(file.peek() != EOF) { rawRead(file, &pathPoint, sizeof(t_pathPoint)); if(pathPoint.time < .0f) @@ -201,7 +219,7 @@ void Renderer::updateAvailableCodecs(int mode, AVCodecID id) void Renderer::initRender(void) { - + //TODO: check values _codecOptions = 0; _destPathIndex = _path.size() - 1; _curPathIndex = 0; diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index 68e7c77..0abd4cb 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/02/04 03:11:24 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 16:43:33 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,7 +17,6 @@ Scene::Scene(std::string &name) { - std::cout << "name : " << name << std::endl; std::ifstream file(name); std::string line; _camera = new Camera(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), -90.0f, 0.0f); diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index 5e844fb..2ae6c47 100644 --- a/srcs/class/Window.cpp +++ b/srcs/class/Window.cpp @@ -6,19 +6,19 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 16:16:24 by TheRed #+# #+# */ -/* Updated: 2025/02/04 00:42:01 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 16:46:29 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "Window.hpp" -Window::Window(Scene *scene, int width, int height, const char *title, int sleep) +Window::Window(Scene *scene, int width, int height, const char *title, int sleep, Arguments &args) { _scene = scene; _fps = 0; _frameCount = 0; _pixelisation = 0; - _renderer = new Renderer(scene, this); + _renderer = new Renderer(scene, this, args); if (!glfwInit()) { From 106db8e29ec2fac7cb0a8b8760bf2ca04598363c Mon Sep 17 00:00:00 2001 From: tomoron Date: Thu, 6 Feb 2025 16:33:19 +0100 Subject: [PATCH 12/21] renderer works in headless mode now --- Makefile | 2 +- imgui.ini | 4 +- includes/RT/Arguments.hpp | 3 +- includes/RT/Renderer.hpp | 3 +- srcs/RT.cpp | 3 +- srcs/class/Arguments.cpp | 50 ++++++++-------- srcs/class/Renderer.cpp | 119 +++++++++++++++++++++++++++++--------- 7 files changed, 126 insertions(+), 58 deletions(-) diff --git a/Makefile b/Makefile index 1a789cb..4cb0d8d 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ else RM := rm -rf DIR_DUP = mkdir -p $(@D) CC := clang++ - CFLAGS := -Wall -Wextra -Werror -g #-O3 + CFLAGS := -Wall -Wextra -Werror -g -O3 IFLAGS := -I./includes -I./includes/RT -I./includes/imgui LDFLAGS += -lglfw -lGL -lGLU -lX11 -lpthread -ldl -lavformat -lavcodec -lavutil -lswscale -lswresample FILE = $(shell ls -lR srcs/ | grep -F .c | wc -l) diff --git a/imgui.ini b/imgui.ini index 1a5d442..b3e0d68 100644 --- a/imgui.ini +++ b/imgui.ini @@ -29,6 +29,6 @@ Pos=1556,610 Size=284,382 [Window][Settings] -Pos=478,75 -Size=336,287 +Pos=83,57 +Size=336,330 diff --git a/includes/RT/Arguments.hpp b/includes/RT/Arguments.hpp index 62c5b12..f5e4eed 100644 --- a/includes/RT/Arguments.hpp +++ b/includes/RT/Arguments.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/04 01:07:08 by tomoron #+# #+# */ -/* Updated: 2025/02/04 17:04:59 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 22:04:04 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -41,6 +41,7 @@ class Arguments int handleArg(char **argv, int argc, int *i); void initArguments(void); void addArgument(char shortName, std::string longName, int isFlag); + int setArg(t_arg arg, char **argv, int argc, int *i); void parseRenderPathName(char * path); diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index b26038e..531b0ef 100644 --- a/includes/RT/Renderer.hpp +++ b/includes/RT/Renderer.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:29:26 by tomoron #+# #+# */ -/* Updated: 2025/02/04 18:46:22 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 21:56:58 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -78,6 +78,7 @@ class Renderer bool _renderSettings; bool _ignoreUnavailableCodec; bool _headless; + bool _tp; bool _shouldClose; int _curPathIndex; diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 74b3eb7..9333913 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/02/06 16:32:04 by tomoron ### ########.fr */ +/* Updated: 2025/02/06 16:32:59 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,7 +15,6 @@ int main(int argc, char **argv) { Arguments args(argc, argv); - args.show(); if(args.error()) return(1); Scene scene(args.getSceneName()); diff --git a/srcs/class/Arguments.cpp b/srcs/class/Arguments.cpp index 9c25399..0f7e7cf 100644 --- a/srcs/class/Arguments.cpp +++ b/srcs/class/Arguments.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/04 01:05:44 by tomoron #+# #+# */ -/* Updated: 2025/02/04 17:10:24 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 22:17:04 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -96,10 +96,25 @@ void Arguments::addArgument(char shortName, std::string longName, int isFlag) _args.push_back(arg); } +int Arguments::setArg(t_arg arg, char **argv, int argc, int *i) +{ + + if(arg.isFlag) + _values[arg.longName] = "yes"; + else if(*i == argc - 1) + { + std::cerr << "missing option for " << arg.longName << std::endl; + return(0); + } + else + _values[arg.longName] = argv[++(*i)]; + return(1); +} int Arguments::handleArg(char **argv, int argc, int *i) { std::string arg(argv[*i]); + std::vector::iterator it; (void)i; if(!arg.size()) @@ -109,18 +124,7 @@ int Arguments::handleArg(char **argv, int argc, int *i) for(std::vector::iterator it = _args.begin(); it != _args.end(); it++) { if((*it).longName == arg.substr(2)) - { - if((*it).isFlag) - _values[(*it).longName] = "yes"; - else if(*i == argc - 1) - { - std::cerr << "missing option for --" << (*it).longName << std::endl; - return(0); - } - else - _values[(*it).longName] = argv[++(*i)]; - return(1); - } + return(setArg((*it), argv, argc, i)); } std::cerr<< "unrecognized option : " << arg << std::endl; return(0); @@ -129,24 +133,20 @@ int Arguments::handleArg(char **argv, int argc, int *i) { for(size_t j = 1; j < arg.size(); j++) { - for(std::vector::iterator it = _args.begin(); it != _args.end(); it++) + for(it = _args.begin(); it != _args.end(); it++) { if((*it).shortName == arg[j]) { - if((*it).isFlag) - _values[(*it).longName] = "yes"; - else if(*i == argc - 1) - { - std::cerr << "missing option for --" << (*it).longName << std::endl; + if(!setArg((*it), argv, argc, i)) return(0); - } - else - _values[(*it).longName] = argv[++(*i)]; - return(1); + break; } } - std::cerr << "unrecognized option : -" << arg[j] << std::endl; - return(0); + if(it == _args.end()) + { + std::cerr << "unrecognized option : -" << arg[j] << std::endl; + return(0); + } } } else diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index cc24d00..c72a118 100644 --- a/srcs/class/Renderer.cpp +++ b/srcs/class/Renderer.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ -/* Updated: 2025/02/04 19:06:00 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 21:56:44 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -31,8 +31,17 @@ Renderer::Renderer(Scene *scene, Window *win, Arguments &args) _shouldClose = 1; } } - if(_headless) - initRender(); + + try{ + if(_headless) + initRender(); + } + catch(std::exception &e) + { + std::cerr << "\033[31m" << e.what() << "\033[0m" << std::endl; + if(_headless) + _shouldClose = 1; + } } void Renderer::init(Scene *scene, Window *win) @@ -42,6 +51,7 @@ void Renderer::init(Scene *scene, Window *win) _min = 0; _sec = 0; _fps = 30; + _tp = 0; _shouldClose = 0; _autoTime = 0; _samples = 1; @@ -219,7 +229,13 @@ void Renderer::updateAvailableCodecs(int mode, AVCodecID id) void Renderer::initRender(void) { - //TODO: check values + if(_path.size() < 2) + throw std::runtime_error("render path doesn't have enough path points"); + if(_path[0].time != 0) + throw std::runtime_error("render path does not start at 0, aborting"); + if(_path[_path.size() - 1].time - _path[0].time <= 0) + throw std::runtime_error("render path is 0 seconds long, aborting"); + _codecOptions = 0; _destPathIndex = _path.size() - 1; _curPathIndex = 0; @@ -230,7 +246,7 @@ void Renderer::initRender(void) _renderStartTime = glfwGetTime(); _scene->getCamera()->setPosition(_path[0].pos); _scene->getCamera()->setDirection(_path[0].dir.x, _path[0].dir.y); - _win->setFrameCount(-1); + _win->setFrameCount(_headless ? 0 : -1); avformat_alloc_output_context2(&_format, nullptr, nullptr, _outputFilename.c_str()); _codec_context = avcodec_alloc_context3(_codecList[_codecIndex]); @@ -248,18 +264,27 @@ void Renderer::initRender(void) _codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; if (avcodec_open2(_codec_context, _codecList[_codecIndex], &_codecOptions) < 0) + { + endRender(); throw std::runtime_error("Failed to open codec"); + } _stream = avformat_new_stream(_format, _codecList[_codecIndex]); if (!_stream) + { + endRender(); throw std::runtime_error("Failed to create stream"); + } _stream->time_base = _codec_context->time_base; avcodec_parameters_from_context(_stream->codecpar, _codec_context); if (!(_format->flags & AVFMT_NOFILE)) { if (avio_open(&_format->pb, _outputFilename.c_str(), AVIO_FLAG_WRITE) < 0) + { + endRender(); throw std::runtime_error("couldn't open " + _outputFilename); + } } (void)avformat_write_header(_format, nullptr); @@ -327,29 +352,40 @@ void Renderer::endRender(void) { AVPacket *pkt; - avcodec_send_frame(_codec_context, 0); - pkt = av_packet_alloc(); - while (avcodec_receive_packet(_codec_context, pkt) == 0) { - pkt->stream_index = _stream->index; - pkt->pts = av_rescale_q(pkt->pts, _codec_context->time_base, _stream->time_base); - pkt->dts = av_rescale_q(pkt->dts, _codec_context->time_base, _stream->time_base); - av_interleaved_write_frame(_format, pkt); - av_packet_unref(pkt); + if(_codec_context) + { + avcodec_send_frame(_codec_context, 0); + pkt = av_packet_alloc(); + while (avcodec_receive_packet(_codec_context, pkt) == 0) { + pkt->stream_index = _stream->index; + pkt->pts = av_rescale_q(pkt->pts, _codec_context->time_base, _stream->time_base); + pkt->dts = av_rescale_q(pkt->dts, _codec_context->time_base, _stream->time_base); + av_interleaved_write_frame(_format, pkt); + av_packet_unref(pkt); + } } av_packet_free(&pkt); - av_write_trailer(_format); - av_frame_free(&_rgb_frame); - av_frame_free(&_yuv_frame); - avcodec_free_context(&_codec_context); - avio_close(_format->pb); - avformat_free_context(_format); - av_dict_free(&_codecOptions); + if(_format) + av_write_trailer(_format); + if(_rgb_frame) + av_frame_free(&_rgb_frame); + if(_yuv_frame) + av_frame_free(&_yuv_frame); + if(_codec_context) + avcodec_free_context(&_codec_context); + if(_format) + avio_close(_format->pb); + if(_format) + avformat_free_context(_format); + if(_codecOptions) + av_dict_free(&_codecOptions); _format = 0; _rgb_frame = 0; _yuv_frame = 0; _codec_context = 0; + _destPathIndex = 0; if(_headless) _shouldClose = 1; } @@ -374,7 +410,6 @@ void Renderer::update(Shader &shader) { double curTime; - (void)shader; if(!_destPathIndex) return; @@ -585,21 +620,44 @@ void Renderer::imguiPathCreation(void) ImGui::Separator(); if(ImGui::SliderInt("minutes", &_min, 0, 2)) + { _autoTime = 0; + _tp = 0; + } if(ImGui::SliderInt("seconds", &_sec, 0, 60)) + { _autoTime = 0; + _tp = 0; + } if(_autoTime) { if(_path.size() > 1) time = _path[_path.size() - 1].time + (glm::distance(_path[_path.size() - 1].pos, _scene->getCamera()->getPosition()) / prevSpeed); else time = (float)_path.size() / 60; + if(std::isnan(time)) + time = _path[_path.size() - 1].time + (1.0f / 60); + _min = time; + _sec = (time - (int)time) * 60; + } + else if(_tp) + { + if(!_path.size()) + time = 0; + else + time = _path[_path.size() - 1].time; _min = time; _sec = (time - (int)time) * 60; } else time = (float)_min + ((float)_sec / 60); + ImGui::Checkbox("guess time automatically", &_autoTime); + if(_autoTime) + _tp = 0; + ImGui::Checkbox("tp", &_tp); + if(_tp) + _autoTime = 0; if(ImGui::Button("add step")) addPoint(time); @@ -743,6 +801,8 @@ void Renderer::imguiRenderSettings(void) ImGui::SliderInt("render spi", &_samples, 1, 1000); ImGui::SliderInt("render fps", &_fps, 30, 120); ImGui::Combo("codec", &_codecIndex, _codecListStr.data(), _codecListStr.size()); + if(ImGui::Checkbox("show all codecs", &_ignoreUnavailableCodec)) + updateAvailableCodecs(_ignoreUnavailableCodec, (AVCodecID)0); if(ImGui::InputText("file name", _filenameBuffer, 512)) { _outputFilename = _filenameBuffer; @@ -750,11 +810,18 @@ void Renderer::imguiRenderSettings(void) } if(_path.size() > 1 && _codecList.size()) { - if(ImGui::Button("start render")) - initRender(); - ImGui::SameLine(); - if(ImGui::Button("save path")) - savePath(); + try + { + if(ImGui::Button("start render")) + initRender(); + ImGui::SameLine(); + if(ImGui::Button("save path")) + savePath(); + } + catch(std::exception &e) + { + std::cerr << "\033[31m" << e.what() << "\033[0m" << std::endl; + } } if(ImGui::Button("go back")) _renderSettings = 0; From 56d564408d28362b9b0410f7d343b4fb8058cb7b Mon Sep 17 00:00:00 2001 From: tomoron Date: Tue, 4 Feb 2025 23:44:23 +0100 Subject: [PATCH 13/21] Renderer now prints status to standard output when in headless mode --- .gitignore | 1 + includes/RT.hpp | 3 +- includes/RT/Renderer.hpp | 4 +-- srcs/class/Renderer.cpp | 70 ++++++++++++++++++++++++++++++---------- 4 files changed, 58 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 7a0338c..128c608 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /RT compile_flags.txt imgui.ini +/output* diff --git a/includes/RT.hpp b/includes/RT.hpp index 9e5aebe..c4d695f 100644 --- a/includes/RT.hpp +++ b/includes/RT.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/27 14:52:10 by TheRed #+# #+# */ -/* Updated: 2025/02/04 01:10:20 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 23:39:14 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -34,6 +34,7 @@ # include # include # include +# include # include # include # include diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index 531b0ef..0e5dcdb 100644 --- a/includes/RT/Renderer.hpp +++ b/includes/RT/Renderer.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:29:26 by tomoron #+# #+# */ -/* Updated: 2025/02/04 21:56:58 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 23:19:37 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,7 +53,7 @@ class Renderer void addImageToRender(Shader &shader); void endRender(void); void imguiPathCreation(void); - void imguiRenderInfo(void); + void showRenderInfo(int isImgui); void imguiRenderSettings(void); std::string floatToTime(double timef); glm::vec2 bezierSphereInterpolate(glm::vec4 control, glm::vec2 from, glm::vec2 to, float time); diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index c72a118..70c7771 100644 --- a/srcs/class/Renderer.cpp +++ b/srcs/class/Renderer.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ -/* Updated: 2025/02/04 21:56:44 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 23:42:00 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -414,6 +414,9 @@ void Renderer::update(Shader &shader) return; _curSamples++; + if(_headless) + showRenderInfo(0); + if((_testMode && _curSamples < _testSamples) || (!_testMode && _curSamples < _samples)) return; @@ -429,6 +432,7 @@ void Renderer::update(Shader &shader) } makeMovement(curTime - _curSplitStart, curTime); _curSamples = 0; + } glm::vec3 Renderer::hermiteInterpolate(glm::vec3 points[4], double alpha) @@ -760,8 +764,9 @@ std::string Renderer::floatToTime(double timef) return(res); } -void Renderer::imguiRenderInfo(void) +void Renderer::showRenderInfo(int isImgui) { + std::ostringstream oss; long int totalFrames; float renderTime; float progress; @@ -776,23 +781,54 @@ void Renderer::imguiRenderInfo(void) timeEst *= (totalFrames * _samples) - ((_frameCount * _samples) + _curSamples); if(timeEst > 1e15) timeEst = 0; - ImGui::Text("render in progress"); - ImGui::Text("samples per frame : %d", _samples); - ImGui::Text("render fps : %d", _fps); - ImGui::Text("total render time : %s", floatToTime((_path[_destPathIndex].time - _path[0].time) * 60).c_str()); - ImGui::Separator(); - ImGui::Text("Frames : %ld / %ld", _frameCount, totalFrames); - ImGui::Text("Frames (with accumulation) : %ld / %ld", (_frameCount * _samples) + _curSamples, totalFrames * _samples); - ImGui::Text("Render time : %dm%f", (int)renderTime, (renderTime - (int)renderTime) * 60); - ImGui::Text("elapsed time : %s", floatToTime(timeElapsed).c_str()); - ImGui::Text("estimated time remaining : %s", floatToTime(timeEst).c_str()); + + oss << std::fixed << std::setprecision(2); + + oss << "render in progress" << std::endl; + oss << "samples per frame : " << _samples << std::endl; + oss << "render fps : " << _fps << std::endl; + oss << "total render time : "; + oss << floatToTime((_path[_destPathIndex].time - _path[0].time) * 60).c_str(); + + if(isImgui) + { + ImGui::Text("%s",oss.str().c_str()); + ImGui::Separator(); + } + else + { + std::cout << "\033[2J\033[H"; + std::cout << oss.str() << std::endl; + std::cout << "-----------------------" << std::endl; + } + oss.str(""); + oss.clear(); + + oss << "Frames : " << _frameCount << " / " << totalFrames << std::endl; + oss << "Frames (with accumulation) : " << (_frameCount * _samples) + _curSamples; + oss << " / " << totalFrames * _samples << std::endl; + oss << "Render time : " << (int)renderTime << "m"; + oss << (renderTime - (int)renderTime) * 60 << "s" << std::endl; + oss << "elapsed time : " << floatToTime(timeElapsed) << std::endl; + oss << "estimated time remaining :" << floatToTime(timeEst); + progress = ((float)_frameCount * _samples) + _curSamples; progress /= (float)totalFrames * _samples; - ImGui::ProgressBar(progress, ImVec2(0, 0)); - if(ImGui::Button("stop")) + + if(isImgui) { - _destPathIndex = 0; - endRender(); + ImGui::Text("%s",oss.str().c_str()); + ImGui::ProgressBar(progress, ImVec2(0, 0)); + if(ImGui::Button("stop")) + { + _destPathIndex = 0; + endRender(); + } + } + else + { + oss << std::endl << progress * 100 << "%"; + std::cout << oss.str() << std::endl; } } @@ -833,7 +869,7 @@ void Renderer::renderImgui(void) if (ImGui::CollapsingHeader("Renderer")) { if(rendering()) - imguiRenderInfo(); + showRenderInfo(1); else if(_renderSettings) imguiRenderSettings(); else From 9e802860ee7da3208d7eabd32b36712b51abbe2b Mon Sep 17 00:00:00 2001 From: RedShip Date: Wed, 5 Feb 2025 20:14:42 +0100 Subject: [PATCH 14/21] + | Almost pixel perfect portals tp --- includes/RT/Camera.hpp | 4 +-- scenes/dragon.rt | 4 +-- scenes/noneuclidian.rt | 12 ++++---- srcs/RT.cpp | 10 +++---- srcs/class/Camera.cpp | 62 ++++++++++++++++++++++-------------------- srcs/class/Window.cpp | 2 +- 6 files changed, 49 insertions(+), 45 deletions(-) diff --git a/includes/RT/Camera.hpp b/includes/RT/Camera.hpp index 757680f..3b81d31 100644 --- a/includes/RT/Camera.hpp +++ b/includes/RT/Camera.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/15 13:59:57 by TheRed #+# #+# */ -/* Updated: 2024/12/23 17:42:18 by ycontre ### ########.fr */ +/* Updated: 2025/02/05 19:05:45 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,7 +42,7 @@ class Camera void updateCameraVectors(); - void portalTeleport(Scene *scene); + int portalTeleport(Scene *scene, float delta_time); glm::vec3 getPosition(); glm::vec2 getDirection(); diff --git a/scenes/dragon.rt b/scenes/dragon.rt index fd53608..3abed3f 100644 --- a/scenes/dragon.rt +++ b/scenes/dragon.rt @@ -24,8 +24,8 @@ pl 0 -2 0 0 1 0 2 // floor qu -1 1.999 -1 0 0 2 2 0 0 1 6 -OBJ scenes/obj/Dragon_800K.obj -0.5 0 0.55 5 0 90 0 -OBJ scenes/obj/Dragon_800K.obj 0.5 0 -0.55 5 0 -90 0 +OBJ obj/Dragon_800K.obj -0.5 0 0.55 5 0 90 0 +OBJ obj/Dragon_800K.obj 0.5 0 -0.55 5 0 -90 0 po -1.99 -0.5 -0.5 0 1 0 0 0 1 0 4 po 1.99 -0.5 -0.5 0 1 0 0 0 1 1 4 diff --git a/scenes/noneuclidian.rt b/scenes/noneuclidian.rt index c9af13c..7ad933b 100644 --- a/scenes/noneuclidian.rt +++ b/scenes/noneuclidian.rt @@ -1,4 +1,4 @@ -CAM 0 2.59881 7 -4.8 -89.9996 0 1 90 5 +CAM -2.43549 3.10568 -6.50845 -16.4 53.8007 0 1 90 5 MAT 100 200 100 0.0 0.0 0.0 // 0 MAT 200 200 200 0.0 0.0 0.0 // 1 @@ -30,10 +30,10 @@ qu 9.5 0 -1 0 3 0 0 0 2 0 1 qu 12.5 0 -1 0 3 0 0 0 2 0 1 qu 9.5 3 -1 3 0 0 0 0 2 0 1 -# small tunnel entrance -# po 9.5 0 1 3 0 0 0 3 0 0 4 -# po -1.5 0 4.99 3 0 0 0 3 0 1 4 +# # small tunnel entrance +# po 9.5 2 1 3 0 0 0 3 0 0 4 +# po -1.5 2 4 3 0 0 0 3 0 1 4 # #small tunnel entrace behind -# po 9.5 0 -1 3 0 0 0 3 0 1 5 -# po -1.5 0 -4.99 3 0 0 0 3 0 0 5 \ No newline at end of file +# po 9.5 2 -1 3 0 0 0 3 0 1 5 +# po -1.5 2 -4 3 0 0 0 3 0 0 5 \ No newline at end of file diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 9333913..4dacf7f 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/02/06 16:32:59 by tomoron ### ########.fr */ +/* Updated: 2025/02/06 16:33:36 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,11 +15,11 @@ int main(int argc, char **argv) { Arguments args(argc, argv); - if(args.error()) - return(1); + if (args.error()) + return (1); Scene scene(args.getSceneName()); - if(scene.fail()) - return(1); + if (scene.fail()) + return (1); Window window(&scene, WIDTH, HEIGHT, "RT_GPU", 0, args); Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/compute.glsl"); // Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/debug.glsl"); diff --git a/srcs/class/Camera.cpp b/srcs/class/Camera.cpp index 450f5ac..3aaf6f7 100644 --- a/srcs/class/Camera.cpp +++ b/srcs/class/Camera.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/15 14:00:38 by TheRed #+# #+# */ -/* Updated: 2025/01/28 02:15:41 by tomoron ### ########.fr */ +/* Updated: 2025/02/05 20:09:58 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,20 +42,20 @@ void Camera::update(Scene *scene, float delta_time) _velocity += _acceleration * delta_time; - if (glm::length(_acceleration) < 0.1f) - _velocity *= std::max(0.0f, 1.0f - _deceleration_rate * delta_time); - - float speed = glm::length(_velocity); - if (speed > _maxSpeed) - _velocity = glm::normalize(_velocity) * _maxSpeed; - - _position += _velocity * delta_time; - _acceleration = glm::vec3(0.0f); + if (glm::length(_acceleration) < 0.1f) + _velocity *= std::max(0.0f, 1.0f - _deceleration_rate * delta_time); + + float speed = glm::length(_velocity); + if (speed > _maxSpeed) + _velocity = glm::normalize(_velocity) * _maxSpeed; + + if (glm::length(_velocity) > 0.0f && !this->portalTeleport(scene, delta_time)) + _position += _velocity * delta_time; - this->portalTeleport(scene); + _acceleration = glm::vec3(0.0f); } -void Camera::portalTeleport(Scene *scene) +int Camera::portalTeleport(Scene *scene, float delta_time) { for (const GPUObject &obj : scene->getObjectData()) { @@ -74,22 +74,26 @@ void Camera::portalTeleport(Scene *scene) glm::dot(point_projected - obj.position, obj.vertex1), glm::dot(point_projected - obj.position, obj.vertex2) ); - glm::vec2 alphaBeta = glm::inverse(A) * b; + glm::vec2 alphaBeta = glm::inverse(A) * b; if (alphaBeta.x >= 0.0f && alphaBeta.x <= 1.0f && alphaBeta.y >= 0.0f && alphaBeta.y <= 1.0f) { - float distance = glm::length(point_projected - _position); - if (distance < 0.1f) + glm::vec3 future_pos = _position + _velocity * delta_time; + + float distance_future_pos = glm::length(future_pos - _position); + float distance_portal = glm::length(point_projected - _position); + + if (distance_portal <= distance_future_pos && glm::dot(glm::normalize(future_pos - _position), obj.normal) > 0.0f) { GPUObject linked_portal = scene->getObjectData()[obj.radius]; - std::cout << glm::to_string(point_projected) << std::endl; - _position = linked_portal.position + (_position - obj.position) - linked_portal.normal * 0.1f; - std::cout << "Teleporting to " << glm::to_string(_position) << std::endl; + _position = (linked_portal.position) + (_position - obj.position) - (((distance_future_pos - distance_portal)) * linked_portal.normal); - break ; + return (1); } } } + + return (0); } void Camera::processMouse(float xoffset, float yoffset, bool constraint_pitch = true) @@ -115,16 +119,16 @@ void Camera::processKeyboard(bool forward, bool backward, bool left, bool right glm::vec3 acceleration(0.0f); if (forward) acceleration += _forward; - if (backward) acceleration -= _forward; - if (right) acceleration += _right; - if (left) acceleration -= _right; - if (up) acceleration += _up; - if (down) acceleration -= _up; - - if (glm::length(acceleration) > 0.1f) - acceleration = glm::normalize(acceleration) * _acceleration_rate; - - _acceleration = acceleration; + if (backward) acceleration -= _forward; + if (right) acceleration += _right; + if (left) acceleration -= _right; + if (up) acceleration += _up; + if (down) acceleration -= _up; + + if (glm::length(acceleration) > 0.1f) + acceleration = glm::normalize(acceleration) * _acceleration_rate; + + _acceleration = acceleration; } glm::mat4 Camera::getViewMatrix() diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index 2ae6c47..108f583 100644 --- a/srcs/class/Window.cpp +++ b/srcs/class/Window.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 16:16:24 by TheRed #+# #+# */ -/* Updated: 2025/02/04 16:46:29 by tomoron ### ########.fr */ +/* Updated: 2025/02/05 20:01:29 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ From 63728e6476c93428b83028dcecd81c4e742cab5c Mon Sep 17 00:00:00 2001 From: tomoron Date: Wed, 5 Feb 2025 20:11:08 +0100 Subject: [PATCH 15/21] clean up renderer --- includes/RT/Renderer.hpp | 86 +++++++++++++---------- srcs/class/Renderer.cpp | 143 +++++++++++++++------------------------ 2 files changed, 104 insertions(+), 125 deletions(-) diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index 0e5dcdb..eb8f5ba 100644 --- a/includes/RT/Renderer.hpp +++ b/includes/RT/Renderer.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:29:26 by tomoron #+# #+# */ -/* Updated: 2025/02/04 23:19:37 by tomoron ### ########.fr */ +/* Updated: 2025/02/05 17:24:37 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,50 +37,46 @@ class Renderer { public: Renderer(Scene *scene, Window *win, Arguments &args); - void renderImgui(void); - void update(Shader &shader); - int rendering(void) const; - bool shouldClose(void) const; + + void update(Shader &shader); + void renderImgui(void); + + int rendering(void) const; + bool shouldClose(void) const; private: - void addPoint(float time); - void init(Scene *scene, Window *win); - void savePath(void); - void rawRead(std::ifstream &file, void *buf, size_t len); - void loadPath(std::string filename); - void makeMovement(float timeFromStart, float curSplitTimeReset); - void initRender(); - void addImageToRender(Shader &shader); - void endRender(void); - void imguiPathCreation(void); - void showRenderInfo(int isImgui); - void imguiRenderSettings(void); + void init(Scene *scene, Window *win); + + void showRenderInfo(int isImgui); std::string floatToTime(double timef); - glm::vec2 bezierSphereInterpolate(glm::vec4 control, glm::vec2 from, glm::vec2 to, float time); - void updateAvailableCodecs(int mode, AVCodecID id); - void fillGoodCodecList(std::vector &lst); + float calcTime(void); + + void addPoint(float time); + void imguiPathCreation(void); + void imguiRenderSettings(void); + + void rawRead(std::ifstream &file, void *buf, size_t len); + void savePath(void); + void loadPath(std::string filename); + + void makeMovement(float timeFromStart, float curSplitTimeReset); + glm::vec2 bezierSphereInterpolate(glm::vec4 control, glm::vec2 from, glm::vec2 to, float time); glm::vec3 hermiteInterpolate(glm::vec3 points[4], double alpha); - int _min; - int _sec; - int _samples; - int _testSamples; - bool _autoTime; - int _fps; - char _filenameBuffer[512]; - std::vector _path; - std::string _outputFilename; + void initRender(); + void fillGoodCodecList(std::vector &lst); + void updateAvailableCodecs(int mode, AVCodecID id); + void addImageToRender(Shader &shader); + void endRender(void); + + Scene *_scene; Window *_win; - std::vector _codecList; - std::vector _codecListStr; - int _codecIndex; - bool _renderSettings; - bool _ignoreUnavailableCodec; - bool _headless; - bool _tp; bool _shouldClose; + bool _headless; + std::string _outputFilename; + std::vector _path; int _curPathIndex; int _destPathIndex; double _curSplitStart; @@ -89,6 +85,22 @@ class Renderer long int _frameCount; float _renderStartTime; + + int _samples; + int _testSamples; + int _min; + int _sec; + int _fps; + char _filenameBuffer[512]; + bool _ignoreUnavailableCodec; + bool _tp; + bool _autoTime; + std::vector _codecListStr; + int _codecIndex; + + bool _renderSettings; + + AVFormatContext *_format; AVCodecContext *_codec_context; AVFrame *_rgb_frame; @@ -96,7 +108,7 @@ class Renderer SwsContext *_sws_context; AVStream *_stream; AVDictionary *_codecOptions; - + std::vector _codecList; }; #endif diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index 70c7771..938559b 100644 --- a/srcs/class/Renderer.cpp +++ b/srcs/class/Renderer.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ -/* Updated: 2025/02/04 23:42:00 by tomoron ### ########.fr */ +/* Updated: 2025/02/05 17:21:00 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,6 +19,7 @@ Renderer::Renderer(Scene *scene, Window *win, Arguments &args) init(scene, win); _headless = args.getHeadless(); renderPath = args.getRenderPath(); + if(renderPath) { try @@ -101,9 +102,7 @@ void Renderer::savePath(void) outputFile.write((char *)&_samples, sizeof(_samples)); outputFile.write((char *)&_fps, sizeof(_fps)); for(std::vector::iterator it = _path.begin(); it != _path.end(); it++) - { outputFile.write((char *)&(*it), sizeof(t_pathPoint)); - } outputFile.close(); } @@ -155,11 +154,6 @@ void Renderer::loadPath(std::string filename) file.close(); } -bool Renderer::shouldClose(void) const -{ - return(_shouldClose); -} - void Renderer::fillGoodCodecList(std::vector &lst) { lst.push_back(AV_CODEC_ID_FFV1); @@ -462,37 +456,6 @@ glm::vec3 Renderer::hermiteInterpolate(glm::vec3 points[4], double alpha) return(coef[0] * points[1] + coef[1] * tang[0] + coef[2] * tang[1] + coef[3] * points[2]); } -//glm::quat eulerToQuaternion(float pitch, float yaw) -//{ -// glm::quat qPitch = glm::angleAxis(glm::radians(pitch), glm::vec3(1, 0, 0)); -// glm::quat qYaw = glm::angleAxis(glm::radians(yaw), glm::vec3(0, 1, 0)); -// -// glm::quat result = qYaw* qPitch; -// return(result); -//} - -//glm::vec2 Renderer::sphereInterpolate(glm::vec2 from, glm::vec2 to, float time) // gud but bad -//{ -// glm::vec3 eulerRes; -// glm::quat qFrom; -// glm::quat qTo; -// glm::quat res; -// float angle; -// float dot; -// -// qFrom = glm::normalize(eulerToQuaternion(from.y, from.x)); -// qTo = glm::normalize(eulerToQuaternion(to.y, to.x)); -// -// dot = glm::dot(qFrom, qTo); -// if(dot < 0) -// to = -to; -// angle = 2 * glm::acos(dot); -// res = (glm::sin((1 - time) * angle / glm::sin(angle)) * qFrom) + ((glm::sin(time * angle) / glm::sin(angle)) * qTo); -// eulerRes = glm::degrees(glm::eulerAngles(res)); -// return(glm::vec2(eulerRes.y, eulerRes.x)); -//} - - glm::vec2 Renderer::bezierSphereInterpolate(glm::vec4 control, glm::vec2 from, glm::vec2 to, float time) { glm::vec2 delta; @@ -570,6 +533,7 @@ void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) bezierControl.y = !_curPathIndex || smallDistPrev ? .1f : .0f; bezierControl.z = 0.8f; bezierControl.w = (size_t)_curPathIndex + 2 >= _path.size() || smallDistNext ? .9f : 1.0f; + dir = bezierSphereInterpolate(bezierControl, from.dir, to.dir, normalTime); if(std::isnan(dir.x) || std::isnan(dir.y)) dir = from.dir; @@ -591,12 +555,7 @@ void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) } } -int Renderer::rendering(void) const -{ - return(_destPathIndex != 0 && !_testMode); -} - -void Renderer::imguiPathCreation(void) +float Renderer::calcTime(void) { float prevSpeed; float time; @@ -606,6 +565,37 @@ void Renderer::imguiPathCreation(void) else prevSpeed = 0; + if(_autoTime) + { + _tp = 0; + if(_path.size() > 1) + time = _path[_path.size() - 1].time + (glm::distance(_path[_path.size() - 1].pos, _scene->getCamera()->getPosition()) / prevSpeed); + else + time = (float)_path.size() / 60; + if(std::isnan(time)) + time = _path[_path.size() - 1].time + (1.0f / 60); + _min = time; + _sec = (time - (int)time) * 60; + } + else if(_tp) + { + _autoTime = 0; + if(!_path.size()) + time = 0; + else + time = _path[_path.size() - 1].time; + _min = time; + _sec = (time - (int)time) * 60; + } + else + time = (float)_min + ((float)_sec / 60); + return time; +} + +void Renderer::imguiPathCreation(void) +{ + float time; + ImGui::SliderInt("test spi", &_testSamples, 1, 10); if(ImGui::Button("render settings")) @@ -633,35 +623,10 @@ void Renderer::imguiPathCreation(void) _autoTime = 0; _tp = 0; } - if(_autoTime) - { - if(_path.size() > 1) - time = _path[_path.size() - 1].time + (glm::distance(_path[_path.size() - 1].pos, _scene->getCamera()->getPosition()) / prevSpeed); - else - time = (float)_path.size() / 60; - if(std::isnan(time)) - time = _path[_path.size() - 1].time + (1.0f / 60); - _min = time; - _sec = (time - (int)time) * 60; - } - else if(_tp) - { - if(!_path.size()) - time = 0; - else - time = _path[_path.size() - 1].time; - _min = time; - _sec = (time - (int)time) * 60; - } - else - time = (float)_min + ((float)_sec / 60); + time = calcTime(); ImGui::Checkbox("guess time automatically", &_autoTime); - if(_autoTime) - _tp = 0; ImGui::Checkbox("tp", &_tp); - if(_tp) - _autoTime = 0; if(ImGui::Button("add step")) addPoint(time); @@ -718,7 +683,7 @@ std::string Renderer::floatToTime(double timef) int firstValue; time = timef; - values[0] = time / (3600 * 24 * 365); + values[0] = time / (3600 * 24 *365); time = time % (3600 * 24 * 365); values[1] = time / (3600 * 24 * 30); time = time % (3600 * 24 * 30); @@ -740,26 +705,19 @@ std::string Renderer::floatToTime(double timef) switch(firstValue) { case 0: - res += std::to_string(values[0]); - res += "Y"; + res += std::to_string(values[0]) + "Y"; case 1: - res += std::to_string(values[1]); - res += "M"; + res += std::to_string(values[1]) + "M"; case 2: - res += std::to_string(values[2]); - res += "W"; + res += std::to_string(values[2]) + "W"; case 3: - res += std::to_string(values[3]); - res += "d"; + res += std::to_string(values[3]) + "d"; case 4: - res += std::to_string(values[4]); - res += "h"; + res += std::to_string(values[4]) + "h"; case 5: - res += std::to_string(values[5]); - res += "m"; + res += std::to_string(values[5]) + "m"; case 6: - res += std::to_string(values[6]); - res += "s"; + res += std::to_string(values[6]) + "s"; } return(res); } @@ -865,7 +823,6 @@ void Renderer::imguiRenderSettings(void) void Renderer::renderImgui(void) { - // ImGui::Begin("Renderer"); if (ImGui::CollapsingHeader("Renderer")) { if(rendering()) @@ -875,5 +832,15 @@ void Renderer::renderImgui(void) else imguiPathCreation(); } - // ImGui::End(); +} + + +bool Renderer::shouldClose(void) const +{ + return(_shouldClose); +} + +int Renderer::rendering(void) const +{ + return(_destPathIndex != 0 && !_testMode); } From b1c9718ae3f467b7acbec3f1b378a3762a27d0e0 Mon Sep 17 00:00:00 2001 From: TheRedShip Date: Thu, 6 Feb 2025 00:16:25 +0100 Subject: [PATCH 16/21] + | Portal viewing angle teleportation --- imgui.ini | 4 ++-- includes/RT/Camera.hpp | 1 + includes/RT/Window.hpp | 1 + includes/RT/objects/Portal.hpp | 12 +--------- scenes/lambo.rt | 2 +- scenes/noneuclidian.rt | 14 ++++++++++-- shaders/compute.glsl | 14 +++++------- srcs/RT.cpp | 2 ++ srcs/class/Camera.cpp | 41 ++++++++++++++++++++++++++++++++-- srcs/class/Window.cpp | 8 ++++++- 10 files changed, 72 insertions(+), 27 deletions(-) diff --git a/imgui.ini b/imgui.ini index b3e0d68..fc7ef94 100644 --- a/imgui.ini +++ b/imgui.ini @@ -29,6 +29,6 @@ Pos=1556,610 Size=284,382 [Window][Settings] -Pos=83,57 -Size=336,330 +Pos=1567,9 +Size=340,941 diff --git a/includes/RT/Camera.hpp b/includes/RT/Camera.hpp index 3b81d31..924f54a 100644 --- a/includes/RT/Camera.hpp +++ b/includes/RT/Camera.hpp @@ -41,6 +41,7 @@ class Camera void processKeyboard(bool forward, bool backward, bool left, bool right, bool up, bool down); void updateCameraVectors(); + void updateCameraDirections(); int portalTeleport(Scene *scene, float delta_time); diff --git a/includes/RT/Window.hpp b/includes/RT/Window.hpp index 4c654d1..e139ddf 100644 --- a/includes/RT/Window.hpp +++ b/includes/RT/Window.hpp @@ -23,6 +23,7 @@ class Window Window(Scene *scene, int width, int height, const char *title, int sleep, Arguments &args); ~Window(void); + void updateDeltaTime(); void display(); void pollEvents(); bool shouldClose(); diff --git a/includes/RT/objects/Portal.hpp b/includes/RT/objects/Portal.hpp index e1ab03f..0e341b3 100644 --- a/includes/RT/objects/Portal.hpp +++ b/includes/RT/objects/Portal.hpp @@ -45,16 +45,10 @@ class Portal : public Object _up = glm::vec3(x1, y1, z1); _right = glm::vec3(x2, y2, z2); - // glm::vec3 temp_right = _right; - // _right = _invert_normal ? _up : _right; - // _up = _invert_normal ? temp_right : _up; - glm::vec3 right = glm::normalize(_right); glm::vec3 up = glm::normalize(_up); glm::vec3 forward = glm::normalize(glm::cross(right, up)); - // up = normalize(glm::cross(forward, right)); - _rotation = glm::mat3(right, up, forward); _normal = forward * (_invert_normal ? -1.0f : 1.0f); @@ -72,10 +66,6 @@ class Portal : public Object glm::vec3 right_dir = glm::normalize(_right); glm::vec3 up_dir = glm::normalize(_up); - // glm::vec3 temp_right = right_dir; - // right_dir = _invert_normal ? right_dir : up_dir; - // up_dir = _invert_normal ? up_dir : temp_right; - float right_length = glm::length(_right) + extension; float up_length = glm::length(_up) + extension; @@ -84,7 +74,7 @@ class Portal : public Object glm::vec3 right = right_dir * right_length; glm::vec3 up = up_dir * up_length; - // position += 10; + return (new Quad(position, right, up, _normal, 1, _mat_index)); } diff --git a/scenes/lambo.rt b/scenes/lambo.rt index 19c8f89..eb4dc9a 100644 --- a/scenes/lambo.rt +++ b/scenes/lambo.rt @@ -19,7 +19,7 @@ cu 0 10 0 5 5 5 3 sp 0 10 0 1 4 -OBJ obj/lambo.obj 0 1.5 0 1 0 0 0 +OBJ scenes/obj/lambo.obj 0 1.5 0 1 0 0 0 diff --git a/scenes/noneuclidian.rt b/scenes/noneuclidian.rt index 7ad933b..55f68cf 100644 --- a/scenes/noneuclidian.rt +++ b/scenes/noneuclidian.rt @@ -1,4 +1,4 @@ -CAM -2.43549 3.10568 -6.50845 -16.4 53.8007 0 1 90 5 +CAM -3.31413 5.09653 9.67312 -19.6 -74.7992 0 1 90 5 MAT 100 200 100 0.0 0.0 0.0 // 0 MAT 200 200 200 0.0 0.0 0.0 // 1 @@ -36,4 +36,14 @@ qu 9.5 3 -1 3 0 0 0 0 2 0 1 # #small tunnel entrace behind # po 9.5 2 -1 3 0 0 0 3 0 1 5 -# po -1.5 2 -4 3 0 0 0 3 0 0 5 \ No newline at end of file +# po -1.5 2 -4 3 0 0 0 3 0 0 5 + +#top portals + +po -6 1 0 3 0 0 0 0 3 1 1 +po -10 1 0 0 3 0 0 0 3 0 1 + + + +po -1 1.5 10 0 1.5 0 1.5 0 0 0 1 +po 1 1.5 10 0 0 1.5 1.5 0 0 0 1 \ No newline at end of file diff --git a/shaders/compute.glsl b/shaders/compute.glsl index febe279..5797d84 100644 --- a/shaders/compute.glsl +++ b/shaders/compute.glsl @@ -187,16 +187,14 @@ vec3 pathtrace(Ray ray, inout uint rng_state) } #endif - - float miss_condition = float(hit.obj_index == -1); - light += miss_condition * transmittance * GetEnvironmentLight(ray); + if (hit.obj_index == -1) + { + light += transmittance * GetEnvironmentLight(ray); + break; + } float p = max(color.r, max(color.g, color.b)); - float rr_continue = float(randomValue(rng_state) <= p); - - float break_condition = miss_condition + (1.0 - rr_continue); - if (break_condition > 0.0) break; - + if (randomValue(rng_state) >= p) break; color /= max(p, 0.001); GPUMaterial mat = materials[hit.mat_index]; diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 4dacf7f..6ff2e28 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -104,6 +104,8 @@ int main(int argc, char **argv) while (!window.shouldClose()) { + window.updateDeltaTime(); + glUseProgram(shader.getProgramCompute()); glBindBuffer(GL_SHADER_STORAGE_BUFFER, materialSSBO); diff --git a/srcs/class/Camera.cpp b/srcs/class/Camera.cpp index 3aaf6f7..29975f1 100644 --- a/srcs/class/Camera.cpp +++ b/srcs/class/Camera.cpp @@ -36,6 +36,19 @@ void Camera::updateCameraVectors() _up = glm::normalize(glm::cross(_right, _forward)); } +void Camera::updateCameraDirections() +{ + glm::vec3 forward_xz = glm::normalize(glm::vec3(_forward.x, 0.0f, _forward.z)); + _pitch = glm::degrees(asin(_forward.y)); + + _yaw = glm::degrees(atan2(-_forward.x, _forward.z)); + + _yaw = fmod(_yaw + 360.0f, 360.0f); + _pitch = glm::clamp(_pitch, -89.0f, 89.0f); + + _yaw += 90; +} + void Camera::update(Scene *scene, float delta_time) { // delta_time = std::min(delta_time, 0.01f); @@ -83,11 +96,35 @@ int Camera::portalTeleport(Scene *scene, float delta_time) float distance_future_pos = glm::length(future_pos - _position); float distance_portal = glm::length(point_projected - _position); + float imprecision = 0.1f; + if (distance_portal <= distance_future_pos && glm::dot(glm::normalize(future_pos - _position), obj.normal) > 0.0f) { GPUObject linked_portal = scene->getObjectData()[obj.radius]; - _position = (linked_portal.position) + (_position - obj.position) - (((distance_future_pos - distance_portal)) * linked_portal.normal); - + + glm::mat4 portal_transform = linked_portal.transform * glm::inverse(obj.transform); + + //teleportation + + glm::vec3 relative_pos = _position - obj.position; + glm::vec3 transformed_relative_pos = glm::vec3(portal_transform * glm::vec4(relative_pos, 1.0f)); + + float remaining_distance = distance_future_pos - distance_portal + imprecision; + glm::vec3 new_movement = remaining_distance * glm::vec3(portal_transform * glm::vec4(linked_portal.normal, 0.0f)); + + _position = linked_portal.position + transformed_relative_pos - new_movement; + // _position = (linked_portal.position) + (_position - obj.position) - (((distance_future_pos - distance_portal + imprecision)) * linked_portal.normal); + + // view direction + + _forward = glm::vec3(portal_transform * glm::vec4(_forward, 1.0f)); + _up = glm::vec3(portal_transform * glm::vec4(_up, 1.0f)); + _right = glm::vec3(portal_transform * glm::vec4(_right, 1.0f)); + + updateCameraDirections(); + + _velocity = glm::vec3(portal_transform * glm::vec4(_velocity, 0.0f)); + return (1); } } diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index 108f583..6794415 100644 --- a/srcs/class/Window.cpp +++ b/srcs/class/Window.cpp @@ -134,7 +134,7 @@ void Window::keyCallback(GLFWwindow *window, int key, int scancode, int action, } } -void Window::display() +void Window::updateDeltaTime() { static double lastTime = glfwGetTime(); double currentTime = glfwGetTime(); @@ -146,6 +146,12 @@ void Window::display() if (accumulate) _frameCount++; +} + +void Window::display() +{ + if (accumulate) + _frameCount++; if (_scene->getCamera()->getVelocity() > 0.0f) _frameCount = 0; From 2b879218ed1128fbd213abff4c1f09c205ae3148 Mon Sep 17 00:00:00 2001 From: tomoron Date: Thu, 6 Feb 2025 03:00:07 +0100 Subject: [PATCH 17/21] fix compilation error unused variable, make getFilePath work on windows (yavin, you should still install linux), add error callback to glfw --- scenes/lambo.rt | 2 +- scenes/sponza.rt | 10 +++++----- scenes/test.rt | 7 ++++--- scenes/volumetric.rt | 2 +- srcs/RT.cpp | 2 +- srcs/class/Camera.cpp | 4 ++-- srcs/class/ObjParser.cpp | 6 +++--- srcs/class/Window.cpp | 12 +++++++----- 8 files changed, 24 insertions(+), 21 deletions(-) diff --git a/scenes/lambo.rt b/scenes/lambo.rt index eb4dc9a..19c8f89 100644 --- a/scenes/lambo.rt +++ b/scenes/lambo.rt @@ -19,7 +19,7 @@ cu 0 10 0 5 5 5 3 sp 0 10 0 1 4 -OBJ scenes/obj/lambo.obj 0 1.5 0 1 0 0 0 +OBJ obj/lambo.obj 0 1.5 0 1 0 0 0 diff --git a/scenes/sponza.rt b/scenes/sponza.rt index 57953f1..f1f51c1 100644 --- a/scenes/sponza.rt +++ b/scenes/sponza.rt @@ -7,11 +7,11 @@ MAT 255 220 50 0.0 1.0 0.5 // dragon 1 MAT 255 255 255 5.0 0.0 0.0 // light 2 sp 0 50 0 25 2 -OBJ scenes/obj/sponza.obj 0 0 0 0.025 +OBJ obj/sponza.obj 0 0 0 0.025 -# OBJ scenes/obj/Dragon_80K.obj 7 2.5 0 9 0 140 0 0 -OBJ scenes/obj/Dragon_80K.obj 9 1.35 -3.5 5 0 40 0 1 +# OBJ obj/Dragon_80K.obj 7 2.5 0 9 0 140 0 0 +OBJ obj/Dragon_80K.obj 9 1.35 -3.5 5 0 40 0 1 -OBJ scenes/obj/Dragon_800K.obj 10 3.35 -3.5 45 0 230 0 0 -# OBJ scenes/obj/Dragon_80K.obj 9 1.35 -3.5 5 0 40 0 1 +OBJ obj/Dragon_800K.obj 10 3.35 -3.5 45 0 230 0 0 +# OBJ obj/Dragon_80K.obj 9 1.35 -3.5 5 0 40 0 1 diff --git a/scenes/test.rt b/scenes/test.rt index 400725e..3211a29 100644 --- a/scenes/test.rt +++ b/scenes/test.rt @@ -11,7 +11,8 @@ MAT 255 255 255 0.0 0.0 0.0 // 1 sp 0 2 0 150 0 -OBJ scenes/obj/jinx.obj -10 0 0 1.25 0 0 0 -# OBJ scenes/obj/Dragon_800K.obj 0 0 0 35 0 0 0 1 +OBJ obj/jinx.obj -10 0 0 1.25 0 0 0 +# OBJ obj/Dragon_800K.obj 0 0 0 35 0 0 0 1 + +OBJ obj/whitedragon.obj 0 0 0 1 0 0 0 -OBJ scenes/obj/whitedragon.obj 0 0 0 1 0 0 0 diff --git a/scenes/volumetric.rt b/scenes/volumetric.rt index 6514a96..b26bc5c 100644 --- a/scenes/volumetric.rt +++ b/scenes/volumetric.rt @@ -37,4 +37,4 @@ sp 0 2.5 0 0.5 5 # sp 0 0 0 5 1 # sp 0 0 0 15 2 -# OBJ scenes/obj/jinx.obj 0 0 -15 \ No newline at end of file +# OBJ obj/jinx.obj 0 0 -15 diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 6ff2e28..4bf3961 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/02/06 16:33:36 by tomoron ### ########.fr */ +/* Updated: 2025/02/06 16:33:54 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/srcs/class/Camera.cpp b/srcs/class/Camera.cpp index 29975f1..21559cd 100644 --- a/srcs/class/Camera.cpp +++ b/srcs/class/Camera.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/15 14:00:38 by TheRed #+# #+# */ -/* Updated: 2025/02/05 20:09:58 by ycontre ### ########.fr */ +/* Updated: 2025/02/06 02:07:47 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -38,7 +38,7 @@ void Camera::updateCameraVectors() void Camera::updateCameraDirections() { - glm::vec3 forward_xz = glm::normalize(glm::vec3(_forward.x, 0.0f, _forward.z)); +// glm::vec3 forward_xz = glm::normalize(glm::vec3(_forward.x, 0.0f, _forward.z)); _pitch = glm::degrees(asin(_forward.y)); _yaw = glm::degrees(atan2(-_forward.x, _forward.z)); diff --git a/srcs/class/ObjParser.cpp b/srcs/class/ObjParser.cpp index 25a882e..924595a 100644 --- a/srcs/class/ObjParser.cpp +++ b/srcs/class/ObjParser.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/16 15:00:33 by tomoron #+# #+# */ -/* Updated: 2025/02/03 19:01:06 by ycontre ### ########.fr */ +/* Updated: 2025/02/06 02:19:50 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -32,10 +32,10 @@ std::string ObjParser::getFilePath(std::string &file) { int index; - if(file.find("/") == std::string::npos) + if(file.find("/") == std::string::npos && file.find("\\") == std::string::npos) return(""); index = file.length() - 1; - while(index && file[index] != '/') + while(index && file[index] != '/' && file[index] != '\\') index--; return(file.substr(0, index + 1)); } diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index 6794415..7b39616 100644 --- a/srcs/class/Window.cpp +++ b/srcs/class/Window.cpp @@ -6,12 +6,17 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 16:16:24 by TheRed #+# #+# */ -/* Updated: 2025/02/05 20:01:29 by ycontre ### ########.fr */ +/* Updated: 2025/02/06 02:57:16 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "Window.hpp" +void GLFWErrorCallback(int error, const char* description) +{ + fprintf(stderr, "GLFW Error (%d): %s\n", error, description); +} + Window::Window(Scene *scene, int width, int height, const char *title, int sleep, Arguments &args) { _scene = scene; @@ -19,7 +24,7 @@ Window::Window(Scene *scene, int width, int height, const char *title, int sleep _frameCount = 0; _pixelisation = 0; _renderer = new Renderer(scene, this, args); - + glfwSetErrorCallback(GLFWErrorCallback); if (!glfwInit()) { fprintf( stderr, "Failed to initialize GLFW\n" ); @@ -143,9 +148,6 @@ void Window::updateDeltaTime() lastTime = currentTime; _fps = 1.0f / _delta; - - if (accumulate) - _frameCount++; } void Window::display() From 47bf193752f9b9655df2957ed5423f47cf770e82 Mon Sep 17 00:00:00 2001 From: RedShip Date: Fri, 7 Feb 2025 20:17:43 +0100 Subject: [PATCH 18/21] ~ | First denoising attempt --- shaders/compute.glsl | 6 +++++- shaders/frag.frag | 38 +++++++++++++++++++++++++++++++++++++- shaders/trace.glsl | 1 + srcs/class/Camera.cpp | 2 +- 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/shaders/compute.glsl b/shaders/compute.glsl index 5797d84..3894ab2 100644 --- a/shaders/compute.glsl +++ b/shaders/compute.glsl @@ -238,7 +238,11 @@ void main() ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy); if (pixel_coords.x >= int(u_resolution.x) || pixel_coords.y >= int(u_resolution.y)) return; - + + // if (pixel_coords.x % 50 == 0 || pixel_coords.y % 50 == 0) + // imageStore(output_image, pixel_coords, vec4(1.,0.,0., 0.)); + // return ; + if (u_pixelisation != 1 && (uint(pixel_coords.x) % u_pixelisation != 0 || uint(pixel_coords.y) % u_pixelisation != 0)) return; diff --git a/shaders/frag.frag b/shaders/frag.frag index 017073a..05e1568 100644 --- a/shaders/frag.frag +++ b/shaders/frag.frag @@ -5,5 +5,41 @@ out vec4 FragColor; uniform sampler2D screenTexture; void main() { - FragColor = texture(screenTexture, TexCoords); + vec2 uv = TexCoords; + + float incr_x = 1.0 / 1920.0 ; + float incr_y = 1.0 / 1080.0 ; + + int iteration = 5; + + if (iteration == 0) {FragColor = texture(screenTexture, uv);return;} + + vec4 color = vec4(vec3(0.), 1.0); + float totalWeight = 0.; + + float kernel[5] = float[5](1.0/16.0, 1.0/4.0, 3.0/8.0, 1.0/4.0, 1.0/16.0); + + for (int i = 0; i < iteration; i++) + { + int holes = int(pow(2, i)); + + for (int x = -2; x <= 2; x++) + { + for (int y = -2; y <= 2; y++) + { + vec2 current_uv = uv + vec2(x * holes * incr_x, y * holes * incr_y); + // if (current_uv.x < 0. || current_uv.y < 0. || current_uv.x > 1. || current_uv.y > 1.) + // continue ; + // current_uv = clamp(current_uv, vec2(0.), vec2(1.)); + + float weight = kernel[x+2] * kernel[y+2]; + + totalWeight += weight; + color += texture(screenTexture, current_uv) * weight; + } + } + } + + + FragColor = color / totalWeight; } \ No newline at end of file diff --git a/shaders/trace.glsl b/shaders/trace.glsl index 50067f2..c23f383 100644 --- a/shaders/trace.glsl +++ b/shaders/trace.glsl @@ -16,6 +16,7 @@ Ray portalRay(Ray ray, hitInfo hit) if (dot(portal_1.normal, portal_2.normal) > 0.0) { mat3 reflection = mat3(1.0) - 2.0 * outerProduct(portal_2.normal, portal_2.normal); + reflection *= inverse(mat3(1)); rotation *= reflection; } diff --git a/srcs/class/Camera.cpp b/srcs/class/Camera.cpp index 21559cd..af49703 100644 --- a/srcs/class/Camera.cpp +++ b/srcs/class/Camera.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/15 14:00:38 by TheRed #+# #+# */ -/* Updated: 2025/02/06 02:07:47 by tomoron ### ########.fr */ +/* Updated: 2025/02/07 18:35:33 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ From cbc2550d7840ad89347463150192a39afb7fd19c Mon Sep 17 00:00:00 2001 From: TheRedShip Date: Fri, 7 Feb 2025 23:32:52 +0100 Subject: [PATCH 19/21] ~ | Pass system shader --- includes/RT/Shader.hpp | 7 ++++++- shaders/denoising.glsl | 20 ++++++++++++++++++++ shaders/frag.frag | 38 +------------------------------------- srcs/RT.cpp | 16 +++++++++++++++- srcs/class/Shader.cpp | 38 ++++++++++++++++++++++++++++++++++---- 5 files changed, 76 insertions(+), 43 deletions(-) create mode 100644 shaders/denoising.glsl diff --git a/includes/RT/Shader.hpp b/includes/RT/Shader.hpp index 2f4db93..30cf82f 100644 --- a/includes/RT/Shader.hpp +++ b/includes/RT/Shader.hpp @@ -18,13 +18,15 @@ class Shader { public: - Shader(std::string vertexPath, std::string fragmentPath, std::string computePath); + Shader(std::string vertexPath, std::string fragmentPath, std::string computePath, std::string denoisingPath); ~Shader(void); void attach(void); void setupVertexBuffer(); void drawTriangles(); + void flipOutputDenoising(bool pass); + // void setBool(const std::string &name, bool value) const; void set_int(const std::string &name, int value) const; void set_float(const std::string &name, float value) const; @@ -37,6 +39,7 @@ class Shader GLuint getProgram(void) const; GLuint getProgramCompute(void) const; + GLuint getProgramComputeDenoising(void) const; std::vector getOutputImage(void); @@ -46,6 +49,7 @@ class Shader GLuint _program; GLuint _program_compute; + GLuint _program_denoising; GLuint _output_texture; GLuint _accumulation_texture; @@ -54,6 +58,7 @@ class Shader GLuint _vertex; GLuint _fragment; GLuint _compute; + GLuint _denoising; size_t _size; diff --git a/shaders/denoising.glsl b/shaders/denoising.glsl new file mode 100644 index 0000000..1a0680c --- /dev/null +++ b/shaders/denoising.glsl @@ -0,0 +1,20 @@ +#version 430 core + +layout(local_size_x = 16, local_size_y = 16) in; +layout(binding = 0, rgba32f) uniform image2D read_texture; +layout(binding = 2, rgba32f) uniform image2D write_texture; + +uniform vec2 u_resolution; + +void main() +{ + ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy); + if (pixel_coords.x >= int(u_resolution.x) || pixel_coords.y >= int(u_resolution.y)) + return; + + vec4 color = imageLoad(read_texture, pixel_coords); + + color *= 0.5; + + imageStore(write_texture, pixel_coords, color); +} \ No newline at end of file diff --git a/shaders/frag.frag b/shaders/frag.frag index 05e1568..017073a 100644 --- a/shaders/frag.frag +++ b/shaders/frag.frag @@ -5,41 +5,5 @@ out vec4 FragColor; uniform sampler2D screenTexture; void main() { - vec2 uv = TexCoords; - - float incr_x = 1.0 / 1920.0 ; - float incr_y = 1.0 / 1080.0 ; - - int iteration = 5; - - if (iteration == 0) {FragColor = texture(screenTexture, uv);return;} - - vec4 color = vec4(vec3(0.), 1.0); - float totalWeight = 0.; - - float kernel[5] = float[5](1.0/16.0, 1.0/4.0, 3.0/8.0, 1.0/4.0, 1.0/16.0); - - for (int i = 0; i < iteration; i++) - { - int holes = int(pow(2, i)); - - for (int x = -2; x <= 2; x++) - { - for (int y = -2; y <= 2; y++) - { - vec2 current_uv = uv + vec2(x * holes * incr_x, y * holes * incr_y); - // if (current_uv.x < 0. || current_uv.y < 0. || current_uv.x > 1. || current_uv.y > 1.) - // continue ; - // current_uv = clamp(current_uv, vec2(0.), vec2(1.)); - - float weight = kernel[x+2] * kernel[y+2]; - - totalWeight += weight; - color += texture(screenTexture, current_uv) * weight; - } - } - } - - - FragColor = color / totalWeight; + FragColor = texture(screenTexture, TexCoords); } \ No newline at end of file diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 4bf3961..88bb58d 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -21,7 +21,7 @@ int main(int argc, char **argv) if (scene.fail()) return (1); Window window(&scene, WIDTH, HEIGHT, "RT_GPU", 0, args); - Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/compute.glsl"); + Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/compute.glsl", "shaders/denoising.glsl"); // Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/debug.glsl"); @@ -141,6 +141,20 @@ int main(int argc, char **argv) glDispatchCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); + // + glUseProgram(shader.getProgramComputeDenoising()); + glUniform2fv(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_resolution"), 1, glm::value_ptr(glm::vec2(WIDTH, HEIGHT))); + + for (int pass = 0; pass < 1; ++pass) + { + shader.flipOutputDenoising(pass % 2 == 0); + + glDispatchCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); + glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); + } + shader.flipOutputDenoising(true); + // + glClear(GL_COLOR_BUFFER_BIT); window.imGuiNewFrame(); diff --git a/srcs/class/Shader.cpp b/srcs/class/Shader.cpp index 9992b8d..db1c1c4 100644 --- a/srcs/class/Shader.cpp +++ b/srcs/class/Shader.cpp @@ -61,11 +61,12 @@ void printWithLineNumbers(const char *str) std::cout << lineNumber++ << ": " << line << std::endl; } -Shader::Shader(std::string vertexPath, std::string fragmentPath, std::string computePath) +Shader::Shader(std::string vertexPath, std::string fragmentPath, std::string computePath, std::string denoisingPath) { const char *vertexCode = loadFileWithIncludes(vertexPath); const char *fragmentCode = loadFileWithIncludes(fragmentPath); const char *computeCode = loadFileWithIncludes(computePath); + const char *denoisingCode = loadFileWithIncludes(denoisingPath); // printWithLineNumbers(computeCode); @@ -89,6 +90,13 @@ Shader::Shader(std::string vertexPath, std::string fragmentPath, std::string com glCompileShader(_compute); checkCompileErrors(_compute); + + _denoising = glCreateShader(GL_COMPUTE_SHADER); + + glShaderSource(_denoising, 1, &denoisingCode, NULL); + glCompileShader(_denoising); + + checkCompileErrors(_denoising); } Shader::~Shader(void) @@ -98,15 +106,14 @@ Shader::~Shader(void) glDeleteShader(_compute); glDeleteProgram(_program); glDeleteProgram(_program_compute); + glDeleteProgram(_denoising); } void Shader::attach(void) { _program = glCreateProgram(); _program_compute = glCreateProgram(); - - glProgramParameteri(_program_compute, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); - glProgramParameteri(_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); + _program_denoising = glCreateProgram(); glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); @@ -114,10 +121,14 @@ void Shader::attach(void) glAttachShader(_program, _vertex); glAttachShader(_program, _fragment); + glAttachShader(_program_compute, _compute); + glAttachShader(_program_denoising, _denoising); + glLinkProgram(_program); glLinkProgram(_program_compute); + glLinkProgram(_program_denoising); glGenTextures(1, &_output_texture); glBindTexture(GL_TEXTURE_2D, _output_texture); @@ -196,6 +207,20 @@ void Shader::drawTriangles() glDrawArrays(GL_TRIANGLES, 0, _size * 3); } +void Shader::flipOutputDenoising(bool pass) +{ + if (pass) + { + glBindImageTexture(0, _output_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); + glBindImageTexture(2, _denoising_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); + } + else + { + glBindImageTexture(0, _denoising_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); + glBindImageTexture(2, _output_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); + } +} + void Shader::set_int(const std::string &name, int value) const { glUniform1i(glGetUniformLocation(_program_compute, name.c_str()), value); @@ -252,6 +277,11 @@ GLuint Shader::getProgramCompute(void) const return (_program_compute); } +GLuint Shader::getProgramComputeDenoising(void) const +{ + return (_program_denoising); +} + std::vector Shader::getOutputImage(void) { std::vector res(WIDTH * HEIGHT * 4); From 39196a00ff1f039747cf0541380679a96bb097d7 Mon Sep 17 00:00:00 2001 From: TheRedShip Date: Sat, 8 Feb 2025 21:43:49 +0100 Subject: [PATCH 20/21] ~ | Working atrous algorithm --- includes/RT/Shader.hpp | 2 ++ scenes/pillard.rt | 12 ++++----- scenes/roughness.rt | 2 +- scenes/stairs.rt | 2 +- scenes/volumetric.rt | 16 ++++++------ scenes/window.rt | 10 ++++---- scenes/window2.rt | 18 ++++++------- shaders/compute.glsl | 11 +++++++- shaders/denoising.glsl | 57 +++++++++++++++++++++++++++++++++++++++--- shaders/light.glsl | 6 ++--- srcs/RT.cpp | 4 ++- srcs/class/Shader.cpp | 20 ++++++++++++++- 12 files changed, 121 insertions(+), 39 deletions(-) diff --git a/includes/RT/Shader.hpp b/includes/RT/Shader.hpp index 30cf82f..1b1583e 100644 --- a/includes/RT/Shader.hpp +++ b/includes/RT/Shader.hpp @@ -54,6 +54,8 @@ class Shader GLuint _output_texture; GLuint _accumulation_texture; GLuint _denoising_texture; + GLuint _normal_texture; + GLuint _position_texture; GLuint _vertex; GLuint _fragment; diff --git a/scenes/pillard.rt b/scenes/pillard.rt index a84ba6d..60aaac6 100644 --- a/scenes/pillard.rt +++ b/scenes/pillard.rt @@ -85,10 +85,10 @@ cy +10.00 +3.000 +15.00 1.5 4.8 +0.000 +1.000 +0.000 5 cy +10.00 +3.000 +25.00 1.5 4.8 +0.000 +1.000 +0.000 5 -qu -35 0 -40 0 20 0 70 0 0 5 -qu 35 0 -40 0 20 0 0 0 100 5 -qu -35 0 -40 0 20 0 0 0 100 5 -qu -50 +20 -50 100 0 0 0 0 100 5 -qu -50 0 -50 100 0 0 0 0 100 5 +qu -35 0 -40 0 20 0 70 0 0 0 5 +qu 35 0 -40 0 20 0 0 0 100 0 5 +qu -35 0 -40 0 20 0 0 0 100 0 5 +qu -50 +20 -50 100 0 0 0 0 100 0 5 +qu -50 0 -50 100 0 0 0 0 100 0 5 -# qu -35 0 50 0 20 0 70 0 0 5 \ No newline at end of file +# qu -35 0 50 0 20 0 70 0 0 0 5 \ No newline at end of file diff --git a/scenes/roughness.rt b/scenes/roughness.rt index 2eb97be..081490d 100644 --- a/scenes/roughness.rt +++ b/scenes/roughness.rt @@ -40,5 +40,5 @@ sp 2.4 1.5 -1 1.5 14 // light quad -qu -1 2.999 -1 0 0 2 2 0 0 0 +qu -1 2.999 -1 0 0 2 2 0 0 0 0 diff --git a/scenes/stairs.rt b/scenes/stairs.rt index d3d58a3..75636c2 100644 --- a/scenes/stairs.rt +++ b/scenes/stairs.rt @@ -3,7 +3,7 @@ CAM -7 10 6 -19.4 -50 0.081 9.417 80.368 10 MAT 255 255 255 2.0 0.0 0.0 //white light sp -10 100 10 50 0 -qu -2.5 15 -9 7 0 0 0 0 7 0 +qu -2.5 15 -9 7 0 0 0 0 7 0 0 MAT 255 100 10 0.0 0.5 1.0 diff --git a/scenes/volumetric.rt b/scenes/volumetric.rt index b26bc5c..92bd930 100644 --- a/scenes/volumetric.rt +++ b/scenes/volumetric.rt @@ -2,7 +2,7 @@ CAM 1.61759 3.23371 -7.26417 -4.0001 105.199 0 2.973 45.75 MAT 255 255 255 2.0 1.0 0.0 // 0 white light # sp -3.5 2.7 0.5 0.2 0 -qu -4 2.375 0 0 0.25 0 0 0 0.25 0 +qu -4 2.375 0 0 0.25 0 0 0 0.25 0 0 MAT 250 250 250 0. 1.0 0.0 // 1 white MAT 250 100 100 0. 1.0 0.0 // 2 red @@ -11,15 +11,15 @@ MAT 100 100 250 0. 1.0 0.0 // 3 blue MAT 250 250 250 0. 1.0 0.05 // 1 white tomato MAT 250 250 250 0. 1.3 0. DIE -1 // 1 white dielectric -qu 2.5 0 -2.5 0 5 0 0 0 5 1 -qu -2.5 0 2.5 0 5 0 5 0 0 2 -qu -2.5 0 -2.5 0 0 5 5 0 0 1 +qu 2.5 0 -2.5 0 5 0 0 0 5 0 1 +qu -2.5 0 2.5 0 5 0 5 0 0 0 2 +qu -2.5 0 -2.5 0 0 5 5 0 0 0 1 -qu -2.5 0 -2.5 0 2.375 0 0 0 5 3 -qu -2.5 2.6275 -2.5 0 2.375 0 0 0 5 3 +qu -2.5 0 -2.5 0 2.375 0 0 0 5 0 3 +qu -2.5 2.6275 -2.5 0 2.375 0 0 0 5 0 3 -qu -2.5 2 0.25 0 1 0 0 0 2.75 3 -qu -2.5 2 -2.5 0 1 0 0 0 2.5 3 +qu -2.5 2 0.25 0 1 0 0 0 2.75 0 3 +qu -2.5 2 -2.5 0 1 0 0 0 2.5 0 3 sp 1.25 1 -1 1.5 4 diff --git a/scenes/window.rt b/scenes/window.rt index 42930b1..9eb803a 100644 --- a/scenes/window.rt +++ b/scenes/window.rt @@ -8,12 +8,12 @@ MAT 255 255 255 5.0 0.0 0.0 //light pl 0 0 0 0 1 0 1 sp -10 10 -9 1 2 -# qu -10 5 -12 0 6 0 0 0 6 2 +# qu -10 5 -12 0 6 0 0 0 6 0 2 -qu 0 0 0 0 6 0 18 0 0 0 -qu 0 0 -18 0 6 0 18 0 0 0 -qu 18 0 -18 0 6 0 0 0 18 0 -qu 0 6 -18 18 0 0 0 0 18 0 +qu 0 0 0 0 6 0 18 0 0 0 0 +qu 0 0 -18 0 6 0 18 0 0 0 0 +qu 18 0 -18 0 6 0 0 0 18 0 0 +qu 0 6 -18 18 0 0 0 0 18 0 0 cu 0.25 3 -0.25 0.5 6 0.5 0 cu 0.25 3 -1.25 0.5 6 0.5 0 diff --git a/scenes/window2.rt b/scenes/window2.rt index 2369d7e..83ba873 100644 --- a/scenes/window2.rt +++ b/scenes/window2.rt @@ -7,21 +7,21 @@ MAT 255 255 255 1.0 0.0 0.0 //light sp -5 5 0 1 2 -# qu -5 0 -2.5 0 5 0 0 0 5 2 +# qu -5 0 -2.5 0 5 0 0 0 5 0 2 pl 0 0 0 0 1 0 1 -qu 2.5 0 -2.5 0 5 0 0 0 5 0 -qu -2.5 0 -2.5 0 5 0 5 0 0 0 -qu -2.5 0 2.5 0 5 0 5 0 0 0 -qu -2.5 5 -2.5 0 0 5 5 0 0 0 +qu 2.5 0 -2.5 0 5 0 0 0 5 0 0 +qu -2.5 0 -2.5 0 5 0 5 0 0 0 0 +qu -2.5 0 2.5 0 5 0 5 0 0 0 0 +qu -2.5 5 -2.5 0 0 5 5 0 0 0 0 -qu -2.5 0 -2.5 0 2.5 0 0 0 5 0 -qu -2.5 3.5 -2.5 0 1.5 0 0 0 5 0 +qu -2.5 0 -2.5 0 2.5 0 0 0 5 0 0 +qu -2.5 3.5 -2.5 0 1.5 0 0 0 5 0 0 -qu -2.5 2.5 0.5 0 1 0 0 0 2 0 -qu -2.5 2.5 -2.5 0 1 0 0 0 2 0 +qu -2.5 2.5 0.5 0 1 0 0 0 2 0 0 +qu -2.5 2.5 -2.5 0 1 0 0 0 2 0 0 diff --git a/shaders/compute.glsl b/shaders/compute.glsl index 3894ab2..5932b8f 100644 --- a/shaders/compute.glsl +++ b/shaders/compute.glsl @@ -4,6 +4,9 @@ layout(local_size_x = 16, local_size_y = 16) in; layout(binding = 0, rgba32f) uniform image2D output_image; layout(binding = 1, rgba32f) uniform image2D accumulation_image; +layout(binding = 3, rgba32f) uniform image2D normal_texture; +layout(binding = 4, rgba32f) uniform image2D position_texture; + struct GPUObject { mat4 rotation; @@ -176,7 +179,7 @@ vec3 pathtrace(Ray ray, inout uint rng_state) for (int i = 0; i < camera.bounce; i++) { hitInfo hit = traceRay(ray); - + #if 0 float t_scatter = 0.0; bool scatter_valid = bool(volume.enabled != 0 && atmosScatter(hit, t_scatter, rng_state)); @@ -193,6 +196,12 @@ vec3 pathtrace(Ray ray, inout uint rng_state) break; } + if (i == 0) + { + imageStore(normal_texture, ivec2(gl_GlobalInvocationID.xy), vec4(hit.normal, 1.0)); + imageStore(position_texture, ivec2(gl_GlobalInvocationID.xy), vec4(hit.position, 1.0)); + } + float p = max(color.r, max(color.g, color.b)); if (randomValue(rng_state) >= p) break; color /= max(p, 0.001); diff --git a/shaders/denoising.glsl b/shaders/denoising.glsl index 1a0680c..893004c 100644 --- a/shaders/denoising.glsl +++ b/shaders/denoising.glsl @@ -4,7 +4,12 @@ layout(local_size_x = 16, local_size_y = 16) in; layout(binding = 0, rgba32f) uniform image2D read_texture; layout(binding = 2, rgba32f) uniform image2D write_texture; +layout(binding = 3, rgba32f) uniform image2D position_texture; +layout(binding = 4, rgba32f) uniform image2D normal_texture; + + uniform vec2 u_resolution; +uniform int u_pass; void main() { @@ -12,9 +17,55 @@ void main() if (pixel_coords.x >= int(u_resolution.x) || pixel_coords.y >= int(u_resolution.y)) return; - vec4 color = imageLoad(read_texture, pixel_coords); + float c_phi = 1.0; + float p_phi = 1.0; + float n_phi = 1.0; + + int holes = int(pow(2, u_pass)); - color *= 0.5; + vec4 color_center = imageLoad(read_texture, pixel_coords); + vec3 position_center = imageLoad(position_texture, pixel_coords).xyz; + vec3 normal_center = imageLoad(normal_texture, pixel_coords).xyz; - imageStore(write_texture, pixel_coords, color); + float kernel[5] = float[5](1.0/16.0, 1.0/4.0, 3.0/8.0, 1.0/4.0, 1.0/16.0); + + float totalWeight = 0.; + vec4 color = vec4(vec3(0.), 1.0); + + for (int x = -2; x <= 2; x++) + { + for (int y = -2; y <= 2; y++) + { + ivec2 coords = pixel_coords + ivec2(x * holes, y * holes); + if (coords.x < 0. || coords.y < 0. || coords.x >= int(u_resolution.x) || coords.y >= int(u_resolution.y)) + continue ; + // coords = clamp(coords, ivec2(-1.0), u_resolution); + + vec4 color_sample = imageLoad(read_texture, coords); + vec3 position_sample = imageLoad(position_texture, coords).xyz; + vec3 normal_sample = imageLoad(normal_texture, coords).xyz; + + // Calculate edge-stopping weights + + // Color weight + float colorDist = distance(color_center, color_sample); + float w_c = exp(-colorDist / c_phi); + + // Position weight + float posDist = distance(position_center, position_sample); + float w_p = exp(-posDist / p_phi); + + // Normal weight + float normalDist = distance(normal_center, normal_sample); + float w_n = exp(-normalDist / n_phi); + + + float weight = kernel[x+2] * kernel[y+2] * w_c * w_p * w_n; + + color += color_sample * weight; + totalWeight += weight; + } + } + + imageStore(write_texture, pixel_coords, color / totalWeight); } \ No newline at end of file diff --git a/shaders/light.glsl b/shaders/light.glsl index 1bf4147..0135093 100644 --- a/shaders/light.glsl +++ b/shaders/light.glsl @@ -2,7 +2,7 @@ hitInfo traceRay(Ray ray); vec3 GetEnvironmentLight(Ray ray) { - // return vec3(0.); + return vec3(0.); vec3 sun_pos = vec3(-0.5, 0.5, 0.5); float SunFocus = 1.5; float SunIntensity = 1.; @@ -65,7 +65,7 @@ vec3 sampleQuadLight(vec3 position, GPUObject obj, int light_index, GPUMaterial vec3 normal = normalize(crossQuad); float cos_theta = max(0.0, dot(normal, -light_dir)); - return mat.emission * mat.color / (light_dist); + return mat.emission * mat.color / (light_dist * light_dist) * pdf; } vec3 sampleLights(vec3 position, inout uint rng_state) @@ -134,6 +134,6 @@ void calculateLightColor(GPUMaterial mat, hitInfo hit, inout vec3 color, inou { color *= mat.color; light += mat.emission * mat.color; + // light += sampleLights(hit.position, rng_state); } - // light += sampleLights(hit.position, rng_state); } \ No newline at end of file diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 88bb58d..ea9e8ab 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -145,10 +145,12 @@ int main(int argc, char **argv) glUseProgram(shader.getProgramComputeDenoising()); glUniform2fv(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_resolution"), 1, glm::value_ptr(glm::vec2(WIDTH, HEIGHT))); - for (int pass = 0; pass < 1; ++pass) + for (int pass = 0; pass < 4; ++pass) { shader.flipOutputDenoising(pass % 2 == 0); + glUniform1i(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_pass"), pass); + glDispatchCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); } diff --git a/srcs/class/Shader.cpp b/srcs/class/Shader.cpp index db1c1c4..1ad46a2 100644 --- a/srcs/class/Shader.cpp +++ b/srcs/class/Shader.cpp @@ -137,7 +137,7 @@ void Shader::attach(void) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); - glBindImageTexture(0, _output_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); + glBindImageTexture(0, _output_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); glGenTextures(1, &_accumulation_texture); glBindTexture(GL_TEXTURE_2D, _accumulation_texture); @@ -156,6 +156,24 @@ void Shader::attach(void) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); glBindImageTexture(2, _denoising_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + + glGenTextures(1, &_normal_texture); + glBindTexture(GL_TEXTURE_2D, _normal_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); + glBindImageTexture(3, _normal_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + + glGenTextures(1, &_position_texture); + glBindTexture(GL_TEXTURE_2D, _position_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); + glBindImageTexture(4, _position_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); } void Shader::checkCompileErrors(GLuint shader) From ee95d9954a1be509122100effcf30d61a20c1ce6 Mon Sep 17 00:00:00 2001 From: TheRedShip Date: Sat, 8 Feb 2025 23:38:49 +0100 Subject: [PATCH 21/21] + | Imgui denoise --- includes/RT/Scene.hpp | 11 +++++++++++ includes/RT/Shader.hpp | 3 +++ shaders/compute.glsl | 10 +++------- shaders/denoising.glsl | 15 +++++++-------- srcs/RT.cpp | 34 ++++++++++++++++++++++------------ srcs/class/Camera.cpp | 1 + srcs/class/Scene.cpp | 10 ++++++++++ srcs/class/Shader.cpp | 10 ++++++++++ srcs/class/Window.cpp | 22 +++++++++++++++++++++- 9 files changed, 88 insertions(+), 28 deletions(-) diff --git a/includes/RT/Scene.hpp b/includes/RT/Scene.hpp index 700399c..16122aa 100644 --- a/includes/RT/Scene.hpp +++ b/includes/RT/Scene.hpp @@ -78,6 +78,15 @@ struct GPUDebug int box_treshold; }; +struct GPUDenoise +{ + int enabled; + int pass; + float c_phi; + float p_phi; + float n_phi; +}; + struct GPUBvh { alignas(16) glm::vec3 min; @@ -135,6 +144,7 @@ class Scene GPUVolume &getVolume(); GPUDebug &getDebug(); + GPUDenoise &getDenoise(); Camera *getCamera(void) const; GPUMaterial getMaterial(int material_index); @@ -162,6 +172,7 @@ class Scene GPUVolume _gpu_volume; GPUDebug _gpu_debug; + GPUDenoise _gpu_denoise; Camera *_camera; }; diff --git a/includes/RT/Shader.hpp b/includes/RT/Shader.hpp index 1b1583e..a76edec 100644 --- a/includes/RT/Shader.hpp +++ b/includes/RT/Shader.hpp @@ -41,6 +41,9 @@ class Shader GLuint getProgramCompute(void) const; GLuint getProgramComputeDenoising(void) const; + GLuint getNormalTexture(void) const; + GLuint getPositionTexture(void) const; + std::vector getOutputImage(void); diff --git a/shaders/compute.glsl b/shaders/compute.glsl index 5932b8f..c712094 100644 --- a/shaders/compute.glsl +++ b/shaders/compute.glsl @@ -198,8 +198,8 @@ vec3 pathtrace(Ray ray, inout uint rng_state) if (i == 0) { - imageStore(normal_texture, ivec2(gl_GlobalInvocationID.xy), vec4(hit.normal, 1.0)); - imageStore(position_texture, ivec2(gl_GlobalInvocationID.xy), vec4(hit.position, 1.0)); + imageStore(normal_texture, ivec2(gl_GlobalInvocationID.xy), vec4(normalize(hit.normal), 1.0)); + imageStore(position_texture, ivec2(gl_GlobalInvocationID.xy), vec4(normalize(hit.position), 1.0)); } float p = max(color.r, max(color.g, color.b)); @@ -248,10 +248,6 @@ void main() if (pixel_coords.x >= int(u_resolution.x) || pixel_coords.y >= int(u_resolution.y)) return; - // if (pixel_coords.x % 50 == 0 || pixel_coords.y % 50 == 0) - // imageStore(output_image, pixel_coords, vec4(1.,0.,0., 0.)); - // return ; - if (u_pixelisation != 1 && (uint(pixel_coords.x) % u_pixelisation != 0 || uint(pixel_coords.y) % u_pixelisation != 0)) return; @@ -260,7 +256,7 @@ void main() vec2 jitter = randomPointInCircle(rng_state) * 1; - vec2 uv = ((vec2(pixel_coords) + jitter) / u_resolution) * 2.0 - 1.0;; + vec2 uv = ((vec2(pixel_coords) + jitter) / u_resolution) * 2.0 - 1.0; uv.x *= u_resolution.x / u_resolution.y; Ray ray = initRay(uv, rng_state); diff --git a/shaders/denoising.glsl b/shaders/denoising.glsl index 893004c..1f94f62 100644 --- a/shaders/denoising.glsl +++ b/shaders/denoising.glsl @@ -11,15 +11,15 @@ layout(binding = 4, rgba32f) uniform image2D normal_texture; uniform vec2 u_resolution; uniform int u_pass; +uniform float u_c_phi; +uniform float u_p_phi; +uniform float u_n_phi; + void main() { ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy); if (pixel_coords.x >= int(u_resolution.x) || pixel_coords.y >= int(u_resolution.y)) return; - - float c_phi = 1.0; - float p_phi = 1.0; - float n_phi = 1.0; int holes = int(pow(2, u_pass)); @@ -49,16 +49,15 @@ void main() // Color weight float colorDist = distance(color_center, color_sample); - float w_c = exp(-colorDist / c_phi); + float w_c = exp(-colorDist / u_c_phi); // Position weight float posDist = distance(position_center, position_sample); - float w_p = exp(-posDist / p_phi); + float w_p = exp(-posDist / u_p_phi); // Normal weight float normalDist = distance(normal_center, normal_sample); - float w_n = exp(-normalDist / n_phi); - + float w_n = exp(-normalDist / u_n_phi); float weight = kernel[x+2] * kernel[y+2] * w_c * w_p * w_n; diff --git a/srcs/RT.cpp b/srcs/RT.cpp index ea9e8ab..6eab635 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -141,21 +141,28 @@ int main(int argc, char **argv) glDispatchCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - // - glUseProgram(shader.getProgramComputeDenoising()); - glUniform2fv(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_resolution"), 1, glm::value_ptr(glm::vec2(WIDTH, HEIGHT))); - - for (int pass = 0; pass < 4; ++pass) + GPUDenoise denoise = scene.getDenoise(); + if (denoise.enabled) { - shader.flipOutputDenoising(pass % 2 == 0); + glUseProgram(shader.getProgramComputeDenoising()); - glUniform1i(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_pass"), pass); - - glDispatchCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); - glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); + glUniform2fv(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_resolution"), 1, glm::value_ptr(glm::vec2(WIDTH, HEIGHT))); + glUniform1f(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_c_phi"), denoise.c_phi); + glUniform1f(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_p_phi"), denoise.p_phi); + glUniform1f(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_n_phi"), denoise.n_phi); + + for (int pass = 0; pass < denoise.pass ; ++pass) + { + shader.flipOutputDenoising(pass % 2 == 0); + + glUniform1i(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_pass"), pass); + + glDispatchCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); + glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); + } + shader.flipOutputDenoising(true); } - shader.flipOutputDenoising(true); - // + glClear(GL_COLOR_BUFFER_BIT); @@ -168,6 +175,9 @@ int main(int argc, char **argv) window.display(); window.pollEvents(); + + glClearTexImage(shader.getNormalTexture(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glClearTexImage(shader.getPositionTexture(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } ImGui_ImplOpenGL3_Shutdown(); diff --git a/srcs/class/Camera.cpp b/srcs/class/Camera.cpp index af49703..9b6d636 100644 --- a/srcs/class/Camera.cpp +++ b/srcs/class/Camera.cpp @@ -100,6 +100,7 @@ int Camera::portalTeleport(Scene *scene, float delta_time) if (distance_portal <= distance_future_pos && glm::dot(glm::normalize(future_pos - _position), obj.normal) > 0.0f) { + std::cout << "Teleportation" << std::endl; GPUObject linked_portal = scene->getObjectData()[obj.radius]; glm::mat4 portal_transform = linked_portal.transform * glm::inverse(obj.transform); diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index 0abd4cb..28437fa 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -33,6 +33,11 @@ Scene::Scene(std::string &name) _gpu_debug.triangle_treshold = 1; _gpu_debug.box_treshold = 1; + _gpu_denoise.enabled = 0; + _gpu_denoise.pass = 0; + _gpu_denoise.c_phi = 0.1f; + _gpu_denoise.p_phi = 0.1f; + _gpu_denoise.n_phi = 0.1f; if (!file.is_open()) { @@ -364,6 +369,11 @@ GPUDebug &Scene::getDebug() return (_gpu_debug); } +GPUDenoise &Scene::getDenoise() +{ + return (_gpu_denoise); +} + std::vector &Scene::getBvhData() { return (_gpu_bvh_data); diff --git a/srcs/class/Shader.cpp b/srcs/class/Shader.cpp index 1ad46a2..b9d211a 100644 --- a/srcs/class/Shader.cpp +++ b/srcs/class/Shader.cpp @@ -300,6 +300,16 @@ GLuint Shader::getProgramComputeDenoising(void) const return (_program_denoising); } +GLuint Shader::getNormalTexture(void) const +{ + return (_normal_texture); +} + +GLuint Shader::getPositionTexture(void) const +{ + return (_position_texture); +} + std::vector Shader::getOutputImage(void) { std::vector res(WIDTH * HEIGHT * 4); diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index 7b39616..11de6d7 100644 --- a/srcs/class/Window.cpp +++ b/srcs/class/Window.cpp @@ -272,17 +272,37 @@ void Window::imGuiRender() has_changed = true; } + if (ImGui::CollapsingHeader("Denoiser")) + { + ImGui::PushID(0); + + ImGui::Checkbox("Enable", (bool *)(&_scene->getDenoise().enabled)); + ImGui::Separator(); + if (ImGui::SliderInt("Pass", &_scene->getDenoise().pass, 0, 8)) + _scene->getDenoise().pass = (_scene->getDenoise().pass / 2) * 2; // make sure it's even + + ImGui::SliderFloat("Color diff", &_scene->getDenoise().c_phi, 0.0f, 1.0f); + ImGui::SliderFloat("Position diff", &_scene->getDenoise().p_phi, 0.0f, 1.0f); + ImGui::SliderFloat("Normal diff", &_scene->getDenoise().n_phi, 0.0f, 1.0f); + + ImGui::PopID(); + } if (ImGui::CollapsingHeader("Debug")) { + ImGui::PushID(0); + has_changed |= ImGui::Checkbox("Enable", (bool *)(&_scene->getDebug().enabled)); ImGui::Separator(); has_changed |= ImGui::SliderInt("Debug mode", &_scene->getDebug().mode, 0, 2); has_changed |= ImGui::SliderInt("Box treshold", &_scene->getDebug().box_treshold, 1, 2000); has_changed |= ImGui::SliderInt("Triangle treshold", &_scene->getDebug().triangle_treshold, 1, 2000); + + ImGui::PopID(); } - _renderer->renderImgui();; + + _renderer->renderImgui(); ImGui::End();