经纬志
首页 / luma.gl / 使用示例

多实例渲染

一个方块被四百个实例复用。顶点属性只上传一次,每个实例读自己的偏移与颜色, 绘制调用仍然只有一次。

luma.gl 9.4 · 更新 2026-10-28
源码与运行效果
运行效果

说明

顶点着色器同时接收顶点属性与实例属性:positions 逐顶点步进, instanceOffsets 与 instanceColors 逐实例步进。 着色器里一次乘法就把单位方块放到实例位置,GPU 对每个实例重复这段计算。

滑块只改 instanceCount。缓冲区按最大数量预分配, 调小只是少画一些实例,不需要重新上传数据。

项目取值说明
顶点数量6两个三角形组成的单位方块
实例数量20 – 400由滑块控制,默认 400
绘制调用1与实例数量无关
顶点步进vertexpositions
实例步进instanceinstanceOffsets、instanceColors
属性格式float32x3三组属性一致

实例属性怎么声明

const model = new Model(device, {
  topology: 'triangle-list',
  vertexCount: 6,
  instanceCount: 400,
  attributes: {
    positions: quadBuffer,
    instanceOffsets: offsetBuffer,
    instanceColors: tintBuffer
  },
  bufferLayout: [
    { name: 'positions', stepMode: 'vertex', format: 'float32x3' },
    { name: 'instanceOffsets', stepMode: 'instance', format: 'float32x3' },
    { name: 'instanceColors', stepMode: 'instance', format: 'float32x3' }
  ],
  vs: vsSource,
  fs: fsSource
});

instanceCount 大于 0 时模型自动按实例化绘制。 stepMode 必须显式写成 instance, 否则这些缓冲区会被当成逐顶点数据,第一个实例之外的位移就读不到了。

着色器里的分工

in vec3 positions;
in vec3 instanceOffsets;
in vec3 instanceColors;
out vec3 vColor;

void main() {
  vColor = instanceColors;
  vec3 p = positions * 0.038 + instanceOffsets;
  gl_Position = vec4(p, 1.0);
}

顶点属性提供形状,实例属性提供摆放与配色。 想再加逐实例的旋转或缩放,加一条 stepMode: 'instance' 的缓冲区即可, 不需要新增绘制调用。

与逐次绘制相比

逐个绘制时,每次调用都要重设属性、走一遍驱动校验;实例化把这些开销摊到一次调用上。 四百个实例的差距不明显,进入几万个实例后通常是数量级的差别。 代价是实例之间只能靠属性区分,无法在两次绘制之间改变管线状态。

GIS 里的对应场景

点要素是最典型的用例:单位圆或图标作为顶点数据,每个点的坐标、颜色、大小作为实例属性。 百万级 POI 之所以能在一帧里画完,靠的就是这条路径。

实例数据要按最大数量预分配。 每帧重建缓冲区会把上传开销拉回逐次绘制的量级。 固定容量、只改绘制数量,才能保住实例化的收益。