经纬志
首页 / luma.gl / 教程

luma.gl 与 deck.gl 的关系

先看结论

deck.gl 画出的每一个图层,最终都落到 luma.gl 的缓冲区、着色器与绘制调用上。 理解这一层,才能判断什么时候该写图层,什么时候该直接写 luma.gl。

最后验证 2026-11-03 · luma.gl 9.4 · 更新 2026-10-27 · 引用本文

两层的分工

luma.gl 是 GPU 抽象层。它把 WebGL2 与 WebGPU 的差异包起来,提供统一的设备、缓冲区、 纹理、着色器、渲染管线与绘制接口。它不关心数据是什么,也不关心地图。

deck.gl 是地理数据可视化框架。它管理图层、数据访问器、坐标系、拾取、动画过渡与视图控制, 并在内部把每个图层编译成 luma.gl 的模型与着色器。图层作者写的是「数据怎么映射」, luma.gl 负责「怎么画到 GPU 上」。

层次负责典型 API
应用层 地图容器、交互、业务图层组合 Deck、MapboxOverlay
图层层(deck.gl) 数据、访问器、聚合、拾取、过渡 ScatterplotLayer、GeoJsonLayer
渲染层(luma.gl) 设备、缓冲区、着色器、管线、绘制 Device、Buffer、Model
图形接口 WebGL2 / WebGPU 浏览器提供

v9 的包结构

luma.gl 从 v9 起拆成多个包,按需引入,避免把 WebGPU 或着色器工具一起打进包体:

包内容是否必需
@luma.gl/core设备、缓冲区、纹理、着色器、渲染管线、渲染通道必需
@luma.gl/webglWebGL2 适配器 webgl2Adapter用 WebGL 时必需
@luma.gl/webgpuWebGPU 适配器用 WebGPU 时必需
@luma.gl/shadertools着色器模块、着色器组装用 Model 时通常需要
@luma.gl/engineModel、AnimationLoop、Geometry、相机控制用高层封装时必需

v9 不再自动注册适配器,创建设备时要显式传入,例如 adapters: [webgl2Adapter]。这是从 v8 升级时最容易漏掉的一步, 漏掉会得到「No matching device found」。

最小代码:谁在做什么

import { luma } from '@luma.gl/core';
import { webgl2Adapter } from '@luma.gl/webgl';
import { Model, AnimationLoop } from '@luma.gl/engine';

// luma.gl:创建设备与 GPU 资源
const device = await luma.createDevice({
  type: 'webgl',
  adapters: [webgl2Adapter],
  createCanvasContext: { canvas }
});

const buffer = device.createBuffer(new Float32Array([
  -0.5, -0.5, 0,
   0.5, -0.5, 0,
   0.0,  0.5, 0
]));

// luma.gl:把着色器、属性与绘制状态合成一个模型
const model = new Model(device, {
  vs: vertexShaderSource,
  fs: fragmentShaderSource,
  attributes: { positions: buffer },
  bufferLayout: [
    { name: 'positions', stepMode: 'vertex', format: 'float32x3' }
  ],
  vertexCount: 3,
  topology: 'triangle-list'
});

// luma.gl:动画循环里开一个渲染通道,画一次
const loop = new AnimationLoop({
  device,
  onRender: function (props) {
    const pass = props.device.beginRenderPass({ clearColor: [0.05, 0.07, 0.1, 1] });
    model.draw(pass);
    pass.end();
  }
});

loop.start();

这段代码里没有任何地理概念。经纬度在哪里、要画多少个点、颜色怎么映射, 都是应用层的事。deck.gl 做的正是把这些封装成图层参数。

什么时候直接用 luma.gl

  • 渲染方式不是「一层数据一种图层」,例如体渲染、流场、屏幕空间特效。
  • 需要精确控制渲染通道、深度、混合、实例化与多次绘制。
  • 已有自己的数据结构与相机,只需要一层薄的 GPU 封装。
  • 要在同一画布上混合 deck.gl 图层与自定义绘制,共用同一个设备与上下文。

什么时候不需要

只要需求能用现成图层表达,直接用 deck.gl 更省事,拾取、过渡、坐标系都已经处理好。 只是想要一个通用三维场景,three.js 的生态与文档更完整。 luma.gl 的定位是「底层但可控」,不是「更简单的 three.js」。

需求更合适的起点
大规模点、线、面、聚合图层deck.gl
三维地球、地形、3D TilesCesium
自定义材质、非地图场景、模型展示three.js
自定义着色器 + 自有数据管线luma.gl

先确认版本。v8 与 v9 的 API 差异很大:Program 被 RenderPipeline 取代,Geometry 变成纯 CPU 容器, AnimationLoop 必须显式传设备。照着旧教程写,会在第一步就卡住。

引用本文

经纬志(2026)。《luma.gl 与 deck.gl 的关系》。https://www.jingweizhi.com/lumagl/tutorial/luma-and-deck.html(访问日期 2026-11-03)。