间接绘制:让 GPU 决定绘制参数
drawIndirect 与 GPU-driven Rendering
计算着色器写入绘制参数缓冲区,随后渲染 pass 用 drawIndirect 消费,无需 CPU 读取。
先明确本课目标
创建 INDIRECT usage 缓冲区
由 compute 写入参数
在同一提交中执行 drawIndirect
普通 draw 的数量来自 JavaScript;indirect draw 从 GPUBuffer 读取参数,使可见性、粒子数量和 LOD 能留在 GPU 端决定。
GPU 怎样自己决定绘制多少实例?
Indirect Draw 从带 INDIRECT usage 的 Buffer 读取绘制参数。Compute Shader 可以先写入可见数量,Render Pass 随后消费,而 CPU 不必把结果读回。
javascript// Buffer 内连续四个 u32:
// vertexCount, instanceCount, firstVertex, firstInstance
computePass.dispatchWorkgroups(cullGroupCount);
renderPass.drawIndirect(indirectBuffer, 0);- 固定二进制布局 drawIndirect 参数是四个 u32;drawIndexedIndirect 使用五个字段。
- Compute 写数量 剔除、LOD 或压缩阶段可更新 instanceCount。
- 留在 GPU 避免 mapAsync 读回造成 CPU/GPU 同步。
GPU 计算结果直接控制后续绘制规模,这是 GPU-driven rendering 的基本闭环。
OPTIONAL · 按需查阅完整术语表与概念边界遇到陌生术语时再展开,不打断主线实验。
展开⌄
边改边运行
浏览器加载后会激活代码编辑器、独立运行环境与实时输出。
实现按材质分桶的多组间接绘制。
回到原理,解释刚才发生了什么
先用结果建立反馈,再按运行流程、核心原理和知识关系逐层深入。
核心讲解
参数布局
drawIndirect 读取四个 u32:vertexCount、instanceCount、firstVertex、firstInstance;drawIndexedIndirect 还包含 baseVertex。
GPU 驱动的价值
计算阶段可做剔除或压缩可见对象,再直接决定后续 draw,避免 CPU/GPU 往返。
OPTIONAL · 迁移时查阅WebGPU 与 WebGL2 对照主线实验完成后,再用完整映射处理跨平台或跨 API 迁移。
展开⌄
WebGL2 核心 API 没有 GPU 生成参数的间接绘制;WebGPU 能让 Compute 决定后续 draw。
WebGL
绘制数量通常由 CPU 参数决定;扩展可能提供 multi-draw,但不是 Storage→Indirect 的同一模型。
WebGPU
Compute 写入带 INDIRECT usage 的 Buffer,RenderPass 用 drawIndirect 消费。
不要把 WEBGL_multi_draw 当作 drawIndirect;前者仍由 CPU 提供数组参数。