Commit: f1bf9d6bfb9edf261586a3907d7197a805ce8c3b Author: Clément Foucault Date: Thu Jul 20 18:40:23 2017 +0200 Branches: blender2.8 https://developer.blender.org/rBf1bf9d6bfb9edf261586a3907d7197a805ce8c3b
Eevee: SSR: Add mipmap filtering and bias to reduce noise. Also fix the roughness factors. =================================================================== M source/blender/draw/CMakeLists.txt M source/blender/draw/engines/eevee/eevee_effects.c M source/blender/draw/engines/eevee/eevee_engine.c M source/blender/draw/engines/eevee/eevee_private.h M source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl A source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl M source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl =================================================================== diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 3ebdea06093..4098cfe696e 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -138,6 +138,7 @@ data_to_c_simple(engines/eevee/shaders/effect_bloom_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_geom.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_downsample_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_ssr_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl SRC) diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 6414ef8ff32..e4c4cb5d790 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -84,7 +84,10 @@ static struct { struct GPUShader *ssr_raytrace_sh; struct GPUShader *ssr_resolve_sh; + struct GPUShader *downsample_sh; + struct GPUTexture *depth_src; + struct GPUTexture *color_src; float pixelprojmat[4][4]; } e_data = {NULL}; /* Engine data */ @@ -99,6 +102,7 @@ extern char datatoc_effect_bloom_frag_glsl[]; extern char datatoc_effect_dof_vert_glsl[]; extern char datatoc_effect_dof_geom_glsl[]; extern char datatoc_effect_dof_frag_glsl[]; +extern char datatoc_effect_downsample_frag_glsl[]; extern char datatoc_lightprobe_lib_glsl[]; extern char datatoc_raytrace_lib_glsl[]; extern char datatoc_tonemap_frag_glsl[]; @@ -192,6 +196,8 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) MEM_freeN(ssr_shader_str); + e_data.downsample_sh = DRW_shader_create_fullscreen(datatoc_effect_downsample_frag_glsl, NULL); + e_data.volumetric_upsample_sh = DRW_shader_create_fullscreen(datatoc_volumetric_frag_glsl, "#define STEP_UPSAMPLE\n"); e_data.minmaxz_downlevel_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, NULL); @@ -578,7 +584,7 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) /* Setup double buffer so we can access last frame as it was before post processes */ if ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0) { - DRWFboTexture tex_double_buffer = {&txl->color_double_buffer, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}; + DRWFboTexture tex_double_buffer = {&txl->color_double_buffer, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP}; DRW_framebuffer_init(&fbl->double_buffer, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1], @@ -711,6 +717,13 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) } { + psl->color_downsample_ps = DRW_pass_create("Downsample", DRW_STATE_WRITE_COLOR); + DRWShadingGroup *grp = DRW_shgroup_create(e_data.downsample_sh, psl->color_downsample_ps); + DRW_shgroup_uniform_buffer(grp, "source", &e_data.color_src); + DRW_shgroup_call_add(grp, quad, NULL); + } + + { psl->minmaxz_downlevel = DRW_pass_create("HiZ Down Level", DRW_STATE_WRITE_COLOR); DRWShadingGroup *grp = DRW_shgroup_create(e_data.minmaxz_downlevel_sh, psl->minmaxz_downlevel); DRW_shgroup_uniform_buffer(grp, "depthBuffer", &stl->g_data->minmaxz); @@ -833,6 +846,12 @@ static void minmax_downsample_cb(void *vedata, int UNUSED(level)) DRW_draw_pass(psl->minmaxz_downlevel); } +static void simple_downsample_cb(void *vedata, int UNUSED(level)) +{ + EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; + DRW_draw_pass(psl->color_downsample_ps); +} + void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src) { EEVEE_PassList *psl = vedata->psl; @@ -851,6 +870,17 @@ void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src) DRW_framebuffer_recursive_downsample(fbl->minmaxz_fb, stl->g_data->minmaxz, 6, &minmax_downsample_cb, vedata); } +/** + * Simple downsampling algorithm. Reconstruct mip chain up to mip level. + **/ +void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src, GPUTexture *texture_src, int level) +{ + e_data.color_src = texture_src; + + /* Create lower levels */ + DRW_framebuffer_recursive_downsample(fb_src, texture_src, level, &simple_downsample_cb, vedata); +} + void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) { EEVEE_PassList *psl = vedata->psl; @@ -902,6 +932,8 @@ void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *veda if ((effects->enabled_effects & EFFECT_SSR) != 0 && stl->g_data->valid_double_buffer) { DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + EEVEE_downsample_buffer(vedata, fbl->minmaxz_fb, txl->color_double_buffer, 5); + /* Raytrace at halfres. */ e_data.depth_src = dtxl->depth; // e_data.depth_src = stl->g_data->minmaxz; @@ -1078,6 +1110,7 @@ void EEVEE_draw_effects(EEVEE_Data *vedata) 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_resolve_sh); diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 59f2613dd06..4ee3dee655f 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -56,7 +56,7 @@ static void EEVEE_engine_init(void *ved) stl->g_data->background_alpha = 1.0f; stl->g_data->valid_double_buffer = (txl->color_double_buffer != NULL); - DRWFboTexture tex = {&txl->color, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}; + DRWFboTexture tex = {&txl->color, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP}; const float *viewport_size = DRW_viewport_size_get(); DRW_framebuffer_init(&fbl->main, &draw_engine_eevee_type, diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 015bc5b6a9e..f31f4f9fe6c 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -111,6 +111,7 @@ typedef struct EEVEE_PassList { struct DRWPass *volumetric_resolve_transmit_ps; struct DRWPass *ssr_raytrace; struct DRWPass *ssr_resolve; + struct DRWPass *color_downsample_ps; struct DRWPass *depth_pass; struct DRWPass *depth_pass_cull; @@ -504,6 +505,7 @@ void EEVEE_lightprobes_free(void); void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata); void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata); void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src); +void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src, struct GPUTexture *texture_src, int level); void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata); void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata); void EEVEE_draw_effects(EEVEE_Data *vedata); diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl index 059f0598156..e6cbcde77c7 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -374,6 +374,22 @@ void accumulate_light(vec3 light, float fac, inout vec4 accum) accum += vec4(light, 1.0) * min(fac, (1.0 - accum.a)); } +/* ----------- Cone Apperture Approximation --------- */ + +/* Return a fitted cone angle given the input roughness */ +float cone_cosine(float r) +{ + /* Using phong gloss + * roughness = sqrt(2/(gloss+2)) */ + float gloss = -2 + 2 / (r * r); + /* Drobot 2014 in GPUPro5 */ + // return cos(2.0 * sqrt(2.0 / (gloss + 2))); + /* Uludag 2014 in GPUPro5 */ + // return pow(0.244, 1 / (gloss + 1)); + /* Jimenez 2016 in Practical Realtime Strategies for Accurate Indirect Occlusion*/ + return exp2(-3.32193 * r * r); +} + /* --------- Closure ---------- */ #ifdef VOLUMETRICS diff --git a/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl new file mode 100644 index 00000000000..4a79fa908b1 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl @@ -0,0 +1,15 @@ +/** + * Simple downsample shader. Takes the average of the 4 texels of lower mip. + **/ + +uniform sampler2D source; + +out vec4 FragColor; + +void main() +{ + /* Reconstructing Target uvs like this avoid missing pixels if NPO2 */ + vec2 uvs = gl_FragCoord.xy * 2.0 / vec2(textureSize(source, 0)); + + FragColor = texture(source, uvs); +} \ No newline at end of file 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 7337ec792c9..4a1cea1338e 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl @@ -4,17 +4,25 @@ uniform sampler2DArray utilTex; #endif /* UTIL_TEX */ -vec3 generate_ray(ivec2 pix, vec3 V, vec3 N, float roughnessSquared, out float pdf) +#define BRDF_BIAS 0.7 + +vec3 generate_ray(ivec2 pix, vec3 V, vec3 N, float a2, out float pdf) { float NH; vec3 T, B; make_orthonormal_basis(N, T, B); /* Generate tangent space */ vec3 rand = texelFetch(utilTex, ivec3(pix % LUT_SIZE, 2), 0).rba; - vec3 H = sample_ggx(rand, roughnessSquared, N, T, B, NH); /* Microfacet normal */ - pdf = max(32e32, pdf_ggx_reflect(NH, roughnessSquared)); /* Theoretical limit of 10bit float (not in practice?) */ + + /* Importance sampling bias */ + rand.x = mix(rand.x, 0.0, BRDF_BIAS); + + vec3 H = sample_ggx(rand, a2, N, T, B, NH); /* Microfacet normal */ + pdf = min(1024e32, pdf_ggx_reflect(NH, a2)); /* Theoretical limit of 16bit float */ return reflect(-V, H); } +#define MAX_MIP 5.0 + #ifdef STEP_RAYTRACE uniform sampler2D depthBuffer; @@ -44,11 +52,12 @@ void main() /* Retrieve pixel data */ vec4 speccol_ro @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs