three.js使用点制作烟雾效果

时间:2019-05-24 10:33:17

标签: javascript animation three.js

我想通过使用点来制作类似demo (Smoke)的烟雾效果。现在我有两个问题。

  1. 动画开始时,所有点都聚集在一起,像云一样上升。
  2. 效果的形状看起来像一个矩形棱柱。如何使其看起来像圆锥形(如下图所示)?

有人可以告诉我如何解决这些问题吗?谢谢!

enter image description here

let renderer, scene, camera;
let controls, stats;

// points
const particleCount = 500;
let points;

function createPoints() {
	const geometry = new THREE.Geometry();

	const texture = new THREE.TextureLoader().load('http://stemkoski.github.io/Three.js/images/smokeparticle.png');
	let material = new THREE.PointsMaterial({
		size: 15,
		map: texture,
		blending: THREE.AdditiveBlending,
		depthWrite: false,
		transparent: true,
		color: 'rgb(30,30,30)'
	});

	const range = 10;
	for (let i = 0; i < particleCount; i++) {
		const x = THREE.Math.randInt(-range, range);
		const y = THREE.Math.randInt(-range, range);
		const z = THREE.Math.randInt(-range, range);
		const point = new THREE.Vector3(x, y, z);
		point.velocityX = THREE.Math.randFloat(-0.01, 0.01);
		point.velocityY = THREE.Math.randFloat(0.1, 0.3);
		geometry.vertices.push(point);
	}

	points = new THREE.Points(geometry, material);
	scene.add(points);
}

function init() {
	// scene
	scene = new THREE.Scene();
	scene.fog = new THREE.FogExp2(0x000000, 0.0008);

	// camera
	camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
	camera.position.set(0, 10, 170);
	camera.lookAt(scene.position);


	let axes = new THREE.AxesHelper(20);
	scene.add(axes);

	// renderer
	renderer = new THREE.WebGLRenderer();
	renderer.setSize(window.innerWidth, window.innerHeight);


	// OrbitControls
	controls = new THREE.OrbitControls( camera, renderer.domElement );

	createPoints();

	document.body.appendChild(renderer.domElement);
}

function pointsAnimation() {
	points.geometry.vertices.forEach(function(v) {
		v.y = v.y + v.velocityY;
		v.x = v.x + v.velocityX;

		if (v.y >= 100) v.y = 0;
	});

	points.geometry.verticesNeedUpdate = true;
}

function render() {
	pointsAnimation();
	requestAnimationFrame(render);
	controls.update();
	renderer.render(scene, camera);
}

window.addEventListener('resize', function() {
	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();
	renderer.setSize(window.innerWidth, window.innerHeight);
});

init();
render();
body {
	margin: 0;
	overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

1 个答案:

答案 0 :(得分:1)

您可以简单地根据点x设置velocityX,例如:

point.velocityX = THREE.Math.randFloat(0.0, 0.1) * Math.sign(x);

别忘了重置x位置:

if (v.y >= 100) {
  v.x = THREE.Math.randInt(-10, 10);
  v.y = 0;
}