Mapbox GL JS поддерживает рендеринг трёхмерного рельефа за счёт использования DEM (Digital Elevation Model) и встроенного механизма преобразования растровых высотных данных в геометрию WebGL-сцены. 3D terrain в этой системе не является отдельной геометрической моделью — это деформация базового земного слоя с применением высотной карты, синхронизированной с камерой и системой тайлов.
Основой 3D-рельефа выступает источник типа raster-dem. В
экосистеме Mapbox это чаще всего один из тайлсетов, содержащих данные
высот в виде RGB-кодированных значений.
Ключевые характеристики DEM:
Добавление источника выполняется через addSource:
map.addSource('mapbox-dem', {
type: 'raster-dem',
url: 'mapbox://mapbox.terrain-rgb',
tileSize: 512,
maxzoom: 14
});
Параметр tileSize критичен для качества визуализации:
меньшие значения повышают детализацию ценой производительности, большие
— ускоряют отрисовку, но сглаживают рельеф.
После подключения DEM необходимо включить его как источник рельефа
сцены. Это выполняется методом setTerrain, который
связывает карту с высотной моделью.
map.setTerrain({
source: 'mapbox-dem',
exaggeration: 1.5
});
Параметр exaggeration управляет вертикальным
масштабированием:
1.0 — физически корректная высота;> 1.0 — усиление рельефа;< 1.0 — сглаживание.Внутренне Mapbox GL JS трансформирует вершинную сетку тайлов, поднимая каждую точку на высоту, полученную из DEM-слоя.
3D terrain становится визуально корректным только при использовании перспективной камеры. В Mapbox GL JS камера определяется через параметры центра, наклона и вращения.
map.setPitch(60);
map.setBearing(-20);
pitch управляет углом наклона камеры относительно
поверхности;bearing задаёт поворот сцены вокруг вертикальной
оси.При увеличении pitch активируется перспектива, при которой горизонт начинает «уходить вдаль», а рельеф приобретает объём.
Рендеринг 3D terrain опирается на WebGL-буферы и фрагментацию тайлов. Производительность зависит от нескольких факторов:
Для стабильной работы используется ограничение:
map.addSource('mapbox-dem', {
type: 'raster-dem',
url: 'mapbox://mapbox.terrain-rgb',
tileSize: 512,
maxzoom: 12
});
Снижение maxzoom уменьшает количество данных,
загружаемых при приближении, снижая нагрузку на GPU.
После включения terrain все слои карты начинают «обтекать» рельеф. Это достигается за счёт пересчёта координат вершин в зависимости от высоты DEM.
Особенно важно поведение следующих типов слоёв:
fill — деформируется по поверхности;line — повторяет контур рельефа;symbol — сохраняет привязку к географическим
координатам;hillshade — усиливает визуальную читаемость
рельефа.Пример добавления слоя поверх terrain:
map.addLayer({
id: 'terrain-layer',
type: 'fill',
source: 'contours',
paint: {
'fill-color': '#4a7',
'fill-opacity': 0.5
}
});
Для корректного восприятия глубины сцены применяется слой неба
(sky). Он создаёт градиентный фон, реагирующий на угол
камеры.
map.addLayer({
id: 'sky',
type: 'sky',
paint: {
'sky-type': 'atmosphere',
'sky-atmosphere-sun-intensity': 10
}
});
Этот слой синхронизируется с освещением сцены и усиливает ощущение глубины при высоком pitch.
3D terrain визуально усиливается при использовании световых эффектов. Mapbox GL JS моделирует освещение через направление «виртуального солнца».
Параметры освещения влияют на:
В сочетании с terrain это создаёт динамическую картину, зависящую от угла обзора.
Параметр exaggeration может изменяться во время работы
карты, что позволяет анимировать рельеф:
map.setTerrain({ source: 'mapbox-dem', exaggeration: 2.0 });
setTimeout(() => {
map.setTerrain({ source: 'mapbox-dem', exaggeration: 1.0 });
}, 3000);
При изменении значения WebGL пересчитывает матрицы высот без перезагрузки тайлов.
Хотя terrain отвечает за рельеф, векторные extrusions зданий работают поверх него. При одновременном использовании:
Важно учитывать порядок слоёв и корректную настройку
fill-extrusion-height, чтобы избежать визуальных артефактов
на пересечении с рельефом.
3D terrain в Mapbox GL JS имеет архитектурные ограничения:
При недостатке ресурсов происходит деградация качества тайлов, выражающаяся в сглаживании высот.
На уровне WebGL процесс включает:
Vertex shader получает высоту как дополнительную координату Z, формируя трёхмерную поверхность без создания отдельных 3D-моделей.
Полная минимальная конфигурация включает:
map.on('load', () => {
map.addSource('mapbox-dem', {
type: 'raster-dem',
url: 'mapbox://mapbox.terrain-rgb',
tileSize: 512,
maxzoom: 14
});
map.setTerrain({
source: 'mapbox-dem',
exaggeration: 1.3
});
map.addLayer({
id: 'sky',
type: 'sky',
paint: {
'sky-type': 'atmosphere'
}
});
map.setPitch(65);
});
Такая конфигурация активирует связку DEM + terrain + sky, формируя полноценную 3D-сцену с непрерывной поверхностью и перспективной камерой.