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

Reply via email to