JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script type="x-shader/x-vertex" id="vertex-shader">
precision highp float;
attribute float alpha;
attribute vec3 position;
attribute float size;
varying float v_alpha;
varying float v_size;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
void main() {
v_alpha = alpha;
v_size = size;
vec4 myPosition = modelViewMatrix * vec4(position, 1.0);
gl_PointSize = v_size * (1. / -myPosition.z);
gl_Position = projectionMatrix * myPosition;
}
</script>
<script type="x-shader/x-fragment" id="fragment-shader">
precision highp float;
uniform vec3 color;
varying float v_alpha;
void main() {
gl_FragColor = vec4(color, v_alpha);
}
</script>
CSS
body{margin:0;
overflow:hidden;}
JavaScript
//All numeric values use SI units.
var camera, scene, renderer;
var gravity = -9.81;
var particleindex = 0, particleCount = 1000,
particle_geometry = new THREE.BufferGeometry();
//Positions as [x,y,z,x,y,z, ...]
var positions = [];
//var colors = [];
var uniforms =
{
color: { value: new THREE.Color(0xff0000)},
};
var alphas = new Float32Array(particleCount * 1);
var size = 200.0;
var sizes = [];
var particle_emitted = [];
var particle_velocities = [];
var particle_has_bounced = [];
var particle_life = 20;
for(var i = 0; i < particleCount; i++)
{
sizes.push(size);
positions.push(0.0, 0.0, 0.0);
//colors.push(255, 0, 0);
alphas[i] = 1.0;
particle_emitted.push(false);
}
//var colorAttribute = new THREE.Uint8BufferAttribute(colors, 3);
//colorAttribute.normalized = true;
particle_geometry.addAttribute('position',
new THREE.Float32BufferAttribute(positions, 3));
//particle_geometry.addAttribute('color', colorAttribute);
particle_geometry.addAttribute('size', new THREE.Float32BufferAttribute(sizes, 1));
particle_geometry.addAttribute( 'alpha', new THREE.BufferAttribute(alphas, 1));
var material = new THREE.RawShaderMaterial
({
uniforms: uniforms,
vertexShader: document.getElementById( 'vertex-shader' ).textContent,
fragmentShader: document.getElementById( 'fragment-shader' ).textContent,
transparent: true
});
var particleSystem = new THREE.Points(particle_geometry, material),
height = 0, max_pos_dist_xz = 20, max_neg_dist_xz = max_pos_dist_xz / 2;
var particle_offset = particle_geometry.attributes.size.array[0];
var dt = 1 / 60;
var planegeometry, planematerial, planemesh;
planegeometry = new THREE.PlaneGeometry(200, 200, 0);
planematerial = new THREE.MeshBasicMaterial();
planemesh = new THREE.Mesh(planegeometry, planematerial);
function init()
{
camera = new THREE.PerspectiveCamera(70, window.innerWidth /
window.innerHeight, 0.01, 1e6);
var controls = new...