使用threejs点云秀出酷炫的图片效果(二)
上一次使用粒子系统,通过改变每一个粒子的位置和颜色构成了一副图片,这次我们使用批量操作粒子移动构成放映机的效果。
首先需要控制每一个粒子移动,每一个粒子就需要两套位置,第一个位置是起始时粒子所在的位置,第二个位置时结束时粒子所在的位置。为了能使每一个粒子单独进行移动这里还给每个粒子设置了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