diff --git a/GLMakie/assets/shader/lines.geom b/GLMakie/assets/shader/lines.geom index 8fb1218d621..0162ca8ec5c 100644 --- a/GLMakie/assets/shader/lines.geom +++ b/GLMakie/assets/shader/lines.geom @@ -55,7 +55,8 @@ void emit_vertex(vec3 position, vec2 uv, int index) f_color = g_color[index]; gl_Position = vec4((position.xy / resolution), position.z, 1.0); f_id = g_id[index]; - f_thickness = g_thickness[index]; + // linewidth scaling may shrink the effective linewidth + f_thickness = abs(uv.y) - AA_THICKNESS; EmitVertex(); } @@ -77,7 +78,7 @@ void emit_vertex(vec3 position, vec2 uv, int index, vec4 color) f_color = color; gl_Position = vec4((position.xy / resolution), position.z, 1.0); f_id = g_id[index]; - f_thickness = g_thickness[index]; + f_thickness = abs(uv.y) - AA_THICKNESS; EmitVertex(); } void emit_vertex(vec3 position, vec2 uv, vec4 color) @@ -618,10 +619,6 @@ void draw_solid_line(bool isvalid[4]) vec3 p2 = screen_space(gl_in[2].gl_Position); // end of current segment, start of next segment vec3 p3 = screen_space(gl_in[3].gl_Position); // end of next segment - // linewidth with padding for anti aliasing - float thickness_aa1 = g_thickness[1] + AA_THICKNESS; - float thickness_aa2 = g_thickness[2] + AA_THICKNESS; - // determine the direction of each of the 3 segments (previous, current, next) vec3 v1 = p2 - p1; float segment_length = length(v1.xy); @@ -641,6 +638,14 @@ void draw_solid_line(bool isvalid[4]) vec2 n1 = vec2(-v1.y, v1.x); vec2 n2 = vec2(-v2.y, v2.x); + // determine stretching of AA border due to linewidth change + float temp = (g_thickness[2] - g_thickness[1]) / segment_length; + float edge_scale = sqrt(1 + temp * temp); + + // linewidth with padding for anti aliasing (used for geometry) + float thickness_aa1 = g_thickness[1] + edge_scale * AA_THICKNESS; + float thickness_aa2 = g_thickness[2] + edge_scale * AA_THICKNESS; + // Setup for sharp corners (see above) vec2 miter_a = normalize(n0 + n1); vec2 miter_b = normalize(n1 + n2); @@ -717,6 +722,10 @@ void draw_solid_line(bool isvalid[4]) segment_length += corner_offset; } + // scaling of uv.y due to different linewidths + // the padding for AA_THICKNESS should always have AA_THICKNESS width in uv + thickness_aa1 = g_thickness[1] / edge_scale + AA_THICKNESS; + thickness_aa2 = g_thickness[2] / edge_scale + AA_THICKNESS; // Generate line segment u1 *= px2uv; diff --git a/NEWS.md b/NEWS.md index ffd4988c568..71b1fa867a5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,8 @@ ## master +- Fix broken AA for lines with strongly varying linewidth [#2953](https://github.com/MakieOrg/Makie.jl/pull/2953) + ## v0.19.5 - Add `loop` option for GIF outputs when recording videos with `record` [#2891](https://github.com/MakieOrg/Makie.jl/pull/2891).