Skip to content

Commit

Permalink
Fix line-pattern artifacts under overscaling and underscaling (mapbox…
Browse files Browse the repository at this point in the history
…#9266)

* Fix line pattern when the pattern size is lower than the line width
Visual differences:
1. When the line pattern fits on a line smaller than its own resolution,
we downscale while keeping the aspect ratio at integer zoom level
2. When the line pattern fits on a line larger than its own resolution,
we upscale while keeping the aspect ratio at integer zoom level
3. When the line pattern has different resolution (1x, 2x, 3x...),
the pattern screenspace resolution should remain stable (e.g. the
physical resolution shouldn't impact the size at which the pattern is
rendered but instead increase the quality of the visual while keeping
its logical resolution)

The current behavior does not account for 1. and 3.

Shader differences:
Try to move for more 'mad' instruction instead of 'div':

per-instruction shader count differences:
 before
  6 mad, 12 div, 12 add, 9 mul
 after
  13 mad, 8 div, 6 add, 9 mul

This increases the number of mad instructions (multiply-add) for
fewer cycles and decreases the number of divisions and additions

Issue #15472

* Update test images to account for new behavior

* Fix marching-ants issue
  • Loading branch information
karimnaaji authored and mike-unearth committed Mar 18, 2020
1 parent 2cacd1b commit 40d2392
Show file tree
Hide file tree
Showing 14 changed files with 19 additions and 14 deletions.
29 changes: 15 additions & 14 deletions src/shaders/line_pattern.fragment.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ varying vec2 v_normal;
varying vec2 v_width2;
varying float v_linesofar;
varying float v_gamma_scale;
varying float v_width;

#pragma mapbox: define lowp vec4 pattern_from
#pragma mapbox: define lowp vec4 pattern_to
Expand All @@ -32,12 +33,15 @@ void main() {
float fromScale = u_scale.z;
float toScale = u_scale.w;

vec2 display_size_a = vec2((pattern_br_a.x - pattern_tl_a.x) / pixelRatio, (pattern_br_a.y - pattern_tl_a.y) / pixelRatio);
vec2 display_size_b = vec2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio);
vec2 display_size_a = (pattern_br_a - pattern_tl_a) / pixelRatio;
vec2 display_size_b = (pattern_br_b - pattern_tl_b) / pixelRatio;

vec2 pattern_size_a = vec2(display_size_a.x * fromScale / tileZoomRatio, display_size_a.y);
vec2 pattern_size_b = vec2(display_size_b.x * toScale / tileZoomRatio, display_size_b.y);

float aspect_a = display_size_a.y / v_width;
float aspect_b = display_size_b.y / v_width;

// Calculate the distance of the pixel from the line in pixels.
float dist = length(v_normal) * v_width2.s;

Expand All @@ -47,18 +51,15 @@ void main() {
float blur2 = (blur + 1.0 / u_device_pixel_ratio) * v_gamma_scale;
float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);

float x_a = mod(v_linesofar / pattern_size_a.x, 1.0);
float x_b = mod(v_linesofar / pattern_size_b.x, 1.0);

// v_normal.y is 0 at the midpoint of the line, -1 at the lower edge, 1 at the upper edge
// we clamp the line width outset to be between 0 and half the pattern height plus padding (2.0)
// to ensure we don't sample outside the designated symbol on the sprite sheet.
// 0.5 is added to shift the component to be bounded between 0 and 1 for interpolation of
// the texture coordinate
float y_a = 0.5 + (v_normal.y * clamp(v_width2.s, 0.0, (pattern_size_a.y + 2.0) / 2.0) / pattern_size_a.y);
float y_b = 0.5 + (v_normal.y * clamp(v_width2.s, 0.0, (pattern_size_b.y + 2.0) / 2.0) / pattern_size_b.y);
vec2 pos_a = mix(pattern_tl_a / u_texsize, pattern_br_a / u_texsize, vec2(x_a, y_a));
vec2 pos_b = mix(pattern_tl_b / u_texsize, pattern_br_b / u_texsize, vec2(x_b, y_b));
float x_a = mod(v_linesofar / pattern_size_a.x * aspect_a, 1.0);
float x_b = mod(v_linesofar / pattern_size_b.x * aspect_b, 1.0);

float y = 0.5 * v_normal.y + 0.5;

vec2 texel_size = 1.0 / u_texsize;

vec2 pos_a = mix(pattern_tl_a * texel_size - texel_size, pattern_br_a * texel_size + texel_size, vec2(x_a, y));
vec2 pos_b = mix(pattern_tl_b * texel_size - texel_size, pattern_br_b * texel_size + texel_size, vec2(x_b, y));

vec4 color = mix(texture2D(u_image, pos_a), texture2D(u_image, pos_b), u_fade);

Expand Down
4 changes: 4 additions & 0 deletions src/shaders/line_pattern.vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ varying vec2 v_normal;
varying vec2 v_width2;
varying float v_linesofar;
varying float v_gamma_scale;
varying float v_width;

#pragma mapbox: define lowp float blur
#pragma mapbox: define lowp float opacity
#pragma mapbox: define lowp float offset
#pragma mapbox: define mediump float gapwidth
#pragma mapbox: define mediump float width
#pragma mapbox: define lowp float floorwidth
#pragma mapbox: define lowp vec4 pattern_from
#pragma mapbox: define lowp vec4 pattern_to

Expand All @@ -37,6 +39,7 @@ void main() {
#pragma mapbox: initialize lowp float offset
#pragma mapbox: initialize mediump float gapwidth
#pragma mapbox: initialize mediump float width
#pragma mapbox: initialize lowp float floorwidth
#pragma mapbox: initialize mediump vec4 pattern_from
#pragma mapbox: initialize mediump vec4 pattern_to

Expand Down Expand Up @@ -88,4 +91,5 @@ void main() {

v_linesofar = a_linesofar;
v_width2 = vec2(outset, inset);
v_width = floorwidth;
}
Binary file modified test/integration/render-tests/line-pattern/@2x/expected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/integration/render-tests/line-pattern/literal/expected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/integration/render-tests/line-pattern/opacity/expected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/integration/render-tests/line-pattern/overscaled/expected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/integration/render-tests/line-pattern/pitch/expected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/integration/render-tests/line-pattern/step-curve/expected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 40d2392

Please sign in to comment.