Three.js:如何沿着线动画粒子

jig*_*lly 3 javascript animation particles three.js

我试图沿着类似于这个铬表现的路径动画粒子:http://armsglobe.chromeexperiments.com/

我已经尝试深入研究这个项目的来源,到目前为止我已经讨论过他们正在使用内置的曲线方法.getPoitns()在他们的行上生成大约30个点.

我正在努力实现的目标是否有更好的例子?是否有一种方法可以在线上获得点数而不是使用.lerp()方法30次获得30分?我应该只使用TWEEN动画吗?

任何帮助或方向将不胜感激.

jig*_*lly 6

我已经找到了解决方案,不确定它是否是最好的,但它运作良好.

你可以在JsFiddle上找到一个演示:https://jsfiddle.net/L4beLw26/

//First create the line that we want to animate the particles along
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(-800, 0, -800));
geometry.vertices.push(new THREE.Vector3(800, 0, 0));

var line = new THREE.Line(geometry, material);
var startPoint = line.geometry.vertices[0];
var endPoint = line.geometry.vertices[1];
scene.add(line);


//next create a set of about 30 animation points along the line
var animationPoints = createLinePoints(startPoint, endPoint);

//add particles to scene
for ( i = 0; i < numParticles; i ++ ) {
  var desiredIndex = i / numParticles * animationPoints.length;
  var rIndex = constrain(Math.floor(desiredIndex),0,animationPoints.length-1);
  var particle = new THREE.Vector3();
  var particle = animationPoints[rIndex].clone();
  particle.moveIndex = rIndex;
  particle.nextIndex = rIndex+1;
  if(particle.nextIndex >= animationPoints.length )
    particle.nextIndex = 0;
  particle.lerpN = 0;
  particle.path = animationPoints;
  particleGeometry.vertices.push( particle );
}

//set particle material
var pMaterial = new THREE.ParticleBasicMaterial({
  color: 0x00FF00,
  size: 50,
  map: THREE.ImageUtils.loadTexture(
    "assets/textures/map_mask.png"
  ),
  blending: THREE.AdditiveBlending,
  transparent: true
});


var particles = new THREE.ParticleSystem( particleGeometry, pMaterial );
particles.sortParticles = true;
particles.dynamic = true;
scene.add(particles);


//update function for each particle animation
particles.update = function(){
  // var time = Date.now()
  for( var i in this.geometry.vertices ){
    var particle = this.geometry.vertices[i];
    var path = particle.path;
    particle.lerpN += 0.05;
    if(particle.lerpN > 1){
      particle.lerpN = 0;
      particle.moveIndex = particle.nextIndex;
      particle.nextIndex++;
      if( particle.nextIndex >= path.length ){
        particle.moveIndex = 0;
        particle.nextIndex = 1;
      }
    }

    var currentPoint = path[particle.moveIndex];
    var nextPoint = path[particle.nextIndex];


    particle.copy( currentPoint );
    particle.lerp( nextPoint, particle.lerpN );
  }
  this.geometry.verticesNeedUpdate = true;
};




function createLinePoints(startPoint, endPoint){
  var numPoints = 30;
  var returnPoints = [];
  for(i=0; i <= numPoints; i ++){
    var thisPoint = startPoint.clone().lerp(endPoint, i/numPoints);
    returnPoints.push(thisPoint);
  }
  return returnPoints;
}

function constrain(v, min, max){
  if( v < min )
    v = min;
  else
    if( v > max )
      v = max;
  return v;
}
Run Code Online (Sandbox Code Playgroud)

然后在动画循环中: