[Bf-blender-cvs] [e1d4bb91d71] temp-ssr: Eevee: SSR: Add double buffer so we can read previous frame color.

Clément Foucault noreply at git.blender.org
Mon Jul 24 15:25:13 CEST 2017


Commit: e1d4bb91d717d3d59aa3e13477f381fa8b1f774b
Author: Clément Foucault
Date:   Wed Jul 19 14:22:03 2017 +0200
Branches: temp-ssr
https://developer.blender.org/rBe1d4bb91d717d3d59aa3e13477f381fa8b1f774b

Eevee: SSR: Add double buffer so we can read previous frame color.

Also add simple reprojection and screen fade to the SSR resolve pass.

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

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
M	source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl

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

diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 9b069db9469..8a401a99d94 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -43,6 +43,7 @@
 
 #include "eevee_private.h"
 #include "GPU_texture.h"
+#include "GPU_framebuffer.h"
 
 #define SHADER_DEFINES \
 	"#define EEVEE_ENGINE\n" \
@@ -508,6 +509,9 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 	if (BKE_collection_engine_property_value_get_bool(props, "ssr_enable")) {
 		effects->enabled_effects |= EFFECT_SSR;
 
+		/* 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};
 		const bool record_two_hit = false;
 		const bool high_qual_input = true; /* TODO dither low quality input */
@@ -517,20 +521,27 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 		if (txl->ssr_normal_input == NULL) {
 			DRWTextureFormat nor_format = DRW_TEX_RG_16;
 			txl->ssr_normal_input = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], nor_format, 0, NULL);
-			DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
 		}
 
 		if (txl->ssr_specrough_input == NULL) {
 			DRWTextureFormat specrough_format = (high_qual_input) ? DRW_TEX_RGBA_16 : DRW_TEX_RGBA_8;
 			txl->ssr_specrough_input = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], specrough_format, 0, NULL);
-			DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
 		}
 
+		/* Reattach textures to the right buffer (because we are alternating between buffers) */
+		/* TODO multiple FBO per texture!!!! */
+		DRW_framebuffer_texture_detach(txl->ssr_normal_input);
+		DRW_framebuffer_texture_detach(txl->ssr_specrough_input);
+		DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
+		DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
+
 		/* Raytracing output */
 		/* TODO try integer format for hit coord to increase precision */
 		DRWFboTexture tex_output[2] = {{&txl->ssr_hit_output, (record_two_hit) ? DRW_TEX_RGBA_16 : DRW_TEX_RG_16, 0},
 		                               {&txl->ssr_pdf_output, (record_two_hit) ? DRW_TEX_RG_16 : DRW_TEX_R_16, 0}};
 
+		DRW_framebuffer_init(&fbl->screen_tracing_fb, &draw_engine_eevee_type, tracing_res[0], tracing_res[1], tex_output, 2);
+
 		/* Compute pixel projection matrix */
 		{
 			float uvpix[4][4], ndcuv[4][4], tmp[4][4], winmat[4][4];
@@ -542,14 +553,12 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 
 			/* UVs to pixels */
 			unit_m4(uvpix);
-			uvpix[0][0] = tracing_res[0];
-			uvpix[1][1] = tracing_res[1];
+			uvpix[0][0] = viewport_size[0];
+			uvpix[1][1] = viewport_size[1];
 
 			mul_m4_m4m4(tmp, uvpix, ndcuv);
 			mul_m4_m4m4(e_data.pixelprojmat, tmp, winmat);
 		}
-
-		DRW_framebuffer_init(&fbl->screen_tracing_fb, &draw_engine_eevee_type, tracing_res[0], tracing_res[1], tex_output, 2);
 	}
 	else {
 		/* Cleanup to release memory */
@@ -559,6 +568,23 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 		DRW_TEXTURE_FREE_SAFE(txl->ssr_pdf_output);
 		DRW_FRAMEBUFFER_FREE_SAFE(fbl->screen_tracing_fb);
 	}
+
+	/* 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};
+
+		DRW_framebuffer_init(&fbl->double_buffer, &draw_engine_eevee_type,
+		                    (int)viewport_size[0], (int)viewport_size[1],
+		                    &tex_double_buffer, 1);
+
+		copy_m4_m4(stl->g_data->prev_persmat, stl->g_data->next_persmat);
+		DRW_viewport_matrix_get(stl->g_data->next_persmat, DRW_MAT_PERS);
+	}
+	else {
+		/* Cleanup to release memory */
+		DRW_TEXTURE_FREE_SAFE(txl->color_double_buffer);
+		DRW_FRAMEBUFFER_FREE_SAFE(fbl->double_buffer);
+	}
 }
 
 static DRWShadingGroup *eevee_create_bloom_pass(const char *name, EEVEE_EffectsInfo *effects, struct GPUShader *sh, DRWPass **pass, bool upsample)
@@ -662,8 +688,10 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 		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);
+		DRW_shgroup_uniform_buffer(grp, "colorBuffer", &txl->color_double_buffer);
 		DRW_shgroup_uniform_buffer(grp, "hitBuffer", &txl->ssr_hit_output);
 		DRW_shgroup_uniform_buffer(grp, "pdfBuffer", &txl->ssr_pdf_output);
+		DRW_shgroup_uniform_mat4(grp, "PastViewProjectionMatrix", (float *)stl->g_data->prev_persmat);
 		DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
 		DRW_shgroup_uniform_int(grp, "probe_count", &sldata->probes->num_render_cube, 1);
 		DRW_shgroup_uniform_float(grp, "lodCubeMax", &sldata->probes->lod_cube_max, 1);
@@ -790,17 +818,6 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 	}
 }
 
-#define SWAP_BUFFERS() {                           \
-	if (effects->source_buffer == txl->color) {    \
-		effects->source_buffer = txl->color_post;  \
-		effects->target_buffer = fbl->main;        \
-	}                                              \
-	else {                                         \
-		effects->source_buffer = txl->color;       \
-		effects->target_buffer = fbl->effect_fb;   \
-	}                                              \
-} ((void)0)
-
 static void minmax_downsample_cb(void *vedata, int UNUSED(level))
 {
 	EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
@@ -873,11 +890,12 @@ void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *veda
 	EEVEE_TextureList *txl = vedata->txl;
 	EEVEE_EffectsInfo *effects = stl->effects;
 
-	if ((effects->enabled_effects & EFFECT_SSR) != 0) {
+	if ((effects->enabled_effects & EFFECT_SSR) != 0 && stl->g_data->valid_double_buffer) {
 		DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
 
 		/* Raytrace at halfres. */
-		e_data.depth_src = stl->g_data->minmaxz;
+		e_data.depth_src = dtxl->depth;
+		// e_data.depth_src = stl->g_data->minmaxz;
 		DRW_framebuffer_bind(fbl->screen_tracing_fb);
 		DRW_draw_pass(psl->ssr_raytrace);
 
@@ -896,6 +914,26 @@ void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *veda
 	}
 }
 
+#define SWAP_DOUBLE_BUFFERS() {                                       \
+	if (swap_double_buffer) {                                         \
+		SWAP(struct GPUFrameBuffer *, fbl->main, fbl->double_buffer); \
+		SWAP(GPUTexture *, txl->color, txl->color_double_buffer);     \
+		swap_double_buffer = false;                                   \
+	}                                                                 \
+} ((void)0)
+
+#define SWAP_BUFFERS() {                           \
+	if (effects->source_buffer == txl->color) {    \
+		effects->source_buffer = txl->color_post;  \
+		effects->target_buffer = fbl->main;        \
+	}                                              \
+	else {                                         \
+		effects->source_buffer = txl->color;       \
+		effects->target_buffer = fbl->effect_fb;   \
+	}                                              \
+	SWAP_DOUBLE_BUFFERS();                         \
+} ((void)0)
+
 void EEVEE_draw_effects(EEVEE_Data *vedata)
 {
 	EEVEE_PassList *psl = vedata->psl;
@@ -904,6 +942,9 @@ void EEVEE_draw_effects(EEVEE_Data *vedata)
 	EEVEE_StorageList *stl = vedata->stl;
 	EEVEE_EffectsInfo *effects = stl->effects;
 
+	/* only once per frame after the first post process */
+	bool swap_double_buffer = ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0);
+
 	/* Default framebuffer and texture */
 	DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
 	DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@@ -1015,6 +1056,15 @@ void EEVEE_draw_effects(EEVEE_Data *vedata)
 
 	/* Tonemapping */
 	DRW_transform_to_display(effects->source_buffer);
+
+	/* If no post processes is enabled, buffers are still not swapped, do it now. */
+	SWAP_DOUBLE_BUFFERS();
+
+	if (!stl->g_data->valid_double_buffer) {
+		/* If history buffer is not valid request another frame.
+		 * This fix black reflections on area resize. */
+		DRW_viewport_request_redraw();
+	}
 }
 
 void EEVEE_effects_free(void)
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index abf9a98f17a..c04cb643af5 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -49,6 +49,13 @@ static void EEVEE_engine_init(void *ved)
 	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__);
+	}
+	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};
 
 	const float *viewport_size = DRW_viewport_size_get();
@@ -56,12 +63,6 @@ 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__);
-	}
-	stl->g_data->background_alpha = 1.0f;
-
 	EEVEE_materials_init(stl);
 	EEVEE_lights_init(sldata);
 	EEVEE_lightprobes_init(sldata, vedata);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index f773c48dc32..015bc5b6a9e 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -138,6 +138,7 @@ typedef struct EEVEE_FramebufferList {
 	struct GPUFrameBuffer *planarref_fb;
 
 	stru

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list