var scene, camera, renderer, clock, tick // define world attributes as globals var vel_funct, curl_funct, geometry, material, body, options // some throwaway variables ( for short term use ) // THE FUNCTION(s) // ........ Edit Here to Change the Function // ........ to avoid writing a parser / something that differentiates functions // ........ the curl_funct should be equal to curl( vel_funct ), to change that you'll have to // ........ calculate the function using 2dCurl( r ) = ( r.y )dx - ( r.x )dy vel_funct = ( r ) => new THREE.Vector3( Math.sin( r.y ), Math.pow( r.x, 3 ), 0 ).multiplyScalar( 0.1 ) curl_funct = ( r ) => 3 * Math.pow( r.x, 2 ) - Math.cos( r.y ) // vel_funct = ( r ) => new THREE.Vector3( Math.sin( r.y * 5 ), 0, 0 ) // curl_funct = ( r ) => - 5 * Math.cos( r.y * 5 ) // vel_funct = ( r ) => new THREE.Vector3( -r.x, -r.y, 0 ) // curl_funct = ( r ) => 0 function build() { // SCENE scene = new THREE.Scene() //CLOCK clock = new THREE.Clock() tick = 0 // CAMERA camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 ) camera.position.z = 2 // RENDERER renderer = new THREE.WebGLRenderer() renderer.setSize( window.innerWidth, window.innerHeight ) document.body.appendChild( renderer.domElement ) // PARTICLES particleSystem = new THREE.GPUParticleSystem( { maxParticles: 500000 } ); scene.add( particleSystem ) particleHandler = new ParticleHandler( vel_funct, curl_funct, 20, 0.1, 500000 ) } function animate() { requestAnimationFrame( animate ) particleHandler.tick() renderer.render( scene, camera ) } class ParticleHandler { constructor( vel_funct, curl_funct, range, timeScale, spawnRate ) { options = { position: new THREE.Vector3(), positionRandomness: 0.1, velocity: new THREE.Vector3(), velocityRandomness: 0, color: 0xaa0000, colorRandomness: 0.5, turbulence: 0, lifetime: 1.5, size: 6, sizeRandomness: 10 } this.timeScale = timeScale this.spawnRate = spawnRate this.range = range this.vel_funct = vel_funct this.curl_funct = curl_funct } tick() { var delta = clock.getDelta() * this.timeScale; tick += delta; if ( tick < 0 ) { tick = 0 }; if ( delta > 0 ) { for ( var x = 0; x < this.spawnRate * delta; x++ ) { options.position.x = ( Math.random( ) * this.range ) - this.range / 2 options.position.y = ( Math.random( ) * this.range ) - this.range / 2 options.velocity = this.vel_funct( options.position ) options.color = new THREE.Color( 0xaaaaaa ).add( new THREE.Color( 0xff0000 ).multiplyScalar( this.curl_funct( options.position ) ) ) particleSystem.spawnParticle( options ) } } particleSystem.update( tick ) } } build() animate()