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

CARTO: Fix seams between tiles in RasterTileLayer #9286

Merged
merged 3 commits into from
Dec 11, 2024
Merged

Conversation

felixpalmer
Copy link
Collaborator

Background

When using a TileLayer to render tiles, thin seams can appear between the tiles due to antialiasing at the edge of each tile. To work around this, use the same RTT workflow as used in the HeatmapTileLayer, which will render all the tiles into a non-AA texture. This is not a great solution for general layers as it will introduce jagged edges, but in the case of the RasterTileLayer the data is so blocky that it isn't obvious

Change List

  • Add RTT modifiers to RasterTileLayer & RasterLayer
  • Reorganize order of calculations in shader to remove inter-cell precision artifacts
  • Add 'no-overlap' as we have in other layers
  • Improve RTTModifier type

@coveralls
Copy link

Coverage Status

coverage: 91.705% (+0.04%) from 91.661%
when pulling 9351647 on felix/raster-rtt
into d1770db on master.

Copy link
Collaborator

@donmccurdy donmccurdy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to double-check on the diagnosis – prior to the fix, do you know whether seams appear even with solid-colored geometry (no textures)?

I'm surprised that antialiasing alone would create seams in otherwise-aligned geometry, so just want to be sure that mipmapping and/or texture filtering issues (which might have simpler fixes than RTT) can be ruled out before we commit to RTT. I see geometry (particularly from 3D scans, or 3D Tiles) split into tiles regularly and just haven't needed to disable antialiasing for that before.

In any case thanks, and changes look good! Approving regardless of the question above.

I'd be curious to test the raster layer in a standalone test app too, but I understand that might not be trivial quite yet. :)

@felixpalmer
Copy link
Collaborator Author

@donmccurdy I can repro in other layers, e.g. BitmapLayer & PolygonLayer - it is just sometimes hard to notice.

You can use this to try and repro yourself:

import {Deck} from '@deck.gl/core';
import {PolygonLayer} from '@deck.gl/layers';

const deck = new Deck({
  canvas: 'deck-canvas',
  controller: true
});
const initialViewState = {
  longitude: 0,
  latitude: 37.74,
  zoom: 2
};
const west = -50;
const east = 50;
const south = -50;
const north = 50;

const data: {polygon: number[][]}[] = [];
const step = 10;
for (let w = west; w < east; w += step) {
  for (let s = south; s < north; s += step) {
    const e = w + step;
    const n = s + step;
    data.push({
      polygon: [
        [w, s],
        [w, n],
        [e, n],
        [e, s],
        [w, s]
      ]
    });
  }
}

const props = {
  getFillColor: [0, 0, 0],
  stroked: false,
  getLineWidth: 1,
  lineWidthUnits: 'pixels'
} as any;
const world = new PolygonLayer({
  id: 'world',
  data,
  ...props
});

const layerPerTile = data.map(
  (d, i) =>
    new PolygonLayer({
      id: `tile-${i}`,
      data: [d],
      ...props
    })
);

//const layers = [world]; // No seams
const layers = layerPerTile; // Inter-layer seams
deck.setProps({initialViewState, layers});

setInterval(() => {
  console.log('redraw');
  deck.setProps({layers: deck.props.layers.map(l => l.clone())});
}, 1000);
Screen.Recording.2024-12-11.at.11.07.22.mov

If we can find that the root cause is something else and we can avoid RTT, I'm all for it - but after days of debugging I'm out of ideas :) The above demo shows how drawing the layers in separate draw calls creates the issue. I think that what is happening is that the edge pixels end up with an alpha value less than one, and then when a neighboring tile is drawn on top (also with alpha less than one) the resulting alpha is not 1.

E.g. with alpha = 0.5 in both cases we have:

alpha_C = alpha_A + alphaB * (1-alpha_A)
              = 0.5 + 0.5 * (1 - 0.5)
              = 0.75

@felixpalmer felixpalmer merged commit 0a4a25a into master Dec 11, 2024
4 checks passed
@felixpalmer felixpalmer deleted the felix/raster-rtt branch December 11, 2024 10:16
@donmccurdy
Copy link
Collaborator

@felixpalmer thanks for the example! Yes, given that the issue appears with untextured geometry I agree with your diagnosis of AA, and given that RTT sounds like the right solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants