Visual LabINTERACTIVE LEARNING
阶段 4 · 计算基础18 分钟

计算 + 渲染:GPU 粒子双缓冲

Ping-Pong Storage Buffer 与跨 Pass 数据流

计算着色器更新粒子,渲染管线读取更新后的缓冲区,一次提交完成模拟和显示。

LEARNING GOALS

先明确本课目标

1

组合 compute pass 与 render pass

2

实现 ping-pong bind groups

3

让 GPU 数据不经过 CPU 直接进入绘制

MENTAL MODEL · 再建立心智模型

两个缓冲区轮流扮演“上一帧输入”和“这一帧输出”,避免同一数据在计算中产生读写冲突。

MINIMAL EXAMPLE

为什么粒子更新需要两个状态缓冲区?

Ping-Pong 用 A 作为只读输入、B 作为写入输出,下一帧交换角色。这样每个 invocation 都读取同一代状态,避免在同一 Pass 中边读边覆盖。

最小例子javascript
let source = 0;

function frame() {
  const destination = 1 - source;
  computePass.setBindGroup(0, groups[source]);
  computePass.dispatchWorkgroups(groupCount);

  renderPass.setBindGroup(0, renderGroups[destination]);
  source = destination;
}
  1. Compute 读 A 写 B 一次更新使用一致的旧状态计算新状态。
  2. Render 读 B 同一 CommandEncoder 中 Compute Pass 结束后,Render Pass 消费更新结果。
  3. 下一帧交换 不用复制全部粒子,只交换两个资源的逻辑角色。

粒子状态始终在 GPU 内循环,CPU 每帧只更新少量时间参数并提交命令。

本课概念
OPTIONAL · 按需查阅完整术语表与概念边界

遇到陌生术语时再展开,不打断主线实验。

展开⌄
LIVE EXPERIMENT · 先获得反馈

边改边运行

浏览器加载后会激活代码编辑器、独立运行环境与实时输出。

本课挑战

加入鼠标吸引力并让粒子按速度着色。

DEEP DIVE · 实验之后

回到原理,解释刚才发生了什么

先用结果建立反馈,再按运行流程、核心原理和知识关系逐层深入。

CORE IDEA

核心讲解

01

GPU 内部闭环

粒子状态常驻 GPU;CPU 只更新时间和交互参数,避免每帧读回再上传。

02

隐式资源转换

WebGPU 根据 pass 边界和声明的 usage 管理必要同步。你仍需避免同一 pass 中不允许的读写别名。

OPTIONAL · 迁移时查阅WebGPU 与 WebGL2 对照

主线实验完成后,再用完整映射处理跨平台或跨 API 迁移。

展开⌄
API COMPARISON

WebGL 用 Transform Feedback/纹理 Ping-Pong 模拟,WebGPU 用 Compute → Render 直接共享数据。

WebGL

顶点 shader 读取上一帧 Buffer,经 Transform Feedback 写入下一帧,再交换绑定。

WebGPU

Compute Shader 从 A 读向 B 写,RenderPass 直接把 B 当作实例/Storage 输入。

保留 Ping-Pong 思想,但移除 Transform Feedback 对顶点输出顺序和 draw 形状的限制。