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

Seams and overdraw visible with transparent raster tiles + globe view #11906

Open
rreusser opened this issue May 18, 2022 · 9 comments
Open

Seams and overdraw visible with transparent raster tiles + globe view #11906

rreusser opened this issue May 18, 2022 · 9 comments

Comments

@rreusser
Copy link
Contributor

rreusser commented May 18, 2022

mapbox-gl-js version: current main

browser: Chrome 101.0.4951.64

Steps to Trigger Behavior

  1. Load a tileset with alpha. One like the following set of tiles (to be placed in debug/transparent-white) will do.
  2. View a map with projection: {name: 'globe'}
  3. Zoom and pan

A single 50% opacity white tile:
0

A tileset of the above, through z=4:
transparent-white.zip

debug/testpage.html
  <!DOCTYPE html>
  <html>
  <head>
      <title>Mapbox GL JS debug page</title>
      <meta charset='utf-8'>
      <meta name='viewport' content='width=device-width, initial-scale=1.0, user-scalable=no'>
      <link rel='stylesheet' href='../dist/mapbox-gl.css' />
      <style>
          body { margin: 0; padding: 0; }
          html, body, #map { height: 100%; }
      </style>
  </head>
  <body>
  <div id="map"></div>
  <script src='../dist/mapbox-gl-dev.js'></script>
  <script src='../debug/access_token_generated.js'></script>
  <script>

  var map = window.map = new mapboxgl.Map({
      container: 'map',
      style: 'mapbox://styles/mapbox/satellite-v9',
      hash: true,
      projection: { name: 'globe' }
  });

  map.on('load', function () {
      map.addSource('transparent-white', {
          type: 'raster',
          minzoom: 0,
          maxzoom: 4,
          tileSize: 512,
          tiles: [
              'http://localhost:9966/debug/transparent-white/{z}/{x}/{y}.png'
          ]
      });

      map.addLayer({
          type: 'raster',
          source: 'transparent-white',
          id: 'transparent-white-layer',
      });
  });

  </script>
  </body>
  </html>

Expected Behavior

A tileset with transparency is rendered correctly—or even not at all, but preferably not incorrectly.

Actual Behavior

Screen Shot 2022-05-18 at 11 27 20 AM

There are two problems:

  • seams between tiles are sometimes visible
  • when zooming out, sometimes multiple tiles are overdrawn such that 50% opacity + 50% opacity ~= 75% opacity. This does not resolve when the map idles.

In my testing, I obtain the expected results on 2D maps, even with projections. It's the globe view where this seems to occur. It seems like a stencil test might be able to prevent this sort of overdraw?

@rreusser
Copy link
Contributor Author

rreusser commented May 18, 2022

Although I should note that if I understand things correctly, while the web is fine, maybe it's best not to rely on transparent tilesets in general. If a platform didn't load webp tiles and png tiles were too big to load, then it'd receive jpeg tiles and transparency wouldn't be possible at all.

@rreusser
Copy link
Contributor Author

rreusser commented Jun 8, 2022

Ah, I see this does occur with projections as well. It doesn't overlap tiles of different zoom (resulting in combined contributions), but it does have very slight seams between the tiles. Here, some transparent cloud with the naturalEarth projection:

Screen Shot 2022-06-08 at 11 38 48 AM

@rreusser
Copy link
Contributor Author

rreusser commented Jun 8, 2022

The seams likely stem from the epsilon-overlap in this PR: #11858

@SnailBones
Copy link
Contributor

@rreusser That was my thinking too, but it seems the fix to that issue hasn't been merged yet.

@karimnaaji
Copy link
Contributor

karimnaaji commented Jun 9, 2022

@rreusser That was my thinking too, but it seems the #11871 to that issue hasn't been merged yet.

Yes I wasn't really happy with the result of #11871, so I left it as an experiment. The issue with adding some extra padding in the proposed PR is that it trades it off for other issues such as overlapping artifacts (such as z-fighting or when using transparent tiles an incorrect transparent contribution). For #11858, one other potential fix would be to draw the background color in the space that's filled by the footprint of the globe, that would get rid of these artifacts but might not work great with transparency.

@rreusser
Copy link
Contributor Author

@karimnaaji two tricks I'm wondering about:

  1. How does stencil clipping work? I never wrapped my head around it. We draw low-zoom (or high-zoom?) tiles first and use stencil to ensure they overlap correctly? Almost like a depth buffer? I can't quite work out in my head how that would work with the tile skirt, for example. Would this enable anything to prevent drawing the same transparent tile on top of already-rendered transparent tiles of different zoom levels—which I think is where the issue is coming from, right?
  2. Would polygon offset offer anything? As long as meshes are exactly identical, this would prevent z-fighting. I think the problem though is for tiles of different zoom levels or for differently-meshed tiles meeting, so that I don't think this would offer anything.
@rreusser
Copy link
Contributor Author

Sorry these are half-formed thoughts, but I'm thinking along the lines of this: #11546 Does this relate to the bug or perhaps offer a solution?

@RomanAtBrief
Copy link

Was it fixed ? Any updates when or workarounds. I am still getting this problem with GL JS

@RomanAtBrief
Copy link

Just to add, the same issue is with any raster layer, not only satellite image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
4 participants