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:
The pipeline consists of these key steps:
- Style Processing: Convert style specification into layer objects with evaluated properties
- Geometry Processing: Organize geometry into "buckets" for efficient rendering
- Program Selection: Choose the appropriate shader program based on layer type and properties
- Buffer Setup: Prepare vertex and index buffers for rendering
- Uniform Values: Set uniform values based on layer properties
- 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:
Line Styling Properties
Lines can be styled with various properties:
line-width: Controls line thicknessline-color: Defines line colorline-opacity: Controls transparencyline-dasharray: Creates dashed line patternsline-gradient: Applies color gradients along linesline-pattern: Applies image patterns
Line Shader Programs
Line rendering uses different shader programs based on styling:
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:
- Standard Fill: For solid-colored fills
- Fill Pattern: For fills with image patterns
- Fill Outline: For fills with distinct outlines
- Fill Outline Pattern: For outlined fills with patterns
Fill Extrusion Layer Rendering
Fill extrusion layers render 3D features like buildings by extruding 2D polygons.
Key features of fill extrusion rendering:
- Height Extrusion: Converting 2D polygons to 3D by extruding upwards
- Lighting Model: Directional and ambient lighting
- Ambient Occlusion: Creating realistic shadowing in corners and crevices
- Edge Radius: Rounded building edges
- Flood Light: Ground-level lighting effects
- Shadow Mapping: Casting shadows onto the ground
Shader Program Configuration
The rendering system dynamically configures shader programs based on layer properties:
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 linesRENDER_LINE_GRADIENT: Enables gradient rendering for linesRENDER_LINE_PATTERN: Enables pattern rendering for linesELEVATED: Enables terrain elevation integrationLIGHTING_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:
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:
- Directional Lighting: Simulates sunlight with configurable direction and intensity
- Ambient Lighting: Provides base illumination for all surfaces
- Shadow Mapping: Creates realistic shadows from buildings and terrain
- 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:
- Shader Program Reuse: Similar layers share compiled shader programs
- Buffer Management: Geometry is stored in optimized buffer layouts
- Instancing: When possible, instanced rendering is used for similar features
- Dynamic Defines: Only necessary shader features are enabled through defines
- 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 Type | Terrain Handling Approach | Key Properties |
|---|---|---|
| Line | Elevation sampling along the line | line-elevation-reference, line-z-offset |
| Fill | Draping over terrain | fill-extrusion-height, fill-extrusion-base |
| Fill-Extrusion | Extending from terrain | Height adjustment based on terrain elevation |
| Symbol | Placement on terrain surface | Position 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.