Skip to content

Layer Rendering

This document describes how Mapbox GL JS renders different layer types to the screen using WebGL. It covers the rendering pipeline, shader programs, and techniques used for various layer types including lines, fills, and 3D extrusions. For information about the overall rendering architecture, see Core Architecture. For details about the Painter class that coordinates rendering, see Painter.

Rendering Pipeline Overview

The layer rendering process transforms style-defined layers into visual elements on the screen through a series of steps:

SVG
100%

The pipeline consists of these key steps:

  1. Style Processing: Convert style specification into layer objects with evaluated properties
  2. Geometry Processing: Organize geometry into "buckets" for efficient rendering
  3. Program Selection: Choose the appropriate shader program based on layer type and properties
  4. Buffer Setup: Prepare vertex and index buffers for rendering
  5. Uniform Values: Set uniform values based on layer properties
  6. Draw Call: Issue WebGL draw commands to render the layer

Layer Types and Their Rendering

Line Layer Rendering

Line layers (like roads, rivers, and boundaries) are rendered using specifically optimized shader programs and buffer layouts.

Line Geometry Representation

Line features are processed into buffers containing:

  • Vertex positions
  • Line normals (for width)
  • Attributes for advanced styling (dasharray, gradients, etc.)

The LineBucket class handles the processing of line geometry:

SVG
100%

Line Styling Properties

Lines can be styled with various properties:

  • line-width: Controls line thickness
  • line-color: Defines line color
  • line-opacity: Controls transparency
  • line-dasharray: Creates dashed line patterns
  • line-gradient: Applies color gradients along lines
  • line-pattern: Applies image patterns

Line Shader Programs

Line rendering uses different shader programs based on styling:

SVG
100%

The vertex shader positions the line geometry and calculates attributes such as:

  • Line normals for width
  • Texture coordinates for patterns/gradients
  • Terrain elevation adjustments

The fragment shader handles:

  • Color application (solid, gradient, or pattern)
  • Dash patterns
  • Alpha blending
  • Anti-aliasing

Fill Layer Rendering

Fill layers render polygon features like land areas, water bodies, and building footprints.

Fill Shader Programs

Fill rendering uses several shader programs:

  1. Standard Fill: For solid-colored fills
  2. Fill Pattern: For fills with image patterns
  3. Fill Outline: For fills with distinct outlines
  4. Fill Outline Pattern: For outlined fills with patterns

Fill Extrusion Layer Rendering

Fill extrusion layers render 3D features like buildings by extruding 2D polygons.

SVG
100%

Key features of fill extrusion rendering:

  1. Height Extrusion: Converting 2D polygons to 3D by extruding upwards
  2. Lighting Model: Directional and ambient lighting
  3. Ambient Occlusion: Creating realistic shadowing in corners and crevices
  4. Edge Radius: Rounded building edges
  5. Flood Light: Ground-level lighting effects
  6. Shadow Mapping: Casting shadows onto the ground

Shader Program Configuration

The rendering system dynamically configures shader programs based on layer properties:

SVG
100%

Shader Defines for Conditional Compilation

Shader programs use preprocessor directives to enable/disable features based on layer properties:

  • RENDER_LINE_DASH: Enables dash pattern rendering for lines
  • RENDER_LINE_GRADIENT: Enables gradient rendering for lines
  • RENDER_LINE_PATTERN: Enables pattern rendering for lines
  • ELEVATED: Enables terrain elevation integration
  • LIGHTING_3D_MODE: Enables advanced 3D lighting

Uniform Values

Uniform values are calculated based on layer properties and set before rendering:

// Line uniform values example (simplified)
const uniformValues = {
    'u_matrix': calculateMatrix(painter, tile, layer, matrix),
    'u_pixels_to_tile_units': pixelsToTileUnits,
    'u_device_pixel_ratio': pixelRatio,
    'u_width_scale': widthScale,
    'u_dash_image': 0,
    'u_gradient_image': 1,
    'u_emissive_strength': layer.paint.get('line-emissive-strength')
};

Advanced Rendering Techniques

Terrain Integration

Layers can be integrated with terrain elevation:

SVG
100%

The code uses special shader logic to handle elevation:

// Example from line vertex shader
#ifdef ELEVATED
float ele0 = sample_elevation(offset_pos);
float ele1 = max(sample_elevation(offset_pos + extrude), sample_elevation(offset_pos + extrude / 2.0));
float ele2 = max(sample_elevation(offset_pos - extrude), sample_elevation(offset_pos - extrude / 2.0));
float ele_max = max(ele0, 0.5 * (ele1 + ele2));
ele = ele_max - ele0 + ele1 + a_z_offset;

Lighting and Shadows

Mapbox GL JS includes a sophisticated lighting system for 3D elements:

  1. Directional Lighting: Simulates sunlight with configurable direction and intensity
  2. Ambient Lighting: Provides base illumination for all surfaces
  3. Shadow Mapping: Creates realistic shadows from buildings and terrain
  4. Flood Light: Ground-level lighting for buildings

Shadow mapping is implemented using shadow maps and depth comparison:

// Shadow mapping in fragment shader
float shadow_occlusion(highp vec4 light_view_pos0, highp vec4 light_view_pos1, float view_depth, highp float bias) {
    // Sample shadow maps and determine if point is in shadow
    // ...
    return 1.0 - (u_shadow_intensity * occlusion);
}

Performance Considerations

The rendering system employs several optimization strategies:

  1. Shader Program Reuse: Similar layers share compiled shader programs
  2. Buffer Management: Geometry is stored in optimized buffer layouts
  3. Instancing: When possible, instanced rendering is used for similar features
  4. Dynamic Defines: Only necessary shader features are enabled through defines
  5. Z-fighting Prevention: Careful management of depth values to prevent visual artifacts

Layer Type-Specific Rendering

Here's a comprehensive view of how different layer types utilize the rendering pipeline:

Layer-Terrain Interaction

When terrain is enabled, layers need special handling to integrate properly with elevation data:

Layer TypeTerrain Handling ApproachKey Properties
LineElevation sampling along the lineline-elevation-reference, line-z-offset
FillDraping over terrainfill-extrusion-height, fill-extrusion-base
Fill-ExtrusionExtending from terrainHeight adjustment based on terrain elevation
SymbolPlacement on terrain surfacePosition adjustment based on elevation

The interaction between layers and terrain is managed through shader code that samples elevation data and adjusts vertex positions accordingly.

In conclusion, the layer rendering system in Mapbox GL JS is a sophisticated pipeline that transforms style definitions into visual elements using WebGL. The system employs various optimization techniques and rendering approaches tailored to each layer type to achieve both performance and visual quality.