»
(040)粒子动画喷射器尾部
(此页面有背景音乐,请调节音量后点击页面)
(背景音乐是自己使用自库乐队制作的低音音乐:宽广的宇宙)
本页面实现的是3D火箭喷射器的粒子动画。粒子系统中的粒子大小完全相同,但是颜色和位置可以不同。为了使得火箭喷射器的效果更逼真,咱们可以批量修改每一个粒子的颜色来达到喷射器的颜色效果。
下面是已经实现的火箭喷射效果的代码:
(桌面端浏览效果最佳)
// 1、画圆形路径(弧形)
let shape = new THREE.Shape();
shape.moveTo(0, 0); // 移动到圆心
shape.absarc(0, 0, 5, 0, Math.PI, false); // 绘制圆弧,半径为5
shape.absarc(0, 0, 5, Math.PI, Math.PI/2, false); // 相同方向绘制圆弧,以闭合形状
// 2、挤出以及倒角配置
var extrudeSettings = {
steps: 1,//挤出体细分
depth: 376,//挤出体深度
bevelEnabled: true,//是否为倒角
bevelThickness: 2,//倒角厚度
bevelSize: 2,//倒角大小
bevelSegments: 32,//倒角分段层数
curveSegments:100,//曲线细分数
// extrudePath: curvePath//挤出路径
};
var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );//应用挤出几何体
var roketBodyPart = new THREE.Mesh( geometry, redIronMaterial );//将几何体与材质合成多面体Mesh
roketBodyPart.rotation.x = - Math.PI/2;//沿x轴平面旋转90度
scene.add( roketBodyPart );
//以下生成粒子系统Points,用于创建火箭喷射的粒子效果
particleCount = 100000;//粒子数
particles = new THREE.BufferGeometry();//粒子缓存
positions = new Float32Array(particleCount * 3);//粒子位置数组
colors = new Float32Array(particleCount * 3);//粒子颜色数组
// sizes = new Float32Array(particleCount);//粒子大小数组,不支持此属性
// opacities = new Float32Array(particleCount);//粒子透明度数组,不支持此属性
for (let i = 0; i < particleCount; i++) {
let theta = 2*Math.PI*Math.random();//圆角度
let random=Math.random();
positions[i * 3 + 1] = - (1-random) * 62;//Z轴高度
let maxRadius = 14/Math.PI*2*Math.atan(1+positions[i * 3 + 1]/62);//圆最大半径,atan画喷射火焰
let radius = 14*Math.random();//随机半径
if(radius>maxRadius){//超出atan范围,则重新计算
--i;
continue;
}
positions[i * 3 + 0] = radius*Math.sin(theta);//x坐标
positions[i * 3 + 2] = radius*Math.cos(theta);//y坐标
// particleSizes.push(positions[i * 3 + 1]/(-62.0)*0.5)
colors[i*3+0]=radius/14;
colors[i*3+1]=170.0/255;
colors[i*3+2]=1.0;
// sizes[i]=positions[i * 3 + 1]/(-62.0);//不支持此属性
// opacities[i]=0.8*(1-radius/maxRadius);//不支持此属性
}
// 让粒子系统进入稳态
for(let j=0;j<380;j++){
++frameCount;
for (let i = 0; i < particleCount; i++) {
positions[i * 3 + 1] -=5.0;//Z轴高度减少(向下移动)
let maxRadius = 14/Math.PI*2*Math.atan(1+positions[i * 3 + 1]/62);//圆最大半径,atan画喷射火焰形状
let radius =Math.sqrt(positions[i * 3 + 0]*positions[i * 3 + 0] + positions[i * 3 + 2]*positions[i * 3 + 2]);//y坐标
if(radius>maxRadius||positions[i*3+1]<=-61.999){
positions[i * 3 + 1] +=72;//Z轴高度减少(向下移动)
if(frameCount/6%10<1){
positions[i * 3 + 1] = (positions[i*3 + 1]-72)*Math.random()+72;//粒子的位置做一个随机数的聚集
}
radius=7*Math.random();
let theta = 2*Math.PI*Math.random();//圆角度
positions[i * 3 + 0] = radius*Math.sin(theta);//x坐标
positions[i * 3 + 2] = radius*Math.cos(theta);//y坐标
}
colors[i*3+0]=170.0/255*(1.5-radius/maxRadius)
colors[i*3+1]=170.0/255*(1.5-radius/maxRadius)
colors[i*3+2]=(1.5-radius/maxRadius)
}
}
particles.setAttribute('position', new THREE.BufferAttribute(positions, 3));
particles.setAttribute('color', new THREE.BufferAttribute(colors, 3));
// particles.setAttribute('opacity',new THREE.BufferAttribute(opacities, 1));//不支持此属性的设置
// particles.setAttribute('size', new THREE.Float32BufferAttribute(sizes, 1));//不支持此属性的设置
const particleMaterial = new THREE.PointsMaterial({
color: 0xeeeeff,
size: 0.05,
transparent: true,
opacity: 1.0,
sizeAttenuation:true,//近处大、远处小效果
vertexColors:true,//每个顶点的颜色可控
});
particleSystem = new THREE.Points(particles, particleMaterial);//材质只能用粒子材质
scene.add(particleSystem);
制作火箭。首先,我们需要实现圆角的圆柱体,一定要长,不然,不像火箭。
也就是一个圆面通过长距离挤出以及倒角得到一个圆角的圆柱体。
而后,使用atan函数来实现粒子物体中的粒子位置得到控制。用atan函数的原因,是因为,那样更像火箭喷射的火焰长尾。
等速率的粒子移动,当帧数不够的时候,很难在动画上表现出粒子的快速移动。因为,粒子具有相同性。要表现喷射器喷射的效果,就要在动画上制作出断续的急促喷射。页面上就不写了,看HTML源文件吧。
————www.v-signon.com学习者共勉