2007/10/15

After Effectsのエクスプレッションでパーティクルを表現する-01

最近はニコニコ動画とかYoutubeの登場によって、After Effectsを利用して映像を製作する人が増えているような気がします。しかしAfter Effectsを解説している日本のサイトは数えられるほど少なく、またその中でエクスプレッションの説明をしているサイトなんていうともうほとんどありません(なんか前もおんなじこと書いたような気がする) というわけでこれからAfter Effectsのエクスプレッション(Expression)の情報を載せていきたいと思います。よくある入門的な記事じゃなく、即戦力になる実用的な使い方を紹介していくつもりです。興味のある人は検索からたどりつくでしょう。たぶん :(

エクスプレッションを使用して似非パーティクルシステムを作る。

After Effectsには一応標準でパーティクルプレイグラウンドという、パーティクルを発生させるエフェクトがあったりするんですけど正直使い勝手はあまりよくありません。そこで今回はエクスプレッションを利用してエミットからパーティクルを放出させるエフェクトを作ってみることにします。

参考にしたサイト

水玉映像・・・基本的な考え方はこのサイトを参考にさせていただきました。ホント勉強になります。感謝。

エクスプレッションを使うメリット
  1. パーティクルの一つ一つに複雑な動きや統一的な動きをつけられる(これが一番大きいです。微調整もしやすいですし、数十個のフッテージを一括して調整できます)
  2. 処理が基本的に軽い。(せいぜい数十個のレイヤーしか扱いませんし)
  3. 手作業でやらなければいけないアニメート作業がエクスプレッションを使用することである程度軽減される
デメリット
  1. いちいちエクスプレッションを書かないといけない
  2. 数百個とか莫大な数のフッテージは処理できない
  3. 数式やプログラムに拒絶反応を示す人は苦手かも
ってなかんじです。パーティクルとまではいかないけど数十個のフッテージの動きを統一させたいなんて場合には使えると思います。

螺旋を描く星群を作る


今回作る動画は次のような感じです。(クリックで動画再生)

モーショングラフィックス的には面白くない動画ですけど、始めはこんなんからやっていきます。
今回使用したプロジェクトデータはこちらからダウンロードできます。

エミッタの動きを作る


それではまずパーティクルの発生源であるエミッタの動きをエクスプレッションでつけていきます。
「レイヤー→新規→ヌルオブジェクト」を選択してヌルオブジェクトを作ります。レイヤー名を"null"にして位置のストップウォッチをAlt + クリック。螺旋の動きをエクスプレッションにて記述していきます。
螺旋の動きを表すベクトルP(t)は

P(t) = ( r(t)cosωt , r(t)sinωt ) , r(t) = R - kt (R,k,ωは定数)

で表現できるので、エクスプレッションは

 
//初期化宣言
var R = 230; //最大半径
var k = -80; //減衰量
var omega = 10; //角速度(rad/s)
var alpha = -1; //開始角度(rad)

//Expression開始。
var r = R + k*time;

if( r < 0){
r = 0;
}

var pos = new Array( r*Math.cos( omega*time + alpha ),
r*Math.sin( omega*time + alpha ));

position + pos;

となります。これで螺旋の動きをつけることができました。

パーティクルを作る


それではパーティクルの製作に取り掛かりたいと思います。制作方法は大まかに


  1. フッテージ(パーティクル)がどの場所で現れるのかエクスプレッションで記述。レイヤー名を"なんたら01"みたいな感じにすることで、複製させたときに01,02,03...と各フッテージにインデックスがつけられるようにする。

  2. エクスプレッションでレイヤー名から自分のインデックスだけを切り出して、適切な場所に配置。

  3. スケールや回転などのアニメーションさせたいプロパティは"null"にアニメーションを記述し、エクスプレッションで参照させることによって一括管理する。



となっています。文章で説明するよりもスクリーンショットを見てもらったほうが早いです。(クリックで拡大)



このエクスプレッションで重要なメソッドとプロパティは以下のようになります。

  • name.slice(val1,val2)
    nameプロパティは自身のレイヤー名を表すプロパティで、slice(val1,val2)メソッドはval1を開始位置、val2を終了位置として文字列を抜き出すメソッドです。この場合は"s_50"という文字列から50が抜き出されることとなります。

  • value_at_time(time)
    特定のプロパティの、任意の時間での値を返します。たとえばposition.value_at_time(1)でしたら1秒の時点での位置情報を返しますし、scale.value_at_time(2)でしたら2秒の時点でのスケールの値を返します。
    ただし注意しなければいけないのが、「value_at_timeメソッドは、エクスプレッションで記述された値を返さない」 ということです。value_at_timeメソッドが返す値はあくまでキーフレームの値であり、エクスプレッションは無視されます。

それではオブジェクトの位置を決定し、スケールをアニメートさせるために、位置とスケールのエクスプレッションを記述します。
パーティクルの表現に重要となるのはインデックスの値です。"s_○○"の○○の値によって、自身が出現するべき時間と位置を決定させます。

位置のエクスプレッション
 
var num = name.slice(2,4)-1;
thisComp.layer("null").position.value_at_time( num *
thisComp.layer("null").effect("比例定数")("スライダ"));

スケールのエクスプレッション
 
var num = name.slice(2,4)-1;
scale = thisComp.layer("null").scale.value_at_time(time -
num*thisComp.layer("null").effect("比例定数")("スライダ"));

とりあえず今回のプロジェクトデータを参照すれば、ある程度分かるかと思います。
今回はとりあえず軽めにいきました。次から少し応用に入っていきます。

0 件のコメント: