版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37338983/article/details/82055220
点云可以用来模拟各种各样的场景,如下雨、下雪和火焰燃烧等;点云在THREE.JS中也称为精灵(sprites);接下来将介绍THREE.JS中点云的两种创建方式:
1.运用于少量点云粒子场景:
代码如下例:
let material = new THREE.SpriteMaterial()
for (let i = -3; i < 3; i++) {
for (let j = -3; j < 3; j++) {
let sprite = new THREE.Sprite(material);//新建精灵
sprite.scale.set(8, 8, 0);//缩放
sprite.position.set(i * 10 - 30, j * 10 + 30, 0);//位置
scene.add(sprite);
}
}
2.运用于大量点云粒子场景:
代码如下例:
let geom = new THREE.Geometry();//几何
let material = new THREE.PointsMaterial({size: 15, vertexColors: true, color: 0xffffff});//点云材料
//创建64万个点云粒子
for (let x = -400; x < 400; x++) {
for (let y = -400; y < 400; y++) {
let particle = new THREE.Vector3(x * Math.random(), y * Math.random(), 0);//三维点
geom.vertices.push(particle);
geom.colors.push(new THREE.Color(0xffffff));
}
}
let cloud = new THREE.Points(geom, material);//新建点云
scene.add(cloud);
当需要处理大量的点云粒子时,运用方法1会遇到性能问题,这个时候可以用方法2;
3 点云贴图
为点云贴图我们使用THREE.TextureLoader()方法首先加载图片,以方法1为例实现代码如下:
let spriteMap = new THREE.TextureLoader().load( "snowflake1.png");//加载图片
for (let i = -3; i < 3; i++) {
for (let j = -3; j < 3; j++) {
let sprite = new THREE.Sprite(new THREE.SpriteMaterial({map: spriteMap, color: 0x009966}));//为材料贴图
sprite.scale.set(8, 8, 0);
sprite.position.set(i * 10 - 30, j * 10 + 30, 0);
scene.add(sprite);
}
}
为点云粒子贴上雪花形状的图片,最后实现效果如下:
4 整个demo代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>particles-01</title>
<script type="text/javascript" src="../build/three.js"></script>
<script type="text/javascript" src="../js/libs/stats.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
background-color: #000000;
}
</style>
</head>
<body>
<script>
let container1 = document.createElement('div');
document.body.appendChild(container1);
let container2 = document.createElement('div');
document.body.appendChild(container2);
let scene, camera, renderer;
let stats;
main();
render();
function initScene() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);
}
function initCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 150);
camera.lookAt(new THREE.Vector3());
}
function initRenderer(container) {
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000, 1.0));
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
}
function main() {
stats = initStats(container2);
initScene();
initCamera();
initRenderer(container1);
createSprites();
createPointCloud();
}
function createSprites() {
let spriteMap = new THREE.TextureLoader().load( "snowflake1.png");
for (let i = -3; i < 3; i++) {
for (let j = -3; j < 3; j++) {
let sprite = new THREE.Sprite(new THREE.SpriteMaterial({map: spriteMap, color: 0x009966}));
sprite.scale.set(8, 8, 0);
sprite.position.set(i * 10 - 30, j * 10 + 30, 0);
scene.add(sprite);
}
}
}
function createPointCloud() {
let geom = new THREE.Geometry();
let spriteMap = new THREE.TextureLoader().load( "snowflake2.png");
let material = new THREE.PointsMaterial({map: spriteMap, size: 15, vertexColors: true, color: 0xffffff});
for (let x = -3; x < 3; x++) {
for (let y = -3; y < 3; y++) {
let particle = new THREE.Vector3(x * 10 + 28, y * 10 - 28, 0);
geom.vertices.push(particle);
geom.colors.push(new THREE.Color(0xffffff));
}
}
let cloud = new THREE.Points(geom, material);
scene.add(cloud);
}
function render() {
stats.update();
requestAnimationFrame(render);
renderer.render(scene, camera);
}
function initStats(container) {
let stats = new Stats();
stats.setMode(0); // 0: fps, 1: ms
// Align top-left
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
container.appendChild(stats.domElement);
return stats;
}
</script>
</body>
</html>