前言
大家好,这里是 CSS 魔法使——alphardex。
以下是最终实现的效果图
撒,哈吉马路由!
准备工作
笔者的three.js 模板:点击右下角的 fork 即可复制一份
世界同步
在我的上一篇博文中,讲到了如何将 HTML 世界和 webgl 的世界同步起来,本文也是同样的思路,先同步好两个世界,再进行特效创作
首先搭建 HTML 和 JS
1 | <div class="relative w-screen h-screen"> |
1 | class ParticleExplode extends Base { |
单位同步
1 | class ParticleExplode extends Base { |
预加载图片
1 | import imagesLoaded from "https://cdn.skypack.dev/imagesloaded@4.1.4"; |
数据同步
创建 DOMMeshObject,用来同步 HTML 和 webgl 世界的数据
这里有一点要注意的是,由于本文创建的是粒子特效,因此不用Mesh
,用的是Points
,它能将Geometry
以点阵的形式表示
1 | class DOMMeshObject { |
创建完点阵后,画面上依旧一片黑,为什么呢?因为我们忘了在顶点着色器中设置点的大小了,在particleExplodeVertexShader
中加入这一行
1 | gl_PointSize=2.; |
可以看到画面上总算有显示了,其实这不是一张平面,而是由成千上万的点组成的“平面”
现在,你可以将你喜欢的图片贴上去了,片元着色器particleExplodeFragmentShader
代码如下
1 | uniform sampler2D uTexture; |
爆炸特效
接下来又到了激动人心的时刻——爆炸特效的实现了!
噪声
爆炸,简而言之就是大量的微粒在一定空间内进行不规则的大幅运动而形成的奇观。说到“不规则”,我们首先就能想到一个词——“噪声”。
噪声有很多种,最常见的有perlin noise
、simplex noise
等,本文用的是基于simplex noise
的curl noise
,在 google 上搜索curl noise glsl
,很容易就能将下面的噪声代码搞到手(谷歌:关键时刻还是得靠劳资)
1 | vec4 permute(vec4 x){return mod(((x*34.)+1.)*x,289.);} |
应用噪声
将噪声函数弄来后,立马就能应用到我们的片元着色器里,思路也很简单粗暴:将位置信息传递给噪声,再给原先的位置加上噪声就 OK 了,由于噪声的值很大,需要慢慢地对值进行调试,这里花的时间相对较多一些
1 | uniform float uTime; |
动起来
将噪声的值调成你预想中的效果后,监听好点击事件,用gsap
来改变爆炸的过程值,这样爆炸效果就实现了
1 | import gsap from "https://cdn.skypack.dev/gsap@3.6.0"; |