WebGL 粒子破碎 | 实现小记

Posted 坏打印机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebGL 粒子破碎 | 实现小记相关的知识,希望对你有一定的参考价值。



    一个月前第一次看到 Edan Kwan 实现这个效果的时候,完全被震撼到了,想着什么时候自己也能做出来。


    于是十月国庆期间学了一下OpenGL,大概了解了计算机图形渲染的流程和着色器用法。最近突然想起来这个心结,于是花了两天,把这个效果模拟出来(除了阴影映射)。




灵感来自 Edan Kwan

模型来自 网络




如何在模型上随机均匀分布粒子?


    第一个想不通的点在于如何把上百万个粒子均匀随机分布在模型表面,后来想了一个思路:


    ①、先取第一个随机值,决定模型上随机一个面;

    ②、再取第二个随机值,决定①中面上随机一个位置。


    但是想想不太对,这样会导致小面上的粒子密度大于大面上的粒子密度。解决办法只能是通过计算每个面的面积来决定 ① 的随机权重。


    没想到在 Three.js 的 example 里面的 js 文件夹里,已经有了解决方案。在js文件夹里有一个 GeometryUtils.js 的文件,提供了在几何体表面随机取点的函数。

    读了一下它的代码,和我想的思路完全一样,直接拿过来用了。


WebGL 粒子破碎 | 实现小记


如何记录、更新粒子的速度和位置信息?


    和用 OpenGL 不同,Three.js 里我记录更新位置和速度,用的是 GPUComputationRenderer.js 这个工具。也是找了很久,才发现 Three.js 自己提供的这样一个工具。


    GPUComputationRenderer.js 使用 WebGLRenderTarget 来记录数据。在我们渲染场景之前,它先渲染一次,更新 WebGLRenderTarget 的纹理信息,而更新的方式,则是我们传进去自定义的片段着色器。


WebGL 粒子破碎 | 实现小记


如何让粒子在被球触碰到后才激活?


    这个就比较简单了,在记录速度的Texture里面,其实是有四个通道,前面三个用来记录三维空间的速度,最后一个通道没有用,可以用来记录是 / 否激活状态。






    粗略算一下,一共码了 JS + GLSL 代码五百多行。


    我做的没有放网上,所以附上 Edan Kwan 这个作品的网址http://edankwan.com/experiments/smashing-mega-scene/,有兴趣的可以用 PC 访问玩一下,很酷炫的一个网页。


    


    最近更推送更得挺勤,对自己肃然起敬。



以上是关于WebGL 粒子破碎 | 实现小记的主要内容,如果未能解决你的问题,请参考以下文章

WebGL实现炫酷地球--数据可视化

WebGL半透明物体的绘制

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

javascript中的高效粒子系统? (WebGL)

将 WebGL 2 中的像素读取为浮点值

WebGL 绘制Line的bug