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);
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Three.js是一个基于WebGLJavaScript库,用于创建和展示3D图形。它提供了丰富的功能和工具,可以轻松地实现各种动态粒子特效。 要实现动态粒子特效,可以按照以下步骤进行: 1. 创建场景(Scene):使用Three.js创建一个场景,用于容纳所有的物体和效果。 2. 创建相机(Camera):选择适合你需求的相机类型,例如透视相机(PerspectiveCamera)或正交相机(OrthographicCamera)。设置相机的位置和朝向,以便正确地观察场景。 3. 创建渲染器(Renderer):创建一个渲染器,将场景和相机渲染到屏幕上。可以选择使用WebGLRenderer或者CanvasRenderer,具体取决于你的需求。 4. 创建粒子(Particle):使用Particle或者Points等对象创建粒子。可以设置粒子的位置、大小、颜色等属性。 5. 创建材质(Material):为粒子创建材质,可以使用PointsMaterial或者ShaderMaterial等。设置材质的颜色、透明度、纹理等属性。 6. 创建动画(Animation):使用Tween.js或者自定义的动画库来实现粒子的动态效果。可以通过改变粒子的位置、大小、颜色等属性来实现动画效果。 7. 添加光源(Light):根据需要添加光源,例如环境光(AmbientLight)、平行光(DirectionalLight)或点光源(PointLight)等。光源可以影响粒子的明暗效果。 8. 渲染场景:在每一帧中,使用渲染器将场景和相机渲染到屏幕上。可以使用requestAnimationFrame来实现动画效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山楂树の

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值