diff --git a/src/render/draw_line.js b/src/render/draw_line.js index 9ee180abdb8..271b5984116 100644 --- a/src/render/draw_line.js +++ b/src/render/draw_line.js @@ -75,7 +75,7 @@ function drawLineTile(program, painter, tile, bucket, layer, coord, programConfi imagePosB = painter.imageManager.getPattern(image.to); if (!imagePosA || !imagePosB) return; - gl.uniform2f(program.uniforms.u_pattern_size_a, imagePosA.displaySize[0] * image.fromScale / tileRatio, imagePosB.displaySize[1]); + gl.uniform2f(program.uniforms.u_pattern_size_a, imagePosA.displaySize[0] * image.fromScale / tileRatio, imagePosA.displaySize[1]); gl.uniform2f(program.uniforms.u_pattern_size_b, imagePosB.displaySize[0] * image.toScale / tileRatio, imagePosB.displaySize[1]); const {width, height} = painter.imageManager.getPixelSize(); diff --git a/src/shaders/line_pattern.fragment.glsl b/src/shaders/line_pattern.fragment.glsl index 59aa2495799..eba93c9f620 100644 --- a/src/shaders/line_pattern.fragment.glsl +++ b/src/shaders/line_pattern.fragment.glsl @@ -32,8 +32,14 @@ void main() { float x_a = mod(v_linesofar / u_pattern_size_a.x, 1.0); float x_b = mod(v_linesofar / u_pattern_size_b.x, 1.0); - float y_a = 0.5 + (v_normal.y * v_width2.s / u_pattern_size_a.y); - float y_b = 0.5 + (v_normal.y * v_width2.s / u_pattern_size_b.y); + + // 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, (u_pattern_size_a.y + 2.0) / 2.0) / u_pattern_size_a.y); + float y_b = 0.5 + (v_normal.y * clamp(v_width2.s, 0.0, (u_pattern_size_b.y + 2.0) / 2.0) / u_pattern_size_b.y); vec2 pos_a = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, vec2(x_a, y_a)); vec2 pos_b = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, vec2(x_b, y_b)); diff --git a/test/integration/render-tests/line-pattern/overscaled/expected.png b/test/integration/render-tests/line-pattern/overscaled/expected.png index c7a56c4165a..67df2d2b72b 100644 Binary files a/test/integration/render-tests/line-pattern/overscaled/expected.png and b/test/integration/render-tests/line-pattern/overscaled/expected.png differ diff --git a/test/integration/render-tests/regressions/mapbox-gl-js#5978/expected.png b/test/integration/render-tests/regressions/mapbox-gl-js#5978/expected.png new file mode 100644 index 00000000000..8e5fd522cd2 Binary files /dev/null and b/test/integration/render-tests/regressions/mapbox-gl-js#5978/expected.png differ diff --git a/test/integration/render-tests/regressions/mapbox-gl-js#5978/style.json b/test/integration/render-tests/regressions/mapbox-gl-js#5978/style.json new file mode 100644 index 00000000000..b0add2c5c6d --- /dev/null +++ b/test/integration/render-tests/regressions/mapbox-gl-js#5978/style.json @@ -0,0 +1,64 @@ +{ + "version": 8, + "metadata": { + "test": { + "width": 64, + "height": 64 + } + }, + "sprite": "local://sprites/emerald", + "sources": { + "a": { + "type": "geojson", + "data": { + "type": "LineString", + "coordinates": [ + [ + -180, + 10 + ], + [ + 180, + 10 + ] + ] + } + }, + "b": { + "type": "geojson", + "data": { + "type": "LineString", + "coordinates": [ + [ + -180, + -10 + ], + [ + 180, + -10 + ] + ] + } + } + }, + "layers": [ + { + "id": "a", + "type": "line", + "source": "a", + "paint": { + "line-width": 4, + "line-pattern": "oneway_road" + } + }, + { + "id": "b", + "type": "line", + "source": "b", + "paint": { + "line-width": 30, + "line-pattern": "default_3" + } + } + ] +} diff --git a/test/integration/render-tests/regressions/mapbox-gl-native#9976/expected.png b/test/integration/render-tests/regressions/mapbox-gl-native#9976/expected.png index 6a21a2ed2cb..c2012253817 100644 Binary files a/test/integration/render-tests/regressions/mapbox-gl-native#9976/expected.png and b/test/integration/render-tests/regressions/mapbox-gl-native#9976/expected.png differ