Open kkaefer opened 5 years ago
@kkaefer Would this also address the issue raised in https://github.com/mapbox/mapbox-gl-js/issues/8476 ?
Related: #8118
@asheemmamoowala to some extent; since the icons are stretched, they're antialiased, and slightly blurry in the stretch direction, but it certainly looks better than before.
GL_NEAREST
)GL_LINEAR
with my local version)The problem in https://github.com/mapbox/mapbox-gl-js/issues/8476 is exacerbated by the fact that icon-text-fit
treats the 1 pixel padding as part of the image that it stretches when it shouldn't do that.
Our goal is to render icons as crisp and sharp as possible. Since our icons are raster based, the best case is doing a 1:1 blit where we transfer the pixels directly, without any kind of interpolation, from the icon atlas texture. To that extent, we are disabling texture interpolation (by using
GL_NEAREST
) in situations where the map is not in the process of being rotated or zoomed, it's not tilted, and only for icons that are not rotated, transformed, or resized in any way. If all of those conditions are met, our map looks like this:However, when one of these isn't met, we resort to linear interpolation, which makes them look like this:
Note how some icons, like the Metro signs, are a bit blurry. To make this easier to see, here's a GIF that swaps both back and forth:
However, there are a lot of caveats with our current approach:
icon-scale
oricon-rotate
(a user hit this problem), or when the icon layer is tiltedI think we should remove our use of
GL_NEAREST
and always use linear interpolation. To keep icons crips, we could ensure that icons that can be rendered crisply use texture coordinates that are aligned to the texture's pixel grid. This would allow us to mix pixel-grid aligned and scaled icons within the same draw call, as well as "fade" between pixel-grid alignment and linearly interpolated icons when rotating or zooming.I've done a few experiments in a local playground, and I believe the way to go is to adjust the texture coordinate in the vertex shader and shift it by the fractional value that the vertex is offset from an integer screen coordinate. This requires a border of 1 pixel around all of our icons to account for the linear interpolation. We already have a 1 pixel padding in our rendering code.
/cc @ansis