利用Three.js構建粒子系統
阿新 • • 發佈:2019-02-13
var scene, camera, renderer, spot1, stats;
var clock = new THREE.Clock();//時鐘
var cameraControls;
var cloud, controls;
function init() {
stats = new initStats();//初始化檢測幀頻
scene = new THREE.Scene();//場景
camera = new THREE.PerspectiveCamera(45 , window.innerWidth / window.innerHeight, 0.1, 1000);//透視相機
camera.position.set(0, 0, 150);//相機位置
scene.add(camera);//add到場景中
spot1 = new THREE.SpotLight(0xffffff, 1);//點光源
spot1.position.set(100, 200, 100);
scene.add(spot1);
renderer = new THREE.WebGLRenderer({antialias: true });//渲染
renderer.setClearColor(0x00000);//設定可以認為是底圖的顏色
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapEnabled = true;//shadow,陰影,表明能渲染陰影
cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement);//相機控制器
cameraControls.target.set(0 , 0, 0);//控制器始終指向原點
document.getElementById('webGL_output').appendChild(renderer.domElement);//將渲染Element新增到Dom中
/*
控制器,用於選擇建立粒子的數量大小等
*/
controls = new function () {
this.createNums = 5000;//預設建立5000個粒子
this.size = 4;//預設大小
this.transparent = true;//透明的
this.opacity = 0.6;//不透明
this.vertexColors = true;//座標點集顏色
this.color = 0xffffff;//控制器本身顏色
this.sizeAttenuation = true;//如果為false 則所有粒子擁有相同的尺寸。無論距離相機多遠
this.rotateSystem = true;//是否旋轉
this.rotateSpeed = 0.005;//預設旋轉速度
this.redraw = function () {
if (scene.getObjectByName('particles')) {
scene.remove(scene.getObjectByName('particles'));
}//存在則清除,然後重製
createParticles(controls.createNums, controls.size, controls.transparent, controls.opacity, controls.vertexColors, controls.sizeAttenuation, controls.color);
}
};
var gui = new dat.GUI();
gui.add(controls, 'createNums', 1, 10000).onChange(controls.redraw);//建立粒子數由1到10000個
gui.add(controls, 'size', 0, 10).onChange(controls.redraw);//大小0——10
gui.add(controls, 'transparent').onChange(controls.redraw);
gui.add(controls, 'opacity', 0, 1).onChange(controls.redraw);
gui.add(controls, 'vertexColors').onChange(controls.redraw);
gui.addColor(controls, 'color').onChange(controls.redraw);
gui.add(controls, 'sizeAttenuation').onChange(controls.redraw);
gui.add(controls, 'rotateSystem').onChange(controls.redraw);
gui.add(controls, 'rotateSpeed', 0.001, 0.01).onChange(controls.redraw);
controls.redraw();
render();
}
/*
將檢測幀頻顯示在左上方。
*/
function initStats() {
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.getElementById('stats_output').appendChild(stats.domElement);
return stats;
}
/*
該函式用於生成粒子
*/
function createParticles(createNums, size, transparent, opacity, vertexColors, sizeAttenuation, color) {
//幾何體
var geom = new THREE.Geometry();
//粒子系統材質,
var material = new THREE.PointCloudMaterial({
size: size,
transparent: transparent,
opacity: opacity,
vertexColors: vertexColors,
sizeAttenuation: sizeAttenuation,
blending:true,
color: color
});
var range = 500;
for (var i = 0; i < createNums; i++) {
var particle = new THREE.Vector3(Math.random() * range - range / 2,
Math.random() * range - range / 2, Math.random() * range - range / 2);
geom.vertices.push(particle);//點加入
var color = new THREE.Color(0x00ff00);//預設,關於顏色的設定只在vertexColors設定為true時使用
color.setHSL(color.getHSL().h, color.getHSL().s, Math.random() * color.getHSL().l);
geom.colors.push(color);//顏色加入
}
cloud = new THREE.PointCloud(geom, material);//粒子云系統
cloud.name = 'particles';//命名名字,在重繪的時候使用
scene.add(cloud);
}
var step = 0;
function render() {
stats.update();
if (controls.rotateSystem) {
step += controls.rotateSpeed;
cloud.rotation.x = step;
// cloud.rotation.y = step;
cloud.rotation.z = step;
}//旋轉起來
requestAnimationFrame(render);//html5的方法,用於繪製一次動畫幀
var delta = clock.getDelta();//根據滑鼠拉扯,相機旋轉
cameraControls.update(delta);
renderer.render(scene, camera);
}
window.onload = init;