From 9516921c05bd9fee5c94942eb8e38f47ba7e4351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 2 Dec 2019 01:40:58 +0100 Subject: Overlay Engine: Refactor & Cleanup This is the unification of all overlays into one overlay engine as described in T65347. I went over all the code making it more future proof with less hacks and removing old / not relevent parts. Goals / Acheivements: - Remove internal shader usage (only drw shaders) - Remove viewportSize and viewportSizeInv and put them in gloabl ubo - Fixed some drawing issues: Missing probe option and Missing Alt+B clipping of some shader - Remove old (legacy) shaders dependancy (not using view UBO). - Less shader variation (less compilation time at first load and less patching needed for vulkan) - removed some geom shaders when I could - Remove static e_data (except shaders storage where it is OK) - Clear the way to fix some anoying limitations (dithered transparency, background image compositing etc...) - Wireframe drawing now uses the same batching capabilities as workbench & eevee (indirect drawing). - Reduced complexity, removed ~3000 Lines of code in draw (also removed a lot of unused shader in GPU). - Post AA to avoid complexity and cost of MSAA. Remaining issues: - ~~Armature edits, overlay toggles, (... others?) are not refreshing viewport after AA is complete~~ - FXAA is not the best for wires, maybe investigate SMAA - Maybe do something more temporally stable for AA. - ~~Paint overlays are not working with AA.~~ - ~~infront objects are difficult to select.~~ - ~~the infront wires sometimes goes through they solid counterpart (missing clear maybe?) (toggle overlays on-off when using infront+wireframe overlay in solid shading)~~ Note: I made some decision to change slightly the appearance of some objects to simplify their drawing. Namely the empty arrows end (which is now hollow/wire) and distance points of the cameras/spots being done by lines. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D6296 --- .../draw/engines/workbench/workbench_deferred.c | 63 +++++++++++++--------- 1 file changed, 38 insertions(+), 25 deletions(-) (limited to 'source/blender/draw/engines/workbench/workbench_deferred.c') diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index f84bd34545c..e5872dbac50 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -74,7 +74,6 @@ static struct { /* TODO(fclem) move everything below to wpd and custom viewlayer data. */ struct GPUTexture *oit_accum_tx; /* ref only, not alloced */ struct GPUTexture *oit_revealage_tx; /* ref only, not alloced */ - struct GPUTexture *ghost_depth_tx; /* ref only, not alloced */ struct GPUTexture *object_id_tx; /* ref only, not alloced */ struct GPUTexture *color_buffer_tx; /* ref only, not alloced */ struct GPUTexture *cavity_buffer_tx; /* ref only, not alloced */ @@ -582,7 +581,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) psl->ghost_resolve_pass = DRW_pass_create("Resolve Ghost Depth", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); grp = DRW_shgroup_create(e_data.ghost_resolve_sh, psl->ghost_resolve_pass); - DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.ghost_depth_tx); + DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth_in_front); DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL); } @@ -621,23 +620,6 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) } } -static void workbench_setup_ghost_framebuffer(WORKBENCH_FramebufferList *fbl) -{ - const float *viewport_size = DRW_viewport_size_get(); - const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; - - e_data.ghost_depth_tx = DRW_texture_pool_query_2d( - size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_workbench_solid); - - GPU_framebuffer_ensure_config(&fbl->ghost_prepass_fb, - { - GPU_ATTACHMENT_TEXTURE(e_data.ghost_depth_tx), - GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx), - GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx), - GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx), - }); -} - void workbench_deferred_engine_free(void) { for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) { @@ -1217,8 +1199,33 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob) } } -void workbench_deferred_cache_finish(WORKBENCH_Data *UNUSED(vedata)) +void workbench_deferred_cache_finish(WORKBENCH_Data *vedata) { + WORKBENCH_PassList *psl = vedata->psl; + WORKBENCH_FramebufferList *fbl = vedata->fbl; + + if (GHOST_ENABLED(psl)) { + /* HACK we allocate the infront depth here to avoid the overhead when if is not needed. */ + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + + DRW_texture_ensure_fullscreen_2d(&dtxl->depth_in_front, GPU_DEPTH24_STENCIL8, 0); + + GPU_framebuffer_ensure_config( + &dfbl->default_fb, + {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)}); + GPU_framebuffer_ensure_config( + &dfbl->in_front_fb, + {GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front), GPU_ATTACHMENT_TEXTURE(dtxl->color)}); + + GPU_framebuffer_ensure_config(&fbl->ghost_prepass_fb, + { + GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front), + GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx), + GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx), + GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx), + }); + } } void workbench_deferred_draw_background(WORKBENCH_Data *vedata) @@ -1252,6 +1259,7 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) WORKBENCH_FramebufferList *fbl = vedata->fbl; WORKBENCH_PrivateData *wpd = stl->g_data; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); if (workbench_is_taa_enabled(wpd)) { workbench_taa_draw_scene_start(vedata); @@ -1262,12 +1270,17 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) DRW_draw_pass(psl->prepass_pass); DRW_draw_pass(psl->prepass_hair_pass); - if (GHOST_ENABLED(psl)) { - /* meh, late init to not request a depth buffer we won't use. */ - workbench_setup_ghost_framebuffer(fbl); - + if (fbl->ghost_prepass_fb) { GPU_framebuffer_bind(fbl->ghost_prepass_fb); GPU_framebuffer_clear_depth(fbl->ghost_prepass_fb, 1.0f); + } + else if (dtxl->depth_in_front) { + /* TODO(fclem) This clear should be done in a global place. */ + GPU_framebuffer_bind(dfbl->in_front_fb); + GPU_framebuffer_clear_depth(dfbl->in_front_fb, 1.0f); + } + + if (GHOST_ENABLED(psl)) { DRW_draw_pass(psl->ghost_prepass_pass); DRW_draw_pass(psl->ghost_prepass_hair_pass); @@ -1318,6 +1331,7 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) /* In order to not draw on top of ghost objects, we clear the stencil * to 0xFF and the ghost object to 0x00 and only draw overlays on top if * stencil is not 0. */ + /* TODO(fclem) Remove this hack. */ GPU_framebuffer_bind(dfbl->depth_only_fb); GPU_framebuffer_clear_stencil(dfbl->depth_only_fb, 0xFF); @@ -1335,7 +1349,6 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) DRW_draw_pass(psl->background_pass); if (OIT_ENABLED(wpd) && !DRW_pass_is_empty(psl->transparent_accum_pass)) { - DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); /* meh, late init to not request buffers we won't use. */ workbench_init_oit_framebuffer(fbl, dtxl); -- cgit v1.2.3