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 2f37aff..a76edec 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 */ /* */ /* ************************************************************************** */ @@ -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,10 @@ class Shader GLuint getProgram(void) const; GLuint getProgramCompute(void) const; + GLuint getProgramComputeDenoising(void) const; + + GLuint getNormalTexture(void) const; + GLuint getPositionTexture(void) const; std::vector getOutputImage(void); @@ -46,13 +52,18 @@ class Shader GLuint _program; GLuint _program_compute; + GLuint _program_denoising; GLuint _output_texture; GLuint _accumulation_texture; + GLuint _denoising_texture; + GLuint _normal_texture; + GLuint _position_texture; GLuint _vertex; GLuint _fragment; GLuint _compute; + GLuint _denoising; size_t _size; diff --git a/scenes/noneuclidian.rt b/scenes/noneuclidian.rt index cb3f4de..93e8aeb 100644 --- a/scenes/noneuclidian.rt +++ b/scenes/noneuclidian.rt @@ -46,4 +46,4 @@ po -10 1 0 0 3 0 0 0 3 0 1 sp -0.75 1.5 9 0.5 1 po -0.75 1.5 10 0 1.5 0 1.5 0 0 0 1 -po 7 1.5 10 0 1.5 0 1.5 0 0 0 1 \ No newline at end of file +po 7 1.5 10 0 1.5 0 1.5 0 0 0 1 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 5797d84..c712094 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(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)); if (randomValue(rng_state) >= p) break; color /= max(p, 0.001); @@ -238,7 +247,7 @@ 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 (u_pixelisation != 1 && (uint(pixel_coords.x) % u_pixelisation != 0 || uint(pixel_coords.y) % u_pixelisation != 0)) return; @@ -247,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 new file mode 100644 index 0000000..1f94f62 --- /dev/null +++ b/shaders/denoising.glsl @@ -0,0 +1,70 @@ +#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; + +layout(binding = 3, rgba32f) uniform image2D position_texture; +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; + + int holes = int(pow(2, u_pass)); + + 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; + + 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 / u_c_phi); + + // Position weight + float posDist = distance(position_center, position_sample); + float w_p = exp(-posDist / u_p_phi); + + // Normal weight + float normalDist = distance(normal_center, normal_sample); + float w_n = exp(-normalDist / u_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 990df9c..6c0852b 100644 --- a/shaders/light.glsl +++ b/shaders/light.glsl @@ -2,7 +2,7 @@ hitInfo traceRay(inout 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 9021c86..2885aef 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,29 @@ int main(int argc, char **argv) glDispatchCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); + GPUDenoise denoise = scene.getDenoise(); + if (denoise.enabled) + { + glUseProgram(shader.getProgramComputeDenoising()); + + 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); + } + + glClear(GL_COLOR_BUFFER_BIT); window.imGuiNewFrame(); @@ -152,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/Scene.cpp b/srcs/class/Scene.cpp index 5bf8a61..fbb4a56 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()) { @@ -366,6 +371,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 c752a1f..c8ceb8a 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); @@ -126,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); @@ -136,6 +147,33 @@ 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); + + 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) @@ -187,6 +225,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); @@ -245,6 +297,21 @@ GLuint Shader::getProgramCompute(void) const return (_program_compute); } +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();