上一次使用粒子系統,通過改變每一個粒子的位置和顏色構成了一副圖片,這次我們使用批量操作粒子移動構成放映機的效果。
首先需要控制每一個粒子移動,每一個粒子就需要兩套位置,第一個位置是起始時粒子所在的位置,第二個位置時結束時粒子所在的位置。爲了能使每一個粒子單獨進行移動這裏還給每個粒子設置了scale速率,當到達1.0時結束移動。
function createPotCloud() { //創建點雲 console.log(imgDate); particles = canvas.width * canvas.height; geometry = new THREE.BufferGeometry(); positions = new Float32Array( particles * 3 ); positions_af = new Float32Array( particles * 3 ); scale = new Float32Array( particles); var colors = new Float32Array( particles * 3 ); for ( var i = 0; i < scale.length; i ++ ) { // positions scale[ i ] = 0; } for ( var i = 0; i < positions.length; i ++ ) { // positions positions[ 3*i ] = 0; positions[ 3*i + 1 ] = 0; positions[ 3*i + 2 ] = 0; // colors colors[ 3*i ] = imgDate.data[ 4*i ]/255.0; colors[ 3*i + 1 ] = imgDate.data[ 4*i + 1]/255.0; colors[ 3*i + 2 ] = imgDate.data[ 4*i + 2]/255.0; } for ( var i = 0; i < positions_af.length; i ++ ) { // positions positions_af[ 3*i ] = -150+parseInt(i%canvas.width)/2; positions_af[ 3*i + 1 ] = 200+ parseInt((canvas.height-i)/canvas.width)/2 ; positions_af[ 3*i + 2 ] = 0; } geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) ); // geometry.computeBoundingSphere(); console.log("geometry",geometry); var material = new THREE.PointsMaterial( { size: 1, vertexColors: THREE.VertexColors } ); console.log("material",material); uniforms = { //uniforms變量 ut:{type: "f", value: 0} }; var shaderMaterial = new THREE.ShaderMaterial( { // uniforms: uniforms, vertexShader:document.getElementById( 'vertexshader' ).textContent, fragmentShader: document.getElementById( 'fragmentshader' ).textContent }); var points = new THREE.Points( geometry, material ); console.log("shaderMaterial",shaderMaterial); scene.add( points ); load_ok = true; }
移動速率使用的是先慢後快的方式,在粒子移動的前90%的路程都採用的慢速移動,以便顯現出放映機的效果,最後時刻增加速度快速到位。在render遍歷粒子對象,每次增加移動粒子的個數。
var now_pot_num = 100; var scale; function render() { //更新點雲位置數據 if(load_ok){ if(now_pot_num < positions.length/3){ now_pot_num+=100; } for ( var i = 0; i < now_pot_num; i ++ ) { if(scale[i] < 1.0){ if( positions[ 3*i +1]< positions_af[3*i+1]*scale[i]*0.9){ scale[i] += 0.1; }else{ scale[i] += 0.015; } } positions[ 3*i ] = positions_af[3*i]*scale[i] ; positions[ 3*i + 1 ] = positions_af[3*i+1]*scale[i]; positions[ 3*i + 2 ] = 0; } geometry.attributes.position.needsUpdate = true; } renderer.render( scene, camera ); controls.update(); }實現效果:
Github:https://github.com/StringKun/ThreeJSPotCloud/tree/master/potcloud2