diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-07-21 16:06:29 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-07-21 16:06:29 +0300 |
commit | c02f8eb749dc1cd4be9e24dbd28b1445dd60352a (patch) | |
tree | 9948ad020dda6ac99d91dc939f182d31fd5f89f3 | |
parent | 3272640d6eb90a3e76cb4dd6e5ba7a4cb491f83e (diff) |
Eevee: SSR: Add fullscreen raytrace.
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_effects.c | 20 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_private.h | 1 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl | 21 |
3 files changed, 36 insertions, 6 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index fe90534c3cb..6280cdbc522 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -84,7 +84,9 @@ static struct { /* Screen Space Reflection */ struct GPUShader *ssr_raytrace_sh; + struct GPUShader *ssr_raytrace_full_sh; struct GPUShader *ssr_resolve_sh; + struct GPUShader *ssr_resolve_full_sh; /* Simple Downsample */ struct GPUShader *downsample_sh; @@ -192,7 +194,11 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) BLI_dynstr_free(ds_frag); e_data.ssr_raytrace_sh = DRW_shader_create_fullscreen(ssr_shader_str, SHADER_DEFINES "#define STEP_RAYTRACE\n"); + e_data.ssr_raytrace_full_sh = DRW_shader_create_fullscreen(ssr_shader_str, SHADER_DEFINES "#define STEP_RAYTRACE\n" + "#define FULLRES\n"); e_data.ssr_resolve_sh = DRW_shader_create_fullscreen(ssr_shader_str, SHADER_DEFINES "#define STEP_RESOLVE\n"); + e_data.ssr_resolve_full_sh = DRW_shader_create_fullscreen(ssr_shader_str, SHADER_DEFINES "#define STEP_RESOLVE\n" + "#define FULLRES\n"); MEM_freeN(ssr_shader_str); @@ -537,7 +543,10 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) /* Enable double buffering to be able to read previous frame color */ effects->enabled_effects |= EFFECT_DOUBLE_BUFFER; - int tracing_res[2] = {(int)viewport_size[0] / 2, (int)viewport_size[1] / 2}; + effects->reflection_trace_full = true; + + const int divisor = (effects->reflection_trace_full) ? 1 : 2; + int tracing_res[2] = {(int)viewport_size[0] / divisor, (int)viewport_size[1] / divisor}; const bool record_two_hit = false; const bool high_qual_input = true; /* TODO dither low quality input */ @@ -699,8 +708,11 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) } if ((effects->enabled_effects & EFFECT_SSR) != 0) { + struct GPUShader *trace_shader = (effects->reflection_trace_full) ? e_data.ssr_raytrace_full_sh : e_data.ssr_raytrace_sh; + struct GPUShader *resolve_shader = (effects->reflection_trace_full) ? e_data.ssr_resolve_full_sh : e_data.ssr_resolve_sh; + psl->ssr_raytrace = DRW_pass_create("SSR Raytrace", DRW_STATE_WRITE_COLOR); - DRWShadingGroup *grp = DRW_shgroup_create(e_data.ssr_raytrace_sh, psl->ssr_raytrace); + DRWShadingGroup *grp = DRW_shgroup_create(trace_shader, psl->ssr_raytrace); DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src); DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input); DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input); @@ -710,7 +722,7 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) DRW_shgroup_call_add(grp, quad, NULL); psl->ssr_resolve = DRW_pass_create("SSR Resolve", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE); - grp = DRW_shgroup_create(e_data.ssr_resolve_sh, psl->ssr_resolve); + grp = DRW_shgroup_create(resolve_shader, psl->ssr_resolve); DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src); DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input); DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input); @@ -1188,7 +1200,9 @@ void EEVEE_effects_free(void) { DRW_SHADER_FREE_SAFE(e_data.downsample_sh); DRW_SHADER_FREE_SAFE(e_data.ssr_raytrace_sh); + DRW_SHADER_FREE_SAFE(e_data.ssr_raytrace_full_sh); DRW_SHADER_FREE_SAFE(e_data.ssr_resolve_sh); + DRW_SHADER_FREE_SAFE(e_data.ssr_resolve_full_sh); DRW_SHADER_FREE_SAFE(e_data.volumetric_upsample_sh); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index eec264f1711..22d100ba13e 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -320,6 +320,7 @@ typedef struct EEVEE_EffectsInfo { /* SSR */ bool use_ssr; + bool reflection_trace_full; /* Ambient Occlusion */ bool use_ao, use_bent_normals; diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl index e266dac6d22..4473d73c5c8 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl @@ -34,15 +34,24 @@ layout(location = 1) out vec4 pdfData; void main() { +#ifdef FULLRES + ivec2 fullres_texel = ivec2(gl_FragCoord.xy); + ivec2 halfres_texel = fullres_texel; +#else ivec2 fullres_texel = ivec2(gl_FragCoord.xy) * 2; ivec2 halfres_texel = ivec2(gl_FragCoord.xy); +#endif + float depth = texelFetch(depthBuffer, fullres_texel, 0).r; /* Early out */ if (depth == 1.0) discard; - vec2 uvs = gl_FragCoord.xy * 2.0 / vec2(textureSize(depthBuffer, 0)); + vec2 uvs = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0)); +#ifndef FULLRES + uvs *= 2.0; +#endif /* Using view space */ vec3 viewPosition = get_view_space_from_depth(uvs, depth); @@ -75,8 +84,10 @@ void main() /* Raycast over screen */ float hit_dist = -1.0; + /* Only raytrace if ray is above the surface normal */ + /* Note : this still fails in some cases like with normal map. + * We should check against the geometric normal but we don't have it at this stage. */ if (dot(R, N) > 0.0001) { - /* Only raytrace if ray is above the surface normal */ hit_dist = raycast(depthBuffer, viewPosition, R); } @@ -195,8 +206,12 @@ float screen_border_mask(vec2 past_hit_co, vec3 hit) void main() { - ivec2 halfres_texel = ivec2(gl_FragCoord.xy / 2.0); ivec2 fullres_texel = ivec2(gl_FragCoord.xy); +#ifdef FULLRES + ivec2 halfres_texel = fullres_texel; +#else + ivec2 halfres_texel = ivec2(gl_FragCoord.xy / 2.0); +#endif vec2 texture_size = vec2(textureSize(depthBuffer, 0)); vec2 uvs = gl_FragCoord.xy / texture_size; vec3 rand = texelFetch(utilTex, ivec3(fullres_texel % LUT_SIZE, 2), 0).rba; |