three.js用粒子使用canvas生成的中文字符位图材质
three.js用粒子使用canvas生成中文字符材质
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js Canvas 文字粒子</title>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/",
"three/addons/geometries/TextGeometry.js": "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/geometries/TextGeometry.js",
"three/addons/loaders/FontLoader.js": "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/loaders/FontLoader.js"
}
}
</script>
<script type="module">
import * as THREE from 'three';
//--------------------------------------
//需要显示的文字
let textDisplayed = "新年好";
// 创建场景、相机和渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 设置相机位置
camera.position.z = 50;
// 创建 Canvas 纹理
function createCanvasTexture(text) {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const size = 300; // Canvas 大小
canvas.width = size;
canvas.height = size;
// 绘制背景
context.fillStyle = 'rgba(0, 0, 0, 0)'; // 透明背景
context.fillRect(0, 0, size, size);
// 绘制文字
context.font = '100px Arial';
context.fillStyle = 'gold';
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillText(text, size / 2, size / 2);
// 将 Canvas 转换为纹理
return new THREE.CanvasTexture(canvas);
}
// 创建粒子系统
const particles = [];
const particleCount = 100;
const geometry = new THREE.BufferGeometry();
const positions = [];
for (let i = 0; i < particleCount; i++) {
// 随机位置
positions.push((Math.random() - 0.5) * 100, (Math.random() - 0.5) * 100, (Math.random() - 0.5) * 100);
}
geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
// 创建粒子材质
const texture = createCanvasTexture(textDisplayed);
const material = new THREE.PointsMaterial({
size: 10,
map: texture,
transparent: true,
alphaTest: 0.5
});
const particleSystem = new THREE.Points(geometry, material);
scene.add(particleSystem);
// 动画循环
let angle = 0;
const radius = 80; // 相机绕场景中心旋转的半径
renderer.setClearColor(0xff0000, 0.5);
function animate() {
requestAnimationFrame(animate);
angle += 0.01;
camera.position.x = radius * Math.cos(angle);
camera.position.z = radius * Math.sin(angle);
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
animate();
</script>
</body>
</html>