【AfterEffects】バウンスのエクスプレッション 式の意味も徹底解説

こんにちわ!

こんな感じのCG合成動画チャンネルを運営中のファイアー飯塚と申します!

 

 

本日はバウンスのエクスプレッションについて解説します!

この記事で学べるエクスプレッション

  • バウンス全体
  • value
  • numKeys
  • nearestKey
  • index
  • velocityAtTime
  • Math.sin
  • ...etc

※全部書いてたらキリがないので抜粋

 

関連記事

【初心者必見】独学でAfterEffectsをゼロからマスターするためのロードマップ【勉強方法、上達への道のり】

コード

amp = 0.1;
freq = 5;
decay = 7;

n = 0;
if (numKeys > 0){
n = nearestKey(time).index;
if (key(n).time > time){
n--;
}
}
if (n == 0){
t = 0;
}else{
t = time - key(n).time;
}

if (n > 0){
v = velocityAtTime(key(n).time - thisComp.frameDuration/10);
value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
}else{
value;
}

使い方

キーフレームがあるパラメータにエクスプレッションを入力

※イージングをかけるとうまくいかないのでリニアにしましょう

 

 

例としてスケールが大きくなる円にバウンスをかけてみましょう

 

 

スケールのキーフレームはこんな感じ

 

 

エクスプレッションが無い状態の動き

 

 

スケールにエクスプレッションを追加するとこんな感じに

動きがポップになり使い勝手が良さそう

 

 

次はバウンスの動きの変え方を教えます

先程の式に

amp = 0.1;
freq = 5;
decay = 7;

という部分があったと思います

 

こちらの数値をいじればバウンスの動きが変わります

  • amp = 振幅
  • freq = 振動数
  • decay = 減衰までの時間調整変数

名称は今僕が決めました

 

値を変えて動きの変化を見てみてください

次章で式の原理を解説します

式の意味を解説

式の意味もわからず使うのはあまり勧めません

応用のためにもぜひ意味を理解しましょう

全体の概要

まずはざっくりと式の中身を見ていきます

amp = 0.1;
freq = 5;
decay = 7;

これは後式の変数を決める部分

その後、エクスプレッションは2つのブロックに分けて見ることができます

①・・・nとtを定義するブロック

②・・・バウンスの実行ブロック

 

 

n ?? t ??

となるかもしれませんがnとtは②でバウンスを実行するために必要な変数なのです

②の式を見てみるとnとtが使われてますよね

 

 

とりあえず大まかにこのプログラムを説明すると

①でnとtを定義し、②でnとtを使いバウンスを実行している

になります

 

それではそれぞれ見ていきましょう

① nとtを定義

①ではnとtを定義していると解説しました

どのように定義しているのでしょうか?

例として、スケールにキーフレームを2つ打った場合を想定します

(2秒でスケール100、5秒でスケール200とする)

 

結論から書くと、nとtは以下のように定義されます

n = 0 (time < 2)
n = 1 (2 < time < 5)
n = 2 (5 < time)

t = 0 (time < 2)
t = 0→3 (2 < time < 5)
t = 0から上昇 (5 < time)

ではなぜそうなるのか

1行1行見ていきます

 

n = 0;

まずnは0と定義

 

if (numKeys > 0){
n = nearestKey(time).index;

もしもキーフレームの数(numKeys)が0以上ならば以下を実行

nは現時間の1番近いキーフレーム(nearestKey(time))のインデックス番号の値(.index)になる

 

MEMO
インデックス番号というのは単にキーフレームが何個目かと言うこと
1個目のキーフレームならインデックス番号は1になるし、10個目ならそれは10です

 

今回キーフレームは2秒と5秒に打っています

例えば、現時間が1.3秒なら1番近いのは1個目のキーフレームなので

n = 1

例えば、現時間が3.8秒なら1番近いのは2個目のキーフレームなので

n = 2

 

現時点でのnの値はこのようになります

 

if (key(n).time > time){
n--;
}

現時間よりもn番目のキーフレーム時間のほうが大きかったら、nにマイナス1

 

例えば、現時間が1.3秒ならn = 1
現時間よりもn個目のキーフレーム時間(2秒)のほうが大きいので

n = 1 - 1
= 0

例えば、現時間が3.8秒ならn = 2
現時間よりもn個目のキーフレーム時間(5秒)のほうが大きいので

n = 2 - 1
= 1

例えば、現時間が5.6秒ならn = 2
現時間よりもn個目のキーフレーム時間(5秒)のほうが小さいので

n =2 のまま

 

よってnは時間によってこのように変化します

 

 

}
if (n == 0){
t = 0;
}else{
t = time - key(n).time;
}

次はtです

nが0ならtも0

nが0じゃないなら、tは現時間からn個目のキーフレーム時間を引いた値になります

 

例えば、現時間が3.8秒なら先程の説明よりn = 1

よってtは

t = 3.8 - 2(1個目のキーフレーム時間)
= 1.8

 

つまりtは時間によって変化する値です

キーフレームに位置ではt =0になりそこから時間と共に上昇する感じですね

 

まとめるとこうなるわけです

② バウンスの実行

①が理解できれば②は非常に簡単

 

if (n > 0){
v = velocityAtTime(key(n).time - thisComp.frameDuration/10);

nが0より大きいなら以下を実行

v = n番目のキーフレーム時間(key(n).time)のちょこっと前の時間(- thisComp.frameDuration/10)の速度

速度は今回でいうとスケールの上昇の速さになります

ややこしいですね でもnは今の例では1と2しかないので簡単です

 

例えば、n = 1の時のvは0になります

なぜかと言うと、1番目のキーフレーム時間(2秒)のちょこっと前の時間(1.98秒とかにしましょう)ではスケールは全く変わっておらず、速度は0だからです

 

n = 2の時のvは値を持ちます

2番目のキーフレーム時間(5秒)のちょこっと前の時間(4.98秒とかにしましょう)ではスケールはまさに大きくなっている最中で速度を持つからです

 

今回はn = 2の時にvは正の値を持ちます

(スケールが減少していればvは負の値になる 今回は正)

 

 

value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
}

value(その時間のスケールの値)にsin関数を自然対数eのべき乗で割ったものを足します

 

 

v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t)

この部分は数学の話になってしまうので詳しくは解説しませんが

最初は値が振動するけどtが増加するにつれて0に収束していくよと言う感じです

 

ここでamp、freq、decayが使われていますね

 

ampを変えれば振幅が変わりそうだし

decayを変えれば収束までの時間が変わりそうでしょう?

この辺は数学の知識なので説明は省きますがなんとなく想像はつくと思います

 

 

さて、vはn = 2の時に値をもちますので

つまりは2番目のキーフレームからvalueの値に関数が足されバウンスの表現を実現できるわけです

else{
value;
}

elseは冒頭のif (numKeys > 0){ にかかってきます

今までの話はすべてキーフレームが存在したらの話でした

つまりはキーフレームがないなら特に何もしないよと

エクスプレッションの中身は理解する必要があるのか?

あると思います

大いに

 

 

例えば、video copilot社のCornerpin to Nullのような難解なエクスプレッションは理解する必要はないと思いますが

このぐらいのエクスプレッションなら絶対に理解するべきです

 

 

特にエクスプレッションをゴリゴリ仕事で使う人なんかはマストだと思います

 

 

まぁ理解してなくても使えるんですけどね

意味がわかってると応用が効くし、バグに対処しやすくなります 絶対に

 

 

しかし、バウンスのエクスプレッションを解説している日本人がいなかった!

ホワイ!?解説する側であれば確実に中身を説明すべきでしょう

「そこまで説明する必要はないと思った」と反論がきそうですが、一部に需要はあるはずです

需要があるのならば補足でもいいから解説すべきだ

 

 

ていうか、解説してるやつらあああああ!!!お前ら中身理解してないで解説してんだろー!!!!

 

憤りを感じた僕は自分で解説するのであった!

まとめ

  • バウンスのコードを解説
  • バウンスは有能なので使おう
  • 式の意味もできれば理解しよう

 

映像を勉強してて思うのは理屈を解説している人が少なすぎると言うこと

このエフェクトとこのエフェクトをかければこうなるよー!

ふぁ!?結果だけじゃなくて理屈も知りたいんじゃこっちはーー!!

・・・なんて言ってますが解説者の方々はパニックを起こさないように簡潔に解説してくれているのだと思いますけどね笑

 

 

そんな中アホみたいに中身を解説する人がいてもいいかなと思いまして!

ってなわけで僕は今後も必ず理屈を解説していきます

理屈を理解することで最強になれるのです

 

nを定義する部分はいろいろ応用できそうですよねぇ・・・

 

それでは!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です