Three.JS提升学习3:粒子

时间:2021-10-06 05:28:33

本文学习资源来自《Three.js开发指南》


一、理解粒子

粒子用来模拟很多细小的物体,如雨滴、雪花、烟等。

1. 使用THREE.Sprite创建简单粒子

关键代码:

        function createSprites() {
var material = new THREE.SpriteMaterial();


for (var x = -5; x < 5; x++) {
for (var y = -5; y < 5; y++) {
var sprite = new THREE.Sprite(material);
sprite.position.set(x * 10, y * 10, 0);
scene.add(sprite);
}
}
}

创建10*10的粒子,一个粒子是一个二维平面,总是面向摄像机。
这些粒子没有指定属性,默认渲染成白色方块。
Three.JS提升学习3:粒子

这里使用的THREE.Sprite用来创建粒子。THREE.Sprite是THREE.Object3D对象的扩展,也就是说THREE.Mesh的大部分属性和函数都可用于THREE.Sprite。

当粒子数量非常大时,使用大量THREE.Sprite会遇到性能问题。

2. 使用THREE.PointCloud处理大量粒子

        function createParticles() {


var geom = new THREE.Geometry();
var material = new THREE.PointCloudMaterial({size: 4, vertexColors: true, color: 0xffffff});

for (var x = -5; x < 5; x++) {
for (var y = -5; y < 5; y++) {
var particle = new THREE.Vector3(x * 10, y * 10, 0);
geom.vertices.push(particle);
geom.colors.push(new THREE.Color(Math.random() * 0x00ffff));
}
}

var cloud = new THREE.PointCloud(geom, material);
scene.add(cloud);
}

这里每个粒子需要创建一个顶点THREE.Vector3对象,并添加到THREE.Geometry中,使用THREE.Geometry和THREE.PointCloudMaterial一起创建THREE.PointCloud,再把云添加到场景中。

Three.JS提升学习3:粒子

3. 给粒子使用样式

       function createParticles(size, transparent, opacity, vertexColors, sizeAttenuation, color) {


var geom = new THREE.Geometry();
var material = new THREE.PointCloudMaterial({
size: size,
transparent: transparent,
opacity: opacity,
vertexColors: vertexColors,

sizeAttenuation: sizeAttenuation,
color: color
});


var range = 500;
for (var i = 0; i < 15000; i++) {
var particle = new THREE.Vector3(Math.random() * range - range / 2, Math.random() * range - range / 2, Math.random() * range - range / 2);
geom.vertices.push(particle);
var color = new THREE.Color(0x00ff00);
color.setHSL(color.getHSL().h, color.getHSL().s, Math.random() * color.getHSL().l);
geom.colors.push(color);

}

cloud = new THREE.PointCloud(geom, material);
cloud.name = "particles";
scene.add(cloud);
}
var step = 0;

function render() {

stats.update();

if (controls.rotateSystem) {
step += 0.01;

cloud.rotation.x = step;
cloud.rotation.z = step;
}


requestAnimationFrame(render);
webGLRenderer.render(scene, camera);
}

书籍官方式示例效果:
Three.JS提升学习3:粒子

3. 使用HTML5画布样式化粒子

Three.js提供了三种使用HTML5画布来样式化粒子的方法。
如果使用的是THREE.CanvasRenderer,可以通过THREE.SpriteCanvasMaterial直接引用HTML5画布。如果用的是THREE.WebGLRenderer,那么需要采取一些额外的步骤才能使用HTML5画布样式化粒子。

在THREE.CanvasRenderer中使用HTML5画布

在WebGLRenderer中使用HTML5画布

4. 使用纹理样式化粒子


function createPointCloud(size, transparent, opacity, sizeAttenuation, color) {

var texture = THREE.ImageUtils.loadTexture("../assets/textures/particles/raindrop-3.png");
var geom = new THREE.Geometry();

var material = new THREE.ParticleBasicMaterial({
size: size,
transparent: transparent,
opacity: opacity,
map: texture,
blending: THREE.AdditiveBlending,
sizeAttenuation: sizeAttenuation,
color: color
});


var range = 40;
for (var i = 0; i < 1500; i++) {
var particle = new THREE.Vector3(
Math.random() * range - range / 2,
Math.random() * range * 1.5,
Math.random() * range - range / 2);
particle.velocityY = 0.1 + Math.random() / 5;
particle.velocityX = (Math.random() - 0.5) / 3;
geom.vertices.push(particle);
}

cloud = new THREE.ParticleSystem(geom, material);
cloud.sortParticles = true;

scene.add(cloud);
}

5. 使用精灵贴图

6. 从高级几何体创建THREE.PointCloud

       render();

// from THREE.js examples
function generateSprite() {

var canvas = document.createElement('canvas');
canvas.width = 16;
canvas.height = 16;

var context = canvas.getContext('2d');
var gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
gradient.addColorStop(0, 'rgba(255,255,255,1)');
gradient.addColorStop(0.2, 'rgba(0,255,255,1)');
gradient.addColorStop(0.4, 'rgba(0,0,64,1)');
gradient.addColorStop(1, 'rgba(0,0,0,1)');

context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);

var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
return texture;

}

function createPointCloud(geom) {
var material = new THREE.PointCloudMaterial({
color: 0xffffff,
size: 3,
transparent: true,
blending: THREE.AdditiveBlending,
map: generateSprite() //把粒子设置成发光点
});

var cloud = new THREE.PointCloud(geom, material);
cloud.sortParticles = true;
return cloud;
}

function createMesh(geom) {

// assign two materials
var meshMaterial = new THREE.MeshNormalMaterial({});
meshMaterial.side = THREE.DoubleSide;

// create a multimaterial
var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial]);

return mesh;
}

function render() {
stats.update();

if (controls.rotate) {
knot.rotation.y = step += 0.01;
}

// render using requestAnimationFrame
requestAnimationFrame(render);
webGLRenderer.render(scene, camera);
}

官方运行示例:
Three.JS提升学习3:粒子
参考:
https://www.cnblogs.com/amy2011/p/6358330.html