three.js использует очки для создания эффекта дыма - PullRequest
0 голосов
/ 24 мая 2019

Я хочу создать эффект дыма, например: 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 Ответ

1 голос
/ 24 мая 2019

Вы можете просто установить velocityX в зависимости от точки x, например:

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...