diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-01-14 20:20:04 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-01-14 20:33:07 +0300 |
commit | 209afa28c6ee4714f375a44824511a8ac6d656a4 (patch) | |
tree | fa1e200837fbf7935730bce7c80c1dfe201ee871 | |
parent | 065bdc0333898b2d721c0241e332deb948c727c0 (diff) |
Object Mode: Outlines: Add support for thicker outline
Base outline is 2px wide (because of how we detect them).
And since inflating this outline will only produce outlines that are 2*x
thick we map the UI scalling and the outline width setting to the closest
match.
Do note that thicker outlines have a performance cost since they need more
texture fetches and passes.
This fixes T60252 3D View Outline Width not working
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 20 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/object_outline_expand_frag.glsl | 14 |
2 files changed, 26 insertions, 8 deletions
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 63273229096..0f69e248409 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -314,6 +314,7 @@ static struct { GPUShader *outline_detect_sh; GPUShader *outline_detect_wire_sh; GPUShader *outline_fade_sh; + GPUShader *outline_fade_large_sh; /* regular shaders */ GPUShader *object_empty_image_sh; @@ -435,6 +436,7 @@ static void OBJECT_engine_init(void *vedata) e_data.outline_fade_sh = DRW_shader_create_fullscreen(datatoc_object_outline_expand_frag_glsl, NULL); + e_data.outline_fade_large_sh = DRW_shader_create_fullscreen(datatoc_object_outline_expand_frag_glsl, "#define LARGE_OUTLINE\n"); /* Empty images */ # define EMPTY_IMAGE_SHADER_DEFINES \ @@ -670,6 +672,7 @@ static void OBJECT_engine_free(void) DRW_SHADER_FREE_SAFE(e_data.outline_detect_sh); DRW_SHADER_FREE_SAFE(e_data.outline_detect_wire_sh); DRW_SHADER_FREE_SAFE(e_data.outline_fade_sh); + DRW_SHADER_FREE_SAFE(e_data.outline_fade_large_sh); DRW_SHADER_FREE_SAFE(e_data.object_empty_image_sh); DRW_SHADER_FREE_SAFE(e_data.object_empty_image_wire_sh); DRW_SHADER_FREE_SAFE(e_data.grid_sh); @@ -985,8 +988,10 @@ static void OBJECT_cache_init(void *vedata) DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); OBJECT_PrivateData *g_data; const DRWContextState *draw_ctx = DRW_context_state_get(); - /* TODO : use dpi setting for enabling the second pass */ - const bool do_outline_expand = false; + + const float outline_width = UI_GetThemeValuef(TH_OUTLINE_WIDTH); + const bool do_outline_expand = (U.pixelsize > 1.0) || (outline_width > 2.0f); + const bool do_large_expand = ((U.pixelsize > 1.0) && (outline_width > 2.0f)) || (outline_width > 4.0f); if (!stl->g_data) { /* Alloc transient pointers */ @@ -1046,9 +1051,6 @@ static void OBJECT_cache_init(void *vedata) struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); /* Don't occlude the "outline" detection pass if in xray mode (too much flickering). */ float alphaOcclu = (g_data->xray_enabled) ? 1.0f : 0.35f; - /* Reminder : bool uniforms need to be 4 bytes. */ - static const int bTrue = true; - static const int bFalse = false; psl->outlines_search = DRW_pass_create("Outlines Detect Pass", state); @@ -1062,11 +1064,13 @@ static void OBJECT_cache_init(void *vedata) DRW_shgroup_uniform_int(grp, "idOffsets", &stl->g_data->id_ofs_active, 4); DRW_shgroup_call_add(grp, quad, NULL); + /* This is the bleed pass if do_outline_expand is false. */ + GPUShader *fade_sh = (do_large_expand) ? e_data.outline_fade_large_sh : e_data.outline_fade_sh; psl->outlines_expand = DRW_pass_create("Outlines Expand Pass", state); - grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_expand); + grp = DRW_shgroup_create(fade_sh, psl->outlines_expand); DRW_shgroup_uniform_texture_ref(grp, "outlineColor", &e_data.outlines_blur_tx); - DRW_shgroup_uniform_bool(grp, "doExpand", (do_outline_expand) ? &bTrue : &bFalse, 1); + DRW_shgroup_uniform_bool_copy(grp, "doExpand", do_outline_expand); DRW_shgroup_call_add(grp, quad, NULL); psl->outlines_bleed = DRW_pass_create("Outlines Bleed Pass", state); @@ -1074,7 +1078,7 @@ static void OBJECT_cache_init(void *vedata) if (do_outline_expand) { grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_bleed); DRW_shgroup_uniform_texture_ref(grp, "outlineColor", &e_data.outlines_color_tx); - DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1); + DRW_shgroup_uniform_bool_copy(grp, "doExpand", false); DRW_shgroup_call_add(grp, quad, NULL); } } diff --git a/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl b/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl index 7e288cde236..8b5603919c4 100644 --- a/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl +++ b/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl @@ -28,6 +28,20 @@ void main() return; } +#ifdef LARGE_OUTLINE + if (!any(btests)) { + color[0] = texelFetchOffset(outlineColor, uv, 0, ivec2( 2, 0)).rgba; + color[1] = texelFetchOffset(outlineColor, uv, 0, ivec2( 0, 2)).rgba; + color[2] = texelFetchOffset(outlineColor, uv, 0, ivec2(-2, 0)).rgba; + color[3] = texelFetchOffset(outlineColor, uv, 0, ivec2( 0, -2)).rgba; + + values = vec4(color[0].a, color[1].a, color[2].a, color[3].a); + + tests = step(vec4(1e-6), values); /* (color.a != 0.0) */ + btests = equal(tests, vec4(1.0)); + } +#endif + FragColor = (btests.x) ? color[0] : FragColor; FragColor = (btests.y) ? color[1] : FragColor; FragColor = (btests.z) ? color[2] : FragColor; |