WebGLCustomLayer

自定义着色器图层,用于在地图的 WebGL 上下文中以自定义 GLSL 着色器绘制内容。

当内置的可视化图层(PolylineLayer、PolygonLayer、Heatmap 等)无法表达所需效果时 ——例如粒子系统、流场、自定义后处理——可使用本图层直接接管绘制:传入顶点与片元着色器 源码及顶点数据,图层负责着色器编译、GL 资源管理与逐帧调度。

几何固定的场景,将数据直接写在构造参数中即可,无需提供 onRender, 图层会按 draw 描述自动完成绘制。

几何逐帧变化,或需要在一帧内多次提交绘制的场景,建议不在构造参数中声明数据, 改由 onRender 回调中的绘制上下文(CustomRenderContext)逐步组织。 两种方式等价,也可混用。

顶点使用图层局部坐标,即相对 referCenter 的百度墨卡托米。顶点属性声明 type: 'lnglat' 时,图层会自动完成经纬度到局部坐标的投影;也可调用 projectToLayer([lng, lat]) 自行换算,该方法不要求图层已加入地图。

z 轴朝上,与 x、y 使用同一单位,高度值直接以米为单位给出。

深度测试、混合模式、面剔除等状态请通过 renderState 声明。地图对这些全局 GL 状态 做了缓存以减少冗余调用,若绕过 renderState 直接调用 gl.enable()、gl.blendFunc() 等接口,缓存将与真实状态不一致,可能导致底图的文字、图标、marker 出现难以定位的渲染异常。

以下 uniform 在着色器中声明后由图层逐帧自动赋值,未声明则不产生任何开销:

u_mvpMatrix(mat4)、u_opacity、u_zoom、u_time、u_resolution(vec2)、 u_pixelRatio、u_unitsPerPixel、u_center(vec2)、u_heading、u_tilt

构造函数

  • 创建自定义着色器图层

    参数类型说明
    optionsWebGLCustomLayerOptions配置项,vertexShader 与 fragmentShader 必填
    属性类型说明
    animationboolean是否每帧自动重绘并推进 u_time。不需要动画就别开 —— 地图渲染线程本来会睡
    attributesWebGLCustomLayerAttributes顶点属性
    drawWebGLCustomLayerDraw绘制指令。没给 onRender 时图层按它自动画一次
    fragmentShaderstring片元着色器源码,必填
    indicesArrayLike<number>索引数据,给了就走 drawElements。普通数组按 Uint16Array 处理
    maxZoomnumber最大显示缩放等级
    minZoomnumber最小显示缩放等级
    onDestroyFunction图层销毁时回调
    onErrorFunction着色器编译失败、纹理加载失败时回调
    onReadyFunction着色器编译通过、声明式资源就绪时回调
    onRenderFunction每帧绘制回调。不给则按 draw 描述自动画一次
    opacitynumber透明度,取值范围 0 - 1。着色器里声明 uniform float u_opacity 即可消费
    referCenterPoint图层参考中心点,决定图层局部坐标的原点。强烈建议传 —— 顶点是 float32,绝对墨卡托坐标量级 1e7 会丢精度
    renderStage"building" | "poi"绘制阶段,图层绘制在该阶段之后(即叠在其上)。 不设表示默认落点:覆盖物之后、3D 楼块之前
    renderStateWebGLCustomLayerRenderState渲染状态
    texturesWebGLCustomLayerTextures纹理
    uniformsWebGLCustomLayerUniformsuniform 值
    unsafeGLboolean是否把原生 WebGL 上下文交给回调。开启后 ctx.gl 不再是白名单门面, 图层会在回调前后做完整的状态保存 / 恢复,但视口、framebuffer、pixelStorei 这类状态无法穷举,出现底图渲染异常请先关掉
    vertexShaderstring顶点着色器源码,必填
    verticesWebGLCustomLayerVertices交错顶点缓冲,与 attributes 可同时使用
    visibleboolean是否显示
    zIndexnumber显示层级,小的先画

    返回值 WebGLCustomLayer

    示例代码1

    // 声明式:数据全在构造参数里,不需要 onRender
    const vs = `
    attribute vec2 a_pos;
    uniform mat4 u_mvpMatrix;
    uniform float u_size;
    uniform float u_pixelRatio;
    void main() {
    gl_Position = u_mvpMatrix * vec4(a_pos, 0.0, 1.0);
    gl_PointSize = u_size * u_pixelRatio;
    }`;
    const fs = `
    precision mediump float;
    uniform vec4 u_color;
    uniform float u_opacity;
    void main() {
    gl_FragColor = vec4(u_color.rgb, u_color.a * u_opacity);
    }`;
    const layer = new BMap.WebGLCustomLayer({
    referCenter: new BMap.Point(116.404, 39.915),
    vertexShader: vs,
    fragmentShader: fs,
    attributes: {
    a_pos: {data: [[116.38, 39.9], [116.42, 39.92]], type: 'lnglat'}
    },
    uniforms: {u_color: [1, 0.2, 0.35, 1], u_size: 24},
    draw: {mode: 'POINTS'}
    });
    map.addLayer(layer);

    示例代码2

    // 命令式:构造参数只给着色器,几何每帧在 onRender 里算
    const layer = new BMap.WebGLCustomLayer({
    referCenter: center,
    vertexShader: vs,
    fragmentShader: fs,
    animation: true,
    onRender(ctx) {
    // 半径在屏幕上恒定 80px
    const r = 80 * ctx.getUnitsPerPixel();
    const t = ctx.getTime();
    const pos: number[] = [];
    for (let i = 0; i < 12; i++) {
    const a = t + (i / 12) * Math.PI * 2;
    pos.push(Math.cos(a) * r, Math.sin(a) * r);
    }
    ctx.setAttribute('a_pos', {data: new Float32Array(pos), size: 2});
    ctx.draw({mode: 'POINTS', count: 12});
    }
    });

动画

  • 是否正在逐帧重绘

    返回值 boolean

  • 主动触发地图重绘一帧

    返回值 void

坐标换算

  • 经纬度 → 图层局部坐标(相对 referCenter 的百度墨卡托米)。 不依赖是否已加入地图,可以在建图层之前先把顶点算好

    参数类型说明
    lngLat[number, number]

    返回值 [number, number]

  • 经纬度 → 图层局部坐标(相对 referCenter 的百度墨卡托米)。 不依赖是否已加入地图,可以在建图层之前先把顶点算好

    参数类型说明
    lngLat[number, number][]

    返回值 [number, number][]

  • 图层局部坐标 → 经纬度

    参数类型说明
    xy[number, number]

    返回值 [number, number]

  • 图层局部坐标 → 经纬度

    参数类型说明
    xy[number, number][]

    返回值 [number, number][]

接入与移除

  • 返回所属地图,未加入返回 null

    返回值 Map

数据与样式

  • 换着色器:重新编译、重建 VAO,已有的属性 / uniform / 纹理原样重放

    参数类型说明
    vertexShaderstring
    fragmentShaderstring

    返回值 WebGLCustomLayer

显示属性

  • 返回图层透明度

    返回值 number

  • 返回参考中心点

    返回值 Point

  • 返回绘制阶段

    返回值 "building" | "poi"

  • 返回显隐状态

    返回值 boolean

  • 返回显示层级

    返回值 number

  • 设置图层透明度,着色器里声明 u_opacity 才会生效

    参数类型说明
    opacitynumber

    返回值 void

  • 设置参考中心点,type: 'lnglat' 的属性会按新原点自动重投影

    参数类型说明
    centerPoint

    返回值 void

  • 设置绘制阶段,传 null 恢复默认落点

    参数类型说明
    stage"building" | "poi"

    返回值 void

  • 设置显隐

    参数类型说明
    visibleboolean

    返回值 void

  • 设置显示层级,小的先画

    参数类型说明
    zIndexnumber

    返回值 void

状态查询

  • 返回图层的绘制上下文,与回调入参是同一个对象。 其绘制类方法仅在 onReady / onRender / onDestroy 回调期间有效

    返回值 CustomRenderContext

  • 当前帧的 mvp 矩阵(图层局部坐标 → 裁剪空间)。 返回复用的对象,不要跨帧缓存这个引用

    返回值 Float64Array

  • 着色器与资源的就绪状态

    返回值 "pending" | "ready" | "error"

  • 图层加入地图起算的秒数

    返回值 number