Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement cross-fading of vector tiles #934

Closed
mourner opened this issue Jan 14, 2015 · 11 comments
Closed

Implement cross-fading of vector tiles #934

mourner opened this issue Jan 14, 2015 · 11 comments
Assignees

Comments

@mourner
Copy link
Member

mourner commented Jan 14, 2015

Currently the awesome smoothness of vector tile rendering in GL JS is hindered by new tiles popping up instantly, sometimes with an unpleasant effect (e.g. lots of labels suddenly appearing).

What does it take to implement cross-fading of vector tiles? Do we need #193 fist? @ansis

@ljbade
Copy link

ljbade commented Jan 15, 2015

We should do something like Google, they don't fade tiles in, but they must somehow pre-fetch tiles along the boundary of the map, and neighbouring zoom levels.

When you pan or zoom it always has some tile there (usually blurry) while detailed tile loads.

There map is certainly a lot more smooth feeling then ours.

@mourner
Copy link
Member Author

mourner commented Jan 15, 2015

If you look closely, you can see that what Google prefetches are actually raster tiles. We can't do that — we need all the rendering to happen on the client with vectors. We had the notion of "pan tile" earlier to simulate the effect, but it was removed for a reason I can't remember.

I'm still interested in cross-fading tiles, so they don't just pop in instantly, but are faded in.

@mourner
Copy link
Member Author

mourner commented Jan 15, 2015

Here's what I mean: gl-fade

@ljbade
Copy link

ljbade commented Jan 15, 2015

Ah I see. Interesting that Google use a raster tile trick.

@ansis
Copy link
Contributor

ansis commented Mar 2, 2015

Last week I was working on fading labels across multiple tiles (when a new tile loads), and on rotation.

https://github.com/mapbox/mapbox-gl-js/tree/placement-fading

I'm putting it on hold for now because:

  • it's blocked by having layer-by-layer rendering
  • it's a big chunk of code that is mostly separate from actual label placement, so I should wrap that up first

How this currently works:
When labels are placed for a tile it creates a typed array of label positions. Each label position has (id, x, y, placementZoom). The array is sorted by id. This array is transferred to the main thread. In the main thread it then compares these label positions with positions from other tiles and figure out which ones were in one/the other/both. It figures out which labels should be shown and whether they need to be shown instantly or faded in/out. It updates the gl buffers with new the new opacities.

@lucaswoj lucaswoj changed the title Cross-fade vector tiles Implement cross-fading of vector tiles Jul 29, 2016
@johnlaur
Copy link
Contributor

johnlaur commented Nov 5, 2016

We are simulating this crossfade effect during zoom on a very busy line style by bringing the data into the tiles one zoom level lower than we want to display it and ramping the opacity from 0-1 over a zoom range of about 0.25 right before the transition where the higher resolution tile is requested. It's not particularly efficient to have all of that data in the lower zoom tiles and not display it, but it gives a nice idea of how this looks.

Ideally though you really only want to apply such cross-fade effects to new geometries appearing on the map. The ideal effect for vertices which are being disambiguated as the higher resolution data comes in or interpolating themselves between vertices of lower resolution data would be to tween the position when new data becomes available. I don't really know if this is easily possible without adding some metadata to the vertices in the tile, but the effect would be really slick.

@ChrisLoer
Copy link
Contributor

This is somewhat ameliorated with #5150 -- new symbols introduced by loading a new tile now fade in. Symbols removed by dropping an old tile still pop out of existence instantly, but the overall the effect is smoother.

The new CrossTileSymbolIndex and time-based opacity-updating code gives us some of the infrastructure we'd need to handle fade animations for symbols in removed tiles, but we'd also need to add logic to hold onto (and keep rendering) symbol buckets for removed tiles until their fade animations had completed.

@mourner
Copy link
Member Author

mourner commented Mar 15, 2018

With the new labeling logic, I think we're good enough now. Keeping lots of duplicate data for full cross-fades would be a performance hit, so probably not worth exploring.

@mourner mourner closed this as completed Mar 15, 2018
@ChrisLoer
Copy link
Contributor

I don't think it's urgent, but I'm thinking of coming back to this at some point: it turned out to be relatively easy to implement cross-fading in gl-native, and the performance hit of simultaneously rendering both tiles during the cross-fade didn't seem to be terrible. Also, it definitely looks better. /cc @nickidlugash

@mourner mourner reopened this Mar 15, 2018
@mourner
Copy link
Member Author

mourner commented Mar 15, 2018

Oh, I didn't know we already have it in native. Let's consider porting to GL JS then!

@ChrisLoer
Copy link
Contributor

Fixed in #6951. I love being able to close sub-four-digit issues. 😄

pirxpilot pushed a commit to pirxpilot/mapbox-gl-js that referenced this issue Sep 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants