three.proton
Version:
three.Proton is an easily customizable html5 particle engine for three.js
172 lines (140 loc) • 4.91 kB
HTML
<html>
<head>
<title>three.proton - customrender</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style type="text/css">
body {
font-family: Monospace;
background-color: #fff;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="../lib/stats.min.js"></script>
<script src="../lib/three.min.js"></script>
<script src="../lib/require.js"></script>
<script src="../lib/config.js"></script>
<script>
var proton, emitter;
var camera, scene, renderer, stats, clock, spring;
var mesh;
function init() {
loadModel(initAll);
}
function initAll() {
initScene();
initLights();
initProton();
addStats();
animate();
}
function initScene() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 500;
scene = new THREE.Scene();
scene.fog = new THREE.Fog(0xffffff, 1, 10000);
clock = new THREE.Clock();
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
}
function initLights() {
var ambientLight = new THREE.AmbientLight(0x101010);
scene.add(ambientLight);
var pointLight = new THREE.PointLight(0xffffff, 2, 1000, 1);
pointLight.position.set(0, 200, 200);
scene.add(pointLight);
}
function addStats() {
stats = new Stats();
stats.showPanel(0);
stats.dom.style.position = 'absolute';
stats.dom.style.left = '0px';
stats.dom.style.top = '0px';
container.appendChild(stats.dom);
}
function initProton() {
proton = new Proton();
proton.addEmitter(createEmitter());
//add custom renderer
var renderer = new Proton.CustomRender();
renderer.onParticleCreated = function(p) {
//p.target = mesh.clone();
p.target = this.targetPool.get(mesh);
p.target.position.copy(p.p);
scene.add(p.target);
}
renderer.onParticleUpdate = function(p) {
p.target.position.copy(p.p);
p.target.rotation.set(p.rotation.x, p.rotation.y, p.rotation.z);
var scale = p.scale * 30;
p.target.scale.set(scale, scale, scale);
}
renderer.onParticleDead = function(p) {
this.targetPool.expire(p.target);
scene.remove(p.target);
p.target = null;
}
proton.addRender(renderer);
}
//load model
function loadModel(callback) {
var material = new THREE.MeshNormalMaterial();
var loader = new THREE.JSONLoader();
loader.load('./assets/suzanne.js', function(geometry) {
geometry.computeVertexNormals();
mesh = new THREE.Mesh(geometry, material);
callback();
});
}
function createEmitter() {
emitter = new Proton.Emitter();
emitter.rate = new Proton.Rate(new Proton.Span(4, 8), new Proton.Span(.2, .5));
emitter.addInitialize(new Proton.Mass(1));
emitter.addInitialize(new Proton.Radius(100));
emitter.addInitialize(new Proton.Life(2, 4));
emitter.addInitialize(new Proton.Velocity(400, new Proton.Vector3D(0, 1, 0), 60));
// //emitter.addBehaviour(new Proton.RandomDrift(30, 30, 30, .05));
emitter.addBehaviour(new Proton.Rotate("random", "random"));
emitter.addBehaviour(new Proton.Scale(1, .1));
emitter.addBehaviour(new Proton.G(6));
var zone = new Proton.BoxZone(600);
zone.friction = 0.95;
zone.max = 7;
emitter.addBehaviour(new Proton.CrossZone(zone, "bound"));
emitter.addBehaviour(new Proton.Color(0xff0000, 'random', Infinity, Proton.easeOutQuart));
emitter.p.x = 0;
emitter.p.y = 0;
emitter.emit();
Proton.Debug.drawZone(proton, scene, zone);
return emitter;
}
function animate() {
stats.begin();
requestAnimationFrame(animate);
render();
stats.end();
}
var tha = 0;
function render() {
proton.update();
renderer.render(scene, camera);
tha += .005;
camera.lookAt(scene.position);
camera.position.x = Math.sin(tha) * 500;
camera.position.z = Math.cos(tha) * 500;
Proton.Debug.renderInfo(proton, 3);
}
function onWindowResize() {
}
</script>
</body>
</html>