Skip to main content
The 3D Terrain and Atmosphere features allow you to create stunning, realistic map visualizations with elevation data and atmospheric effects. These features work together to create immersive 3D map experiences.

Overview

The SDK provides two main components:
  • Terrain - Adds 3D elevation to the map using raster DEM (Digital Elevation Model) data
  • Atmosphere - Creates realistic sky and atmospheric effects around the globe

Basic Setup

1

Import the components

import {
  MapView,
  Camera,
  RasterDemSource,
  Terrain,
  Atmosphere,
} from '@rnmapbox/maps';
2

Add a RasterDemSource

<RasterDemSource
  id="mapbox-dem"
  url="mapbox://mapbox.mapbox-terrain-dem-v1"
  tileSize={514}
  maxZoomLevel={14}
>
  {/* Terrain and Atmosphere go here */}
</RasterDemSource>
3

Add Terrain and Atmosphere

<RasterDemSource id="mapbox-dem" url="mapbox://mapbox.mapbox-terrain-dem-v1">
  <Terrain style={{ exaggeration: 1.5 }} />
  <Atmosphere
    style={{
      color: 'rgb(186, 210, 235)',
      highColor: 'rgb(36, 92, 223)',
      horizonBlend: 0.02,
    }}
  />
</RasterDemSource>

Terrain Component

The Terrain component adds 3D elevation data to your map, creating realistic mountain ranges, valleys, and topographic features.

Basic Terrain

import { MapView, Camera, RasterDemSource, Terrain } from '@rnmapbox/maps';

const TerrainMap = () => {
  return (
    <MapView style={{ flex: 1 }}>
      <Camera
        centerCoordinate={[-114.34411, 32.6141]}
        zoomLevel={13}
        pitch={60}
        heading={80}
      />

      <RasterDemSource
        id="terrain-source"
        url="mapbox://mapbox.mapbox-terrain-dem-v1"
        tileSize={514}
        maxZoomLevel={14}
      >
        <Terrain style={{ exaggeration: 1.5 }} />
      </RasterDemSource>
    </MapView>
  );
};

Terrain Props

PropTypeDescription
sourceIDstringName of the raster DEM source to use for elevation
styleTerrainLayerStylePropsTerrain style properties

Terrain Style Properties

PropertyTypeDefaultDescription
exaggerationnumber | Expression1.0Multiplier for elevation values (1.0 = actual elevation)

Exaggeration Examples

<Terrain style={{ exaggeration: 1.0 }} />
// Actual terrain elevation
Higher exaggeration values make terrain more dramatic but may look unrealistic. Experiment to find the right balance for your use case.

Atmosphere Component

The Atmosphere component creates realistic atmospheric effects, including horizon blending, sky gradients, and star fields.

Basic Atmosphere

import { Atmosphere } from '@rnmapbox/maps';

<Atmosphere
  style={{
    color: 'rgb(186, 210, 235)',
    highColor: 'rgb(36, 92, 223)',
    horizonBlend: 0.02,
    spaceColor: 'rgb(11, 11, 25)',
    starIntensity: 0.6,
  }}
/>

Atmosphere Style Properties

PropertyTypeDefaultDescription
colorstring'rgb(255, 255, 255)'Color of the atmosphere near the horizon
highColorstring'rgb(255, 255, 255)'Color of the atmosphere at high altitudes
horizonBlendnumber0.1Blend factor between horizon and high altitude (0-1)
spaceColorstring'rgb(0, 0, 0)'Color of outer space
starIntensitynumber0.0Intensity of stars (0-1)

Atmosphere Presets

<Atmosphere
  style={{
    color: 'rgb(186, 210, 235)',      // Light blue
    highColor: 'rgb(36, 92, 223)',     // Deeper blue
    horizonBlend: 0.02,
    spaceColor: 'rgb(11, 11, 25)',     // Dark space
    starIntensity: 0.0,                 // No stars
  }}
/>

Complete 3D Terrain Example

import React, { useRef } from 'react';
import { View, Button } from 'react-native';
import {
  MapView,
  Camera,
  RasterDemSource,
  Terrain,
  Atmosphere,
  SkyLayer,
} from '@rnmapbox/maps';

const TerrainExample = () => {
  const cameraRef = useRef<Camera>(null);

  const flyToMountains = () => {
    cameraRef.current?.setCamera({
      centerCoordinate: [-114.34411, 32.6141],
      zoomLevel: 13.5,
      pitch: 85,
      heading: 60,
      animationDuration: 3000,
    });
  };

  return (
    <>
      <MapView
        style={{ flex: 1 }}
        styleURL="mapbox://styles/mapbox-map-design/ckhqrf2tz0dt119ny6azh975y"
      >
        <Camera
          ref={cameraRef}
          centerCoordinate={[-114.34411, 32.6141]}
          zoomLevel={13.1}
          pitch={85}
          heading={80}
        />

        <RasterDemSource
          id="mapbox-dem"
          url="mapbox://mapbox.mapbox-terrain-dem-v1"
          tileSize={514}
          maxZoomLevel={14}
        >
          {/* 3D Terrain */}
          <Terrain style={{ exaggeration: 1.5 }} />

          {/* Atmosphere Effects */}
          <Atmosphere
            style={{
              color: 'rgb(186, 210, 235)',
              highColor: 'rgb(36, 92, 223)',
              horizonBlend: 0.02,
              spaceColor: 'rgb(11, 11, 25)',
              starIntensity: 0.6,
            }}
          />

          {/* Sky Layer */}
          <SkyLayer
            id="sky-layer"
            style={{
              skyType: 'atmosphere',
              skyAtmosphereSun: [0.0, 0.0],
              skyAtmosphereSunIntensity: 15.0,
            }}
          />
        </RasterDemSource>
      </MapView>

      <View style={{ position: 'absolute', top: 20, left: 20 }}>
        <Button title="Fly to Mountains" onPress={flyToMountains} />
      </View>
    </>
  );
};

export default TerrainExample;

SkyLayer Integration

Combine Atmosphere with SkyLayer for enhanced sky effects:
import { SkyLayer, Atmosphere } from '@rnmapbox/maps';

<RasterDemSource id="mapbox-dem" url="mapbox://mapbox.mapbox-terrain-dem-v1">
  <Atmosphere
    style={{
      color: 'rgb(186, 210, 235)',
      highColor: 'rgb(36, 92, 223)',
      horizonBlend: 0.02,
    }}
  />
  
  <SkyLayer
    id="sky"
    style={{
      skyType: 'atmosphere',
      skyAtmosphereSun: [0.0, 0.0],
      skyAtmosphereSunIntensity: 15.0,
    }}
  />
  
  <Terrain style={{ exaggeration: 1.5 }} />
</RasterDemSource>

Camera Settings for 3D Terrain

Optimal camera settings to showcase terrain:
<Camera
  centerCoordinate={[-114.34411, 32.6141]}
  zoomLevel={13}      // Close enough to see detail
  pitch={60}          // Tilt for 3D perspective (0-85 degrees)
  heading={80}        // Rotation angle
/>
Terrain TypeZoomPitchExaggeration
Mountains12-1460-851.5-2.5
Hills11-1345-601.2-1.8
Valleys12-1550-701.3-2.0
Flat areas10-1230-451.0-1.5

Custom DEM Sources

Use your own terrain data:
<RasterDemSource
  id="custom-dem"
  url="https://example.com/terrain/{z}/{x}/{y}.png"
  tileSize={256}
  encoding="terrarium" // or 'mapbox'
>
  <Terrain style={{ exaggeration: 2.0 }} />
</RasterDemSource>

DEM Encoding Types

  • mapbox - Mapbox Terrain-DEM v1 format
  • terrarium - Terrarium format (elevation = (R * 256 + G + B / 256) - 32768)

Performance Considerations

  • Terrain rendering is GPU-intensive; test on target devices
  • Higher maxZoomLevel on DEM sources increases memory usage
  • Lower tileSize values improve performance but reduce quality
  • Disable terrain for low-end devices if needed

Toggling Terrain

import { useState } from 'react';

const ToggleableTerrain = () => {
  const [terrainEnabled, setTerrainEnabled] = useState(true);

  return (
    <>
      <MapView style={{ flex: 1 }}>
        <Camera centerCoordinate={[-114.34411, 32.6141]} zoomLevel={13} pitch={60} />
        
        {terrainEnabled && (
          <RasterDemSource
            id="mapbox-dem"
            url="mapbox://mapbox.mapbox-terrain-dem-v1"
            tileSize={514}
          >
            <Terrain style={{ exaggeration: 1.5 }} />
            <Atmosphere style={{ color: 'rgb(186, 210, 235)' }} />
          </RasterDemSource>
        )}
      </MapView>
      
      <Button
        title={terrainEnabled ? 'Disable Terrain' : 'Enable Terrain'}
        onPress={() => setTerrainEnabled(!terrainEnabled)}
      />
    </>
  );
};

Best Practices

  • Use pitch values of 45-85 degrees to showcase terrain
  • Adjust exaggeration based on terrain type (subtle for plains, dramatic for mountains)
  • Combine with appropriate map styles (satellite works great with terrain)
  • Test atmosphere colors with your map style
  • Consider device performance when enabling terrain
  • Use appropriate zoom levels for the terrain detail level
High terrain exaggeration values (>3.0) may cause visual artifacts or performance issues on some devices.

Style Compatibility

Terrain works best with these Mapbox styles:
import { StyleURL } from '@rnmapbox/maps';

// Recommended styles
styleURL={StyleURL.Satellite}        // Best for terrain
styleURL={StyleURL.SatelliteStreet}  // Good balance
styleURL={StyleURL.Outdoors}         // Topographic feel

Reference

  • Terrain: src/components/Terrain.tsx:1
  • Atmosphere: src/components/Atmosphere.tsx:1
  • RasterDemSource: src/components/RasterDemSource.tsx:1
  • SkyLayer: src/components/SkyLayer.tsx:1

Build docs developers (and LLMs) love