Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/overlay/overlay_antialiasing.c')
-rw-r--r--source/blender/draw/engines/overlay/overlay_antialiasing.c222
1 files changed, 71 insertions, 151 deletions
diff --git a/source/blender/draw/engines/overlay/overlay_antialiasing.c b/source/blender/draw/engines/overlay/overlay_antialiasing.c
index 779ec1035a3..54a598633fb 100644
--- a/source/blender/draw/engines/overlay/overlay_antialiasing.c
+++ b/source/blender/draw/engines/overlay/overlay_antialiasing.c
@@ -18,6 +18,40 @@
/** \file
* \ingroup draw_engine
+ *
+ * Overlay antialiasing:
+ *
+ * Most of the overlays are wires which causes a lot of flickering in motions
+ * due to aliasing problems.
+ *
+ * Our goal is to have a technique that works with single sample per pixel
+ * to avoid extra cost of managing MSAA or additional texture buffers and jitters.
+ *
+ * To solve this we use a simple and effective post-process AA. The technique
+ * goes like this:
+ *
+ * - During wireframe rendering, we output the line color, the line direction
+ * and the distance from the line for the pixel center.
+ *
+ * - Then, in a post process pass, for each pixels we gather all lines in a search area
+ * that could cover (even partially) the center pixel.
+ * We compute the coverage of each line and do a sorted alpha compositing of them.
+ *
+ * This technique has one major shortcoming compared to MSAA:
+ * - It handles (initial) partial visibility poorly (because of single sample). This makes
+ * overlaping / crossing wires a bit too thin at their intersection.
+ * Wireframe meshes overlaid over solid meshes can have half of the edge missing due to
+ * z-fighting (this has workaround).
+ * Another manifestation of this, is fickering of really dense wireframe if using small
+ * line thickness (also has workaround).
+ *
+ * The pros of this approach are many:
+ * - Works without geometry shader.
+ * - Can inflate line thickness.
+ * - Coverage is very close to perfect and can even be filtered (Blackman-Harris, gaussian).
+ * - Wires can "bleed" / overlap non-line objects since the filter is in screenspace.
+ * - Only uses one additional lightweight fullscreen buffer (compared to MSAA/SMAA).
+ * - No convergence time (compared to TAA).
*/
#include "DRW_render.h"
@@ -25,12 +59,6 @@
#include "ED_screen.h"
#include "overlay_private.h"
-#include "smaa_textures.h"
-
-struct {
- GPUTexture *smaa_search_tx;
- GPUTexture *smaa_area_tx;
-} e_data = {NULL};
void OVERLAY_antialiasing_reset(OVERLAY_Data *vedata)
{
@@ -55,51 +83,12 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
/* TODO Get real userpref option and remove MSAA buffer. */
pd->antialiasing.enabled = dtxl->multisample_color != NULL;
- if (pd->antialiasing.enabled) {
-
- if (e_data.smaa_search_tx == NULL) {
- e_data.smaa_search_tx = GPU_texture_create_nD(SEARCHTEX_WIDTH,
- SEARCHTEX_HEIGHT,
- 0,
- 2,
- searchTexBytes,
- GPU_R8,
- GPU_DATA_UNSIGNED_BYTE,
- 0,
- false,
- NULL);
-
- e_data.smaa_area_tx = GPU_texture_create_nD(AREATEX_WIDTH,
- AREATEX_HEIGHT,
- 0,
- 2,
- areaTexBytes,
- GPU_RG8,
- GPU_DATA_UNSIGNED_BYTE,
- 0,
- false,
- NULL);
- GPU_texture_bind(e_data.smaa_area_tx, 0);
- GPU_texture_filter_mode(e_data.smaa_area_tx, true);
- GPU_texture_unbind(e_data.smaa_area_tx);
-
- GPU_texture_bind(e_data.smaa_search_tx, 0);
- GPU_texture_filter_mode(e_data.smaa_search_tx, true);
- GPU_texture_unbind(e_data.smaa_search_tx);
- }
+ /* Use default view */
+ pd->view_default = (DRWView *)DRW_view_default_get();
- pd->antialiasing.target_sample = 4;
-
- bool valid_history = true;
- if (txl->overlay_color_history_tx == NULL || pd->antialiasing.sample == 0) {
- valid_history = false;
- }
-
- DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, 0);
+ if (pd->antialiasing.enabled) {
DRW_texture_ensure_fullscreen_2d(&txl->overlay_color_tx, GPU_RGBA8, DRW_TEX_FILTER);
- DRW_texture_ensure_fullscreen_2d(&txl->overlay_color_history_tx, GPU_RGBA8, DRW_TEX_FILTER);
- DRW_texture_ensure_fullscreen_2d(&txl->smaa_edge_tx, GPU_RG8, DRW_TEX_FILTER);
- DRW_texture_ensure_fullscreen_2d(&txl->smaa_blend_tx, GPU_RGBA8, DRW_TEX_FILTER);
+ DRW_texture_ensure_fullscreen_2d(&txl->overlay_line_tx, GPU_RGBA8, 0);
GPU_framebuffer_ensure_config(
&fbl->overlay_color_only_fb,
@@ -107,63 +96,10 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
GPU_framebuffer_ensure_config(
&fbl->overlay_default_fb,
{GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(txl->overlay_color_tx)});
- GPU_framebuffer_ensure_config(&fbl->overlay_in_front_fb,
- {GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front),
- GPU_ATTACHMENT_TEXTURE(txl->overlay_color_tx)});
-
- GPU_framebuffer_ensure_config(
- &fbl->overlay_color_history_fb,
- {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->overlay_color_history_tx)});
- GPU_framebuffer_ensure_config(
- &fbl->smaa_edge_fb,
- {GPU_ATTACHMENT_TEXTURE(txl->temp_depth_tx), GPU_ATTACHMENT_TEXTURE(txl->smaa_edge_tx)});
- GPU_framebuffer_ensure_config(
- &fbl->smaa_blend_fb,
- {GPU_ATTACHMENT_TEXTURE(txl->temp_depth_tx), GPU_ATTACHMENT_TEXTURE(txl->smaa_blend_tx)});
-
- /* Test if we can do TAA */
- if (valid_history) {
- float persmat[4][4];
- DRW_view_persmat_get(NULL, persmat, false);
- valid_history = compare_m4m4(persmat, pd->antialiasing.prev_persmat, FLT_MIN);
- copy_m4_m4(pd->antialiasing.prev_persmat, persmat);
- }
-
- const DRWContextState *draw_ctx = DRW_context_state_get();
- if (valid_history && draw_ctx->evil_C != NULL) {
- struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
- valid_history = (ED_screen_animation_no_scrub(wm) == NULL);
- }
-
- if (valid_history) {
- /* TAA */
- float persmat[4][4], viewmat[4][4], winmat[4][4];
- DRW_view_persmat_get(NULL, persmat, false);
- DRW_view_viewmat_get(NULL, viewmat, false);
- DRW_view_winmat_get(NULL, winmat, false);
-
- const float *viewport_size = DRW_viewport_size_get();
- int nr = min_ii(pd->antialiasing.sample, pd->antialiasing.target_sample);
- /* x4 rotated grid. TODO(fclem) better patterns. */
- const float samples_pos[5][2] = {{0, 0}, {-2, -6}, {6, -2}, {-6, 2}, {2, 6}};
- /* For nr = 0,we should sample {0, 0} (goes through the FXAA branch). */
- float ofs[2] = {samples_pos[nr][0] / 6.0f, samples_pos[nr][1] / 6.0f};
-
- // window_translate_m4(winmat, persmat, ofs[0] / viewport_size[0], ofs[1] /
- // viewport_size[1]);
-
- const DRWView *default_view = DRW_view_default_get();
- pd->view_default = DRW_view_create_sub(default_view, viewmat, winmat);
-
- /* Avoid infinite sample count. */
- CLAMP_MAX(pd->antialiasing.sample, pd->antialiasing.target_sample + 1);
- }
- else {
- /* FXAA */
- OVERLAY_antialiasing_reset(vedata);
- /* Use default view */
- pd->view_default = (DRWView *)DRW_view_default_get();
- }
+ GPU_framebuffer_ensure_config(&fbl->overlay_line_fb,
+ {GPU_ATTACHMENT_TEXTURE(dtxl->depth),
+ GPU_ATTACHMENT_TEXTURE(txl->overlay_color_tx),
+ GPU_ATTACHMENT_TEXTURE(txl->overlay_line_tx)});
}
else {
/* Just a copy of the defaults framebuffers. */
@@ -173,11 +109,8 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
&fbl->overlay_default_fb,
{GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
GPU_framebuffer_ensure_config(
- &fbl->overlay_in_front_fb,
- {GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
-
- /* Use default view */
- pd->view_default = (DRWView *)DRW_view_default_get();
+ &fbl->overlay_line_fb,
+ {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
}
}
@@ -191,33 +124,34 @@ void OVERLAY_antialiasing_cache_init(OVERLAY_Data *vedata)
DRWShadingGroup *grp;
if (pd->antialiasing.enabled) {
- DRW_PASS_CREATE(psl->smaa_edge_detect_ps,
- DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS);
- DRW_PASS_CREATE(psl->smaa_blend_weight_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL);
- DRW_PASS_CREATE(psl->smaa_resolve_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL);
+ DRW_PASS_CREATE(psl->antialiasing_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL);
- sh = OVERLAY_shader_antialiasing(0);
- grp = DRW_shgroup_create(sh, psl->smaa_edge_detect_ps);
+ sh = OVERLAY_shader_antialiasing();
+ grp = DRW_shgroup_create(sh, psl->antialiasing_ps);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
+ DRW_shgroup_uniform_texture_ref(grp, "depthTex", &dtxl->depth);
DRW_shgroup_uniform_texture_ref(grp, "colorTex", &txl->overlay_color_tx);
- DRW_shgroup_stencil_mask(grp, 0xFF);
+ DRW_shgroup_uniform_texture_ref(grp, "lineTex", &txl->overlay_line_tx);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+ }
+}
- sh = OVERLAY_shader_antialiasing(1);
- grp = DRW_shgroup_create(sh, psl->smaa_blend_weight_ps);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
- DRW_shgroup_uniform_texture_ref(grp, "edgesTex", &txl->smaa_edge_tx);
- DRW_shgroup_uniform_texture(grp, "areaTex", e_data.smaa_area_tx);
- DRW_shgroup_uniform_texture(grp, "searchTex", e_data.smaa_search_tx);
- DRW_shgroup_stencil_mask(grp, 0xFF);
- DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+void OVERLAY_antialiasing_cache_finish(OVERLAY_Data *vedata)
+{
+ OVERLAY_FramebufferList *fbl = vedata->fbl;
+ OVERLAY_TextureList *txl = vedata->txl;
+ OVERLAY_PrivateData *pd = vedata->stl->pd;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- sh = OVERLAY_shader_antialiasing(2);
- grp = DRW_shgroup_create(sh, psl->smaa_resolve_ps);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
- DRW_shgroup_uniform_texture_ref(grp, "blendTex", &txl->smaa_blend_tx);
- DRW_shgroup_uniform_texture_ref(grp, "colorTex", &txl->overlay_color_tx);
- DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+ if (pd->antialiasing.enabled) {
+ GPU_framebuffer_ensure_config(&fbl->overlay_in_front_fb,
+ {GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front),
+ GPU_ATTACHMENT_TEXTURE(txl->overlay_color_tx)});
+ }
+ else {
+ GPU_framebuffer_ensure_config(
+ &fbl->overlay_in_front_fb,
+ {GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
}
}
@@ -228,8 +162,10 @@ void OVERLAY_antialiasing_start(OVERLAY_Data *vedata)
if (pd->antialiasing.enabled) {
float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ GPU_framebuffer_bind(fbl->overlay_line_fb);
+ GPU_framebuffer_clear_color(fbl->overlay_line_fb, clear_col);
+
GPU_framebuffer_bind(fbl->overlay_default_fb);
- GPU_framebuffer_clear_color(fbl->overlay_default_fb, clear_col);
}
}
@@ -237,28 +173,12 @@ void OVERLAY_antialiasing_end(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
- OVERLAY_FramebufferList *fbl = vedata->fbl;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
if (pd->antialiasing.enabled) {
- float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-
- GPU_framebuffer_bind(fbl->smaa_edge_fb);
- GPU_framebuffer_clear_color(fbl->smaa_edge_fb, clear_col);
- GPU_framebuffer_clear_stencil(fbl->smaa_edge_fb, 0x00);
- DRW_draw_pass(psl->smaa_edge_detect_ps);
-
- GPU_framebuffer_bind(fbl->smaa_blend_fb);
- GPU_framebuffer_clear_color(fbl->smaa_blend_fb, clear_col);
- DRW_draw_pass(psl->smaa_blend_weight_ps);
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ DRW_draw_pass(psl->antialiasing_ps);
GPU_framebuffer_bind(dfbl->default_fb);
- DRW_draw_pass(psl->smaa_resolve_ps);
}
}
-
-void OVERLAY_antialiasing_free(void)
-{
- DRW_TEXTURE_FREE_SAFE(e_data.smaa_area_tx);
- DRW_TEXTURE_FREE_SAFE(e_data.smaa_search_tx);
-}