Skip to content

Commit

Permalink
[MAPS3D-1467] Fix precision related flickering on far plane (internal…
Browse files Browse the repository at this point in the history
…-1876)

The high resolution of depth buffer is not required for very high zooms (e.g. 19) while the flickering effects are possible on sources with low max zoom. Anyway, when tilting the map to show horizon, a way further far distance is used with no problems so there should be no issues for doing the same in this case.
  • Loading branch information
astojilj authored and mourner committed Sep 26, 2024
1 parent 8abc9f4 commit 67672bc
Show file tree
Hide file tree
Showing 7 changed files with 13 additions and 2 deletions.
8 changes: 7 additions & 1 deletion src/geo/projection/far_z.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,16 @@ export function farthestPixelDistanceOnPlane(tr: Transform, pixelsPerMeter: numb
const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * cameraToSeaLevelDistance / Math.sin(Math.max(Math.PI / 2.0 - tr._pitch - fovAboveCenter, 0.01));

// Calculate z distance of the farthest fragment that should be rendered.
const furthestDistance = Math.sin(tr._pitch) * topHalfSurfaceDistance + cameraToSeaLevelDistance;
let furthestDistance = Math.sin(tr._pitch) * topHalfSurfaceDistance + cameraToSeaLevelDistance;
const horizonDistance = cameraToSeaLevelDistance * (1 / tr._horizonShift);

// Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance`
// Due to precision of sources with low maxZoom, content is prone to flickering on zoom above 18.
// Use larger furthest distance also on pitch before the horizon, especially on higher zoom to limit
// the performance and depth range resolution impact.
if (!tr.elevation || tr.elevation.exaggeration() === 0) {
furthestDistance *= (1.0 + Math.max(tr.zoom - 17, 0));
}
return Math.min(furthestDistance * 1.01, horizonDistance);
}

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/integration/render-tests/model-layer/model-rts/expected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 6 additions & 1 deletion test/unit/geo/projection/far_z.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,14 @@ describe('FarZ', () => {
pixelsPerMeter = mercator.pixelsPerMeter(tr.center.lat, tr.worldSize);
expect(farthestPixelDistanceOnPlane(tr, pixelsPerMeter).toFixed(3)).toBe("151.500");

tr.zoom = 22.0;
tr.zoom = 17.0;
pixelsPerMeter = mercator.pixelsPerMeter(tr.center.lat, tr.worldSize);
expect(farthestPixelDistanceOnPlane(tr, pixelsPerMeter).toFixed(3)).toBe("151.500");

// Expanded furthest distance to prevent flicker on far plane
tr.zoom = 22.0;
pixelsPerMeter = mercator.pixelsPerMeter(tr.center.lat, tr.worldSize);
expect(farthestPixelDistanceOnPlane(tr, pixelsPerMeter).toFixed(3)).toBe("909.000");
});

test('farthestPixelDistanceOnSphere', () => {
Expand Down

0 comments on commit 67672bc

Please sign in to comment.