Three.js university Sprite vague de particules

Créer une vague de particules avec Three.js

Préparation de l’environnement – Variables globales

Commençons par créer quelques variables globales :

// Wave configuration
var wavespeed = 1;
var wavewidth = 200;
var waveheight = 100;
var objects_margin = 20;

//Array
var waveobjects = new Array();
  • wavespeed – Vitesse des vagues
  • wavewidth – Largeur des vagues
  • waveheight – Hauteur des vagues
  • objects_margin – Espacement entre les particules
  • waveobjects – Liste des particules de la scène

Préparation de l’environnement – Création des particules

Puis, à l’aide d’une imbrication de boucles for, nous créons les particules composant notre vague. Notre groupe de particules sera ordonné en carré via une simple incrémentation sur les axes X et Z.

Chaque particule est un objet Three.js de type Sprite.

// ---------------- PARTICLES ----------------

const loader = new THREE.TextureLoader();
var particleTexture = loader.load( '../Particles/firefly.png' );
var spriteMaterial = new THREE.SpriteMaterial( { map: particleTexture, transparent : true, opacity :1, color: 0x000000 } );
				  
for ( var x = 0; x < 100; x ++ )
{
	  for ( var y = 0; y < 100; y ++ )
	  {			
			// Sprite creation
			var mesh = new THREE.Sprite( spriteMaterial );
			
			mesh.scale.set(10,10,10); 				// scale
			mesh.position.x = x * objects_margin;	// POSITION X
			mesh.position.y = 0;
			mesh.position.z = y * objects_margin;	//POSITION Y
			scene.add( mesh );

			waveobjects.push(mesh); 
	  }
}

Comme expliqué, la position de chaque Sprite sur les axes X et Z dépend de son ordre de création dans les boucles for.

Les Particules que nous créons, instances de Sprite, sont ajoutées à la scène et référencées dans la structure waveobjects de type Array.

Création des vagues de particules

Le mouvement de chaque particule est calculé grâce à la fonction Math.sin, de sa position dans le groupe et du temps écoulé.
Ainsi, la combinaison de ces trois paramètres est utilisée pour calculer la position de chaque particule de la scène, et ainsi créer une animation de vague.

Three.js Clock et Math.sin

Ainsi, pour garder un œil sur le temps écoulé, nous créons une instance de la classe Clock de Three.js.

clock = new THREE.Clock();

Puis, dans notre boucle principale :

function animate()
{
	var delta = clock.getDelta();
	var elapsed = clock.elapsedTime;

	[...]
}

Notons que la variable elapsed contient le nombre total de secondes écoulées depuis le lancement de l’application.

Animation des particules

Toujours dans la boucle principale, nous bouclons sur la liste des particules afin de modifier unitairement les positions :

for(var i = 0 ; i < waveobjects.length ; i++)
{

    waveobjects[i].position.y = Math.cos( (elapsed + (waveobjects[i].position.x /wavewidth) + (waveobjects[i].position.z /wavewidth) ) *wavespeed ) * waveheight;
}

Comme expliqué, nous déterminons la nouvelle position de chaque particule par sa position sur les axes X et Z, le temps écoulé et la méthode Math.sin.

Code final et résultat

// Wave configuration
var wavespeed = 1;
var wavewidth = 200;
var waveheight = 100;
var objects_margin = 20;

//Array
var waveobjects = new Array();

[...]

clock = new THREE.Clock();

[...]

// ---------------- PARTICLES ----------------

const loader = new THREE.TextureLoader();
var particleTexture = loader.load( '../Particles/firefly.png' );
var spriteMaterial = new THREE.SpriteMaterial( { map: particleTexture, transparent : true, opacity :1, color: 0x000000 } );
				  
for ( var x = 0; x < 100; x ++ )
{
	  for ( var y = 0; y < 100; y ++ )
	  {			
			// Sprite creation
			var mesh = new THREE.Sprite( spriteMaterial );
			
			mesh.scale.set(10,10,10); 				// scale
			mesh.position.x = x * objects_margin;	// POSITION X
			mesh.position.y = 0;
			mesh.position.z = y * objects_margin;	//POSITION Y
			scene.add( mesh );

			waveobjects.push(mesh); 
	  }
}

[...]

function animate()
{
	var delta = clock.getDelta();
	var elapsed = clock.elapsedTime;
        
	requestAnimationFrame( animate );

	for(var i = 0 ; i < waveobjects.length ; i++)
	{

	waveobjects[i].position.y = Math.cos( (elapsed + (waveobjects[i].position.x /wavewidth) + (waveobjects[i].position.z /wavewidth) ) *wavespeed ) * waveheight;
	}

	renderer.render( scene, camera );
}

(2 commentaires)

Les commentaires sont fermés.