diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index f64df0e7142..9e6662855cc 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -3934,10 +3934,12 @@ static struct { uint colid_id, muted_id; uint dim_factor_id; uint thickness_id; + uint dash_factor_id; GPUVertBufRaw p0_step, p1_step, p2_step, p3_step; GPUVertBufRaw colid_step, muted_step; GPUVertBufRaw dim_factor_step; GPUVertBufRaw thickness_step; + GPUVertBufRaw dash_factor_step; uint count; bool enabled; } g_batch_link; @@ -3956,6 +3958,8 @@ static void nodelink_batch_reset() g_batch_link.inst_vbo, g_batch_link.dim_factor_id, &g_batch_link.dim_factor_step); 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); g_batch_link.count = 0; } @@ -4077,6 +4081,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.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); @@ -4154,7 +4160,8 @@ static void nodelink_batch_add_link(const SpaceNode *snode, bool drawarrow, bool drawmuted, float dim_factor, - float thickness) + float thickness, + float dash_factor) { /* Only allow these colors. If more is needed, you need to modify the shader accordingly. */ BLI_assert(ELEM(th_col1, TH_WIRE_INNER, TH_WIRE, TH_ACTIVE, TH_EDGE_SELECT, TH_REDALERT)); @@ -4175,6 +4182,7 @@ static void nodelink_batch_add_link(const SpaceNode *snode, muted[0] = drawmuted; *(float *)GPU_vertbuf_raw_step(&g_batch_link.dim_factor_step) = dim_factor; *(float *)GPU_vertbuf_raw_step(&g_batch_link.thickness_step) = thickness; + *(float *)GPU_vertbuf_raw_step(&g_batch_link.dash_factor_step) = dash_factor; if (g_batch_link.count == NODELINK_GROUP_SIZE) { nodelink_batch_draw(snode); @@ -4191,10 +4199,13 @@ void node_draw_link_bezier(const View2D *v2d, { const float dim_factor = node_link_dim_factor(v2d, link); float thickness = 1.5f; + float dash_factor = 1.0f; if (snode->edittree->type == NTREE_GEOMETRY) { if (link->fromsock && link->fromsock->display_shape == SOCK_DISPLAY_SHAPE_DIAMOND) { /* Make field links a bit thinner. */ thickness = 1.0f; + /* Draw field as dashes. */ + dash_factor = 0.75f; } } @@ -4221,7 +4232,8 @@ void node_draw_link_bezier(const View2D *v2d, drawarrow, drawmuted, dim_factor, - thickness); + thickness, + dash_factor); } else { /* Draw single link. */ @@ -4248,6 +4260,7 @@ void node_draw_link_bezier(const View2D *v2d, GPU_batch_uniform_1i(batch, "doMuted", drawmuted); GPU_batch_uniform_1f(batch, "dim_factor", dim_factor); GPU_batch_uniform_1f(batch, "thickness", thickness); + GPU_batch_uniform_1f(batch, "dash_factor", dash_factor); GPU_batch_draw(batch); } } diff --git a/source/blender/gpu/shaders/gpu_shader_2D_nodelink_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_nodelink_frag.glsl index f07bd7f1d6f..55d5d941290 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_nodelink_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_nodelink_frag.glsl @@ -1,11 +1,41 @@ in float colorGradient; in vec4 finalColor; +in float lineU; +flat in float lineLength; +flat in float dashFactor; +flat in int isMainLine; out vec4 fragColor; +#define DASH_WIDTH 20.0 +#define ANTIALIAS 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 / DASH_WIDTH); + + /* 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 normalized_distance_triangle = + 1.0 - abs((fract((distance_along_line - dash_center) / DASH_WIDTH)) * 2.0 - 1.0); + float t = ANTIALIAS / DASH_WIDTH; + float slope = 1.0 / (2.0 * t); + + float alpha = min(1.0, max(0.0, slope * (normalized_distance_triangle - dashFactor + t))); + + if (alpha < 0.0) { + discard; + } + + fragColor.a *= 1.0 - alpha; + } + fragColor.a *= smoothstep(1.0, 0.1, abs(colorGradient)); } diff --git a/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl index 2194d23a4ea..8f46c8eda4b 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl @@ -20,6 +20,7 @@ in ivec4 colid_doarrow; in ivec2 domuted; in float dim_factor; in float thickness; +in float dash_factor; uniform vec4 colors[6]; @@ -43,6 +44,7 @@ uniform bool doArrow; uniform bool doMuted; uniform float dim_factor; uniform float thickness; +uniform float dash_factor; # define colShadow colors[0] # define colStart colors[1] @@ -56,9 +58,21 @@ uniform mat4 ModelViewProjectionMatrix; out float colorGradient; out vec4 finalColor; +out float lineU; +flat out float lineLength; +flat out float dashFactor; +flat out int isMainLine; void main(void) { + /* Parameters for the dashed line. */ + isMainLine = expand.y != 1.0 ? 0 : 1; + dashFactor = dash_factor; + /* Approximate line length, no need for real bezier length calculation. */ + lineLength = distance(P0, P3); + /* TODO: Incorrect U, this leads to non-uniform dash distribution. */ + lineU = uv.x; + float t = uv.x; float t2 = t * t; float t2_3 = 3.0 * t2;