WIP: Node Editor: Improve readability of dashed node links #114716

Draft
Leon Schittek wants to merge 3 commits from lone_noel/blender:nodelink-dash-readability into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 37 additions and 13 deletions

View File

@ -2137,7 +2137,7 @@ static NodeLinkDrawConfig nodelink_get_draw_config(const bContext &C,
const float scale = UI_view2d_scale_get_x(&v2d);
/* Clamp the thickness to make the links more readable when zooming out. */
draw_config.thickness = LINK_WIDTH * max_ff(UI_SCALE_FAC * scale, 1.0f) *
draw_config.thickness = LINK_WIDTH * max_ff(UI_SCALE_FAC * scale, 1.25f) *
(field_link ? 0.7f : 1.0f);
draw_config.highlighted = link.flag & NODE_LINK_TEMP_HIGHLIGHT;
draw_config.drawarrow = ((link.tonode && (link.tonode->type == NODE_REROUTE)) &&

View File

@ -5,28 +5,50 @@
#define ANTIALIAS 1.5
#define MINIMUM_ALPHA 0.5
float dash_mask(float distance_along_line, float dash_length, float dash_factor)
{
float normalized_distance = fract(distance_along_line / dash_length);
/* Checking if `normalized_distance <= dashFactor` is already enough for a basic
* dash, however we want to handle a nice antialias. */
float normalized_distance_triangle = abs(normalized_distance * 2.0 - 1.0);
float t = aspect * ANTIALIAS / dash_length;
float slope = 1.0 / (2.0 * t);
float unclamped_alpha = 1.0 - slope * (normalized_distance_triangle - dash_factor + t);
return max(0.0, min(unclamped_alpha, 1.0));
}
void main()
{
fragColor = finalColor;
if ((isMainLine != 0) && (dashFactor < 1.0)) {
float distance_along_line = lineLength * lineU;
float normalized_distance = fract(distance_along_line / dashLength);
/* Checking if `normalized_distance <= dashFactor` is already enough for a basic
* dash, however we want to handle a nice anti-alias. */
float current_scale_level = floor(dashLevel);
float next_scale_level = ceil(dashLevel);
/* Smoothly blend between two levels of dash sizes. The interval was chosen by feel. */
float mix_factor = smoothstep(0.6, 0.9, fract(dashLevel));
float dash_center = dashLength * dashFactor * 0.5;
float normalized_distance_triangle =
1.0 - abs((fract((distance_along_line - dash_center) / dashLength)) * 2.0 - 1.0);
float t = aspect * ANTIALIAS / dashLength;
float slope = 1.0 / (2.0 * t);
float current_dash_length = dashLength * pow(2.0, current_scale_level);
float unclamped_alpha = 1.0 - slope * (normalized_distance_triangle - dashFactor + t);
float alpha = max(dashAlpha, min(unclamped_alpha, 1.0));
/* Widen the gap to approach the width of the next level.
* This assumes the dashFactor is at least 0.5. */
float current_dash_factor = 1.0 - ((1.0 - dashFactor) * (1.0 + mix_factor));
float current_level_dash_mask = dash_mask(
distance_along_line, current_dash_length, current_dash_factor);
fragColor.a *= alpha;
float next_dash_length = current_dash_length * 2.0;
float next_level_dash_mask = dash_mask(distance_along_line, next_dash_length, dashFactor);
float dash_alpha = max(dashAlpha, current_level_dash_mask + mix_factor * next_level_dash_mask);
fragColor.a *= dash_alpha;
}
fragColor.a *= smoothstep(lineThickness, lineThickness - ANTIALIAS, abs(colorGradient));
fragColor.a = min(fragColor.a,
smoothstep(lineThickness, lineThickness - ANTIALIAS, abs(colorGradient)));
}

View File

@ -108,6 +108,7 @@ void main(void)
float expand_dist = line_thickness * (uv.y * 2.0 - 1.0);
colorGradient = expand_dist;
lineThickness = line_thickness;
dashLevel = max(0.5, log(node_link_data.aspect) / log(2.0));
finalColor[3] *= dim_factor;

View File

@ -17,6 +17,7 @@ GPU_SHADER_INTERFACE_INFO(nodelink_iface, "")
.flat(Type::FLOAT, "dashLength")
.flat(Type::FLOAT, "dashFactor")
.flat(Type::FLOAT, "dashAlpha")
.flat(Type::FLOAT, "dashLevel")
.flat(Type::INT, "isMainLine")
.flat(Type::FLOAT, "aspect");