Three.js中用TSL实现一个炫酷的粒子场景
最近一直在关注学习three.js中webGPU渲染方面的内容,虽然元宇宙这波热度已经过去,但我们学习web 3D的热情没有减弱,当初入门的时候元宇宙的概念还没有在国内兴起,完全是凭兴趣在学习,本着不忘初心的精神,我们要继续学习让自己掌握的技术创造更多的可能性。
我还会继续分享web 3D方面最新的技术,主要也是对自己学习过程的一个记录,此外AI方面的内容也是我后面要分享的重点之一;好了书归正传,下面我介绍这次要分享的一个小案例。
这次也是用TSL来实现这个粒子场景中的大部分效果,TSL是Three Shading Language的缩写,一种中间层的渲染器格式转换成webGPU的WGSL代码或者是webGL的GLSL代码,TSL可以大大的减少我们写shader代码的工作量,同时学习起来也很有趣;入门TSL我强烈推荐Christian Helgeson的这篇TSL入门指引,我也会在文末列出一些入门的参考资料。
创建地面反射效果
这个效果的制作方法,我在之前的这篇《webGPU实现车身速度光线流动特效》做过介绍,不同的是我在地面的边缘做了一些模糊过渡处理,让远处的地平线看起来更自然一些。

floorMaterial.opacityNode = float(1).sub(
smoothstep(0.02, 0.2, distance(uv(), vec2(0.5)))
);
只需一句简单TSL就可以实现地面边缘的过渡效果,是不是很简单。
人物动画
人物的模型是我在blender制作的,导出为fbx格式然后在Adobe Mixamo里导入制作骨骼动画,选一段跳舞的动画导出,Mixamo目前只支持导出fbx格式的动画模型文件,我们可以在blender转换一下导出对web更友好的glb格式,可以选择draco压缩减少模型文件体积大小。

背景环境贴图
为了制作背景环境天空贴图,我先创建了一个球体,然后在球体内面用TSL画渐变色模拟出天空背景效果,这里用到了上中下三种渐变色,具体的颜色可以根据自己的需要来调整。
const colorTop = color(0x0e1c3e);
const colorMiddle = color(0xff7b05);
const colorBottom = color(0x160c2a);
const geometry = new SphereGeometry(60, 32, 32);
const material = new MeshBasicNodeMaterial({
color: new Color(0xff0000),
side: BackSide,
});
const middle = float(0.1);
const blendIntensity = 0.06;
const mixColor = mix(colorBottom, colorTop, smoothstep(0.45, 0.55, uv().y));
const blendMiddle = smoothstep(float(0.5).sub(middle), 0.5, uv().y).mul(
smoothstep(float(0.5).add(middle), 0.5, uv().y).mul(blendIntensity)
);
const finalColopr = mix(mixColor, colorMiddle, blendMiddle);
material.colorNode = finalColopr;
this.mesh = new Mesh(geometry, material);

粒子效果实现
粒子效果我是从wawa sensei的VFX粒子系统获得的灵感,他的代码是基于React Three Fiber的,我用原生+TSL的方式进行了改写,完善一下后面可以分享出来。
参考资料
Three.JS WebGPURenderer by Christian Helgeson