WebGPU学习(十):介绍“GPU实现粒子效果”
大家好,本文介绍了“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端执行,只能串行计算,一共需要计算15001500次;
如果在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实现粒子效果”的更多相关文章
- WebGPU学习(九):学习“fractalCube”示例
大家好,本文学习Chrome->webgpu-samplers->fractalCube示例. 上一篇博文: WebGPU学习(八):学习"texturedCube"示 ...
- WebGPU学习(十一):学习两个优化:“reuse render command buffer”和“dynamic uniform buffer offset”
大家好,本文介绍了"reuse render command buffer"和"dynamic uniform buffer offset"这两个优化,以及Ch ...
- three.js粒子效果(分别基于CPU&GPU实现)
前段时间做了一个基于CPU和GPU对比的粒子效果丢在学习WebGL的群里,技术上没有多作讲解,有同学反馈看不太懂GPU版本,干脆开一篇文章,重点讲解基于GPU开发的版本. 一.概况 废话不多说,先丢上 ...
- cocos2d 粒子效果以及Particle Designer粒子工具的学习
最近在学习cocos2d中的粒子效果吧,下面就把学到的和大家分享下吧! Now!我们先了解下类结构吧 -- CCParticleSystem(所有粒子系统的父类) -- CCParticleSyste ...
- iOS开发——UI进阶篇(十八)核心动画小例子,转盘(裁剪图片、自定义按钮、旋转)图片折叠、音量震动条、倒影、粒子效果
一.转盘(裁剪图片.自定义按钮.旋转) 1.裁剪图片 将一张大图片裁剪为多张 // CGImageCreateWithImageInRect:用来裁剪图片 // image:需要裁剪的图片 // re ...
- cocos2d-x 3.1.1 学习笔记[16] Particle 粒子效果
//plist文件中面有粒子效果的各种參数 //textureFileName相应着使用粒子的图片 auto particle = ParticleSystemQuad::create("s ...
- iOS学习笔记-084.粒子效果——路径移动
https://blog.csdn.net/qiwenmingshiwo/article/details/75806637 粒子效果路径移动一说明1 效果2 步骤分析二代码1 VCViewh2 VCV ...
- 强化学习(十五) A3C
在强化学习(十四) Actor-Critic中,我们讨论了Actor-Critic的算法流程,但是由于普通的Actor-Critic算法难以收敛,需要一些其他的优化.而Asynchronous Adv ...
- 对比深度学习十大框架:TensorFlow 并非最好?
http://www.oschina.net/news/80593/deep-learning-frameworks-a-review-before-finishing-2016 TensorFlow ...
随机推荐
- iOS图片折叠效果:Layer的contentsRect属性和渐变层
http://www.cocoachina.com/ios/20150722/12622.html 作者:@吖了个峥 授权本站转载. 前言 此次文章,讲述的是Layer的一个属性contentsRec ...
- Effective C++: 05实现
26:尽可能延后变量定义式的出现时间 1:只要你定义了一个变量而其类型带有一个构造函数或析构函数,那么当程序的控制流到达这个变量定义式时,你便得承受构造成本:当这个变量离开其作用域时,你便得承受析构成 ...
- Python基础:15私有化
默认情况下,属性在Python 中都是“public”. 1:双下划线(__) Python 为类元素(属性和方法)的私有性提供初步的形式.由双下划线开始的属性在运行时被“混淆”,所以直接访问是不允许 ...
- vue-router2.0的用法
随着vue越来越火,而vue-router却是一个项目不可或缺的,所以在这里结合实例总结一下router的用法,也是给自己的一个总结. 1.首先第一步当然是安装vue-router依赖,当然也可直接s ...
- Twitter 宣布抛弃 Mesos,全面转向Kubernetes
摘要: 从最早Mesos“代言人”到如今的全面转向“Kubernetes Native”,Twitter的举动再一次佐证了‘Kuberentes已经成为容器编排事实标准’这一断言. 本文作者:张磊 阿 ...
- HZOJ 方程的解
乍一看还以为是道水题,没想到这玩意这么难搞. 看题显然是exgcd,然而exgcd求的是一个解而不是解的个数(考试的时候不记得通解的式子然后挂了). 对于40%的数据,直接枚举计数即可. 对于另为20 ...
- behavior planning——11 create a cost function speed penalty
A key part of getting transitions to happen when we want them to is the design of reasonable cost ...
- vue1——vue引入方法,npm本地安装
博客地址 :https://www.cnblogs.com/sandraryan/ Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架.Vue 只关注视图层, 采用 ...
- OJ大集合、
转载自:传送门 什么是OJ Online Judge系统(简称OJ)是一个在线的判题系统.用户可以在线提交程序源代码,系统对源代码进行编译和执行,并通过预先设计的测试数据来检验程序源代码的正确性. 一 ...
- oracle避免在索引列上使用计算
WHERE子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描. 举例: 低效: SELECT … FROM DEPT WHERE SAL * 12 > 25000; 高效: SE ...