Firefly : 2D Particle System で色変化の表現をしてみる

街中にデジタルサイネージが増えてきましたが、ときどき広告じゃなくて抽象的なデジタルアートを掲載しているものも見かけます。そんな雰囲気の作品をProcessingでスケッチしてみたので、書き留めておきます。




ProcessingのParticleは、Processing公式サイトにサンプルが掲載されているので、参考にできます。
ただし、このサンプルにはバグがあるので、ついでにここで修正しておきます。

 // Is the particle still useful?
  boolean isDead() {
    if (lifespan <= 0.0) {//ここを<から<=に変更する
      return true;
    } else {
      return false;
    }
  }

このサンプルではlifespanがそのままParticleのアルファになっているのですが、この条件判定とrun()の実行順序だと、最後のdisplay()のときにアルファが-1で描画されます。 すると、最後の一瞬だけアルファがかからない状態になってしまうため、実行すると画面内でParticleの消失が起きたときに、ちらちらノイズが載ってしまいます。
サンプル上は消失は画面外ですが、変更した表現をするとこの現象に遭遇します。



この作品ではParticleSystem全体に対して色が時間で変化する表現をさせています。最初の色から、次の色へ時間経過に応じてグラデーションで変化するようになっています。ここでは、その説明を掲載します。

下記は2Dで画面にグラデーションをかけるコードの応用です。
ポジションでグラデーションするのではなく、時間でグラデーションするようにしています。

 //constructor
  ParticleSystem() {
    particles = new ArrayList();

    //setup gradation
    col1 = color(#806FFF);
    col2 = color(#FFEB6F);
    dr = (red(col2)-red(col1))/BASE;
    dg = (green(col2)-green(col1))/BASE;
    db = (blue(col2)-blue(col1))/BASE;
    delta = 0;
    direction = 1;
  }

  void addParticle() {
    color pc = color(
      (red(col1) + delta*dr),
      (green(col1) + delta*dg),
      (blue(col1) + delta*db)
    );
    particles.add(new Particle(new PVector(random(0,width),random(0,height)), pc, random(4,24)));
    if(delta > BASE){
      direction = -1;
    } else if (delta < 0) {
      direction = 1;
    }
    delta = delta + direction;
  }



次はParticleSystemをベースにユーザアクションとのインタラクションやもう少し複雑な動きをする作品を作ってみたいと思います。