Three.js制作物体粒子爆炸特效,Shader实现
·
PBomb
首先,遍历构成飞机模型的物体信息,得到由每个物体顶点信息组成的points对象组成的group组
console.log(this.fighterGroup, '飞机模型如下图');
this.createPoints(this.fighterGroup); // 飞机模型
createPoints(object3d) {
if (!this.fighterPointsGroup) {
this.fighterPointsGroup = this.transformPoints(object3d);
this.scene.add(this.fighterPointsGroup); // 由每个物体顶点信息组成的points对象的group
}
}
transformPoints(object3d) {
const texture = new THREE.TextureLoader().load("./assets/particles/1.png"); // 创建纹理图像
const group = new THREE.Group();
function createPoints(object3d, newObject3d) {
if (object3d.children.length > 0) {
object3d.children.forEach((child) => {
if (child.isMesh) {
const color = new THREE.Color( // 随机生成颜色
Math.random(),
Math.random(),
Math.random()
);
const material = new THREE.ShaderMaterial({
uniforms: {
uColor: { value: color },
uTexture: { value: texture },
uTime: {
value: 0,
},
},
vertexShader: vertexShader, // 顶点着色器
fragmentShader: fragmentShader, // 片元着色器
blending: THREE.AdditiveBlending,
transparent: true,
depthTest: false,
});
const points = new THREE.Points(child.geometry, material);
points.position.copy(child.position);
points.rotation.copy(child.rotation);
points.scale.copy(child.scale);
newObject3d.add(points);
createPoints(child, points);
}
});
}
}
createPoints(object3d, group);
return group;
}
操作用于传递到每个物体的着色器材质ShaderMaterial中的顶点着色器配置信息,遍历物体顶点组,得到每个每个物体的顶点信息对象points,设置所有物体所有顶点的xyz移动范围为-10到10,将坐标信息设置到每个物体缓冲区对象中,由顶点着色器接收
this.fighterPointsGroup.traverse((child) => {
if (child.isPoints) {
let randomPositionArray = new Float32Array(
child.geometry.attributes.position.count * 3
);
for (let i = 0; i < child.geometry.attributes.position.count; i++) { // 每个物体顶点数量
randomPositionArray[i * 3 + 0] = (Math.random() * 2 - 1) * 10; // -10~10
randomPositionArray[i * 3 + 1] = (Math.random() * 2 - 1) * 10;
randomPositionArray[i * 3 + 2] = (Math.random() * 2 - 1) * 10;
}
child.geometry.setAttribute(
"aPosition",
new THREE.BufferAttribute(randomPositionArray, 3)
);
// 设置执行时间
gsap.to(child.material.uniforms.uTime, {
value: 10,
duration: 10,
});
}
});
顶点着色
attribute vec3 aPosition; // 最终位置(三维向量xyz)
uniform float uTime; // 动画帧时间
void main(){
vec4 currentPosition = modelMatrix * vec4(position, 1.0);
vec3 direction = aPosition - currentPosition.xyz; // 当前点最终位置减去起始位置
vec3 targetPosition = currentPosition.xyz + direction * 0.1 * uTime;
vec4 vPosition = viewMatrix * vec4(targetPosition, 1.0);
gl_Position = projectionMatrix*vPosition;
gl_PointSize = -100.0/vPosition.z; // 设置顶点近大远小效果
}
片元着色
uniform sampler2D uTexture;
uniform vec3 uColor;
void main(){
vec4 uTextureColor = texture2D(uTexture, gl_PointCoord);
gl_FragColor = vec4(uColor, uTextureColor.x);
}
更多推荐
已为社区贡献6条内容
所有评论(0)