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 ...
随机推荐
- HDU-1024_Max Sum Plus Plus
Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) P ...
- 前端基础☞CSS
css的四种引入方式 1.行内式 行内式是在标记的style属性中设定CSS样式.这种方式没有体现出CSS的优势,不推荐使用. <p style="background-color: ...
- oracle函数 INSTR(C1,C2[,I[,J]])
[功能]在一个字符串中搜索指定的字符,返回发现指定的字符的位置; [说明]多字节符(汉字.全角符等),按1个字符计算 [参数] C1 被搜索的字符串 C2 希望搜索的字符串 I 搜 ...
- oracle函数 UPPER(c1)
[功能]将字符串全部转为大写 [参数]c1,字符表达式 [返回]字符型 [示例] SQL> select upper('AaBbCcDd') upper from dual; UPPER --- ...
- Facebook F8|闲鱼高级技术专家参会分享
笔者代表闲鱼参加了Facebook在4月30日举行的为期二天的F8大会,地点加州.将会议概括和一些收获分享给大家.对国内开发者而言,Facebook的产品设计.社区.VR/AR等有一些借鉴意义:对海外 ...
- [ZJOI2007] 小Q的矩阵游戏 (模板—Dinic)
B. 矩阵游戏 题目描述 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行 ...
- GPU选型
1-基本概念 显存带宽 是指显示芯片与显存之间的数据传输速率,它以字节/秒为单位.显存带宽是决定显卡性能和速度最重要的因素之一. 2-常见GPU性能参数 GPU型号 单卡显存 cuda 计算能 ...
- Android Animation动画详解(二): 组合动画特效
前言 上一篇博客Android Animation动画详解(一): 补间动画 我已经为大家介绍了Android补间动画的四种形式,相信读过该博客的兄弟们一起都了解了.如果你还不了解,那点链接过去研读一 ...
- 5 分钟入门 Google 最强NLP模型:BERT
BERT (Bidirectional Encoder Representations from Transformers) 10月11日,Google AI Language 发布了论文 BERT: ...
- Python--day61--ORM介绍及Django使用ORM创建表
ORM: 使用django的ORM详细步骤:(pymysql操作数据库:) #1,自己动手创建数据库(create database 数据库名字;) #2,在Django项目中(setting.py文 ...