粒子效果创建云朵与创建海洋

164 阅读1分钟

创建云朵类

class Clouds{
    constructor(
    // 云朵高度
    height = 5,
    // 粒子大小
    size = 20,
    // 云朵方块大小
    scale = 5,
    autoRotate = true
    ){
        this.height = height
        this.num = num
        this.size = size
        this.scale = scale
        this.autoRotate = autoRotate
        // 纹理加载器
        const textureLoader = new THREE.TextureLoader()
        // 加载三个纹理
        const map1 = textureLoader.load('path')
        const map2 = textureLoader.load('path')
        const map3 = textureLoader.load('path')
        
        // 声明材质数组
        const materials = []
        // 创建粒子材质 1 2 
        const material1 = new THREE.PointsMaterial({
            size: this.size * 0.2,
            transparent : true,
            blending: THREE.AdditiveBlending,
            color : 0xffffff,
            // 深度检测
            depthWrite : false,
            depthTest : false,
            map: map1,
            alphaMap : map2, // 透明贴图
        })
        // 2 3
        const material2 = new THREE.PointsMaterial({
            size: this.size *  0.4,
            transparent : true,
            blending: THREE.AdditiveBlending,
            color : 0xffffff,
            // 深度检测
            depthWrite : false,
            depthTest : false,
            map : map2,
            alphaMap : map3
        })
        // 3 1
        const material3 = new THREE.PointsMaterial({
            size: this.size * 0.6,
            transparent : true,
            blending: THREE.AdditiveBlending,
            color : 0xffffff,
            // 深度检测
            depthWrite : false,
            depthTest : false,
            map : map3,
            alphaMap : map2
        })
        // 2 1
        const material4 = new THREE.PointsMaterial({
            size: this.size * 0.8,
            transparent : true,
            blending: THREE.AdditiveBlending,
            color : 0xffffff,
            // 深度检测
            depthWrite : false,
            depthTest : false,
            map : map2,
            alphaMap : map1
        })
        materials.push(material1, material2, material3, material4)
        this.mesh = new THREE.Group()
        // 每种材质生成一种粒子效果
        for(let i = 0; i < materials.length;i++){
            let material = materials[i]
            const geometry = this.createGeometry()
            const points = new THREE.Points(geometry,material)
            this.mesh.add(points)
        }
        if(this.autoRotate){
            this.animate()
        }
    }
    // 创建几何体
    createGeometry(num = 100){
        // 声明顶点数组
        const positionArr = []
        const geometry = new THREE.BufferGeometry()
        for(let i = 0;i < num;i++){
            let randomX = (Math.random() - 0.5) * 2 *  this.scale
            let randomY = Math.random() * (this.height / 2) + this.height
            let randomZ = (Math.random() - 0.5) * 2 * this.scale
            positionArr.push(randomX, randomY, randomZ)
        }
        // 给几何体设置属性
        geometry.setAttribute('position',   
        new THREE.Float32BufferAttribute(positionArr,3))

        return geometry
    }
    // 运动函数
    animate(){
        // 声明一个变量,用来计算速度
        let i = 1
        // 遍历Group
        this.mesh.traverse(item =>{
            let speed = 20 * i
            // 根据类型
            if(item instanceof THREE.Points){
                gsap.to(item.rotation,{
                    duration : speed,
                    repeat: -1,
                    y : Math.PI *2
                })
            }
            i++
        })
    }
}

创建海洋类

class Ocean {
  constructor(radius = 1000) {
    // 创建水平
    this.waterGeometry = new THREE.CircleBufferGeometry(radius, 128);
    this.water = new Water(this.waterGeometry, {
      textureWidth: 1024,
      textureHeight: 1024,
      color: 0x08dbea,
      flowDirection: new THREE.Vector2(1, 1), // 流动方向二维向量
      scale: 100,
    });
    this.water.position.y = -5;
    this.water.rotation.x = -Math.PI / 2;
    this.mesh = this.water;
    // 渲染优先级
    this.water.renderOrder = -1;

    // 根据视图动态修改海面的效果
    this.water.material.fragmentShader =
      this.water.material.fragmentShader.replace(
        "gl_FragColor = vec4( color, 1.0 ) * mix( refractColor, reflectColor, reflectance );",
        `
        gl_FragColor = vec4( color, 1.0 ) * mix( refractColor, reflectColor, reflectance );
        // 根据z轴,动态算出gl_FragColor与vec4的混合比例
        gl_FragColor = mix( gl_FragColor, vec4(0.05,0.3,0.7,1.0), vToEye.z*0.0005+0.5 );
        
        `
      );
  }

需要将three自带的水纹理手动放到项目的资源根目录下的"textures\water"