Skip to content

Commit 37c32ec

Browse files
astojiljgithub-actions[bot]
authored andcommitted
Fix for flickering of aliased thin lines by widening lines and
diluting frag colors. GitOrigin-RevId: 2b7f0ea679404f21da4c4c8cc8e8ecde8f1d9a3c
1 parent 3b1142f commit 37c32ec

36 files changed

Lines changed: 67 additions & 18 deletions

File tree

src/shaders/line.fragment.glsl

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ uniform highp vec2 u_trim_fade_range;
1111
uniform highp vec2 u_trim_gradient_mix_range;
1212
uniform lowp vec4 u_trim_color;
1313

14-
in vec2 v_width2;
14+
in vec4 v_width2_dilute;
1515
in vec2 v_normal;
1616
in float v_gamma_scale;
1717
in highp vec3 v_uv;
@@ -75,16 +75,17 @@ void main() {
7575
#pragma mapbox: initialize lowp float emissive_strength
7676

7777
// Calculate the distance of the pixel from the line in pixels.
78-
float dist = length(v_normal) * v_width2.s;
78+
float dist = length(v_normal) * v_width2_dilute.x;
7979

8080
// Calculate the antialiasing fade factor. This is either when fading in
81-
// the line in case of an offset line (v_width2.t) or when fading out
82-
// (v_width2.s)
81+
// the line in case of an offset line (v_width2_dilute.y) or when fading out
82+
// (v_width2_dilute.x)
8383
#ifdef VARIABLE_LINE_WIDTH
8484
blur = mix(blur, 0.0, stub_side);
8585
#endif
86+
float diluted_opacity = opacity * v_width2_dilute.z;
8687
float blur2 = (u_width_scale * blur + 1.0 / u_device_pixel_ratio) * v_gamma_scale;
87-
float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);
88+
float alpha = clamp(min(dist - (v_width2_dilute.y - blur2), v_width2_dilute.x - dist) / blur2, 0.0, 1.0);
8889
#ifdef VARIABLE_LINE_WIDTH
8990
alpha = mix(alpha, 1.0, stub_side);
9091
#endif
@@ -141,7 +142,7 @@ void main() {
141142
#ifdef RENDER_LINE_BORDER
142143
#ifndef VARIABLE_LINE_WIDTH
143144
float edgeBlur = ((border_width * u_width_scale) + 1.0 / u_device_pixel_ratio);
144-
float alpha2 = clamp(min(dist - (v_width2.t - edgeBlur), v_width2.s - dist) / edgeBlur, 0.0, 1.0);
145+
float alpha2 = clamp(min(dist - (v_width2_dilute.y - edgeBlur), v_width2_dilute.x - dist) / edgeBlur, 0.0, 1.0);
145146
if (alpha2 < 1.) {
146147
float smoothAlpha = smoothstep(0.6, 1.0, alpha2);
147148
if (border_color.a == 0.0) {
@@ -156,6 +157,7 @@ void main() {
156157
} else {
157158
out_color = mix(border_color * trim_alpha, out_color, smoothAlpha);
158159
}
160+
out_color *= v_width2_dilute.w;
159161
}
160162
#endif
161163
#endif
@@ -176,7 +178,7 @@ void main() {
176178
out_color = fog_dither(fog_apply_premultiplied(out_color, v_fog_pos));
177179
#endif
178180

179-
out_color *= (alpha * opacity);
181+
out_color *= (alpha * diluted_opacity);
180182

181183
#ifdef INDICATOR_CUTOUT
182184
out_color = applyCutout(out_color, v_z_offset);

src/shaders/line.vertex.glsl

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ float sample_elevation(vec2 apos) {
6060
#endif
6161

6262
out vec2 v_normal;
63-
out vec2 v_width2;
63+
out vec4 v_width2_dilute; // xy fow width, z for dilute of whole line w for dilute of border
6464
out float v_gamma_scale;
6565
out highp vec3 v_uv;
6666
#ifdef ELEVATED_ROADS
@@ -230,6 +230,8 @@ void main() {
230230
// moved them into the shader for clarity and simplicity.
231231
gapwidth = gapwidth / 2.0;
232232
float halfwidth;
233+
float dilute_scale = 1.0;
234+
float dilute_border_scale = 1.0;
233235
#ifdef VARIABLE_LINE_WIDTH
234236
float left_width = a_z_offset_width.y;
235237
float right_width = a_z_offset_width.z;
@@ -283,7 +285,7 @@ void main() {
283285
vec2 projected_extrude_xy = projected_extrude.xy;
284286
#ifdef ELEVATED_ROADS
285287
v_road_z_offset = a_z_offset;
286-
gl_Position = u_matrix * vec4(pos + offset2 * u_pixels_to_tile_units, a_z_offset, 1.0) + projected_extrude;
288+
gl_Position = u_matrix * vec4(pos + offset2 * u_pixels_to_tile_units, a_z_offset, 1.0);
287289
#else
288290
#ifdef ELEVATED
289291
vec2 offsetTile = offset2 * u_pixels_to_tile_units;
@@ -321,10 +323,47 @@ void main() {
321323
gl_Position.z -= (gl_Position.w * zbias);
322324
gl_Position = mix(gl_Position, AWAY, hidden);
323325
#else // ELEVATED
324-
gl_Position = mix(u_matrix * vec4(pos + offset2 * u_pixels_to_tile_units, 0.0, 1.0) + projected_extrude, AWAY, hidden);
326+
gl_Position = u_matrix * vec4(pos + offset2 * u_pixels_to_tile_units, 0.0, 1.0);
325327
#endif // ELEVATED
326328
#endif // ELEVATED_ROADS
327329

330+
#ifndef ELEVATED
331+
#ifndef VARIABLE_LINE_WIDTH
332+
#ifndef RENDER_TO_TEXTURE
333+
// Scale up sub-pixel extrusions of inner line width to ensure minimum half-pixel visibility
334+
float base_w = gl_Position.w;
335+
vec2 screen_width = abs(projected_extrude.xy / base_w * u_units_to_pixels);
336+
float max_extrude_component = max(screen_width.x, screen_width.y);
337+
if (base_w > 0.0 && max_extrude_component > 0.0001) {
338+
float min_pixel = 1.05; // u_units_to_pixels is [2 / width, 2 / height], not using half pixel for halfwidth here
339+
if (max_extrude_component < min_pixel) {
340+
vec2 abs_pos = abs(gl_Position.xy);
341+
float is_out = max(abs_pos.x, abs_pos.y) / base_w;
342+
// smoothly disable dilute for a very long lines outside viewport (2.5 -> 4.5)
343+
// bump width here and reduce opacity in fragment shader by dilute_scale factor
344+
dilute_scale = mix(max_extrude_component / min_pixel, 1.0, smoothstep(2.5, 4.5, is_out));
345+
projected_extrude /= dilute_scale;
346+
}
347+
else
348+
{
349+
#ifdef RENDER_LINE_BORDER
350+
// if line is wide enough, reduce opacity of thin borders only - no change of border width
351+
float border_ratio = (border_width * u_width_scale + ANTIALIASING) / outset;
352+
screen_width *= border_ratio;
353+
float max_border_component = max(screen_width.x, screen_width.y);
354+
dilute_border_scale = min(1.0, max_border_component / min_pixel);
355+
#endif
356+
}
357+
}
358+
#endif
359+
#endif
360+
#ifdef ELEVATED_ROADS
361+
gl_Position = gl_Position + projected_extrude;
362+
#else
363+
gl_Position = mix(gl_Position + projected_extrude, AWAY, hidden);
364+
#endif
365+
#endif
366+
328367
#ifdef ELEVATED_ROADS
329368
#ifdef RENDER_SHADOWS
330369
vec3 shd_pos = vec3(pos + (offset2 + dist) * u_pixels_to_tile_units, a_z_offset);
@@ -371,7 +410,7 @@ void main() {
371410
v_tex = vec2(a_linesofar * scale / (floorwidth * u_floor_width_scale), (-normal.y * height + dash.x + 0.5) / u_texsize.y);
372411
#endif
373412

374-
v_width2 = vec2(outset, inset);
413+
v_width2_dilute = vec4(outset, inset, dilute_scale, dilute_border_scale);
375414

376415
#ifdef FOG
377416
v_fog_pos = fog_position(pos);
12.4 KB
Loading

test/integration/render-tests/3d-intersections/guard-rail-color-feature-dependent/style.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"metadata": {
44
"test": {
55
"mapMode": "static",
6-
"allowed": 0.00026,
6+
"allowed": 0.0003,
77
"spriteFormat": "raster"
88
}
99
},

test/integration/render-tests/debug/overdraw/style.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"version": 8,
33
"metadata": {
44
"test": {
5-
"showOverdrawInspector": true
5+
"showOverdrawInspector": true,
6+
"allowed": 0.0003
67
}
78
},
89
"center": [
Loading
1.99 KB
Loading
2.97 KB
Loading
4.21 KB
Loading
4.94 KB
Loading

0 commit comments

Comments
 (0)