diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-12-02 03:40:58 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-12-02 15:15:52 +0300 |
commit | 9516921c05bd9fee5c94942eb8e38f47ba7e4351 (patch) | |
tree | da007fc17bc6a02f849dae2e8f76f5ab304fe4dc /source/blender/draw/engines/workbench/workbench_deferred.c | |
parent | 1f6c3699a836d485ed37f443cd0fcd19e978dbb6 (diff) |
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
Diffstat (limited to 'source/blender/draw/engines/workbench/workbench_deferred.c')
-rw-r--r-- | source/blender/draw/engines/workbench/workbench_deferred.c | 63 |
1 files changed, 38 insertions, 25 deletions
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); |