经纬志
首页 / luma.gl / API 文档

CommandEncoder

先看结论

命令录制器:把多个通道、拷贝与查询按顺序写进一条命令流, finish() 得到不可变的命令缓冲。

最后验证 2026-11-03 · luma.gl 9.4 · 更新 2026-10-29 · 引用本文
device.createCommandEncoder(props?) → CommandEncoder

设备还提供一个默认编码器 device.commandEncoder,device.beginRenderPass 等便捷方法用的就是它。

方法

方法返回说明
beginRenderPass(props?)RenderPass在本编码器上开始渲染通道
beginComputePass(props?)ComputePass在本编码器上开始计算通道
copyBufferToBuffer(options)void缓冲区之间的区域拷贝
copyBufferToTexture(options)void缓冲区内容写入纹理
copyTextureToBuffer(options)void纹理内容读入缓冲区
copyTextureToTexture(options)void纹理之间的区域拷贝
resolveQuerySet()void把查询结果解析到缓冲区
finish()CommandBuffer结束录制并锁死编码器
pushDebugGroup(label) / popDebugGroup()void命令流分组标记
insertDebugMarker(label)void单点标记,便于在调试工具里定位

显式录制

const encoder = device.createCommandEncoder({ id: 'frame' });

/* 第一趟:离屏渲染 */
const offscreen = encoder.beginRenderPass({
  framebuffer: fbo,
  clearColor: [0, 0, 0, 1]
});
offscreen.setPipeline(offscreenPipeline);
offscreen.setVertexArray(quadArray);
offscreen.draw({ vertexCount: 6 });
offscreen.end();

/* 第二趟:画到画布 */
const screen = encoder.beginRenderPass({
  clearColor: [0.04, 0.06, 0.09, 1]
});
screen.setPipeline(postPipeline);
screen.setVertexArray(quadArray);
screen.setBindings({ uScene: colorTexture });
screen.draw({ vertexCount: 6 });
screen.end();

const commandBuffer = encoder.finish();
device.submit(commandBuffer);

通道属于创建它的编码器,调用 end() 只是结束通道, 不会单独产生可提交对象。真正的提交点在 finish() 之后的 device.submit。

拷贝命令的位置

拷贝不必包在通道里:它们直接记录到编码器,与通道按记录顺序执行。 需要「先渲染到纹理,再拷到缓冲区回读」时,两件事放在同一个编码器里, 顺序由调用先后保证。

const encoder = device.createCommandEncoder();

const pass = encoder.beginRenderPass({
  framebuffer: fbo,
  clearColor: [0.1, 0.2, 0.3, 1]
});
pass.end();

encoder.copyTextureToBuffer(copyOptions);

device.submit(encoder.finish());

const pixels = await readbackBuffer.readAsync();

跨编码器的命令没有顺序保证。先写的渲染、后写的拷贝如果分属两个编码器, 必须分成两次提交,或在第二次提交前等待第一次完成。

录制完成后不可复用

finish() 会锁死编码器,之后再调用任何记录方法都会失败。 每帧新建一个编码器,不要跨帧缓存。 命令缓冲继承编码器的 id 与 userData,便于调试定位。

WebGL 的执行差异

WebGL 后端没有真正的延迟执行,通道状态与清除在记录时就地生效, 拷贝命令推迟到提交时回放。代码结构可以保持与 WebGPU 相同, 但不要指望在 WebGL 上通过「先记录、后修改资源」来得到快照语义。

计算通道在 WebGL 上不可用。 在 WebGL 后端创建计算通道会抛错。需要同一份代码跑两种后端时, 把计算能力隔离成可选模块,而不是在启动时无条件创建。

引用本文

经纬志(2026)。《CommandEncoder》。https://www.jingweizhi.com/lumagl/api/command-encoder.html(访问日期 2026-11-03)。