お久しぶりです。それではAfter Effectsのエクスプレッションでパーティクルを表現する記事の第三回目です。今回は今までの知識を応用しつつ、もうすこしパーティクルの挙動を複雑にしていきます。途中で少し数式が出てきますがそんな難しくないんで大丈夫だと思います。(クリックで動画再生)
前回より少し複雑な運動にしてみました。それではこのような表現をExpressionでつけていきます。このプロジェクトのデータはこちらからダウンロードできます。
基本的な考え方
基本的な考えは前回と同様です。ただ今回はパーティクルの動きを複雑化するために、少し数学の力を借りることにします。
今回は曲線が中央から飛び出すような表現にしたかったので、パーティクルの動きを二次元の極座標として考えて、運動を記述することにしました。画面中央を原点とすると、パーティクルの位置ベクトルxは、
で考えると都合がよさそうです。ですがべつにこれといって根拠があるわけではないので、そこは各々が適当にやればいいような気がします。後はこのkr,Cr,θ0,Cθの値を各インデックスごとにランダムにしてやればうまくいきそうです。
しかし様々な曲線が飛び交うようにするには、Cθの値をある程度極端にしなければなりません。ただCθを、例えば-10 < Cθ < 10として、その値を一様な乱数で決定してしまうと、Cθ ~ 0、つまり直線も曲線と同じ割合で作られてしまいます。それはできるだけ避けたかったので、今回は練習がてら「確率密度関数」を始めに定義して、その確率分布に従う乱数を生成するようにしました。
確率密度関数
今回はCθ~0の部分をなるべく作らないように、確率密度関数f(x)を
として定義しました。
(イメージとしてはこんな感じ)
今回はこの確率密度関数f(x)を用いて、Cθを作ることにします。
それではエクスプレッションを記述します。nullを作成。レイヤー名を"system"とし、スケールにアニメーションを打ち、パーティクルの名前を"c_01"とします。そしてパーティクルの位置とスケールのエクスプレッションに以下を記述します。
位置のエクスプレッション
var system = thisComp.layer("system");
var rate = thisComp.layer("system").effect("レート")("スライダ");
var seed = thisComp.layer("system").effect("シード")("スライダ");
var centre = thisComp.layer("system").position;
var varR = thisComp.layer("system").effect("半径のヴァリエーション")("スライダ");
var VR = thisComp.layer("system").effect("半径速度")("スライダ");
var varVR = thisComp.layer("system").effect("半径速度のヴァリエーション")("スライダ");
var kr = thisComp.layer("system").effect("半径変位量")("スライダ");
var ktheta = thisComp.layer("system").effect("角度変位量")("スライダ");
/*--------Expression記述-----------*/
var index = name.slice(2,4)-1;
seedRandom( seed+index ,true );
var otime = time - index/rate;
var t;
if(otime > 0){
t = otime;
}else{
t = 0;
}
//運動式の記述
var r = random(kr-varR, kr+varR)*Math.log( random(VR-varVR,VR+varVR)*t + 1);
var theta = random(6.283) + RZRandom(ktheta)*t;
var pos = [r*Math.cos(theta),r*Math.sin(theta)];
centre + pos;
//棄却法を用いて確率分布を作成。
function RZRandom(alpha){
var x,y;
while(1){
x = random(-alpha, alpha);
y = random(0, alpha);
if( Math.abs(x) > y ){
return x;
}
}
}
確率密度関数のところは棄却法を用いました。
スケールのエクスプレッション
var system = thisComp.layer("system");
var rate = thisComp.layer("system").effect("レート")("スライダ");
var seed = thisComp.layer("system").effect("シード")("スライダ");
var variation = thisComp.layer("system").effect("スケールのヴァリエーション")("スライダ");
/*----------Expression開始------------*/
var index = name.slice(2,4)-1;
seedRandom( seed+index,true );
random(1-variation, 1+variation)*system.scale.value_at_time( time - index/rate );
最後にエコーとグローを加え、タイムリマップで強調させて完成です。レンダリングは正直かなり重いですが、それでもパーティクルのレートや速度、その変化量まで柔軟に変更できるという点が便利かと。
0 件のコメント:
コメントを投稿