[Bf-blender-cvs] [4f9d1a5765d] eevee-motionblur-object: EEVEE: Motion Blur: Use less VRAM and improve larger blur
Clément Foucault
noreply at git.blender.org
Fri Jun 12 15:17:32 CEST 2020
Commit: 4f9d1a5765d6e6906c002c89b2b9a3b280ac6809
Author: Clément Foucault
Date: Thu Jun 11 20:37:51 2020 +0200
Branches: eevee-motionblur-object
https://developer.blender.org/rB4f9d1a5765d6e6906c002c89b2b9a3b280ac6809
EEVEE: Motion Blur: Use less VRAM and improve larger blur
Larger blur now use a more stable approach. We repeat the expand process
instead of making tiles bigger.
===================================================================
M source/blender/draw/engines/eevee/eevee_motion_blur.c
M source/blender/draw/engines/eevee/eevee_private.h
M source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl
M source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl
===================================================================
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c
index 51b5cdcb13b..bb9138bcc6c 100644
--- a/source/blender/draw/engines/eevee/eevee_motion_blur.c
+++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c
@@ -59,18 +59,26 @@ extern char datatoc_object_motion_frag_glsl[];
extern char datatoc_object_motion_vert_glsl[];
extern char datatoc_common_view_lib_glsl[];
+#define EEVEE_VELOCITY_TILE_SIZE 32
+
static void eevee_create_shader_motion_blur(void)
{
- e_data.motion_blur_sh = DRW_shader_create_fullscreen(datatoc_effect_motion_blur_frag_glsl, NULL);
+ e_data.motion_blur_sh = DRW_shader_create_fullscreen(
+ datatoc_effect_motion_blur_frag_glsl,
+ "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n");
e_data.motion_blur_object_sh = DRW_shader_create_with_lib(datatoc_object_motion_vert_glsl,
NULL,
datatoc_object_motion_frag_glsl,
datatoc_common_view_lib_glsl,
NULL);
- e_data.velocity_tiles_sh = DRW_shader_create_fullscreen(datatoc_effect_velocity_tile_frag_glsl,
- "#define TILE_GATHER\n");
+ e_data.velocity_tiles_sh = DRW_shader_create_fullscreen(
+ datatoc_effect_velocity_tile_frag_glsl,
+ "#define TILE_GATHER\n"
+ "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n");
e_data.velocity_tiles_expand_sh = DRW_shader_create_fullscreen(
- datatoc_effect_velocity_tile_frag_glsl, "#define TILE_EXPANSION\n");
+ datatoc_effect_velocity_tile_frag_glsl,
+ "#define TILE_EXPANSION\n"
+ "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n");
}
#if 0
@@ -184,14 +192,14 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda
}
#endif
- effects->motion_blur_max = max_ii(16, scene->eevee.motion_blur_max);
+ effects->motion_blur_max = max_ii(0, scene->eevee.motion_blur_max);
const float *fs_size = DRW_viewport_size_get();
- int tx_size[2] = {1 + ((int)fs_size[0] / effects->motion_blur_max),
- 1 + ((int)fs_size[1] / effects->motion_blur_max)};
+ int tx_size[2] = {1 + ((int)fs_size[0] / EEVEE_VELOCITY_TILE_SIZE),
+ 1 + ((int)fs_size[1] / EEVEE_VELOCITY_TILE_SIZE)};
effects->velocity_tiles_x_tx = DRW_texture_pool_query_2d(
tx_size[0], fs_size[1], GPU_RGBA16, &draw_engine_eevee_type);
- GPU_framebuffer_ensure_config(&fbl->velocity_tiles_x_fb,
+ GPU_framebuffer_ensure_config(&fbl->velocity_tiles_fb[0],
{
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(effects->velocity_tiles_x_tx),
@@ -199,20 +207,12 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda
effects->velocity_tiles_tx = DRW_texture_pool_query_2d(
tx_size[0], tx_size[1], GPU_RGBA16, &draw_engine_eevee_type);
- GPU_framebuffer_ensure_config(&fbl->velocity_tiles_fb,
+ GPU_framebuffer_ensure_config(&fbl->velocity_tiles_fb[1],
{
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(effects->velocity_tiles_tx),
});
- effects->velocity_tiles_expand_tx = DRW_texture_pool_query_2d(
- tx_size[0], tx_size[1], GPU_RGBA16, &draw_engine_eevee_type);
- GPU_framebuffer_ensure_config(&fbl->velocity_tiles_expand_fb,
- {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(effects->velocity_tiles_expand_tx),
- });
-
return EFFECT_MOTION_BLUR | EFFECT_POST_BUFFER | EFFECT_VELOCITY_BUFFER;
}
return 0;
@@ -239,53 +239,63 @@ void EEVEE_motion_blur_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
Scene *scene = draw_ctx->scene;
if ((effects->enabled_effects & EFFECT_MOTION_BLUR) != 0) {
+ const float *fs_size = DRW_viewport_size_get();
+ int tx_size[2] = {GPU_texture_width(effects->velocity_tiles_tx),
+ GPU_texture_height(effects->velocity_tiles_tx)};
DRWShadingGroup *grp;
{
DRW_PASS_CREATE(psl->velocity_tiles_x, DRW_STATE_WRITE_COLOR);
DRW_PASS_CREATE(psl->velocity_tiles, DRW_STATE_WRITE_COLOR);
- DRW_PASS_CREATE(psl->velocity_tiles_expand, DRW_STATE_WRITE_COLOR);
- eGPUSamplerState state = 0;
/* Create max velocity tiles in 2 passes. One for X and one for Y */
GPUShader *sh = e_data.velocity_tiles_sh;
grp = DRW_shgroup_create(sh, psl->velocity_tiles_x);
- DRW_shgroup_uniform_texture_ex(grp, "velocityBuffer", effects->velocity_tx, state);
- DRW_shgroup_uniform_int_copy(grp, "maxBlurRadius", effects->motion_blur_max);
+ DRW_shgroup_uniform_texture(grp, "velocityBuffer", effects->velocity_tx);
+ DRW_shgroup_uniform_ivec2_copy(grp, "velocityBufferSize", (int[2]){fs_size[0], fs_size[1]});
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
DRW_shgroup_uniform_ivec2_copy(grp, "gatherStep", (int[2]){1, 0});
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
grp = DRW_shgroup_create(sh, psl->velocity_tiles);
- DRW_shgroup_uniform_texture_ex(grp, "velocityBuffer", effects->velocity_tiles_x_tx, state);
+ DRW_shgroup_uniform_texture(grp, "velocityBuffer", effects->velocity_tiles_x_tx);
+ DRW_shgroup_uniform_ivec2_copy(grp, "velocityBufferSize", (int[2]){tx_size[0], fs_size[1]});
DRW_shgroup_uniform_ivec2_copy(grp, "gatherStep", (int[2]){0, 1});
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
/* Expand max tiles by keeping the max tile in each tile neighborhood. */
- GPUShader *sh_expand = e_data.velocity_tiles_expand_sh;
- grp = DRW_shgroup_create(sh_expand, psl->velocity_tiles_expand);
- DRW_shgroup_uniform_texture_ex(grp, "velocityBuffer", effects->velocity_tiles_tx, state);
- DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+ DRW_PASS_CREATE(psl->velocity_tiles_expand[0], DRW_STATE_WRITE_COLOR);
+ DRW_PASS_CREATE(psl->velocity_tiles_expand[1], DRW_STATE_WRITE_COLOR);
+ for (int i = 0; i < 2; i++) {
+ GPUTexture *tile_tx = (i == 0) ? effects->velocity_tiles_tx : effects->velocity_tiles_x_tx;
+ GPUShader *sh_expand = e_data.velocity_tiles_expand_sh;
+ grp = DRW_shgroup_create(sh_expand, psl->velocity_tiles_expand[i]);
+ DRW_shgroup_uniform_ivec2_copy(grp, "velocityBufferSize", tx_size);
+ DRW_shgroup_uniform_texture(grp, "velocityBuffer", tile_tx);
+ DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
+ DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+ }
}
{
DRW_PASS_CREATE(psl->motion_blur, DRW_STATE_WRITE_COLOR);
eGPUSamplerState state = 0;
+ int expand_steps = 1 + (max_ii(0, effects->motion_blur_max - 1) / EEVEE_VELOCITY_TILE_SIZE);
+ GPUTexture *tile_tx = (expand_steps & 1) ? effects->velocity_tiles_x_tx :
+ effects->velocity_tiles_tx;
grp = DRW_shgroup_create(e_data.motion_blur_sh, psl->motion_blur);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_texture_ref_ex(grp, "colorBuffer", &effects->source_buffer, state);
DRW_shgroup_uniform_texture_ref_ex(grp, "depthBuffer", &dtxl->depth, state);
DRW_shgroup_uniform_texture_ref_ex(grp, "velocityBuffer", &effects->velocity_tx, state);
- DRW_shgroup_uniform_texture_ref_ex(
- grp, "tileMaxBuffer", &effects->velocity_tiles_expand_tx, state);
+ DRW_shgroup_uniform_texture(grp, "tileMaxBuffer", tile_tx);
DRW_shgroup_uniform_float_copy(grp, "depthScale", scene->eevee.motion_blur_depth_scale);
- DRW_shgroup_uniform_int_copy(grp, "maxBlurRadius", effects->motion_blur_max);
DRW_shgroup_uniform_vec2(grp, "nearFar", effects->motion_blur_near_far, 1);
DRW_shgroup_uniform_bool_copy(grp, "isPerspective", DRW_view_is_persp_get(NULL));
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_uniform_ivec2_copy(grp, "tileBufferSize", tx_size);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
{
@@ -430,14 +440,29 @@ void EEVEE_motion_blur_draw(EEVEE_Data *vedata)
BLI_halton_1d(2, 0.0, sample - 1, &r);
effects->motion_blur_sample_offset = r;
- GPU_framebuffer_bind(fbl->velocity_tiles_x_fb);
+ /* Create velocity max tiles in 2 passes. One for each dimension. */
+ GPU_framebuffer_bind(fbl->velocity_tiles_fb[0]);
DRW_draw_pass(psl->velocity_tiles_x);
- GPU_framebuffer_bind(fbl->velocity_tiles_fb);
+ GPU_framebuffer_bind(fbl->velocity_tiles_fb[1]);
DRW_draw_pass(psl->velocity_tiles);
- GPU_framebuffer_bind(fbl->velocity_tiles_expand_fb);
- DRW_draw_pass(psl->velocity_tiles_expand);
+ /* Expand the tiles by reading the neighborhood. Do as many passes as required. */
+ int buf = 0;
+ for (int i = effects->motion_blur_max; i > 0; i -= EEVEE_VELOCITY_TILE_SIZE) {
+ GPU_framebuffer_bind(fbl->velocity_tiles_fb[buf]);
+
+ /* Change viewport to avoid invoking more pixel shaders than necessary since in one of the
+ * buffer the texture
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list