diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2021-03-13 13:44:46 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2021-03-13 22:59:20 +0300 |
commit | 267a9e14f5a7cda16309937b5b8fba700f8c833b (patch) | |
tree | af7cb664c3c87dfd93565d2ce5679ce37775d006 /source/blender/draw | |
parent | b79f209041700acec9ace9c5091b6706a21b1e96 (diff) |
EEVEE: ScreenSpaceReflections: Add back multi ray-hitpoint reuse
We now reuse 9 hitpoints from the neighboorhood using a blue noise
sample distribution as mentionned in the reference presentation.
Reusing more rays does however make some area a bit more blury.
The resulting noise is quite lower compared to previous implementation
which was only reusing 4 hits.
Diffstat (limited to 'source/blender/draw')
4 files changed, 74 insertions, 17 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index f73f10360e9..fdee4fd3c5e 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -723,7 +723,6 @@ typedef struct EEVEE_EffectsInfo { bool reflection_trace_full; bool ssr_was_persp; bool ssr_was_valid_double_buffer; - int ssr_neighbor_ofs; struct GPUTexture *ssr_normal_input; /* Textures from pool */ struct GPUTexture *ssr_specrough_input; struct GPUTexture *ssr_hit_output; diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c index 75219b88e78..54f23073bd0 100644 --- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c +++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c @@ -32,11 +32,6 @@ #include "GPU_texture.h" #include "eevee_private.h" -static struct { - /* These are just references, not actually allocated */ - struct GPUTexture *depth_src; -} e_data = {NULL}; /* Engine data */ - int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; @@ -186,7 +181,7 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); - DRW_shgroup_uniform_int(grp, "neighborOffset", &effects->ssr_neighbor_ofs, 1); + DRW_shgroup_uniform_int(grp, "samplePoolOffset", &effects->taa_current_sample, 1); DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons); DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } @@ -216,9 +211,6 @@ void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v EEVEE_EffectsInfo *effects = stl->effects; if (((effects->enabled_effects & EFFECT_SSR) != 0) && stl->g_data->valid_double_buffer) { - DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - e_data.depth_src = dtxl->depth; - DRW_stats_group_start("SSR"); /* Raytrace. */ diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl index 0f3f04596a8..cc73bbbfe29 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl @@ -46,3 +46,56 @@ HitData decode_hit_data(vec4 hit_data, float hit_depth) data.is_hit = (hit_data.w > 0.0); return data; } + +/* Blue noise categorised into 4 sets of samples. + * See "Stochastic all the things" presentation slide 32-37. */ +const int resolve_samples_count = 9; +const vec2 resolve_sample_offsets[36] = vec2[36]( + /* Set 1. */ + /* First Ring (2x2). */ + vec2(0, 0), + /* Second Ring (6x6). */ + vec2(-1, 3), + vec2(1, 3), + vec2(-1, 1), + vec2(3, 1), + vec2(-2, 0), + vec2(3, 0), + vec2(2, -1), + vec2(1, -2), + /* Set 2. */ + /* First Ring (2x2). */ + vec2(1, 1), + /* Second Ring (6x6). */ + vec2(-2, 3), + vec2(3, 3), + vec2(0, 2), + vec2(2, 2), + vec2(-2, -1), + vec2(1, -1), + vec2(0, -2), + vec2(3, -2), + /* Set 3. */ + /* First Ring (2x2). */ + vec2(0, 1), + /* Second Ring (6x6). */ + vec2(0, 3), + vec2(3, 2), + vec2(-2, 1), + vec2(2, 1), + vec2(-1, 0), + vec2(-2, -2), + vec2(0, -1), + vec2(2, -2), + /* Set 4. */ + /* First Ring (2x2). */ + vec2(1, 0), + /* Second Ring (6x6). */ + vec2(2, 3), + vec2(-2, 2), + vec2(-1, 2), + vec2(1, 2), + vec2(2, 0), + vec2(-1, -1), + vec2(3, -1), + vec2(-1, -2));
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl index 45057109cdf..d2f4245c603 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl @@ -24,6 +24,8 @@ uniform sampler2D specroughBuffer; uniform sampler2D hitBuffer; uniform sampler2D hitDepth; +uniform int samplePoolOffset; + in vec4 uvcoordsvar; out vec4 fragColor; @@ -75,8 +77,8 @@ void resolve_reflection_sample(int planar_index, inout float weight_accum, inout vec4 ssr_accum) { - vec4 hit_data = texture(hitBuffer, sample_uv * ssrUvScale); - float hit_depth = texture(hitDepth, sample_uv * ssrUvScale).r; + vec4 hit_data = texture(hitBuffer, sample_uv); + float hit_depth = texture(hitDepth, sample_uv).r; HitData data = decode_hit_data(hit_data, hit_depth); float hit_dist = length(data.hit_dir); @@ -86,9 +88,12 @@ void resolve_reflection_sample(int planar_index, float weight = bsdf * data.ray_pdf_inv; + /* Do not reuse hitpoint from planar reflections for normal reflections and vice versa. */ + if ((planar_index == -1 && data.is_planar) || (planar_index != -1 && !data.is_planar)) { + return; + } /* Do not add light if ray has failed but still weight it. */ - if (!data.is_hit || (planar_index == -1 && data.is_planar) || - (planar_index != -1 && !data.is_planar)) { + if (!data.is_hit) { weight_accum += weight; return; } @@ -155,10 +160,18 @@ void raytrace_resolve(ClosureInputGlossy cl_in, float cone_tan = sqrt(1.0 - cone_cos * cone_cos) / cone_cos; cone_tan *= mix(saturate(dot(vN, -vV) * 2.0), 1.0, roughness); /* Elongation fit */ - vec2 sample_uv = uvcoordsvar.xy; + int sample_pool = int((uint(gl_FragCoord.x) & 1u) + (uint(gl_FragCoord.y) & 1u) * 2u); + sample_pool = (sample_pool + (samplePoolOffset / 5)) % 4; - resolve_reflection_sample( - planar_index, sample_uv, vP, vN, vV, roughness_squared, cone_tan, weight_acc, ssr_accum); + for (int i = 0; i < resolve_samples_count; i++) { + int sample_id = sample_pool * resolve_samples_count + i; + vec2 texture_size = vec2(textureSize(hitBuffer, 0)); + vec2 sample_texel = texture_size * uvcoordsvar.xy * ssrUvScale; + vec2 sample_uv = (sample_texel + resolve_sample_offsets[sample_id]) / texture_size; + + resolve_reflection_sample( + planar_index, sample_uv, vP, vN, vV, roughness_squared, cone_tan, weight_acc, ssr_accum); + } } /* Compute SSR contribution */ |