大家好,本文介绍了“GPU实现粒子效果”的基本思想,并推荐了相应的学习资料。

本文学习webgpu-samplers->computeBoids示例,它展示了如何用compute shader实现粒子效果,模拟鸟群的行为。

上一篇博文:

WebGPU学习(九):学习“fractalCube”示例

下一篇博文:

WebGPU学习(十一):学习两个优化:“reuse render command buffer”和“dynamic uniform buffer offset”

最终渲染结果:

为什么不在CPU端实现粒子效果?

虽然在CPU端实现会更灵活和可控,但如果粒子数量很大(如上百万),且与场景有交互,则最好在GPU端实现。

示例的实现思想

首先执行compute pass

代码如下:

  const numParticles = 1500;

  ...

  let t = 0;
return function frame() {
... const commandEncoder = device.createCommandEncoder({});
{
const passEncoder = commandEncoder.beginComputePass();
passEncoder.setPipeline(computePipeline);
passEncoder.setBindGroup(0, particleBindGroups[t % 2]);
passEncoder.dispatch(numParticles);
passEncoder.endPass();
}
... ++t;
}

我们对这个pass进行分析:

particleBindGroups包含两个storage buffer:ParticlesA和ParticlesB

ParticlesA存储了上一帧所有粒子的数据。compute shader首先读取它,然后计算出下一帧所有粒子的数据,最好写到ParticlesB中。这样就打了一个ping-pong操作;

注:storage buffer在shader中可被读或写,而uniform buffer、vertex buffer等在shader中只能被读

dispatch到1500个instance,每个instance执行一次compute shader

compute shader计算每个粒子的数据时,需要遍历其它的所有粒子,计算相互的交互作用。

一共有1500个粒子,共需要计算15001500次。

如果在CPU端执行,只能串行计算,一共需要计算1500
1500次;

如果在GPU端执行,GPU有1500个instance,每个instance并行地计算1500次,因此一共只需要计算1500次,大大提高了效率。

然后执行render pass

代码如下:

  const numParticles = 1500;

  ...

  const renderPipeline = device.createRenderPipeline({
...
vertexState: {
vertexBuffers: [{
// instanced particles buffer
arrayStride: 4 * 4,
stepMode: "instance",
attributes: [{
// instance position
shaderLocation: 0,
offset: 0,
format: "float2"
}, {
// instance velocity
shaderLocation: 1,
offset: 2 * 4,
format: "float2"
}],
}, {
// vertex buffer
arrayStride: 2 * 4,
stepMode: "vertex",
attributes: [{
// vertex positions
shaderLocation: 2,
offset: 0,
format: "float2"
}],
}],
},
...
}); ... const vertexBufferData = new Float32Array([-0.01, -0.02, 0.01, -0.02, 0.00, 0.02]);
const verticesBuffer = device.createBuffer({
size: vertexBufferData.byteLength,
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
});
verticesBuffer.setSubData(0, vertexBufferData); ... return function frame() {
... const commandEncoder = device.createCommandEncoder({});
...
{
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
passEncoder.setPipeline(renderPipeline);
//ParticlesB使用“instance”的stepMode,被设置到第一个vertex buffer中
passEncoder.setVertexBuffer(0, particleBuffers[(t + 1) % 2]);
//vertices buffer(包含3个顶点数据,每个顶点数据包含x坐标和y坐标)使用“vertex”的stepMode,被设置到第二个vertex buffer中
passEncoder.setVertexBuffer(1, verticesBuffer);
//draw一次,绘制1500个实例(使用ParticlesB的数据),其中每个实例有3个顶点(使用vertices buffer的数据)
//注:每个粒子作为一个实例,由包含3个顶点的三角形组成
passEncoder.draw(3, numParticles, 0, 0);
passEncoder.endPass();
}
...
}

推荐学习资料

大家可以参考WebGPU-8,来学习示例的具体的代码。

虽然该文对应的示例代码的版本比较老(如它的示例中是1000个粒子,而不是1500个粒子),但与本文对应的最新版本基本上相同,而且它对示例代码分析得比较详细,所以推荐大家学习。

另外,大家可以通过Get started with GPU Compute on the Web,学习如何使用compute shader计算矩阵运算。

参考资料

WebGPU-8

webgpu-samplers Github Repo

WebGPU学习(十):介绍“GPU实现粒子效果”的更多相关文章

  1. WebGPU学习(九):学习“fractalCube”示例

    大家好,本文学习Chrome->webgpu-samplers->fractalCube示例. 上一篇博文: WebGPU学习(八):学习"texturedCube"示 ...

  2. WebGPU学习(十一):学习两个优化:“reuse render command buffer”和“dynamic uniform buffer offset”

    大家好,本文介绍了"reuse render command buffer"和"dynamic uniform buffer offset"这两个优化,以及Ch ...

  3. three.js粒子效果(分别基于CPU&GPU实现)

    前段时间做了一个基于CPU和GPU对比的粒子效果丢在学习WebGL的群里,技术上没有多作讲解,有同学反馈看不太懂GPU版本,干脆开一篇文章,重点讲解基于GPU开发的版本. 一.概况 废话不多说,先丢上 ...

  4. cocos2d 粒子效果以及Particle Designer粒子工具的学习

    最近在学习cocos2d中的粒子效果吧,下面就把学到的和大家分享下吧! Now!我们先了解下类结构吧 -- CCParticleSystem(所有粒子系统的父类) -- CCParticleSyste ...

  5. iOS开发——UI进阶篇(十八)核心动画小例子,转盘(裁剪图片、自定义按钮、旋转)图片折叠、音量震动条、倒影、粒子效果

    一.转盘(裁剪图片.自定义按钮.旋转) 1.裁剪图片 将一张大图片裁剪为多张 // CGImageCreateWithImageInRect:用来裁剪图片 // image:需要裁剪的图片 // re ...

  6. cocos2d-x 3.1.1 学习笔记[16] Particle 粒子效果

    //plist文件中面有粒子效果的各种參数 //textureFileName相应着使用粒子的图片 auto particle = ParticleSystemQuad::create("s ...

  7. iOS学习笔记-084.粒子效果——路径移动

    https://blog.csdn.net/qiwenmingshiwo/article/details/75806637 粒子效果路径移动一说明1 效果2 步骤分析二代码1 VCViewh2 VCV ...

  8. 强化学习(十五) A3C

    在强化学习(十四) Actor-Critic中,我们讨论了Actor-Critic的算法流程,但是由于普通的Actor-Critic算法难以收敛,需要一些其他的优化.而Asynchronous Adv ...

  9. 对比深度学习十大框架:TensorFlow 并非最好?

    http://www.oschina.net/news/80593/deep-learning-frameworks-a-review-before-finishing-2016 TensorFlow ...

随机推荐

  1. 洛谷1758 BZOJ1566 管道取珠题解

    题目链接 一道人类智慧的dp题 首先我们可以将∑ai^2转化为求取两次,两次一样的方案数 然后用f[i][j][k][l]表示第一个人在第一个串中取到i第二个串中取到j 第二个人在一个串中取到k第二个 ...

  2. F4NNIU 的 Docker 学习资料整理

    F4NNIU 的 Docker 学习资料整理 Docker 介绍 以下来自 Wikipedia Docker是一个开放源代码软件项目,让应用程序部署在软件货柜下的工作可以自动化进行,借此在Linux操 ...

  3. shell爬虫

    #!/bin/bash curl_str='curl -x "http://http-pro.abuyun.com:9010" --proxy-basic --proxy-user ...

  4. 19-1 djanjo中admin的简单用法

    1. 创建管理员账号 python3 manage.py createsuperuser 2. 在admin注册我们的表 在app目录下面的admin.py里面按以下语法注册 admin.site.r ...

  5. Python多版本pip安装库的问题

    引 机器上总是会有Python2.7的版本和Python3.x的版本,今天接触到一台服务器上面有Python2.7和Python3.4,想在Python3.4下安装一个TensorFlow,但不管怎么 ...

  6. hdu 3805 Triangle Conjecture

    Problem - 3805 题意是给出边的长度的,求出边长相等的三角形,输出任意一种答案.边长是1~n的数,每个只能用一次. 其实比较容易可以看出,无论我们怎么操作,只要保持边长总和都是相邻整数就是 ...

  7. Android本地数据存储: ASimpleCache

    一:前言 在上一篇博客Android本地数据存储: Reservoir 博客中,我提到,除了Reservoir库,还可以采用ASimpleCache开源库,来实现本地数据存储.昨天并没有仔细的对比Re ...

  8. Jieba分词包(一)——解析主函数cut

    1. 解析主函数cut Jieba分词包的主函数在jieba文件夹下的__init__.py中,在这个py文件中有个cut的函数,这个就是控制着整个jieba分词包的主函数.    cut函数的定义如 ...

  9. Python--day62--Django安装,配置,web请求流程,views.py总结

    1,安装Django 2,创建Django项目: 3,配置Django项目 1.settinngs.py文件 1.templates文件夹的位置 2.静态文件 1,STATIC_URL   ----- ...

  10. H3C HDLC协议特点