From 39196a00ff1f039747cf0541380679a96bb097d7 Mon Sep 17 00:00:00 2001 From: TheRedShip Date: Sat, 8 Feb 2025 21:43:49 +0100 Subject: [PATCH] ~ | 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)