From ee95d9954a1be509122100effcf30d61a20c1ce6 Mon Sep 17 00:00:00 2001 From: TheRedShip Date: Sat, 8 Feb 2025 23:38:49 +0100 Subject: [PATCH] + | 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();