Skip to content

Instantly share code, notes, and snippets.

@ManasN
Created September 12, 2015 10:10
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save ManasN/5c85da98560a847f2f03 to your computer and use it in GitHub Desktop.
Save ManasN/5c85da98560a847f2f03 to your computer and use it in GitHub Desktop.
3D Particles forming shapes

3D Particles forming shapes

My first take at a 3D particle system. Using three.js the particles jump between having targets in a sphere shape and a (filled) box shape.

A Pen by Pål Smitt-Amundsen on CodePen.

License.

<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, user-scalable=0" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.js"></script>
var mousePos = {x:.5,y:.5};
document.addEventListener('mousemove', function (event) { mousePos = {x:event.clientX/window.innerWidth, y:event.clientY/window.innerHeight};});
var phase = 0;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(95, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 30;
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var boxSize = 0.2;
var geometry = new THREE.BoxGeometry(boxSize, boxSize, boxSize);
var materialGreen = new THREE.MeshBasicMaterial({transparent: true, color: 0xff0000, opacity: 0.4, side: THREE.DoubleSide});
var pitchSegments = 60;
var elevationSegments = pitchSegments/2;
var particles = pitchSegments*elevationSegments
var side = Math.pow(particles, 1/3);
var radius = 16;
var parentContainer = new THREE.Object3D();
scene.add(parentContainer);
function posInBox(place) {
return ((place/side) - 0.5) * radius * 1.2;
}
//Plant the seeds, grow some trees in a grid!
for (var p = 0; p < pitchSegments; p++) {
var pitch = Math.PI * 2 * p / pitchSegments ;
for (var e = 0; e < elevationSegments; e++) {
var elevation = Math.PI * ((e / elevationSegments)-0.5)
var particle = new THREE.Mesh(geometry, materialGreen);
parentContainer.add(particle);
var dest = new THREE.Vector3();
dest.z = (Math.sin(pitch) * Math.cos(elevation)) * radius; //z pos in sphere
dest.x = (Math.cos(pitch) * Math.cos(elevation)) * radius; //x pos in sphere
dest.y = Math.sin(elevation) * radius; //y pos in sphere
particle.position.x = posInBox(parentContainer.children.length % side);
particle.position.y = posInBox(Math.floor(parentContainer.children.length/side) % side);
particle.position.z = posInBox(Math.floor(parentContainer.children.length/Math.pow(side,2)) % side);
console.log(side, parentContainer.children.length, particle.position.x, particle.position.y, particle.position.z)
particle.userData = {dests: [dest,particle.position.clone()], speed: new THREE.Vector3() };
}
}
function render() {
phase += 0.002;
for (var i = 0, l = parentContainer.children.length; i < l; i++) {
var particle = parentContainer.children[i];
var dest = particle.userData.dests[Math.floor(phase)%particle.userData.dests.length].clone();
var diff = dest.sub(particle.position);
particle.userData.speed.divideScalar(1.02); // Some drag on the speed
particle.userData.speed.add(diff.divideScalar(400));// Modify speed by a fraction of the distance to the dest
particle.position.add(particle.userData.speed);
particle.lookAt(dest);
}
parentContainer.rotation.y = phase*3;
parentContainer.rotation.x = (mousePos.y-0.5) * Math.PI;
parentContainer.rotation.z = (mousePos.x-0.5) * Math.PI;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
* {margin:0;background:black;}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment