看不到北方的白雪,那就自己做一个七彩的雪花吧。具体效果如下:
首先需要搭建基础环境,场景、相机和渲染器,不清楚的可以查看three.js基础案例day01也可以查看下面的源码。
1.创建多个随机点
注:点的材质是图片,需要先使用TextureLoader加载图片
// geometry
geometry = new THREE.BufferGeometry()
vertices = []
for (let i = 0; i < 10000; i++) {
const x = 2000 * Math.random() - 1000
const y = 2000 * Math.random() - 1000
const z = 2000 * Math.random() - 1000
vertices.push(x, y, z)
}
geometry.setAttribute(
'position',
new THREE.Float32BufferAttribute(vertices, 3),
)
// material
const texture = new THREE.TextureLoader().load(
'static/textures/sprites/snowflake2.png',
)
material = new THREE.PointsMaterial({
size: 50,
map: texture,
transparent: true,
opcity: 1,
depthTest: false, // 可以去掉texture的黑色背景
blending: THREE.AdditiveBlending,
})
particles = new THREE.Points(geometry, material)
scene.add(particles)
2. 添加事件,当鼠标移动时,场景也变化(其实就是移动相机位置)
document.body.addEventListener('pointermove', (event) => {
mouseX = event.clientX - window.innerWidth / 2
mouseY = event.clientY - window.innerHeight / 2
})
// 鼠标移动,相机位置也变化
camera.position.x += (mouseX - camera.position.x) * 0.05
camera.position.y += (mouseY - camera.position.y) * 0.05
camera.lookAt(0, 0, 0)
3. 设置颜色变化
const time = Date.now() * 0.00005
const h = ((360 * (1.0 + time)) % 360) / 360
material.color.setHSL(h, 0.5, 0.5)
全部代码:
<template>
<div id="threeId" ref="elementRef"></div>
</template>
<script setup>
import * as THREE from 'three'
import { ref, onMounted } from 'vue'
let width, height, scene, camera, renderer
let mouseX = 0, mouseY = 0
let particles, geometry, material, vertices
const elementRef = ref(null)
onMounted(() => {
const element = elementRef.value
width = element.offsetWidth
height = element.offsetHeight
initScene()
initMeshes()
})
function initScene() {
// 初始化场景: 创建场景,相机,物体,渲染器
scene = new THREE.Scene()
screen.fog = new THREE.FogExp2(0x000000, 0.1)
camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000)
camera.position.set(0, 0, 100)
scene.add(camera)
// const axesHelper = new THREE.AxesHelper(40)
// scene.add(axesHelper)
renderer = new THREE.WebGLRenderer()
renderer.setSize(width, height)
elementRef.value.appendChild(renderer.domElement)
renderer.outputEncoding = THREE.sRGBEncoding
document.body.addEventListener('pointermove', (event) => {
mouseX = event.clientX - window.innerWidth / 2
mouseY = event.clientY - window.innerHeight / 2
})
}
function initMeshes() {
// geometry
geometry = new THREE.BufferGeometry()
vertices = []
for (let i = 0; i < 10000; i++) {
const x = 2000 * Math.random() - 1000
const y = 2000 * Math.random() - 1000
const z = 2000 * Math.random() - 1000
vertices.push(x, y, z)
}
geometry.setAttribute(
'position',
new THREE.Float32BufferAttribute(vertices, 3),
)
// material
const texture = new THREE.TextureLoader().load(
'static/textures/sprites/snowflake2.png',
)
material = new THREE.PointsMaterial({
size: 50,
map: texture,
transparent: true,
opcity: 1,
depthTest: false, // 可以去掉texture的黑色背景
blending: THREE.AdditiveBlending,
})
particles = new THREE.Points(geometry, material)
scene.add(particles)
render()
}
function render() {
requestAnimationFrame(render)
const time = Date.now() * 0.00005
camera.position.x += (mouseX - camera.position.x) * 0.05
camera.position.y += (mouseY - camera.position.y) * 0.05
camera.lookAt(0, 0, 0)
const h = ((360 * (1.0 + time)) % 360) / 360
material.color.setHSL(h, 0.5, 0.5)
renderer.render(scene, camera)
}
</script>
<style lang="scss" scoped>
#threeId {
width: 100%;
height: 100%;
}
</style>