简体   繁体   中英

three.js using points to make smoke effect

I want to make a smoke effect like this demo (Smoke) by using points. Now I have two problems.

  1. At the beginning of the animation, all points get together and go up together like cloud.
  2. the shape of the effect looks like a rectangular prism. How to make it looks like a cone (like the following picture)?

Can somebody please tell me how to fix these problems? Thanks!

在此处输入图片说明

 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) { vy = vy + v.velocityY; vx = vx + v.velocityX; if (vy >= 100) vy = 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> 

You could simply set velocityX depending on point x, eg :

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

Don't forget to reset x position :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM