• 當前位置:首頁 > IT技術 > Web編程 > 正文

    THREE.js 下雪效果
    2022-05-11 10:58:42

    image

    snow.js

    import * as THREE from "three";
    
    class Snow {
        #time = 0
        #textureLoader = new THREE.TextureLoader()
    
        constructor(num = 0, range = 0, texture = '') {
            this.num = num
            this.range = range
            this.particle = null
            this.texture = texture
            this.texturesMaps = []
            this.position = null
            this.gen()
        }
    
        gen() {
            const {num, range, texture,} = this
            const geometry = new THREE.BufferGeometry()
            const material = new THREE.PointsMaterial({
                size: 6,
                transparent: true,
                opacity: .6,
                depthWrite: false,
                vertexColors: true,
                map: this.#textureLoader.load(texture),
                blending: THREE.AdditiveBlending // 將黑色雪花與背景色融合
            })
            const position = [] // 每個粒子的位置
            const colors = []
            for (let x = 0; x < num; x++) {
                // 采用HSL顏色模式使得雪花明暗度變化
                const color = new THREE.Color()
                const asHSL = {h: 0, s: 0, l: 0}
                color.getHSL(asHSL)
                color.setHSL(asHSL.h, asHSL.s, asHSL.l * Math.random())
                colors.push(color.r, color.g, color.b)
    
                // 生成隨機點坐標
                position.push(
                    THREE.MathUtils.randFloatSpread(range * 2),
                    THREE.MathUtils.randFloatSpread(range * 2),
                    THREE.MathUtils.randFloatSpread(range * 2)
                )
    
            }
            this.position = new THREE.Float32BufferAttribute(position, 3)
            geometry.setAttribute('position', this.position)
            geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3))
            this.particle = new THREE.Points(geometry, material)
        }
    
        snowing(speed = 0, fps = 0) {
            this.#time += 1
            if (fps > 0) {
                if (this.#time < fps * 60) return
                this.#time = 0
            }
            const {position, range} = this
            for (let i = 0; i < position.count; i++) {
                let pos_x = position.getX(i)
                let pos_y = position.getY(i)
                let pos_z = position.getZ(i)
    
                pos_x -= speed
                pos_y -= speed
                pos_z -= speed
    
                if (pos_x < -range) pos_x = range
                if (pos_y < -range) pos_y = range
                if (pos_z < -range) pos_z = range
    
                position.setX(i, pos_x)
                position.setY(i, pos_y)
                position.setZ(i, pos_z)
            }
            // 更新 position
            position.needsUpdate = true
        }
    }
    
    export default Snow
    

    index.js

    import * as THREE from 'three'
    import {OrbitControls} from "three/examples/jsm/controls/OrbitControls"
    
    import Snow from "./snow";
    import snowImg from "@/assets/textures/particles/snowflake1.png";
    const {innerWidth: WIDTH, innerHeight: HEIGHT} = window
    
    const scene = new THREE.Scene()
    const camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, .1, 1000)
    camera.position.set(0, 0, 160)
    camera.lookAt(scene.position)
    
    const ambientLight = new THREE.AmbientLight(0x666666)
    scene.add(ambientLight)
    
    const spotLight = new THREE.SpotLight(0xffffff)
    spotLight.castShadow = true
    spotLight.position.set(-50, 80, 50)
    scene.add(spotLight)
    
    const snow = new Snow(10000, 100, snowImg)
    scene.add(snow.particle)
    
    const renderer = new THREE.WebGLRenderer({antialias: true})
    renderer.setSize(WIDTH, HEIGHT)
    renderer.shadowMap.enabled = true
    document.body.appendChild(renderer.domElement)
    
    new OrbitControls(camera, renderer.domElement)
    const render = () => {
        snow.snowing(.3, .03)
        requestAnimationFrame(render)
        renderer.render(scene, camera)
    }
    
    render()
    

    附件 snowflake1.png

    image

    本文摘自 :https://www.cnblogs.com/

    開通會員,享受整站包年服務
    国产呦精品一区二区三区网站|久久www免费人咸|精品无码人妻一区二区|久99久热只有精品国产15|中文字幕亚洲无线码