[Bf-blender-cvs] [7938848b636] blender2.8: Eevee: SSR: Add double buffer so we can read previous frame color.
Clément Foucault
noreply at git.blender.org
Mon Jul 24 15:55:41 CEST 2017
Commit: 7938848b636335b0d59cc7cbb42c223ec309c0d7
Author: Clément Foucault
Date: Wed Jul 19 14:22:03 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB7938848b636335b0d59cc7cbb42c223ec309c0d7
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 c9ed4970889..f5a943bfb3f 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -45,6 +45,7 @@
#include "eevee_private.h"
#include "GPU_texture.h"
+#include "GPU_framebuffer.h"
#define SHADER_DEFINES \
"#define EEVEE_ENGINE\n" \
@@ -513,6 +514,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 */
@@ -522,20 +526,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];
@@ -547,14 +558,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 */
@@ -564,6 +573,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)
@@ -667,8 +693,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);
@@ -795,17 +823,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;
@@ -878,11 +895,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);
@@ -901,6 +919,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;
@@ -909,6 +947,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();
@@ -1020,6 +1061,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 c8dc8c67c04..59f2613dd06 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