1. 程式人生 > >利用Three.js構建粒子系統

利用Three.js構建粒子系統

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;