Fix: Display nodelinks consistently across different UI scales #111270

Merged
Leon Schittek merged 3 commits from lone_noel/blender:nodelink-consistent-scale into main 2023-08-22 19:24:16 +02:00
5 changed files with 37 additions and 38 deletions

View File

@ -1707,7 +1707,7 @@ void node_link_bezier_points_evaluated(const bNodeLink &link,
#define NODELINK_GROUP_SIZE 256
#define LINK_RESOL 24
#define LINK_WIDTH (2.5f * UI_SCALE_FAC)
#define LINK_WIDTH 2.5f
#define ARROW_SIZE (7 * UI_SCALE_FAC)
/* Reroute arrow shape and mute bar. These are expanded here and shrunk in the GLSL code.
@ -1726,14 +1726,12 @@ static struct {
uint colid_id, muted_id, start_color_id, end_color_id;
uint dim_factor_id;
uint thickness_id;
uint dash_factor_id;
uint dash_alpha_id;
uint dash_params_id;
GPUVertBufRaw p0_step, p1_step, p2_step, p3_step;
GPUVertBufRaw colid_step, muted_step, start_color_step, end_color_step;
GPUVertBufRaw dim_factor_step;
GPUVertBufRaw thickness_step;
GPUVertBufRaw dash_factor_step;
GPUVertBufRaw dash_alpha_step;
GPUVertBufRaw dash_params_step;
uint count;
bool enabled;
} g_batch_link;
@ -1753,9 +1751,7 @@ static void nodelink_batch_reset()
GPU_vertbuf_attr_get_raw_data(
g_batch_link.inst_vbo, g_batch_link.thickness_id, &g_batch_link.thickness_step);
GPU_vertbuf_attr_get_raw_data(
g_batch_link.inst_vbo, g_batch_link.dash_factor_id, &g_batch_link.dash_factor_step);
GPU_vertbuf_attr_get_raw_data(
g_batch_link.inst_vbo, g_batch_link.dash_alpha_id, &g_batch_link.dash_alpha_step);
g_batch_link.inst_vbo, g_batch_link.dash_params_id, &g_batch_link.dash_params_step);
GPU_vertbuf_attr_get_raw_data(
g_batch_link.inst_vbo, g_batch_link.start_color_id, &g_batch_link.start_color_step);
GPU_vertbuf_attr_get_raw_data(
@ -1885,10 +1881,8 @@ static void nodelink_batch_init()
&format_inst, "dim_factor", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
g_batch_link.thickness_id = GPU_vertformat_attr_add(
&format_inst, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
g_batch_link.dash_factor_id = GPU_vertformat_attr_add(
&format_inst, "dash_factor", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
g_batch_link.dash_alpha_id = GPU_vertformat_attr_add(
&format_inst, "dash_alpha", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
g_batch_link.dash_params_id = GPU_vertformat_attr_add(
&format_inst, "dash_params", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
g_batch_link.inst_vbo = GPU_vertbuf_create_with_format_ex(&format_inst, GPU_USAGE_STREAM);
/* Alloc max count but only draw the range we need. */
GPU_vertbuf_data_alloc(g_batch_link.inst_vbo, NODELINK_GROUP_SIZE);
@ -1930,7 +1924,7 @@ static void nodelink_batch_draw(const SpaceNode &snode)
UI_GetThemeColor4fv(TH_EDGE_SELECT,
node_link_data.colors[nodelink_get_color_id(TH_EDGE_SELECT)]);
UI_GetThemeColor4fv(TH_REDALERT, node_link_data.colors[nodelink_get_color_id(TH_REDALERT)]);
node_link_data.expandSize = snode.runtime->aspect * LINK_WIDTH;
node_link_data.aspect = snode.runtime->aspect;
node_link_data.arrowSize = ARROW_SIZE;
GPUUniformBuf *ubo = GPU_uniformbuf_create_ex(sizeof(node_link_data), &node_link_data, __func__);
@ -1976,6 +1970,7 @@ struct NodeLinkDrawConfig {
float dim_factor;
float thickness;
float dash_length;
float dash_factor;
float dash_alpha;
};
@ -2008,8 +2003,8 @@ static void nodelink_batch_add_link(const SpaceNode &snode,
muted[0] = draw_config.drawmuted;
*(float *)GPU_vertbuf_raw_step(&g_batch_link.dim_factor_step) = draw_config.dim_factor;
*(float *)GPU_vertbuf_raw_step(&g_batch_link.thickness_step) = draw_config.thickness;
*(float *)GPU_vertbuf_raw_step(&g_batch_link.dash_factor_step) = draw_config.dash_factor;
*(float *)GPU_vertbuf_raw_step(&g_batch_link.dash_alpha_step) = draw_config.dash_alpha;
float3 dash_params(draw_config.dash_length, draw_config.dash_factor, draw_config.dash_alpha);
copy_v3_v3((float *)GPU_vertbuf_raw_step(&g_batch_link.dash_params_step), dash_params);
if (g_batch_link.count == NODELINK_GROUP_SIZE) {
nodelink_batch_draw(snode);
@ -2081,10 +2076,12 @@ static NodeLinkDrawConfig nodelink_get_draw_config(const bContext &C,
const bool field_link = node_link_is_field_link(snode, link);
draw_config.dash_factor = field_link ? 0.75f : 1.0f;
draw_config.dash_length = 10.0f * UI_SCALE_FAC;
const float scale = UI_view2d_scale_get_x(&v2d);
/* Clamp the thickness to make the links more readable when zooming out. */
draw_config.thickness = max_ff(scale, 1.0f) * (field_link ? 0.7f : 1.0f);
draw_config.thickness = LINK_WIDTH * max_ff(UI_SCALE_FAC * scale, 1.0f) *
(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)) &&
(link.fromnode && (link.fromnode->type == NODE_REROUTE)));
@ -2171,9 +2168,10 @@ static void node_draw_link_bezier_ex(const SpaceNode &snode,
node_link_data.doMuted = draw_config.drawmuted;
node_link_data.dim_factor = draw_config.dim_factor;
node_link_data.thickness = draw_config.thickness;
node_link_data.dash_factor = draw_config.dash_factor;
node_link_data.dash_alpha = draw_config.dash_alpha;
node_link_data.expandSize = snode.runtime->aspect * LINK_WIDTH;
node_link_data.dash_params[0] = draw_config.dash_length;
node_link_data.dash_params[1] = draw_config.dash_factor;
node_link_data.dash_params[2] = draw_config.dash_alpha;
node_link_data.aspect = snode.runtime->aspect;
node_link_data.arrowSize = ARROW_SIZE;
GPUBatch *batch = g_batch_link.batch_single;

View File

@ -39,16 +39,16 @@ struct NodeLinkData {
bool1 doMuted;
float dim_factor;
float thickness;
float dash_factor;
float dash_alpha;
float expandSize;
float4 dash_params;
float aspect;
float arrowSize;
float2 _pad;
};
BLI_STATIC_ASSERT_ALIGN(struct NodeLinkData, 16)
struct NodeLinkInstanceData {
float4 colors[6];
float expandSize;
float aspect;
float arrowSize;
float2 _pad;
};

View File

@ -1,6 +1,5 @@
#define DASH_WIDTH 10.0
#define ANTIALIAS 1.0
#define ANTIALIAS 1.5
#define MINIMUM_ALPHA 0.5
void main()
@ -9,15 +8,15 @@ void main()
if ((isMainLine != 0) && (dashFactor < 1.0)) {
float distance_along_line = lineLength * lineU;
float normalized_distance = fract(distance_along_line / DASH_WIDTH);
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 antialias. */
float dash_center = DASH_WIDTH * dashFactor * 0.5;
float dash_center = dashLength * dashFactor * 0.5;
float normalized_distance_triangle =
1.0 - abs((fract((distance_along_line - dash_center) / DASH_WIDTH)) * 2.0 - 1.0);
float t = ANTIALIAS / DASH_WIDTH;
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 unclamped_alpha = 1.0 - slope * (normalized_distance_triangle - dashFactor + t);
@ -26,5 +25,5 @@ void main()
fragColor.a *= alpha;
}
fragColor.a *= smoothstep(lineThickness, lineThickness - 0.6, abs(colorGradient));
fragColor.a *= smoothstep(lineThickness, lineThickness - ANTIALIAS, abs(colorGradient));
}

View File

@ -30,8 +30,7 @@ void main(void)
bool doMuted = node_link_data.doMuted;
float dim_factor = node_link_data.dim_factor;
float thickness = node_link_data.thickness;
float dash_factor = node_link_data.dash_factor;
float dash_alpha = node_link_data.dash_alpha;
vec3 dash_params = node_link_data.dash_params.xyz;
vec4 colShadow = node_link_data.colors[0];
vec4 colStart = node_link_data.colors[1];
@ -63,10 +62,12 @@ void main(void)
}
}
aspect = node_link_data.aspect;
/* Parameters for the dashed line. */
isMainLine = expand.y != 1.0 ? 0 : 1;
dashFactor = dash_factor;
dashAlpha = dash_alpha;
dashLength = dash_params.x;
dashFactor = dash_params.y;
dashAlpha = dash_params.z;
/* Approximate line length, no need for real bezier length calculation. */
lineLength = distance(P0, P3);
/* TODO: Incorrect U, this leads to non-uniform dash distribution. */
@ -107,7 +108,7 @@ void main(void)
finalColor[3] *= dim_factor;
/* Expand into a line */
gl_Position.xy += exp_axis * node_link_data.expandSize * expand_dist;
gl_Position.xy += exp_axis * node_link_data.aspect * expand_dist;
/* If the link is not muted or is not a reroute arrow the points are squashed to the center of
* the line. Magic numbers are defined in drawnode.c */

View File

@ -14,9 +14,11 @@ GPU_SHADER_INTERFACE_INFO(nodelink_iface, "")
.smooth(Type::FLOAT, "lineU")
.flat(Type::FLOAT, "lineLength")
.flat(Type::FLOAT, "lineThickness")
.flat(Type::FLOAT, "dashLength")
.flat(Type::FLOAT, "dashFactor")
.flat(Type::FLOAT, "dashAlpha")
.flat(Type::INT, "isMainLine");
.flat(Type::INT, "isMainLine")
.flat(Type::FLOAT, "aspect");
GPU_SHADER_CREATE_INFO(gpu_shader_2D_nodelink)
.vertex_in(0, Type::VEC2, "uv")
@ -45,8 +47,7 @@ GPU_SHADER_CREATE_INFO(gpu_shader_2D_nodelink_inst)
.vertex_in(10, Type::UVEC2, "domuted")
.vertex_in(11, Type::FLOAT, "dim_factor")
.vertex_in(12, Type::FLOAT, "thickness")
lone_noel marked this conversation as resolved Outdated

I guess this is working around a limitation of the number of vertex inputs? Might be nice to mention that in the commit message.

I guess this is working around a limitation of the number of vertex inputs? Might be nice to mention that in the commit message.

Yeah, exactly. Added that to the commit message!

Yeah, exactly. Added that to the commit message!
.vertex_in(13, Type::FLOAT, "dash_factor")
.vertex_in(14, Type::FLOAT, "dash_alpha")
.vertex_in(13, Type::VEC3, "dash_params")
.vertex_out(nodelink_iface)
.fragment_out(0, Type::VEC4, "fragColor")
.uniform_buf(0, "NodeLinkInstanceData", "node_link_data", Frequency::PASS)