渲染系统
Mapbox GL JS 中的渲染系统负责将地理数据和样式信息转换为屏幕上的视觉表示。它利用 WebGL 提供地图元素的硬件加速渲染,包括填充、线条、符号以及地形和建筑等 3D 功能。本页面解释了核心渲染架构、着色器系统和渲染过程,为理解系统的更具体方面提供了基础。有关协调渲染操作的 Painter 类的详细信息,请参阅 绘图器,有关特定图层类型的信息,请参阅 图层渲染。
渲染架构
Mapbox GL JS 渲染系统遵循管道架构,将地理数据和样式转换为屏幕上的像素。
关键组件
- Painter:协调渲染过程,管理 WebGL 上下文,并处理不同图层类型的绘制。Painter 控制渲染顺序、深度和模板设置,并将绘制调用分派到 GPU。
- Shader Programs:为每种图层类型专门化的 WebGL 着色器程序,具有:
- 用于位置转换和属性处理的顶点着色器
- 用于确定像素颜色、纹理和效果的片段着色器
- Data Buckets:为高效渲染优化的图层特定数据结构,包含:
- 几何数据的顶点数组
- 用于定义图元的索引数组
- 样式属性的程序配置
- Transform State:管理视口、相机位置和用于将地理坐标转换为屏幕空间的投影矩阵。
Shader 系统
Mapbox GL JS 使用 GLSL (OpenGL 着色语言)着色器来渲染具有专门视觉效果的不同图层类型。着色器系统由多个相互连接的组件组成:
Shader 前言
着色器前言包含在顶点和片段着色器的开头,以提供通用功能:
Terrain Prelude (
_prelude_terrain.vertex.glsl):- 处理从 DEM 纹理采样高程
- 计算地形高程和夸张
- 为跟随地形的图层提供顶点位移
Lighting Prelude (
_prelude_lighting.glsl):- 实现环境和方向光照计算
- 处理阴影映射和光照效果
- 控制 3D 对象的材质属性
Fog Prelude (
_prelude_fog.fragment.glsl):- 实现大气效果和距离雾
- 处理基于距离的颜色混合
Shadow Prelude (
_prelude_shadow.fragment.glsl):- 实现阴影映射技术
- 处理阴影采样和过滤
- 控制阴影强度和偏移
GLSL Pragma 指令
着色器系统使用特殊的基于 Pragma 的模板系统来将样式属性注入着色器中:
#pragma mapbox: define highp vec4 color
#pragma mapbox: define lowp float opacity
// 后续在着色器中:
#pragma mapbox: initialize highp vec4 color
#pragma mapbox: initialize lowp float opacity这允许着色器访问样式规范中定义的样式属性,桥接 JavaScript 样式定义和 GLSL 着色器代码之间的差距。
渲染过程
渲染管道通过几个阶段将数据从源处理到屏幕:
图层渲染
让我们以线图层为例来检查如何渲染:
准备阶段:
- 检查图层是否具有不透明度和宽度
- 加载必要的纹理(用于图案或渐变)
- 确定用于地形交互的凸起部分
着色器选择:
- 在常规线或图案程序之间选择
- 为虚线、渐变或边框等功能添加适当的 #define 值
绘制调用执行:
- 设置适当的深度和模板状态
- 上传矩阵、宽度和颜色等 uniforms
- 绑定顶点和索引缓冲区
- 执行 WebGL 绘制调用
Uniform 值
Uniforms 将样式属性和状态传输到着色器。对于线图层,这些包括:
// From line_program.ts
'u_matrix': calculateMatrix(painter, tile, layer, matrix),
'u_pixels_to_tile_units': pixelsToTileUnits,
'u_device_pixel_ratio': pixelRatio,
'u_width_scale': widthScale,
'u_floor_width_scale': floorWidthScale,
'u_units_to_pixels': [
1 / transform.pixelsToGLUnits[0],
1 / transform.pixelsToGLUnits[1]
],
// ... additional uniforms数据结构
为了高效地组织几何数据以进行渲染,Mapbox GL JS 使用专门的数据结构:
Bucket 系统
每种图层类型都有对应的 bucket 类型,用于组织数据以进行渲染:
数组类型
Mapbox GL JS 使用具有特定布局的类型化数组来高效地将数据传输到 WebGL:
这些数组类型使用特定的内存布局来精确匹配 WebGL 顶点属性,最小化数据转换开销。
高级渲染功能
Mapbox GL JS 包括几个高级渲染功能:
地形渲染
地形系统采样高程数据以创建 3D 地形表面,并影响其他图层的渲染方式:
光照系统
3D 光照系统为 3D 元素提供逼真的着色:
光照系统支持用于简单地图的平面光照和用于具有地形和 3D 建筑的更复杂场景的 3D 光照。
渲染模式和效果
Mapbox GL JS 支持各种渲染模式和效果,可以组合以创建多样化的视觉样式:
| 效果 | 描述 | 关键文件 |
|---|---|---|
| Fill | 渲染填充多边形 | fill.vertex.glsl, fill.fragment.glsl |
| Line | 使用各种样式渲染线条 | line.vertex.glsl, line.fragment.glsl |
| Pattern | 纹理化填充和线条 | fill_pattern.vertex.glsl, line_pattern.vertex.glsl |
| Extrusion | 3D 建筑和拉伸多边形 | fill_extrusion.vertex.glsl, fill_extrusion.fragment.glsl |
| Terrain | 基于高程的地形渲染 | _prelude_terrain.vertex.glsl |
| Fog | 大气距离雾 | _prelude_fog.fragment.glsl |
| Shadows | 3D 元素的动态阴影 | _prelude_shadow.fragment.glsl, _prelude_shadow.vertex.glsl |
WebGL 集成
Mapbox GL JS 通过精心设计的抽象层与 WebGL 交互:
这个抽象层提供:
- WebGL 状态缓存以最小化冗余状态更改
- 跨浏览器兼容性处理
- 程序、缓冲区和纹理的资源管理
- 错误处理和调试支持
性能优化
渲染系统采用多种优化来保持高性能:
- Bucket 系统:为高效的 GPU 传输和渲染组织数据
- 着色器预处理:为不同的样式需求生成专门的着色器
- 缓冲区重用:最小化 GPU 内存分配和传输
- 绘制调用批处理:减少 WebGL 状态更改
- WebGL 状态缓存:避免冗余状态更改
- Web Workers:在并行线程中处理瓦片数据
这些优化使 Mapbox GL JS 即使在移动设备上也能以高性能渲染复杂的地图。