それではAfter Effectsのエクスプレッション(Expression)でパーティクルを表現する記事の第二回目です。前回はあまり面白くない動画となってしまったので、少し手を加えてみることにしました。(クリックで動画再生)
このように星が外側に流れていく表現をエクスプレッションでつけていきます。今回のプロジェクトデータはこちらからダウンロードできます。
基本的な考え方
基本的な考えは前回と変わらず、
- レイヤーの名前を利用してインデックスを指定し、
- インデックスを利用してアニメートする時間を決定
random()メソッドについて
今回重要となるのがrandom()メソッドについてです。random()メソッドは文字通り0~1のランダムな値を返すメソッドで、AEのエクスプレッションでは非常によく使われる関数です。ただ、このまま使用してしまうと1フレームごとに異なる値が帰ってきてしまいます。通常の使用用途でしたらこれでいいのですが、今回は時間で変わることのない値を返してほしいので、random()メソッドの前にseedRandom()関数を記述します。
seedRandom(offset,timeless)関数は乱数シード値を変更するメソッドです。offsetにはシードの値、timelessにはrandom()メソッドの乱数シード値に時間を使用するかを記述します。通常ではtimeless=falseとなっていますが、今回はtrueにしてrandom()メソッドを時間に依存しないようにしました。
エクスプレッション
それではエクスプレッションを記述していきます。nullを作成しスケールに0→100→0%となるようにキーフレームを打ち、パーティクルの名前を"s_01"とします。そしてパーティクルの位置とスケールのエクスプレッションに以下を記述します。
位置のエクスプレッション
var centre = [320,240]; //中心点
var radius = 209; //半径
var seed = 10; //シード
var rate = 28; //一秒間に何回パーティクルが出現するか
var vel = 1; //速度比例定数
/************Expression開始*************/
var num = name.slice(2,4)-1;
seedRandom( seed+num,true );
//初期位置に関する記述
var r = random(radius);
var theta = random(6.283);
var pos = new Array( r*Math.cos(theta),r*Math.sin(theta) );
//移動に関する記述
var t_start = num/rate; var transfer;
if(time < t_start){
transfer = new Array(0,0);
}else{
transfer = mul( pos , vel*(time - t_start) );
}
//最終位置の決定
centre + pos + transfer;
スケールのエクスプレッション
var rate = 28; //一秒間に何回パーティクルが出現するか
var num = name.slice(2,4)-1;
thisComp.layer("null").scale.value_at_time( time - num/rate );
もちろん最初の変数は変更しやすくするために、nullにエクスプレッション制御のエフェクトを追加して指定させてあげたほうが使いやすいと思います。
その後にCtrl+dキーを使ってパーティクルを大量に複製させ、グロー処理を行ったりとかの味付けをして完成です。背景の星空はフラクタルノイズを使用しました。よーく見ると背景もアニメーションしているのが分かるはずです。
ただ正直この程度だったらエクスプレッションを使用せずにパーティクルエフェクトを使用したほうが現実的ですね。一応半径を変形できたり後に動きを柔軟につけられるとか利点はあるんですけど。次回はエクスプレッションならではのアニメーションをさせてみます。
補足説明
AfterEffectsはベクトル関係のメソッドが充実しています。小さな三角形をクリックして、"Vector Math"を調べると加算、減算、スカラー倍、内積、外積、単位ベクトル化など大体のベクトル演算が揃っていることがわかります。ちなみにこのメソッドを使わなくても、
- 加算:vec1 + vec2
- 減算:vec1 - vec2
- スカラー倍:k*vec1
程度だったらわざわざメソッドで処理しなくてもきちんと認識してくれます。もちろん"vec1*vec2"のようなものはエラーになります。