[Bf-blender-cvs] [2c7f6db8d1b] blender2.8: Eevee: Minmax Depth Pyramid.

Clément Foucault noreply at git.blender.org
Thu Jun 22 04:01:06 CEST 2017


Commit: 2c7f6db8d1b2d2a0d59d5212899632ec838e86cc
Author: Clément Foucault
Date:   Thu Jun 22 02:28:49 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB2c7f6db8d1b2d2a0d59d5212899632ec838e86cc

Eevee: Minmax Depth Pyramid.

This commit introduce the computation of a depth pyramid containing min and max depth values of the original depth buffer.
This is useful for Clustered Light Culling but also for raytracing on the depth buffer (SSR).
It's also usefull to have to fetch higher mips in order to improve texture cache usage.

As of now, 1st mip (highest res) is half the resolution of the depth buffer, but everything is already done to be able to make a fullres copy of the depth buffer in the 1st mip instead of downsampling.
Also, the texture used is RG_32F which is a too much but enough to cover the 24bits of the depth buffer. Reducing the texture size would make things quite faster.

===================================================================

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
A	source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl
M	source/blender/draw/intern/draw_manager.c

===================================================================

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 5e9b8f84b29..7c4b5428d75 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -118,6 +118,7 @@ data_to_c_simple(engines/clay/shaders/ssao_groundtruth.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/default_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/default_world_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/background_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_minmaxz_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/lightprobe_geom.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 6aa70e980a7..e7fa51ad929 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -51,6 +51,11 @@ typedef struct EEVEE_LightProbeData {
 #define ENABLE_EFFECT_DOF 1
 
 static struct {
+	/* Downsample Depth */
+	struct GPUShader *minmaxz_downlevel_sh;
+	struct GPUShader *minmaxz_downdepth_sh;
+	struct GPUShader *minmaxz_copydepth_sh;
+
 	/* Motion Blur */
 	struct GPUShader *motion_blur_sh;
 
@@ -66,6 +71,7 @@ static struct {
 	struct GPUShader *dof_resolve_sh;
 } e_data = {NULL}; /* Engine data */
 
+extern char datatoc_effect_minmaxz_frag_glsl[];
 extern char datatoc_effect_motion_blur_frag_glsl[];
 extern char datatoc_effect_bloom_frag_glsl[];
 extern char datatoc_effect_dof_vert_glsl[];
@@ -141,20 +147,22 @@ void EEVEE_effects_init(EEVEE_Data *vedata)
 
 	const float *viewport_size = DRW_viewport_size_get();
 
+	/* Shaders */
 	if (!e_data.motion_blur_sh) {
+		e_data.minmaxz_downlevel_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, NULL);
+		e_data.minmaxz_downdepth_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define INPUT_DEPTH\n");
+		e_data.minmaxz_copydepth_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define INPUT_DEPTH\n"
+		                                                                                             "#define COPY_DEPTH\n");
+
 		e_data.motion_blur_sh = DRW_shader_create_fullscreen(datatoc_effect_motion_blur_frag_glsl, NULL);
-	}
 
-	if (!e_data.dof_downsample_sh) {
 		e_data.dof_downsample_sh = DRW_shader_create(datatoc_effect_dof_vert_glsl, NULL,
 		                                                datatoc_effect_dof_frag_glsl, "#define STEP_DOWNSAMPLE\n");
 		e_data.dof_scatter_sh = DRW_shader_create(datatoc_effect_dof_vert_glsl, NULL,
 		                                             datatoc_effect_dof_frag_glsl, "#define STEP_SCATTER\n");
 		e_data.dof_resolve_sh = DRW_shader_create(datatoc_effect_dof_vert_glsl, NULL,
 		                                             datatoc_effect_dof_frag_glsl, "#define STEP_RESOLVE\n");
-	}
 
-	if (!e_data.bloom_blit_sh[0]) {
 		e_data.bloom_blit_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_BLIT\n");
 		e_data.bloom_blit_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_BLIT\n"
 		                                                                                       "#define HIGH_QUALITY\n");
@@ -378,6 +386,14 @@ void EEVEE_effects_init(EEVEE_Data *vedata)
 		                    (int)viewport_size[0], (int)viewport_size[1],
 		                    &tex, 1);
 	}
+	/* MinMax Pyramid */
+	/* TODO reduce precision */
+	DRWFboTexture tex = {&stl->g_data->minmaxz, DRW_TEX_RG_32, DRW_TEX_MIPMAP | DRW_TEX_TEMP};
+
+	DRW_framebuffer_init(&fbl->minmaxz_fb, &draw_engine_eevee_type,
+	                    (int)viewport_size[0] / 2, (int)viewport_size[1] / 2,
+	                    &tex, 1);
+
 }
 
 static DRWShadingGroup *eevee_create_bloom_pass(const char *name, EEVEE_EffectsInfo *effects, struct GPUShader *sh, DRWPass **pass, bool upsample)
@@ -409,6 +425,23 @@ void EEVEE_effects_cache_init(EEVEE_Data *vedata)
 	struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
 
 	{
+		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);
+		DRW_shgroup_call_add(grp, quad, NULL);
+
+		psl->minmaxz_downdepth = DRW_pass_create("HiZ Down Depth", DRW_STATE_WRITE_COLOR);
+		grp = DRW_shgroup_create(e_data.minmaxz_downdepth_sh, psl->minmaxz_downdepth);
+		DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
+		DRW_shgroup_call_add(grp, quad, NULL);
+
+		psl->minmaxz_copydepth = DRW_pass_create("HiZ Copy Depth", DRW_STATE_WRITE_COLOR);
+		grp = DRW_shgroup_create(e_data.minmaxz_copydepth_sh, psl->minmaxz_copydepth);
+		DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
+		DRW_shgroup_call_add(grp, quad, NULL);
+	}
+
+	{
 		psl->motion_blur = DRW_pass_create("Motion Blur", DRW_STATE_WRITE_COLOR);
 
 		DRWShadingGroup *grp = DRW_shgroup_create(e_data.motion_blur_sh, psl->motion_blur);
@@ -519,6 +552,28 @@ void EEVEE_effects_cache_init(EEVEE_Data *vedata)
 	}                                              \
 } ((void)0)
 
+static void minmax_downsample_cb(void *vedata, int UNUSED(level))
+{
+	EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
+	DRW_draw_pass(psl->minmaxz_downlevel);
+}
+
+void EEVEE_create_minmax_buffer(EEVEE_Data *vedata)
+{
+	EEVEE_PassList *psl = vedata->psl;
+	EEVEE_FramebufferList *fbl = vedata->fbl;
+	EEVEE_StorageList *stl = vedata->stl;
+
+	/* Copy depth buffer to minmax texture top level */
+	DRW_framebuffer_texture_attach(fbl->minmaxz_fb, stl->g_data->minmaxz, 0, 0);
+	DRW_framebuffer_bind(fbl->minmaxz_fb);
+	DRW_draw_pass(psl->minmaxz_downdepth);
+	DRW_framebuffer_texture_detach(stl->g_data->minmaxz);
+
+	/* Create lower levels */
+	DRW_framebuffer_recursive_downsample(fbl->minmaxz_fb, stl->g_data->minmaxz, 6, &minmax_downsample_cb, vedata);
+}
+
 void EEVEE_draw_effects(EEVEE_Data *vedata)
 {
 	EEVEE_PassList *psl = vedata->psl;
@@ -642,6 +697,10 @@ void EEVEE_draw_effects(EEVEE_Data *vedata)
 
 void EEVEE_effects_free(void)
 {
+	DRW_SHADER_FREE_SAFE(e_data.minmaxz_downlevel_sh);
+	DRW_SHADER_FREE_SAFE(e_data.minmaxz_downdepth_sh);
+	DRW_SHADER_FREE_SAFE(e_data.minmaxz_copydepth_sh);
+
 	DRW_SHADER_FREE_SAFE(e_data.motion_blur_sh);
 	DRW_SHADER_FREE_SAFE(e_data.dof_downsample_sh);
 	DRW_SHADER_FREE_SAFE(e_data.dof_scatter_sh);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 729e44b0def..a125bb97a91 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -46,6 +46,7 @@ static void EEVEE_engine_init(void *ved)
 	EEVEE_Data *vedata = (EEVEE_Data *)ved;
 	EEVEE_TextureList *txl = vedata->txl;
 	EEVEE_FramebufferList *fbl = vedata->fbl;
+	EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
 	EEVEE_SceneLayerData *sldata = EEVEE_scene_layer_data_get();
 
 	DRWFboTexture tex = {&txl->color, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER};
@@ -55,6 +56,11 @@ static void EEVEE_engine_init(void *ved)
 	                    (int)viewport_size[0], (int)viewport_size[1],
 	                    &tex, 1);
 
+	if (!stl->g_data) {
+		/* Alloc transient pointers */
+		stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+	}
+
 	EEVEE_materials_init();
 	EEVEE_lights_init(sldata);
 	EEVEE_lightprobes_init(sldata, vedata);
@@ -67,11 +73,6 @@ static void EEVEE_cache_init(void *vedata)
 	EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
 	EEVEE_SceneLayerData *sldata = EEVEE_scene_layer_data_get();
 
-	if (!stl->g_data) {
-		/* Alloc transient pointers */
-		stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
-	}
-
 	EEVEE_materials_cache_init(vedata);
 	EEVEE_lights_cache_init(sldata, psl);
 	EEVEE_lightprobes_cache_init(sldata, psl, stl);
@@ -148,6 +149,12 @@ static void EEVEE_draw_scene(void *vedata)
 	DRW_draw_pass(psl->depth_pass);
 	DRW_draw_pass(psl->depth_pass_cull);
 
+	/* Create minmax texture */
+	EEVEE_create_minmax_buffer(vedata);
+
+	/* Restore main FB */
+	DRW_framebuffer_bind(fbl->main);
+
 	/* Shading pass */
 	DRW_draw_pass(psl->probe_display);
 	DRW_draw_pass(psl->default_pass);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 530a9b894a2..ea63919b23d 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -69,6 +69,9 @@ typedef struct EEVEE_PassList {
 	struct DRWPass *dof_down;
 	struct DRWPass *dof_scatter;
 	struct DRWPass *dof_resolve;
+	struct DRWPass *minmaxz_downlevel;
+	struct DRWPass *minmaxz_downdepth;
+	struct DRWPass *minmaxz_copydepth;
 
 	struct DRWPass *depth_pass;
 	struct DRWPass *depth_pass_cull;
@@ -83,6 +86,7 @@ typedef struct EEVEE_PassList {
 
 typedef struct EEVEE_FramebufferList {
 	/* Effects */
+	struct GPUFrameBuffer *minmaxz_fb;
 	struct GPUFrameBuffer *effect_fb; /* HDR */
 	struct GPUFrameBuffer *bloom_blit_fb; /* HDR */
 	struct GPUFrameBuffer *bloom_down_fb[MAX_BLOOM_STEP]; /* HDR */
@@ -371,6 +375,7 @@ typedef struct EEVEE_PrivateData {
 	struct DRWShadingGroup *cube_display_shgrp;
 	struct GHash *material_hash;
 	struct GHash *hair_material_hash;
+	struct GPUTexture *minmaxz;
 } EEVEE_PrivateData; /* Transient data */
 
 /* eevee_data.c */
@@ -413,6 +418,7 @@ void EEVEE_lightprobes_free(void);
 /* eevee_effects.c */
 void EEVEE_effects_init(EEVEE_Data *vedata);
 void EEVEE_effects_cache_init(EEVEE_Data *vedata);
+void EEVEE_create_minmax_buffer(EEVEE_Data *vedata);
 void EEVEE_draw_effects(EEVEE_Data *vedata);
 void EEVEE_effects_free(void);
 
diff --git a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl
new file mode 100644
index 00000000000..9f81206070b
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl
@@ -0,0 +1,66 @@
+/**
+ * Shader that downsample d

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list