three.js实现雪花场景效果

点击获取雪花图片素材

提取码:lywa

javascript 复制代码
// 雪花效果
import * as THREE from "three"
export function getsnowEffect(th) {
    console.log('th', th) // this 场景
    var that = th
    // 创建一个BufferGeometry对象,用于存储顶点数据  
    const geometry = new THREE.BufferGeometry();
    const vertices = [];
    let renderer;
    // 创建一个纹理加载器  
    const textureLoader = new THREE.TextureLoader();

    // 加载五个不同的雪花纹理  
    const sprite1 = textureLoader.load('/public/data/snowflake1.png');
    const sprite2 = textureLoader.load('/public/data/snowflake2.png');
    const sprite3 = textureLoader.load('/public/data/snowflake3.png');
    const sprite4 = textureLoader.load('/public/data/snowflake4.png');
    const sprite5 = textureLoader.load('/public/data/snowflake5.png');

    // 生成10000个随机顶点位置  
    for (let i = 0; i < 10000; i++) {
        const x = Math.random() * 2000 - 1000;
        const y = Math.random() * 2000 - 1000;
        const z = Math.random() * 2000 - 1000;
        vertices.push(x, y, z);
    }

    // 将顶点数据设置为BufferGeometry的属性  
    geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));

    // 定义一个参数数组,包含颜色、纹理和大小 
    let parameters = [
        [
            [1.0, 0.2, 0.5], sprite2, 5
        ],
        [
            [0.95, 0.1, 0.5], sprite3, 5
        ],
        [
            [0.90, 0.05, 0.5], sprite1, 5
        ],
        [
            [0.85, 0, 0.5], sprite5, 5
        ],
        [
            [0.80, 0, 0.5], sprite4, 5
        ]
    ];
    const materials = [];
    // 根据参数数组创建多个粒子系统,并将它们添加到场景中
    for (let i = 0; i < parameters.length; i++) {
        const color = parameters[i][0];
        const sprite = parameters[i][1];
        const size = parameters[i][2];
        // 创建一个PointsMaterial,设置其大小、纹理、混合模式等属性  
        materials[i] = new THREE.PointsMaterial({
            size: size,
            map: sprite,
            blending: THREE.AdditiveBlending,
            depthTest: false,
            transparent: true
        });
        materials[i].color.setHSL(color[0], color[1], color[2]);
        // 创建一个Points对象,并使用之前定义的geometry和material 
        const particles = new THREE.Points(geometry, materials[i]);
        // 为粒子系统设置随机的旋转值  
        particles.rotation.x = Math.random() * 6;
        particles.rotation.y = Math.random() * 6;
        particles.rotation.z = Math.random() * 6;
        // 将粒子系统添加到场景中
        that.scene.add(particles);
    }
    // 这里应该初始化renderer,并设置其大小和dom元素  
    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);

    animate();

    function animate() {
        requestAnimationFrame(animate);
        render();
    }

    function render() {
        const time = Date.now() * 0.00005;
        for (let i = 0; i < that.scene.children.length; i++) {
            const object = that.scene.children[i];
            if (object instanceof THREE.Points) {

                object.rotation.y = time * (i < 4 ? i + 1 : -(i + 1));
            }
        }

        for (let i = 0; i < materials.length; i++) {
            const color = parameters[i][0];
            const h = (360 * (color[0] + time) % 360) / 360;
            materials[i].color.setHSL(h, color[1], color[2]);
        }
    }
}

结果

相关推荐
大怪v5 小时前
AI抢饭?前端佬:我要验牌!
前端·人工智能·程序员
新酱爱学习5 小时前
字节外包一年,我的技术成长之路
前端·程序员·年终总结
小兵张健5 小时前
开源 playwright-pool 会话池来了
前端·javascript·github
IT_陈寒8 小时前
Python开发者必知的5大性能陷阱:90%的人都踩过的坑!
前端·人工智能·后端
codingWhat8 小时前
介绍一个手势识别库——AlloyFinger
前端·javascript·vue.js
Lee川8 小时前
深度拆解:基于面向对象思维的“就地编辑”组件全模块解析
javascript·架构
代码老中医8 小时前
2026年CSS彻底疯了:这6个新特性让我删掉了三分之一JS代码
前端
进击的尘埃8 小时前
Web Worker 与 OffscreenCanvas:把主线程从重活里解放出来
javascript
不会敲代码18 小时前
Zustand:轻量级状态管理,从入门到实践
前端·typescript
踩着两条虫8 小时前
VTJ.PRO 双向代码转换原理揭秘
前端·vue.js·人工智能