diff --git a/ref/vk/shaders/lk_dnsr_compose.comp b/ref/vk/shaders/lk_dnsr_compose.comp index 5e0ecb52d3..f9321e1f54 100644 --- a/ref/vk/shaders/lk_dnsr_compose.comp +++ b/ref/vk/shaders/lk_dnsr_compose.comp @@ -25,19 +25,21 @@ layout(set = 0, binding = 8, rgba16f) uniform readonly image2D gi_sh1_denoised; layout(set = 0, binding = 9, rgba16f) uniform readonly image2D gi_sh2_denoised; layout(set = 0, binding = 10, rgba32f) uniform readonly image2D refl_position_t; -layout(set = 0, binding = 12, rgba16f) uniform readonly image2D blue_noise; +layout(set = 0, binding = 11, rgba16f) uniform readonly image2D blue_noise; -//layout(set = 0, binding = 13, rgba16f) uniform writeonly image2D out_temporal_gi_sh1_denoised; -//layout(set = 0, binding = 14, rgba16f) uniform writeonly image2D out_temporal_gi_sh2_denoised; +layout(set = 0, binding = 12, rgba16f) uniform writeonly image2D out_temporal_gi_sh1_denoised; +layout(set = 0, binding = 13, rgba16f) uniform writeonly image2D out_temporal_gi_sh2_denoised; -//layout(set = 0, binding = 10, rgba16f) uniform readonly image2D gi_sh1_accum; -//layout(set = 0, binding = 11, rgba16f) uniform readonly image2D gi_sh2_accum; +layout(set = 0, binding = 14, rgba16f) uniform readonly image2D gi_sh1_accum; +layout(set = 0, binding = 15, rgba16f) uniform readonly image2D gi_sh2_accum; + +layout(set = 0, binding = 16, rgba32f) uniform readonly image2D gi_position_t; #define GLSL #include "ray_interop.h" #undef GLSL -layout(set = 0, binding = 11) uniform UBO { UniformBuffer ubo; } ubo; +layout(set = 0, binding = 17) uniform UBO { UniformBuffer ubo; } ubo; // Blatantly copypasted from https://www.shadertoy.com/view/XsGfWV vec3 aces_tonemap(vec3 color){ @@ -151,7 +153,7 @@ void main() { // low_freq.CoCg = FIX_NAN(imageLoad(gi_sh2_accum, pix)).xy; // colour = project_SH_irradiance(low_freq, shading_normal) / STORAGE_SCALE_LF; - //colour = diffuse_gi; +// colour = normalize(imageLoad(gi_position_t, pix).xyz); //colour = FIX_NAN(imageLoad(diffuse_denoised, pix)).rgb; @@ -194,8 +196,8 @@ void main() { imageStore(out_composed, pix, vec4(colour, 0.)); - //imageStore(out_temporal_gi_sh1_denoised, pix, low_freq.shY); - //imageStore(out_temporal_gi_sh2_denoised, pix, vec4(low_freq.CoCg, 0., 0.)); + imageStore(out_temporal_gi_sh1_denoised, pix, low_freq.shY); + imageStore(out_temporal_gi_sh2_denoised, pix, vec4(low_freq.CoCg, 0., 0.)); //imageStore(dest, pix, FIX_NAN(imageLoad(light_direct_poly, pix))); } diff --git a/ref/vk/shaders/lk_dnsr_light_gi_point_w23.comp b/ref/vk/shaders/lk_dnsr_light_gi_point_w23.comp new file mode 100644 index 0000000000..6dfbf13abc --- /dev/null +++ b/ref/vk/shaders/lk_dnsr_light_gi_point_w23.comp @@ -0,0 +1,15 @@ +#version 460 core +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_ray_query: require + +#define RAY_QUERY + +#define SECOND_POSITION gi_position_t + +#define GI + +#define LIGHT_POINT 1 +#define OUTPUTS(X) \ + X(20, light_point_diffuse_gi, rgba16f) \ + X(21, light_point_specular_gi, rgba16f) +#include "lk_dnsr_lights_direct_w23.glsl" diff --git a/ref/vk/shaders/lk_dnsr_lighting_mix.comp b/ref/vk/shaders/lk_dnsr_lighting_mix.comp index df7ba1500c..d793ced319 100644 --- a/ref/vk/shaders/lk_dnsr_lighting_mix.comp +++ b/ref/vk/shaders/lk_dnsr_lighting_mix.comp @@ -30,16 +30,18 @@ layout(set = 0, binding = 10, rgba16f) uniform readonly image2D light_poly_refl; layout(set = 0, binding = 11, rgba16f) uniform readonly image2D light_point_diffuse_refl; layout(set = 0, binding = 12, rgba16f) uniform readonly image2D light_point_specular_refl; -/* + layout(set = 0, binding = 11, rgba16f) uniform readonly image2D light_poly_gi; -layout(set = 0, binding = 12, rgba16f) uniform readonly image2D light_point_gi; -*/ -layout(set = 0, binding = 13, rgba16f) uniform readonly image2D refl_emissive; -/*layout(set = 0, binding = 14, rgba16f) uniform readonly image2D gi_emissive; -layout(set = 0, binding = 15, rgba8) uniform readonly image2D gi_base_color_a; -layout(set = 0, binding = 16, rgba16f) uniform readonly image2D gi_troughput; -layout(set = 0, binding = 17, rgba32f) uniform readonly image2D gi_position_t; -layout(set = 0, binding = 18, rgba32f) uniform readonly image2D gi_prev_bounce_pos;*/ + +layout(set = 0, binding = 12, rgba16f) uniform readonly image2D light_point_diffuse_gi; +layout(set = 0, binding = 13, rgba16f) uniform readonly image2D light_point_specular_gi; + +layout(set = 0, binding = 14, rgba16f) uniform readonly image2D refl_emissive; +layout(set = 0, binding = 15, rgba16f) uniform readonly image2D gi_emissive; +layout(set = 0, binding = 16, rgba8) uniform readonly image2D gi_base_color_a; +layout(set = 0, binding = 17, rgba16f) uniform readonly image2D gi_troughput; +layout(set = 0, binding = 18, rgba32f) uniform readonly image2D gi_position_t; +layout(set = 0, binding = 19, rgba32f) uniform readonly image2D gi_prev_bounce_pos; @@ -79,20 +81,20 @@ void main() { return; } - const vec3 diffuse = FIX_NAN(imageLoad(light_point_diffuse, pix)).rgb - + FIX_NAN(imageLoad(light_poly_diffuse, pix)).rgb; + //const vec3 diffuse = FIX_NAN(imageLoad(light_point_diffuse, pix)).rgb + // + FIX_NAN(imageLoad(light_poly_diffuse, pix)).rgb; const vec3 specular = FIX_NAN(imageLoad(light_poly_refl, pix)).rgb + FIX_NAN(imageLoad(light_point_diffuse_refl, pix)).rgb + FIX_NAN(imageLoad(light_point_specular_refl, pix)).rgb - + FIX_NAN(imageLoad(light_poly_specular, pix)).rgb + //+ FIX_NAN(imageLoad(light_poly_specular, pix)).rgb + FIX_NAN(imageLoad(light_point_specular, pix)).rgb + FIX_NAN(imageLoad(refl_emissive, pix)).rgb; - imageStore(out_diffuse_accum, pix, vec4(diffuse, 0.)); + //imageStore(out_diffuse_accum, pix, vec4(diffuse, 0.)); imageStore(out_specular_accum, pix, vec4(specular, 0.)); - imageStore(out_gi_sh1_accum, pix, vec4(0.)); - imageStore(out_gi_sh2_accum, pix, vec4(0.)); + //imageStore(out_gi_sh1_accum, pix, vec4(0.)); + //imageStore(out_gi_sh2_accum, pix, vec4(0.)); //vec3 irradiance1 = @@ -136,7 +138,7 @@ void main() { imageStore(out_diffuse_accum, pix, vec4(diffuse, 0.)); imageStore(out_specular_accum, pix, vec4(reflection, 0.)); - + */ vec4 gi_sh1_sum = vec4(0.); vec2 gi_sh2_sum = vec2(0.); @@ -151,11 +153,12 @@ void main() { continue; // global illumination - vec3 global_illumination = FIX_NAN(imageLoad(light_poly_gi, pix_gi)).rgb + - FIX_NAN(imageLoad(light_point_gi, pix_gi)).rgb + - FIX_NAN(imageLoad(gi_emissive, pix_gi)).rgb * 100.0f; + vec3 global_illumination = (FIX_NAN(imageLoad(light_poly_gi, pix_gi)).rgb + + FIX_NAN(imageLoad(light_point_diffuse_gi, pix_gi)).rgb + + FIX_NAN(imageLoad(light_point_specular_gi, pix_gi)).rgb + + FIX_NAN(imageLoad(gi_emissive, pix_gi)).rgb) * 100.0f; - global_illumination = vec3(1.); + //global_illumination = vec3(1.); //global_illumination *= gi_troughput; //global_illumination *= float(GI_DOWNSAMPLE * GI_DOWNSAMPLE) * 10.; @@ -194,7 +197,7 @@ void main() { imageStore(out_gi_sh2_accum, pix_gi, vec4(gi_sh2_sum, 0., 0.)); } } -// imageStore(out_gi_sh1_accum, pix * GI_DOWNSAMPLE, gi_sh1_sum); -// imageStore(out_gi_sh2_accum, pix * GI_DOWNSAMPLE, vec4(gi_sh2_sum, 0., 0.)); - }*/ + imageStore(out_gi_sh1_accum, pix * GI_DOWNSAMPLE, gi_sh1_sum); + imageStore(out_gi_sh2_accum, pix * GI_DOWNSAMPLE, vec4(gi_sh2_sum, 0., 0.)); + } } diff --git a/ref/vk/shaders/lk_dnsr_lighting_mix_diffuse.comp b/ref/vk/shaders/lk_dnsr_lighting_mix_diffuse.comp new file mode 100644 index 0000000000..208fa9cf4d --- /dev/null +++ b/ref/vk/shaders/lk_dnsr_lighting_mix_diffuse.comp @@ -0,0 +1,54 @@ +#version 460 + +#include "noise.glsl" +#include "utils.glsl" +#include "brdf.h" +#include "lk_dnsr_config.glsl" +#include "lk_dnsr_spherical_harmonics.glsl" +#include "lk_dnsr_utils.glsl" +#include "color_spaces.glsl" + +#define GI_LIMIT_LUMINANCE 0.2 + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +layout(set = 0, binding = 0, rgba16f) uniform image2D out_specular_accum; +layout(set = 0, binding = 1, rgba16f) uniform image2D out_diffuse_accum; +layout(set = 0, binding = 2, rgba16f) uniform image2D out_gi_sh1_accum; +layout(set = 0, binding = 3, rgba16f) uniform image2D out_gi_sh2_accum; + +layout(set = 0, binding = 4, rgba8) uniform readonly image2D base_color_a; +layout(set = 0, binding = 5, rgba8) uniform readonly image2D refl_base_color_a; + +layout(set = 0, binding = 6, rgba16f) uniform readonly image2D light_poly_diffuse; + +layout(set = 0, binding = 7, rgba16f) uniform readonly image2D light_point_diffuse; + + + +vec3 samplePolyDirect(ivec2 pix, ivec2 res) { + if (any(lessThan(pix, ivec2(0))) && any(greaterThanEqual(pix, res))) return vec3(-100.); + return FIX_NAN(imageLoad(light_poly_diffuse, pix)).rgb; +} + +vec3 samplePolyDirectOpposite(ivec2 pix1, ivec2 pix2, ivec2 res) { + const vec3 first = samplePolyDirect(pix1, res); + const vec3 second = samplePolyDirect(pix2, res); + if (first.x < 0.99) return second; + else if (first.x < 0.99) return first; + return (first + second) / 2.; +} + +void main() { + ivec2 res = ivec2(imageSize(base_color_a)); + ivec2 pix = ivec2(gl_GlobalInvocationID); + + if (any(greaterThanEqual(pix, res))) { + return; + } + + const vec3 diffuse = FIX_NAN(imageLoad(light_point_diffuse, pix)).rgb + + FIX_NAN(imageLoad(light_poly_diffuse, pix)).rgb; + + imageStore(out_diffuse_accum, pix, vec4(diffuse, 0.)); +} diff --git a/ref/vk/shaders/lk_dnsr_lights_direct_w23.glsl b/ref/vk/shaders/lk_dnsr_lights_direct_w23.glsl index 38b0c19076..ca705b5c24 100644 --- a/ref/vk/shaders/lk_dnsr_lights_direct_w23.glsl +++ b/ref/vk/shaders/lk_dnsr_lights_direct_w23.glsl @@ -85,17 +85,22 @@ void main() { const vec3 throughput = vec3(1.); vec3 diffuse = vec3(0.), specular = vec3(0.); - computeLighting(pos + geometry_normal * .001, shading_normal, throughput, -direction, material, diffuse, specular); + //computeLighting(pos + geometry_normal * .001, shading_normal, throughput, -direction, material, diffuse, specular); #if LIGHT_POINT #ifdef PRIMARY_VIEW imageStore(out_light_point_diffuse, pix, vec4(diffuse, 0.f)); imageStore(out_light_point_specular, pix, vec4(specular, 0.f)); +#else +#ifdef GI + imageStore(out_light_point_diffuse_gi, pix, vec4(diffuse, 0.f)); + imageStore(out_light_point_specular_gi, pix, vec4(specular, 0.f)); #else imageStore(out_light_point_diffuse_refl, pix, vec4(diffuse, 0.f)); imageStore(out_light_point_specular_refl, pix, vec4(specular, 0.f)); #endif #endif +#endif #if LIGHT_POLYGON imageStore(out_light_poly_diffuse, pix, vec4(diffuse, 0.f)); diff --git a/ref/vk/shaders/lk_dnsr_ray_gi_bounces.comp b/ref/vk/shaders/lk_dnsr_ray_gi_bounces.comp index e3a2dfdcce..8c9b760992 100644 --- a/ref/vk/shaders/lk_dnsr_ray_gi_bounces.comp +++ b/ref/vk/shaders/lk_dnsr_ray_gi_bounces.comp @@ -123,7 +123,7 @@ bool bool getHit(vec3 origin, vec3 direction, int mask, inout RayPayloadPrimary bool getHit(vec3 origin, vec3 direction, int mask, inout RayPayloadPrimary payload) { - float L = 1000.; + float L = 100000.; rayQueryEXT rq; const uint flags = 0 @@ -238,7 +238,7 @@ void main() { } vec3 gi_direction = vec3(1.); float adapt_weight = 1.; - + /* const float random_choose_pos = rand01(); if (dir_weights_sum > 0. && GI_DIR_ADAPTIVE_CANDIDATES > 1) { float sample_rnd_start = 0.; @@ -252,10 +252,10 @@ void main() { adapt_weight = curr_weight; } } - } else { + } else {*/ gi_direction = dir_candidates[0]; adapt_weight = 1.0; - } + /*}*/ adapt_weight = 1.0f; // rag for remove fireflyes? @@ -264,7 +264,7 @@ void main() { const ivec2 out_pix = pix + (res / GI_DOWNSAMPLE) * ivec2(bounce / GI_DOWNSAMPLE, bounce % GI_DOWNSAMPLE); if (any(greaterThanEqual(out_pix, res))) continue; - /* + RayPayloadPrimary payload; payload.hit_t = vec4(0.); payload.base_color_a = vec4(0.); @@ -272,7 +272,7 @@ void main() { payload.material_rmxx = vec4(0.); payload.emissive = vec4(0.); - bool isSky = getHit(gi_origin, normalize(gi_direction), GEOMETRY_BIT_OPAQUE, payload); + bool isSky = getHit(gi_origin, normalize(-gi_direction), GEOMETRY_BIT_OPAQUE, payload); if (any(lessThan(gi_troughput, vec3(0.001)))) { break; @@ -308,9 +308,9 @@ void main() { imageStore(out_gi_emissive, out_pix, vec4((payload.emissive.xyz * gi_troughput) / adapt_weight, 0.)); break; } - }*/ + } imageStore(out_gi_troughput,out_pix, vec4(1., 1., 1., 0.)); - imageStore(out_gi_emissive, out_pix, vec4(10., 0., 0., 1.)); + //imageStore(out_gi_emissive, out_pix, vec4(10., 0., 0., 1.)); imageStore(out_gi_emissive, out_pix, vec4(10., 0., 0., 1.)); } diff --git a/ref/vk/shaders/lk_dnsr_ray_primary.comp b/ref/vk/shaders/lk_dnsr_ray_primary.comp index 22267480d5..c440a57089 100644 --- a/ref/vk/shaders/lk_dnsr_ray_primary.comp +++ b/ref/vk/shaders/lk_dnsr_ray_primary.comp @@ -105,7 +105,7 @@ vec3 PowRand( vec3 rand, vec3 axis, float fpow ) bool getHit(vec3 origin, vec3 direction, int mask, inout RayPayloadPrimary payload) { - float L = 1000.; + float L = 100000.; rayQueryEXT rq; const uint flags = 0 diff --git a/ref/vk/shaders/lk_dnsr_skip_denoising.comp b/ref/vk/shaders/lk_dnsr_skip_denoising.comp index 8ac6d54add..515f617ac8 100644 --- a/ref/vk/shaders/lk_dnsr_skip_denoising.comp +++ b/ref/vk/shaders/lk_dnsr_skip_denoising.comp @@ -14,8 +14,8 @@ layout(set = 0, binding = 1, rgba16f) uniform writeonly image2D out_diffuse_deno layout(set = 0, binding = 2, rgba16f) uniform writeonly image2D out_gi_sh1_denoised; layout(set = 0, binding = 3, rgba16f) uniform writeonly image2D out_gi_sh2_denoised; -layout(set = 0, binding = 4, rgba16f) uniform readonly image2D specular_accum; -layout(set = 0, binding = 5, rgba16f) uniform readonly image2D diffuse_accum; +layout(set = 0, binding = 4, rgba16f) uniform readonly image2D specular_pre_blured; +layout(set = 0, binding = 5, rgba16f) uniform readonly image2D diffuse_pre_blured; layout(set = 0, binding = 6, rgba16f) uniform readonly image2D gi_sh1_accum; layout(set = 0, binding = 7, rgba16f) uniform readonly image2D gi_sh2_accum; @@ -35,8 +35,8 @@ void main() { // imageStore(out_gi_sh2_denoised, pix, vec4(0.)); - imageStore(out_specular_denoised, pix, imageLoad(specular_accum, pix)); - imageStore(out_diffuse_denoised, pix, imageLoad(diffuse_accum, pix)); + imageStore(out_specular_denoised, pix, imageLoad(specular_pre_blured, pix)); + imageStore(out_diffuse_denoised, pix, imageLoad(diffuse_pre_blured, pix)); imageStore(out_gi_sh1_denoised, pix, imageLoad(gi_sh1_accum, pix)); imageStore(out_gi_sh2_denoised, pix, imageLoad(gi_sh2_accum, pix)); } diff --git a/ref/vk/shaders/lk_dnsr_specular_pre_blur_2.comp b/ref/vk/shaders/lk_dnsr_specular_pre_blur_2.comp index 9ec256a392..7fce48fb6d 100644 --- a/ref/vk/shaders/lk_dnsr_specular_pre_blur_2.comp +++ b/ref/vk/shaders/lk_dnsr_specular_pre_blur_2.comp @@ -3,7 +3,7 @@ #define SVGF_STEP_SIZE 2 #define INPUT_IMAGE specular_pre_blur_1 -#define OUTPUT_IMAGE out_specular_pre_blured +#define OUTPUT_IMAGE out_specular_pre_blur_2 //#define VARIANCE_IMAGE specular_variance #define MAXIMAL_VARIANCE 1 diff --git a/ref/vk/shaders/lk_dnsr_specular_pre_blur_3.comp b/ref/vk/shaders/lk_dnsr_specular_pre_blur_3.comp new file mode 100644 index 0000000000..72a631c367 --- /dev/null +++ b/ref/vk/shaders/lk_dnsr_specular_pre_blur_3.comp @@ -0,0 +1,11 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require + +#define SVGF_STEP_SIZE 4 +#define INPUT_IMAGE specular_pre_blur_2 +#define OUTPUT_IMAGE out_specular_pre_blured +//#define VARIANCE_IMAGE specular_variance + +#define MAXIMAL_VARIANCE 1 + +#include "lk_dnsr_svgf_kernel.glsl" diff --git a/ref/vk/shaders/lk_dnsr_svgf_kernel_large.glsl b/ref/vk/shaders/lk_dnsr_svgf_kernel_large.glsl new file mode 100644 index 0000000000..7ae263c32b --- /dev/null +++ b/ref/vk/shaders/lk_dnsr_svgf_kernel_large.glsl @@ -0,0 +1,270 @@ + +#include "noise.glsl" +#include "brdf.h" +#include "utils.glsl" +#include "lk_dnsr_utils.glsl" + +// used in multi-pass filtering as 1, 2, 4 and more step sizes +#ifndef SVGF_STEP_SIZE + #define SVGF_STEP_SIZE 1 +#endif + +#define DRIVEN_BY_NORMALS 1 +//#define DRIVEN_BY_DEPTH 1 +#define DRIVEN_BY_VARIANCE 1 + +#define PHI_COLOR 10. +#define KERNEL_SIZE 8 +#define DEPTH_FACTOR 10. + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +layout(set = 0, binding = 0, rgba16f) uniform image2D OUTPUT_IMAGE; + +layout(set = 0, binding = 1, rgba16f) uniform readonly image2D INPUT_IMAGE; + +layout(set = 0, binding = 2, rgba16f) uniform readonly image2D normals_gs; +layout(set = 0, binding = 3, rgba32f) uniform readonly image2D position_t; // for depth +layout(set = 0, binding = 4, rgba8) uniform readonly image2D material_rmxx; + +#ifndef MAXIMAL_VARIANCE +layout(set = 0, binding = 5, rgba16f) uniform readonly image2D VARIANCE_IMAGE; +#endif + +#define CACHE_WIDTH (KERNEL_SIZE * 2 + 8) +shared vec4 normalDepth_Cache[CACHE_WIDTH][CACHE_WIDTH]; +shared vec4 irradianceRoughness_Cache[CACHE_WIDTH][CACHE_WIDTH]; + +//#ifdef DRIVEN_BY_RAY_LENGTH +// layout(set = 0, binding = 6, rgba32f) uniform readonly image2D refl_position_t; // for reflection ray length +//#endif + +// Normal-weighting function (4.4.1) +float normalWeight(vec3 normal0, vec3 normal1) { + const float exponent = 64.0; + return pow(max(0.0, dot(normal0, normal1)), exponent); +} + +// Depth-weighting function (4.4.2) +float depthWeight(float depth0, float depth1, vec2 grad, vec2 offset) { + // paper uses eps = 0.005 for a normalized depth buffer + // ours is not but 0.1 seems to work fine + const float eps = 0.1; + return exp((-abs(depth0 - depth1)) / (abs(dot(grad, offset)) + eps)); +} + +// Self-made depth gradient for compute shader (is it fine on edges?) +vec2 depthGradient(float depth, ivec2 pix, ivec2 res) { + vec4 depth_samples = vec4(depth); + if ((pix.x + 1) < res.x) depth_samples.x = imageLoad(position_t, pix + ivec2(1, 0)).w; + if ((pix.x - 1) >= 0) depth_samples.y = imageLoad(position_t, pix - ivec2(1, 0)).w; + if ((pix.y + 1) < res.y) depth_samples.z = imageLoad(position_t, pix + ivec2(0, 1)).w; + if ((pix.y - 1) >= 0) depth_samples.w = imageLoad(position_t, pix - ivec2(0, 1)).w; + return (depth_samples.xz - depth_samples.yw) / 2.; +} + +// Luminance-weighting function (4.4.3) +float luminanceWeight(float lum0, float lum1, float variance) { + const float strictness = 30.0; + const float eps = 0.05; + return exp((-abs(lum0 - lum1)) / (strictness * variance + eps)); +} + + +void readNormals(ivec2 uv, out vec3 geometry_normal, out vec3 shading_normal) { + const vec4 n = imageLoad(normals_gs, uv); + geometry_normal = normalDecode(n.xy); + shading_normal = normalDecode(n.zw); +} + + + +float depth_edge_stopping_weight(float center_depth, float sample_depth, float phi) +{ + return exp(-abs(center_depth - sample_depth) / phi); +} + +float luma_edge_stopping_weight(float center_luma, float sample_luma, float phi) +{ + return abs(center_luma - sample_luma) / phi; +} + + +// The next function implements the filtering method described in the two papers +// linked below. +// +// "Progressive Spatiotemporal Variance-Guided Filtering" +// https://pdfs.semanticscholar.org/a81a/4eed7f303f7e7f3ca1914ccab66351ce662b.pdf +// +// "Edge-Avoiding ?-Trous Wavelet Transform for fast Global Illumination Filtering" +// https://jo.dreggn.org/home/2010_atrous.pdf +// + + + +void main() { + ivec2 res = ivec2(imageSize(INPUT_IMAGE)); + ivec2 pix = ivec2(gl_GlobalInvocationID); + ivec2 loc = ivec2(gl_LocalInvocationID); + + if (any(greaterThanEqual(pix, res))) { + return; + } + + const vec4 center_irradiance = FIX_NAN(imageLoad(INPUT_IMAGE, pix)); + const float center_luminance = luminance(center_irradiance.rgb); + + const vec4 material_rmxx = FIX_NAN(imageLoad(material_rmxx, pix)); + const int texel_flags = int(material_rmxx.b + 0.01); + + ivec3 pix_no_checker = CheckerboardToPix(pix, res); + int is_transparent_texel = pix_no_checker.z; + + for (int x = -KERNEL_SIZE; x < (KERNEL_SIZE + 8); x++) { + for (int y = -KERNEL_SIZE; y < (KERNEL_SIZE + 8); y++) { + const ivec2 offset = ivec2(x, y) * SVGF_STEP_SIZE; + const ivec2 p = texel_flags > 0 ? (pix + offset) : // transparent or refract, use checkerboard coords + PixToCheckerboard(pix_no_checker.xy + offset, res, is_transparent_texel).xy; + if (any(greaterThanEqual(p, res)) || any(lessThan(p, ivec2(0)))) { + continue; + } + + if ((loc.x != x % 8) || loc.y != y % 8)) + continue; + + const vec3 normal = FIX_NAN(imageLoad(normals_gs, p)).zw; + const float depth = FIX_NAN(imageLoad(position_t, p)).w; + irradianceRoughness_Cache[x + KERNEL_SIZE][y + KERNEL_SIZE] = vec4(irradiance, .5f); + normalDepth_Cache[x + KERNEL_SIZE][y + KERNEL_SIZE] = vec4(luminance(irradiance), normal, depth); + } + } + + barrier(); + +//#ifdef MAXIMAL_VARIANCE + const float reproject_variance = 1.; +//#else +// const float reproject_variance = max(0.001, FIX_NAN(imageLoad(VARIANCE_IMAGE, pix)).r); +//#endif + + //const vec3 center_irradiance = FIX_NAN(imageLoad(INPUT_IMAGE, pix).rgb; + const float depth = FIX_NAN(imageLoad(position_t, pix)).w; + const vec2 depth_offset = vec2(1.); + //const float reproject_variance = 1.0; // need to calculate in reprojection + //const float phi = PHI_COLOR * sqrt(max(0.0, 0.0001 + reproject_variance)); + + vec3 geometry_normal, shading_normal; + readNormals(pix, geometry_normal, shading_normal); + + + // depth-gradient estimation from screen-space derivatives +// const vec2 depth_gradient = depthGradient(depth, pix, res); + + const float kernel[2][2] = { + { 1.0 / 4.0, 1.0 / 8.0 }, + { 1.0 / 8.0, 1.0 / 16.0 } + }; + + float variance = 0.; // default value + /*{ + const float sigma = KERNEL_SIZE / 2.; + vec2 sigma_variance = vec2(0.0, 0.0); + float weight_sum = 0.; + for (int x = -KERNEL_SIZE; x <= KERNEL_SIZE; ++x) { + for (int y = -KERNEL_SIZE; y <= KERNEL_SIZE; ++y) { + const ivec2 p = pix + ivec2(x, y) * SVGF_STEP_SIZE; + if (any(greaterThanEqual(p, res)) || any(lessThan(p, ivec2(0)))) { + continue; + } + + //float weight = kernel[abs(x)][abs(y)]; + const float weight = normpdf(x, sigma) * normpdf(y, sigma); + //const float weight = 1.; + + const vec3 current_irradiance = imageLoad(INPUT_IMAGE, p).rgb; + float current_luminance = luminance(current_irradiance); + sigma_variance += vec2(current_luminance, current_luminance * current_luminance ) * weight; + weight_sum += weight; + } + } + + if (weight_sum > 0.) { + sigma_variance /= weight_sum; + variance = max(0.0, sigma_variance.y - sigma_variance.x * sigma_variance.x); + } + }*/ + + vec3 irradiance = vec3(0.); + float weight_sum = 0.; + const float sigma = KERNEL_SIZE / 2.; + for (int x = -KERNEL_SIZE; x <= KERNEL_SIZE; ++x) { + for (int y = -KERNEL_SIZE; y <= KERNEL_SIZE; ++y) { + const ivec2 offset = ivec2(x, y) * SVGF_STEP_SIZE; + const ivec2 p = texel_flags > 0 ? (pix + offset) : // transparent or refract, use checkerboard coords + PixToCheckerboard(pix_no_checker.xy + offset, res, is_transparent_texel).xy; + if (any(greaterThanEqual(p, res)) || any(lessThan(p, ivec2(0)))) { + continue; + } + + const vec4 lumNormDepth = lumNormDepth_Cache[x + KERNEL_SIZE][y + KERNEL_SIZE]; + + const float depth_current = lumNormDepth.w; + + + //const vec3 current_irradiance = FIX_NAN(imageLoad(INPUT_IMAGE, p)).rgb; + //const float depth_current = FIX_NAN(imageLoad(position_depth, p)).w; + + float weight = normpdf(x, sigma) * normpdf(y, sigma); + //float weight = kernel[abs(x)][abs(y)]; + + // combine the weights from above + #ifdef DRIVEN_BY_NORMALS + //vec3 current_geometry_normal, current_shading_normal; + //readNormals(p, current_geometry_normal, current_shading_normal); + const vec3 current_shading_normal = normalDecode(lumNormDepth.yz); + weight *= normalWeight(shading_normal, current_shading_normal); + #endif + + #ifdef DRIVEN_BY_DEPTH + weight *= depth_edge_stopping_weight(depth, depth_current, DEPTH_FACTOR); +// weight *= depthWeight(depth, depth_current, depth_gradient, depth_offset); + #endif +// + #ifdef DRIVEN_BY_VARIANCE + const float current_luminance = lumNormDepth.x; + //const float current_luminance = luminance(current_irradiance); + //weight *= luma_edge_stopping_weight(center_luminance, current_luminance, phi); + weight *= luminanceWeight(center_luminance, current_luminance, reproject_variance); + #endif +// +// #ifdef DRIVEN_BY_RAY_LENGTH +// //// TODO: release this for specular +// //const vec4 current_refl_ray_length = depth_current + FIX_NAN(imageLoad(refl_position_t, p)).w; +// //weight *= rayLengthWeight(current_refl_ray_length, refl_ray_length); // is not implemented now +// #endif + + //weight = max(0., weight) * filterKernel[(x + 1) + (y + 1) * 3]; + weight = max(0., weight); + + //float weightDepth = abs(curDepth - depth.x) / (depth.y * length(float2(xx, yy)) + 1.0e-2); + //float weightNormal = pow(max(0, dot(curNormal, normal)), 128.0); + + //float w = exp(-weightDepth) * weightNormal; + + // add to total irradiance + if (weight > 0.) { + const vec3 current_irradiance = irradianceRoughness_Cache[x + KERNEL_SIZE][y + KERNEL_SIZE].rgb; + irradiance += current_irradiance * weight; + weight_sum += weight; + } + } + } + + if (weight_sum > 0.) { + irradiance /= weight_sum; + } + + imageStore(OUTPUT_IMAGE, pix, FIX_NAN(vec4(irradiance, center_irradiance.w))); +} + + diff --git a/ref/vk/shaders/rt.json b/ref/vk/shaders/rt.json index 22866d7631..da6e664a13 100644 --- a/ref/vk/shaders/rt.json +++ b/ref/vk/shaders/rt.json @@ -5,24 +5,48 @@ "lk_dnsr_reprojecting": { "comp": "lk_dnsr_reprojecting" }, + "lk_dnsr_ray_gi_bounces": { + "comp": "lk_dnsr_ray_gi_bounces" + }, + "lk_dnsr_light_direct_poly_choose": { "comp": "lk_dnsr_light_direct_poly_choose" }, "lk_dnsr_light_direct_poly_sample": { "comp": "lk_dnsr_light_direct_poly_sample" }, + "lk_dnsr_light_direct_point_w23": { + "comp": "lk_dnsr_light_direct_point_w23" + }, + "lk_dnsr_lighting_mix_diffuse": { + "comp": "lk_dnsr_lighting_mix_diffuse" + }, + "lk_dnsr_diffuse_pre_blur_1": { + "comp": "lk_dnsr_diffuse_pre_blur_1" + }, + "lk_dnsr_diffuse_pre_blur_2": { + "comp": "lk_dnsr_diffuse_pre_blur_2" + }, + "lk_dnsr_light_refl_poly_choose": { "comp": "lk_dnsr_light_refl_poly_choose" }, "lk_dnsr_light_refl_poly_sample": { "comp": "lk_dnsr_light_refl_poly_sample" }, - "lk_dnsr_light_direct_point_w23": { - "comp": "lk_dnsr_light_direct_point_w23" + "lk_dnsr_light_gi_poly_choose": { + "comp": "lk_dnsr_light_gi_poly_choose" + }, + "lk_dnsr_light_gi_poly_sample": { + "comp": "lk_dnsr_light_gi_poly_sample" }, "lk_dnsr_light_refl_point_w23": { "comp": "lk_dnsr_light_refl_point_w23" }, + "lk_dnsr_light_gi_point_w23": { + "comp": "lk_dnsr_light_gi_point_w23" + }, + /* "lk_dnsr_light_refl_point_choose": { "comp": "lk_dnsr_light_refl_point_choose" }, @@ -41,6 +65,24 @@ "lk_dnsr_lighting_mix": { "comp": "lk_dnsr_lighting_mix" }, + "lk_dnsr_specular_pre_blur_1": { + "comp": "lk_dnsr_specular_pre_blur_1" + }, + "lk_dnsr_specular_pre_blur_2": { + "comp": "lk_dnsr_specular_pre_blur_2" + }, + "lk_dnsr_specular_pre_blur_3": { + "comp": "lk_dnsr_specular_pre_blur_3" + }, + //"lk_dnsr_gi_pre_blur_pass_1.comp": { + // "comp": "lk_dnsr_gi_pre_blur_pass_1" + //}, + //"lk_dnsr_gi_pre_blur_pass_2.comp": { + // "comp": "lk_dnsr_gi_pre_blur_pass_2" + //}, + //"lk_dnsr_gi_pre_blur_pass_3.comp": { + // "comp": "lk_dnsr_gi_pre_blur_pass_3" + //}, "lk_dnsr_skip_denoising": { "comp": "lk_dnsr_skip_denoising" },