UNPKG

threex

Version:

Game Extensions for three.js http://www.threejsgames.com/extensions/

145 lines (135 loc) 4.48 kB
<!DOCTYPE html> <script src="../../../vendor/three.js/build/three.min.js"></script> <script src="../../threex.loop/THREEx.Loop.js"></script> <body style='margin: 0px; background-color: #bbbbbb;overflow: hidden;'><script> var renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); var updateFcts = []; var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.z = 3; var loop = new THREEx.Loop().start(); var geometry = new THREE.TorusGeometry( 0.35, 0.15 ); var material = new THREE.MeshNormalMaterial(); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); mesh.position.y = -0.5; mesh.rotation.x = Math.PI/2; var position = new THREE.Vector3 var emitter = new BlackSmoke(scene).start(mesh.position) loop.hook(function(delta, now){ emitter.update(delta, now) }) loop.hook(function(delta, now){ renderer.render( scene, camera ); }) ////////////////////////////////////////////////////////////////////////////////// // comment // ////////////////////////////////////////////////////////////////////////////////// function BlackSmoke(container){ var updateFcts = [] var texture = THREE.ImageUtils.loadTexture('images/cloud10.png') var center = new THREE.Vector3(0,-0.8, 0) var maxAge = 1.5; var age2Friction= (function(){ var gradient = createLinearGradient([ {x : 0.00, y: 1.00}, {x : 0.50, y: 1.00}, {x : 0.70, y: 0.90}, {x : 1.00, y: 0.90} ]); return function(age, maxAge){ return gradient(age/maxAge) } })(); var age2Opacity = createTweenMidi(maxAge, 0.05*maxAge, 0.4*maxAge); this.emit = function(position){ // init sprite material var material = new THREE.SpriteMaterial({ map : texture, useScreenCoordinates : false, }) // init sprite var sprite = new THREE.Sprite(material) sprite.position.copy(position) sprite.position.x += (Math.random()-0.5)*0.1 sprite.position.y += (Math.random()-0.5)*0.0001 sprite.position.z += (Math.random()-0.5)*0.1 container.add(sprite) // set velocity var velocity = new THREE.Vector3(0, 1, 0) velocity.x += (Math.random()-0.5)*0.3; velocity.y += (Math.random()-0.5)*0.1; velocity.z += (Math.random()-0.5)*0.3; velocity.setLength(1.15 + (Math.random()-0.5)*0.3) // init patterm material.color.setHex( 0x010101*Math.floor(255*(Math.random()*0.1+0.3)) ); sprite.scale.set(1,1,1).multiplyScalar(0.8 + Math.random()*0.2) sprite.rotation = Math.random() * Math.PI*2 material.opacity= age2Opacity(0) var birthDate = Date.now()/1000; updateFcts.push(function callback(delta, now){ var age = now - birthDate; if( age >= maxAge ){ sprite.parent.remove(sprite) updateFcts.splice(updateFcts.indexOf(callback),1) return; } // handle friction velocity.multiplyScalar( age2Friction(age, maxAge) ) // move by velocity sprite.position.add( velocity.clone().multiplyScalar(delta) ) // make it grow sprite.scale.multiplyScalar( 1.005 ) material.opacity = age2Opacity(age) }) } var _loopCb = null; this.start = function(position, rate){ rate = rate !== undefined ? rate : 5; var lastEmit = 0; updateFcts.push(_loopCb = function(delta, now){ // rate limiter emition if( rate === 0 || now - lastEmit < 1/rate ) return; lastEmit = now; this.emit(position) }.bind(this)) return this; } this.stop = function(){ updateFcts.splice(updateFcts.indexOf(_loopCb),1) return this; } this.update = function(delta, now){ updateFcts.forEach(function(updateFct){ updateFct(delta, now) }) } function createTweenMidi(maxAge, attackTime, releaseTime){ return function(age){ if( age < attackTime ){ return age / attackTime }else if( age < maxAge - releaseTime ){ return 1; }else{ return (maxAge - age) / releaseTime } } } function createLinearGradient(keyPoints){ return function(x){ // find the keyPoints for( var i = 0; i < keyPoints.length; i++ ){ if( x <= keyPoints[i].x ) break; } if( i === 0 ) return keyPoints[0].y; // sanity check console.assert(i < keyPoints.length ); // compute the y var previous = keyPoints[i-1]; var next = keyPoints[i]; var ratio = (x - previous.x) / (next.x - previous.x) var y = previous.y + ratio * (next.y - previous.y) // return y return y; } } } </script></body>