maplibre / maplibre-gl-js

MapLibre GL JS - Interactive vector tile maps in the browser
https://maplibre.org/maplibre-gl-js/docs/
Other
6.29k stars 685 forks source link

3D Terrain significantly decrease performance of the map #4487

Open AEiosApp opened 1 month ago

AEiosApp commented 1 month ago

maplibre-gl-js version: 4.5.0 browser: Chrome, Android WebView with Chrome version 60

Steps to Trigger Behavior

  1. Define terrain source, type of 'raster-dem' in the style (do not add 'terrain' configuration to the style)
  2. Create new map in your app, on map 'load' event - add terrain control with a terrain source defined in the style
  3. Check the map working with terrain disabled - should work fast & smooth
  4. Click on the 'terrain' control button to enable terrain - check the map working with terrain - should work slow
  5. Click again on the 'terrain' control button to disable terrain - check the map again - should work fast & smooth

Link to Demonstration

Hey guys, thanks a lot for the 3D terrain support, it is really great!

However, I'm facing a performance issue when I use it. Please, see the video below:

Is there a chanse to figure out with the performance? Because of this issue, we can't use this great feature in production.

Let me know if you'd like me to provide more information or make more tests.

https://github.com/user-attachments/assets/67df8c6a-6aa0-445d-bee7-b3c2c1f391ad

Style sample

{
  "version": 8,
  "name": "App Raster",
  "sources": {
    "raster-tiles": {
      "type": "raster",
      "tiles": ["https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png"],
      "tileSize": 256
    },
    "terrainSource": {
      "type": "raster-dem",
      "url": "./hillshades/budapest/terrainTiles.json",
      "tileSize": 256
    },
    "hillshadeSource": {
      "type": "raster-dem",
      "url": "./hillshades/budapest/terrainTiles.json",
      "tileSize": 256
    }
  },
  "layers": [
    {
      "id": "simple-tiles",
      "type": "raster",
      "source": "raster-tiles",
      "minzoom": 0,
      "maxzoom": 22
    },
    {
      "id": "hills",
      "type": "hillshade",
      "source": "hillshadeSource",
      "layout": { "visibility": "visible" },
      "paint": { "hillshade-shadow-color": "#473B24" }
    }
  ]
}

Code sample

import { Map, TerrainControl } from 'maplibre-gl'

let map = new Map({
        container: 'mapContainer',
        center: [11.39085, 47.27574],
        style: mapStyle as StyleSpecification,
        zoom: this.$preset.defMap.zoom,
        pitch: this.$preset.defMap.pitch,
        bearing: this.$preset.defMap.bearing,
        attributionControl: false,
        hash: true,
      });

map.on('load', () => {
        map.addControl(
          new TerrainControl({
            source: 'terrainSource',
            exaggeration: 1,
          })
      );
});
HarelM commented 1 month ago

This is a known limitation of the terrain implementation (along other issues). You are welcome to dig into it and open a PR if you find ways to improve the performance.

AEiosApp commented 3 weeks ago

I've made few more tests and localized the issue a bit more.

1. Issue is only on Android browser - WebView with Chrome 60+ Same code works fine:

Don't think it's a lack of memory or CPU of my Android device, I'm using Xiaomi Note 12 Pro 5G with:

2. Issue depends on the map zoom level If my map tiles includes zoom levels 0 to 14: