From d0493796a6f40db8dcdd4a9058b98a69282d4759 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 23 Sep 2021 15:53:38 +0200 Subject: Cleanup: Remove hardcoded values and rename keyframe shape shaders No functional change. The shader is complicated by itself, having hardcoded values makes it even more cryptic. I also renamed the shader because the shader is not for the keyfarme diamond only, but for all the keyframe shapes. Differential Revision: https://developer.blender.org/D12615 --- source/blender/editors/animation/keyframes_draw.c | 18 ++-- source/blender/editors/include/ED_keyframes_draw.h | 2 +- source/blender/editors/interface/interface_icons.c | 2 +- .../editors/space_clip/clip_dopesheet_draw.c | 2 +- source/blender/editors/space_nla/nla_draw.c | 2 +- source/blender/editors/space_node/node_draw.cc | 18 ++-- source/blender/gpu/CMakeLists.txt | 4 +- source/blender/gpu/GPU_shader.h | 15 ++- source/blender/gpu/intern/gpu_shader_builtin.c | 12 +-- .../shaders/gpu_shader_keyframe_diamond_frag.glsl | 89 ------------------ .../shaders/gpu_shader_keyframe_diamond_vert.glsl | 86 ----------------- .../shaders/gpu_shader_keyframe_shape_frag.glsl | 102 +++++++++++++++++++++ .../shaders/gpu_shader_keyframe_shape_vert.glsl | 99 ++++++++++++++++++++ .../blender/gpu/tests/gpu_shader_builtin_test.cc | 2 +- 14 files changed, 243 insertions(+), 210 deletions(-) delete mode 100644 source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl delete mode 100644 source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl create mode 100644 source/blender/gpu/shaders/gpu_shader_keyframe_shape_frag.glsl create mode 100644 source/blender/gpu/shaders/gpu_shader_keyframe_shape_vert.glsl diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index ac7db9f4f46..e3ea8f0ab21 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -146,31 +146,31 @@ void draw_keyframe_shape(float x, /* Handle type to outline shape. */ switch (handle_type) { case KEYFRAME_HANDLE_AUTO_CLAMP: - flags = 0x2; + flags = GPU_KEYFRAME_SHAPE_CIRCLE; break; /* circle */ case KEYFRAME_HANDLE_AUTO: - flags = 0x12; + flags = GPU_KEYFRAME_SHAPE_CIRCLE | GPU_KEYFRAME_SHAPE_INNER_DOT; break; /* circle with dot */ case KEYFRAME_HANDLE_VECTOR: - flags = 0xC; + flags = GPU_KEYFRAME_SHAPE_SQUARE; break; /* square */ case KEYFRAME_HANDLE_ALIGNED: - flags = 0x5; + flags = GPU_KEYFRAME_SHAPE_DIAMOND | GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL; break; /* clipped diamond */ case KEYFRAME_HANDLE_FREE: default: - flags = 1; /* diamond */ + flags = GPU_KEYFRAME_SHAPE_DIAMOND; /* diamond */ } /* Extreme type to arrow-like shading. */ if (extreme_type & KEYFRAME_EXTREME_MAX) { - flags |= 0x100; + flags |= GPU_KEYFRAME_SHAPE_ARROW_END_MAX; } if (extreme_type & KEYFRAME_EXTREME_MIN) { - flags |= 0x200; + flags |= GPU_KEYFRAME_SHAPE_ARROW_END_MIN; } - if (extreme_type & KEYFRAME_EXTREME_MIXED) { + if (extreme_type & GPU_KEYFRAME_SHAPE_ARROW_END_MIXED) { flags |= 0x400; } } @@ -584,7 +584,7 @@ static void ED_keylist_draw_list_draw_keys(AnimKeylistDrawList *draw_list, View2 sh_bindings.flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); GPU_program_point_size(true); - immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); + immBindBuiltinProgram(GPU_SHADER_KEYFRAME_SHAPE); immUniform1f("outline_scale", 1.0f); immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1); immBegin(GPU_PRIM_POINTS, visible_key_len); diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index 61e37f20b1b..6a7037c3eed 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -41,7 +41,7 @@ struct bDopeSheet; struct bGPDlayer; /* draw simple diamond-shape keyframe */ -/* caller should set up vertex format, bind GPU_SHADER_KEYFRAME_DIAMOND, +/* caller should set up vertex format, bind GPU_SHADER_KEYFRAME_SHAPE, * immBegin(GPU_PRIM_POINTS, n), then call this n times */ typedef struct KeyframeShaderBindings { uint pos_id; diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index f739830cfdb..7f1a8ee99e0 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -309,7 +309,7 @@ static void vicon_keytype_draw_wrapper( sh_bindings.flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); GPU_program_point_size(true); - immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); + immBindBuiltinProgram(GPU_SHADER_KEYFRAME_SHAPE); immUniform1f("outline_scale", 1.0f); immUniform2f("ViewportSize", -1.0f, -1.0f); immBegin(GPU_PRIM_POINTS, 1); diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index 8aaf3faffec..42fda3ef464 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -224,7 +224,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *region, Scene *scene) uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); GPU_program_point_size(true); - immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); + immBindBuiltinProgram(GPU_SHADER_KEYFRAME_SHAPE); immUniform1f("outline_scale", 1.0f); immUniform2f( "ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1); diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index c1b308d213f..4694d8652f6 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -152,7 +152,7 @@ static void nla_action_draw_keyframes( format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); GPU_program_point_size(true); - immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); + immBindBuiltinProgram(GPU_SHADER_KEYFRAME_SHAPE); immUniform1f("outline_scale", 1.0f); immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1); immBegin(GPU_PRIM_POINTS, key_len); diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 10a3285be8b..b57696cb676 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -733,12 +733,6 @@ static void node_draw_mute_line(const View2D *v2d, const SpaceNode *snode, const GPU_blend(GPU_BLEND_NONE); } -/* Flags used in gpu_shader_keyframe_diamond_frag.glsl. */ -#define MARKER_SHAPE_DIAMOND 0x1 -#define MARKER_SHAPE_SQUARE 0xC -#define MARKER_SHAPE_CIRCLE 0x2 -#define MARKER_SHAPE_INNER_DOT 0x10 - static void node_socket_draw(const bNodeSocket *sock, const float color[4], const float color_outline[4], @@ -757,16 +751,16 @@ static void node_socket_draw(const bNodeSocket *sock, switch (sock->display_shape) { case SOCK_DISPLAY_SHAPE_DIAMOND: case SOCK_DISPLAY_SHAPE_DIAMOND_DOT: - flags = MARKER_SHAPE_DIAMOND; + flags = GPU_KEYFRAME_SHAPE_DIAMOND; break; case SOCK_DISPLAY_SHAPE_SQUARE: case SOCK_DISPLAY_SHAPE_SQUARE_DOT: - flags = MARKER_SHAPE_SQUARE; + flags = GPU_KEYFRAME_SHAPE_SQUARE; break; default: case SOCK_DISPLAY_SHAPE_CIRCLE: case SOCK_DISPLAY_SHAPE_CIRCLE_DOT: - flags = MARKER_SHAPE_CIRCLE; + flags = GPU_KEYFRAME_SHAPE_CIRCLE; break; } @@ -774,7 +768,7 @@ static void node_socket_draw(const bNodeSocket *sock, SOCK_DISPLAY_SHAPE_DIAMOND_DOT, SOCK_DISPLAY_SHAPE_SQUARE_DOT, SOCK_DISPLAY_SHAPE_CIRCLE_DOT)) { - flags |= MARKER_SHAPE_INNER_DOT; + flags |= GPU_KEYFRAME_SHAPE_INNER_DOT; } immAttr4fv(col_id, color); @@ -1132,7 +1126,7 @@ void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[ GPU_blend(GPU_BLEND_ALPHA); GPU_program_point_size(true); - immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); + immBindBuiltinProgram(GPU_SHADER_KEYFRAME_SHAPE); immUniform1f("outline_scale", 0.7f); immUniform2f("ViewportSize", -1.0f, -1.0f); @@ -1277,7 +1271,7 @@ void node_draw_sockets(const View2D *v2d, GPU_blend(GPU_BLEND_ALPHA); GPU_program_point_size(true); - immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); + immBindBuiltinProgram(GPU_SHADER_KEYFRAME_SHAPE); immUniform1f("outline_scale", 0.7f); immUniform2f("ViewportSize", -1.0f, -1.0f); diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index b7dc3210c41..df370c7079b 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -268,8 +268,8 @@ data_to_c_simple(shaders/gpu_shader_2D_edituvs_stretch_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_text_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_text_frag.glsl SRC) -data_to_c_simple(shaders/gpu_shader_keyframe_diamond_vert.glsl SRC) -data_to_c_simple(shaders/gpu_shader_keyframe_diamond_frag.glsl SRC) +data_to_c_simple(shaders/gpu_shader_keyframe_shape_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_keyframe_shape_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_codegen_lib.glsl SRC) diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 62b748b7edf..c6cfac79699 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -169,7 +169,7 @@ void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear); typedef enum eGPUBuiltinShader { /* specialized drawing */ GPU_SHADER_TEXT, - GPU_SHADER_KEYFRAME_DIAMOND, + GPU_SHADER_KEYFRAME_SHAPE, GPU_SHADER_SIMPLE_LIGHTING, /* for simple 2D drawing */ /** @@ -423,6 +423,19 @@ void GPU_shader_free_builtin_shaders(void); /* Determined by the maximum uniform buffer size divided by chunk size. */ #define GPU_MAX_UNIFORM_ATTR 8 +typedef enum eGPUKeyframeShapes { + GPU_KEYFRAME_SHAPE_DIAMOND = (1 << 0), + GPU_KEYFRAME_SHAPE_CIRCLE = (1 << 1), + GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL = (1 << 2), + GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL = (1 << 3), + GPU_KEYFRAME_SHAPE_INNER_DOT = (1 << 4), + GPU_KEYFRAME_SHAPE_ARROW_END_MAX = (1 << 8), + GPU_KEYFRAME_SHAPE_ARROW_END_MIN = (1 << 9), + GPU_KEYFRAME_SHAPE_ARROW_END_MIXED = (1 << 10), +} eGPUKeyframeShapes; +#define GPU_KEYFRAME_SHAPE_SQUARE \ + (GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL | GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL) + #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/intern/gpu_shader_builtin.c b/source/blender/gpu/intern/gpu_shader_builtin.c index c5122b76001..9ea46788f44 100644 --- a/source/blender/gpu/intern/gpu_shader_builtin.c +++ b/source/blender/gpu/intern/gpu_shader_builtin.c @@ -121,8 +121,8 @@ extern char datatoc_gpu_shader_3D_line_dashed_uniform_color_vert_glsl[]; extern char datatoc_gpu_shader_text_vert_glsl[]; extern char datatoc_gpu_shader_text_frag_glsl[]; -extern char datatoc_gpu_shader_keyframe_diamond_vert_glsl[]; -extern char datatoc_gpu_shader_keyframe_diamond_frag_glsl[]; +extern char datatoc_gpu_shader_keyframe_shape_vert_glsl[]; +extern char datatoc_gpu_shader_keyframe_shape_frag_glsl[]; extern char datatoc_gpu_shader_gpencil_stroke_vert_glsl[]; extern char datatoc_gpu_shader_gpencil_stroke_frag_glsl[]; @@ -166,11 +166,11 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = { .vert = datatoc_gpu_shader_text_vert_glsl, .frag = datatoc_gpu_shader_text_frag_glsl, }, - [GPU_SHADER_KEYFRAME_DIAMOND] = + [GPU_SHADER_KEYFRAME_SHAPE] = { - .name = "GPU_SHADER_KEYFRAME_DIAMOND", - .vert = datatoc_gpu_shader_keyframe_diamond_vert_glsl, - .frag = datatoc_gpu_shader_keyframe_diamond_frag_glsl, + .name = "GPU_SHADER_KEYFRAME_SHAPE", + .vert = datatoc_gpu_shader_keyframe_shape_vert_glsl, + .frag = datatoc_gpu_shader_keyframe_shape_frag_glsl, }, [GPU_SHADER_SIMPLE_LIGHTING] = { diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl deleted file mode 100644 index 1c4039bc590..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl +++ /dev/null @@ -1,89 +0,0 @@ -flat in vec4 radii; -flat in vec4 thresholds; - -flat in vec4 finalColor; -flat in vec4 finalOutlineColor; - -flat in int finalFlags; - -out vec4 fragColor; - -const float diagonal_scale = sqrt(0.5); - -const float minmax_bias = 0.7; -const float minmax_scale = sqrt(1.0 / (1.0 + 1.0 / minmax_bias)); - -bool test(int bit) -{ - return (finalFlags & bit) != 0; -} - -void main() -{ - vec2 pos = gl_PointCoord - vec2(0.5); - vec2 absPos = abs(pos); - float radius = (absPos.x + absPos.y) * diagonal_scale; - - float outline_dist = -1.0; - - /* Diamond outline */ - if (test(0x1)) { - outline_dist = max(outline_dist, radius - radii[0]); - } - - /* Circle outline */ - if (test(0x2)) { - radius = length(absPos); - - outline_dist = max(outline_dist, radius - radii[1]); - } - - /* Top & Bottom clamp */ - if (test(0x4)) { - outline_dist = max(outline_dist, absPos.y - radii[2]); - } - - /* Left & Right clamp */ - if (test(0x8)) { - outline_dist = max(outline_dist, absPos.x - radii[2]); - } - - float alpha = 1 - smoothstep(thresholds[0], thresholds[1], abs(outline_dist)); - - /* Inside the outline. */ - if (outline_dist < 0) { - /* Middle dot */ - if (test(0x10)) { - alpha = max(alpha, 1 - smoothstep(thresholds[2], thresholds[3], radius)); - } - - /* Up and down arrow-like shading. */ - if (test(0x300)) { - float ypos = -1.0; - - /* Up arrow (maximum) */ - if (test(0x100)) { - ypos = max(ypos, pos.y); - } - /* Down arrow (minimum) */ - if (test(0x200)) { - ypos = max(ypos, -pos.y); - } - - /* Arrow shape threshold. */ - float minmax_dist = (ypos - radii[3]) - absPos.x * minmax_bias; - float minmax_step = smoothstep(thresholds[0], thresholds[1], minmax_dist * minmax_scale); - - /* Reduced alpha for uncertain extremes. */ - float minmax_alpha = test(0x400) ? 0.55 : 0.85; - - alpha = max(alpha, minmax_step * minmax_alpha); - } - - fragColor = mix(finalColor, finalOutlineColor, alpha); - } - /* Outside the outline. */ - else { - fragColor = vec4(finalOutlineColor.rgb, finalOutlineColor.a * alpha); - } -} diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl deleted file mode 100644 index 2ba89230d80..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl +++ /dev/null @@ -1,86 +0,0 @@ - -uniform mat4 ModelViewProjectionMatrix; -uniform vec2 ViewportSize = vec2(-1, -1); -uniform float outline_scale = 1.0; - -const float line_falloff = 1.0; -const float circle_scale = sqrt(2.0 / 3.1416); -const float square_scale = sqrt(0.5); -const float diagonal_scale = sqrt(0.5); - -in vec2 pos; -in float size; -in vec4 color; -in vec4 outlineColor; -in int flags; - -flat out vec4 finalColor; -flat out vec4 finalOutlineColor; - -flat out int finalFlags; - -flat out vec4 radii; -flat out vec4 thresholds; - -bool test(int bit) -{ - return (flags & bit) != 0; -} - -vec2 line_thresholds(float width) -{ - return vec2(max(0, width - line_falloff), width); -} - -void main() -{ - gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); - - /* Align to pixel grid if the viewport size is known. */ - if (ViewportSize.x > 0) { - vec2 scale = ViewportSize * 0.5; - vec2 px_pos = (gl_Position.xy + 1) * scale; - vec2 adj_pos = round(px_pos - 0.5) + 0.5; - gl_Position.xy = adj_pos / scale - 1; - } - - /* Pass through parameters. */ - finalColor = color; - finalOutlineColor = outlineColor; - finalFlags = flags; - - if (!test(0xF)) { - finalFlags |= 1; - } - - /* Size-dependent line thickness. */ - float half_width = (0.06 + (size - 10) * 0.04); - float line_width = half_width + line_falloff; - - /* Outline thresholds. */ - thresholds.xy = line_thresholds(line_width * outline_scale); - - /* Inner dot thresholds. */ - thresholds.zw = line_thresholds(line_width * 1.6); - - /* Extend the primitive size by half line width on either side; odd for symmetry. */ - float ext_radius = round(0.5 * size) + thresholds.x; - - gl_PointSize = ceil(ext_radius + thresholds.y) * 2 + 1; - - /* Diamond radius. */ - radii[0] = ext_radius * diagonal_scale; - - /* Circle radius. */ - radii[1] = ext_radius * circle_scale; - - /* Square radius. */ - radii[2] = round(ext_radius * square_scale); - - /* Min/max cutout offset. */ - radii[3] = -line_falloff; - - /* Convert to PointCoord units. */ - radii /= gl_PointSize; - thresholds /= gl_PointSize; -} diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_shape_frag.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_shape_frag.glsl new file mode 100644 index 00000000000..f0ff70f7690 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_keyframe_shape_frag.glsl @@ -0,0 +1,102 @@ + +/* Values in GPU_shader.h. */ +#define GPU_KEYFRAME_SHAPE_DIAMOND (1 << 0) +#define GPU_KEYFRAME_SHAPE_CIRCLE (1 << 1) +#define GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL (1 << 2) +#define GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL (1 << 3) +#define GPU_KEYFRAME_SHAPE_INNER_DOT (1 << 4) +#define GPU_KEYFRAME_SHAPE_ARROW_END_MAX (1 << 8) +#define GPU_KEYFRAME_SHAPE_ARROW_END_MIN (1 << 9) +#define GPU_KEYFRAME_SHAPE_ARROW_END_MIXED (1 << 10) +#define GPU_KEYFRAME_SHAPE_SQUARE \ + (GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL | GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL) + +flat in vec4 radii; +flat in vec4 thresholds; + +flat in vec4 finalColor; +flat in vec4 finalOutlineColor; + +flat in int finalFlags; + +out vec4 fragColor; + +const float diagonal_scale = sqrt(0.5); + +const float minmax_bias = 0.7; +const float minmax_scale = sqrt(1.0 / (1.0 + 1.0 / minmax_bias)); + +bool test(int bit) +{ + return (finalFlags & bit) != 0; +} + +void main() +{ + vec2 pos = gl_PointCoord - vec2(0.5); + vec2 absPos = abs(pos); + float radius = (absPos.x + absPos.y) * diagonal_scale; + + float outline_dist = -1.0; + + /* Diamond outline */ + if (test(GPU_KEYFRAME_SHAPE_DIAMOND)) { + outline_dist = max(outline_dist, radius - radii[0]); + } + + /* Circle outline */ + if (test(GPU_KEYFRAME_SHAPE_CIRCLE)) { + radius = length(absPos); + + outline_dist = max(outline_dist, radius - radii[1]); + } + + /* Top & Bottom clamp */ + if (test(GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL)) { + outline_dist = max(outline_dist, absPos.y - radii[2]); + } + + /* Left & Right clamp */ + if (test(GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL)) { + outline_dist = max(outline_dist, absPos.x - radii[2]); + } + + float alpha = 1 - smoothstep(thresholds[0], thresholds[1], abs(outline_dist)); + + /* Inside the outline. */ + if (outline_dist < 0) { + /* Middle dot */ + if (test(GPU_KEYFRAME_SHAPE_INNER_DOT)) { + alpha = max(alpha, 1 - smoothstep(thresholds[2], thresholds[3], radius)); + } + + /* Up and down arrow-like shading. */ + if (test(GPU_KEYFRAME_SHAPE_ARROW_END_MAX | GPU_KEYFRAME_SHAPE_ARROW_END_MIN)) { + float ypos = -1.0; + + /* Up arrow (maximum) */ + if (test(GPU_KEYFRAME_SHAPE_ARROW_END_MAX)) { + ypos = max(ypos, pos.y); + } + /* Down arrow (minimum) */ + if (test(GPU_KEYFRAME_SHAPE_ARROW_END_MIN)) { + ypos = max(ypos, -pos.y); + } + + /* Arrow shape threshold. */ + float minmax_dist = (ypos - radii[3]) - absPos.x * minmax_bias; + float minmax_step = smoothstep(thresholds[0], thresholds[1], minmax_dist * minmax_scale); + + /* Reduced alpha for uncertain extremes. */ + float minmax_alpha = test(GPU_KEYFRAME_SHAPE_ARROW_END_MIXED) ? 0.55 : 0.85; + + alpha = max(alpha, minmax_step * minmax_alpha); + } + + fragColor = mix(finalColor, finalOutlineColor, alpha); + } + /* Outside the outline. */ + else { + fragColor = vec4(finalOutlineColor.rgb, finalOutlineColor.a * alpha); + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_shape_vert.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_shape_vert.glsl new file mode 100644 index 00000000000..18e8b76ba23 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_keyframe_shape_vert.glsl @@ -0,0 +1,99 @@ + +/* Values in GPU_shader.h. */ +#define GPU_KEYFRAME_SHAPE_DIAMOND (1 << 0) +#define GPU_KEYFRAME_SHAPE_CIRCLE (1 << 1) +#define GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL (1 << 2) +#define GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL (1 << 3) +#define GPU_KEYFRAME_SHAPE_INNER_DOT (1 << 4) +#define GPU_KEYFRAME_SHAPE_ARROW_END_MAX (1 << 8) +#define GPU_KEYFRAME_SHAPE_ARROW_END_MIN (1 << 9) +#define GPU_KEYFRAME_SHAPE_ARROW_END_MIXED (1 << 10) +#define GPU_KEYFRAME_SHAPE_SQUARE \ + (GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL | GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL) + +uniform mat4 ModelViewProjectionMatrix; +uniform vec2 ViewportSize = vec2(-1, -1); +uniform float outline_scale = 1.0; + +const float line_falloff = 1.0; +const float circle_scale = sqrt(2.0 / 3.1416); +const float square_scale = sqrt(0.5); +const float diagonal_scale = sqrt(0.5); + +in vec2 pos; +in float size; +in vec4 color; +in vec4 outlineColor; +in int flags; + +flat out vec4 finalColor; +flat out vec4 finalOutlineColor; + +flat out int finalFlags; + +flat out vec4 radii; +flat out vec4 thresholds; + +bool test(int bit) +{ + return (flags & bit) != 0; +} + +vec2 line_thresholds(float width) +{ + return vec2(max(0, width - line_falloff), width); +} + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + + /* Align to pixel grid if the viewport size is known. */ + if (ViewportSize.x > 0) { + vec2 scale = ViewportSize * 0.5; + vec2 px_pos = (gl_Position.xy + 1) * scale; + vec2 adj_pos = round(px_pos - 0.5) + 0.5; + gl_Position.xy = adj_pos / scale - 1; + } + + /* Pass through parameters. */ + finalColor = color; + finalOutlineColor = outlineColor; + finalFlags = flags; + + if (!test(GPU_KEYFRAME_SHAPE_DIAMOND | GPU_KEYFRAME_SHAPE_CIRCLE | + GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL | GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL)) { + finalFlags |= GPU_KEYFRAME_SHAPE_DIAMOND; + } + + /* Size-dependent line thickness. */ + float half_width = (0.06 + (size - 10) * 0.04); + float line_width = half_width + line_falloff; + + /* Outline thresholds. */ + thresholds.xy = line_thresholds(line_width * outline_scale); + + /* Inner dot thresholds. */ + thresholds.zw = line_thresholds(line_width * 1.6); + + /* Extend the primitive size by half line width on either side; odd for symmetry. */ + float ext_radius = round(0.5 * size) + thresholds.x; + + gl_PointSize = ceil(ext_radius + thresholds.y) * 2 + 1; + + /* Diamond radius. */ + radii[0] = ext_radius * diagonal_scale; + + /* Circle radius. */ + radii[1] = ext_radius * circle_scale; + + /* Square radius. */ + radii[2] = round(ext_radius * square_scale); + + /* Min/max cutout offset. */ + radii[3] = -line_falloff; + + /* Convert to PointCoord units. */ + radii /= gl_PointSize; + thresholds /= gl_PointSize; +} diff --git a/source/blender/gpu/tests/gpu_shader_builtin_test.cc b/source/blender/gpu/tests/gpu_shader_builtin_test.cc index f0061a6bf5c..523a7e5b881 100644 --- a/source/blender/gpu/tests/gpu_shader_builtin_test.cc +++ b/source/blender/gpu/tests/gpu_shader_builtin_test.cc @@ -32,7 +32,7 @@ static void test_shader_builtin() test_compile_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA); test_compile_builtin_shader(GPU_SHADER_TEXT, GPU_SHADER_CFG_DEFAULT); - test_compile_builtin_shader(GPU_SHADER_KEYFRAME_DIAMOND, GPU_SHADER_CFG_DEFAULT); + test_compile_builtin_shader(GPU_SHADER_KEYFRAME_SHAPE, GPU_SHADER_CFG_DEFAULT); test_compile_builtin_shader(GPU_SHADER_SIMPLE_LIGHTING, GPU_SHADER_CFG_DEFAULT); test_compile_builtin_shader(GPU_SHADER_2D_UNIFORM_COLOR, GPU_SHADER_CFG_DEFAULT); test_compile_builtin_shader(GPU_SHADER_2D_FLAT_COLOR, GPU_SHADER_CFG_DEFAULT); -- cgit v1.2.3