イージングスクリプト『EaseSwingerPro』を作ったときにグラフについて色々調べたので、書きます。
グラフエディターについてデザイナーが直感的に理解すればいいこと
グラフエディター画面はトーンカーブと同じく、曲線をながめながら「ここが〇〇を表すから…」と頭をひねりながら考える必要はなく「どんな形がどんな結果になるのか」をだいたい把握しておけばよいです。以下がコツです。
■値グラフ
グラフの上天井が2番目のキーフレームの値を表しています。上に近づけば近づくほど終点の値に近いということです。
*2番目のキーフレームのほうが値が小さい場合はグラフが上下逆になり、下が終点です。
■速度グラフ
一番高いところのスピードが一番速いです。
例えば、スピードが速いところでレイヤーを入れ替えて「いつのまにか▲が■に変身した」みたいなことをやるとき、入れ替えるタイミングはこの一番高いところにしたほうが、入れ替えがバレないのでよい、ということです。
詳しい理解
デザイン、アニメーション作業であれば上記だけ覚えておけばよいのですが、より詳しく理解すると「なんでポジションはXYに分解しないと値グラフが出ないんだろう?」という疑問が解決したり、スクリプトでグラフを扱うのが楽になったりします。
物理学用語(高校物理らしい…)で値グラフをX-Tグラフ、速度グラフをV-Tグラフと呼ぶようです。筆者はゴリゴリの文系なので予想ですが、Tはタイム、Vはベロシティ、Xは昔懐かしい『速さ、時間、距離』のハジキの式のキョリをXとした式からきているのでは?と思います。
物理学の知識はほぼゼロですが、AEで答え合わせをする限り合っているので、よろしければ以下をご覧ください!
どうやってあの形になっているのか?
値グラフ、速度グラフともに形を決めているのは、キーフレームを右クリックで出てくる『キーフレーム速度』欄の『速度』と『影響』です。1つ注意なのは、欄に出てくるのはキーフレーム単位のインの値、アウトの値です。それに対して、グラフを作っているのはキーフレーム1のアウトの値(出る速度)、キーフレーム2のインの値(入る速度)である、ということ注意してください。
つまり、グラフを形作っている値をいっぺんに見ることはできない仕様なんですね…。
■値グラフ
まずはキー1です。
値グラフはベジェ曲線なのですが、ハンドル位置=『速度』や『影響』ではありません。それらを計算することによってハンドル位置が決まる仕様です。逆に、ハンドル位置をカーソル操作すると『速度』と『影響』が自動計算され値が入ります。
- 影響:キー1から2までの間を0~100%として、入力されている%が横軸の座標位置です。
- 速度:『キーからそのまままっすぐ値が増えたとして、1秒経ったらキーから見てどんな値になる?」というものです。素直に縦軸の座標を表しているわけではないんですね。曲者です。
この『速度』の棒を『影響』の直線でズバッとカットしたところが、ハンドル位置となります。
次にキー2です。
影響の向きが逆です。が、速度は向きが変わらないという罠があることに注意してください。
■速度グラフ
速度グラフのほうがハンドル位置は分かりやすいですね。X軸が『影響』、Y軸が『速度』となります。
『影響』の向きはやはり向かい合っています。値グラフと違い全体の半分がそれぞれの100%であることに注意してください。
とここで「値グラフはベジェ曲線だけど、速度グラフの曲線はどうやって決まるの?」という疑問がわきますよね。
正直、ベジェ曲線ではない曲線の、直接の算出方法がわかっていないのですが、以下のようにして値グラフのベジェ曲線から作る方法があります。
値グラフから速度グラフを作ってみる
いかがでしょうか?値グラフと速度グラフは関連しているんですね!
動画中で速度座標から値を引いているのは、
動画で算出している値グラフの速度座標は『値から出発した速度値』つまり『値+速度値』なのに対して、
速度グラフの縦軸には値の分は入っておらず、純粋に速度のみを表しているので、
値の分がいらないから引いた、ということです。
ちなみに豆知識ですが、値グラフだと『影響、速度、時間、値』を直接、あるいは間接的にカーソルで変えられます。が速度グラフには値を変えるすべはありません。値グラフに比べ、速度グラフはコントロールできるものが1つ少ない、ということです。
なぜ、波のような値グラフが作れないプロパティがあるのか?
『いったん戻って進み、通り過ぎてから止まる』という以下のような値グラフを作りたいのに、ハンドルが出てこなくて作れない場合があります。いったいなぜなのでしょうか?
それは、『移り変わる値にプラスマイナスの概念がないものは』戻った値や通り過ぎた値の算出ができないからです。
代表的なものに『次元に分割していないポジション』があります。
考えてみれば、位置プロパティには座標が入っており、座標はXとY、値が2つあります。じゃあ、速度グラフの縦軸『速度』はなんの速度なんでしょうか?答えは『移動距離』なんですね!
以下の段落で合っているかの実験をしますが、読み飛ばしても問題なしです。
ヌルを作って時間ゼロに[0,0]、1秒に[100,100]というまっすぐリニアの移動キーを打ってみます。小数点fpsだとぴったり1秒にキーが打てないので30fpsとか24fpsにして行ってください。そこでキー1の『出る速度』を見ると『141.42136』Pixel/秒という謎数値があります。速度は『1秒後にリニアで進むと値は何か』なので、1秒のところにあるキー2の『グラフ上での“縦軸値”』が『141.42136』だ、ということです。グラフの軸は単一数値でなければ可視化できないので「縦軸値は『[100,100]』だ」と座標で表せないのはわかりますが、この『141.42136』とはいったい?
次に、テキストレイヤーを作って、エクスプレッションで『length(ヌルのポジション.key(1).value , ヌルのポジション.key(2).value)』と入れて距離を測ってみましょう。『141.421356…』AEの内部処理的な切り捨てを考えれば、同値ですね!
以上からわかるように、『次元に分割していないポジション』の速度は『移動距離』の速度なんですね。そして例えば、Xはプラスに進んでいるがYはマイナスに進んでいる場合、どの方向をプラスと言っていいのか決められないですね。このような、速度の方向にプラスマイナスが無いプロパティは、プラスマイナスをグラフで表されても結果を計算できません。なので、最初の値グラフのような『最初に下限値を下回ってから上がり、上限値を超えてから下がる』ようなグラフをユーザーが作らないように、ハンドルがなく、参照しかできないんですね!
このような、波状グラフが作れないプロパティに、波状になる数値を入力すると自動でクロップされます。
以下『EaseSwingerPro』を作ったときに調べた『値グラフが編集できるか』の表です。
プロパティ例 | 速度の単位 (/秒は省略) | 値グラフ編集 | スクリプトの propertyValueType | 備考 |
---|---|---|---|---|
単一の浮動小数点値 次元分割した位置等 | プロパティに よる | 〇 | OneD | 不透明度は0~100でクリップされる |
要素2つの配列 シェイプのスケール | % | 〇 | TwoD | 例外的に『速度欄』に2つ入力できる。 |
要素3つの配列 スケール | % | 〇 | ThreeD | 例外的に『速度欄』に3つ入力できる。 |
2次元座標 シェイプの位置等 | 距離 | × | TwoD_SPATIAL | |
3次元座標その1 次元分割していない位置等 | 距離 | × | ThreeD_SPATIAL | |
3次元座標その2 方向 | 単位無し | × | ThreeD_SPATIAL | 3つがどんな値でも表中ではキー1の値が0、キー2の値が1となる。 |
色 エフェクトのカラー値等 | 上限値255の RGB3つの値を 座標化した 疑似的な距離 (RGBA4つ?) | × | COLOR | 16bitでも上限値は255のまま。 valueで得られる値は 0~255ではなく0~1なので変換が必要なことに注意。 |
その他 シェイプパス等 | 単位無し | × | その他 | シェイプパスは値グラフの表示もできない。表中ではキー1の値が0、キー2の値が1となる。 |
*自作のイージングスクリプトを作りたい場合のヒント
『どうやってあの形になっているのか?』の項でハンドル位置がわかるので、グラフの形を得られますが、別のプロパティに適用する場合、時間軸と値軸の幅が違うと同じ形にならないです。得られたグラフの形を左下[0,0]右上[1,1]の単位グラフにし、別のプロパティのそれぞれの軸の長さを得て変換、という形が効率がよいです。
また、グラフが右肩下がりの場合もあり、形を得るときは右肩上がり単位グラフに変換し、適用するプロパティが右肩下がりであれば上下反転させる必要があります。
速度グラフをシェイプパスにしてみよう
最後に、記事を書いてるときに『速度グラフをパスにする方法』を思いついたのでエクスプレッションで作ってみました!
作り方
- キー2つで動いているオブジェクト(平面とか)を用意し、目玉を消します。このキー2つからなる速度グラフを画面表示させるのが最終目的です。
- 時間をX軸、速度をY軸としたモーションパスを作ってから、それをパスに変換するので、モーションパス用ヌルを作ります。
- 速度はvelocityAtTimeで簡単に広範囲を得られるので、for文で動いている間の速度を全て得て、それをヌルのY座標とします。ただ、画面内に収めたいので一番高い速度値と一番低い速度値を上限下限にします。速度グラフとAEの座標はYが逆なので反転させます。
- ヌルのX座標はキーが始まる時間に画面左端(ゼロ)、終わる時間に画面右端(thisComp.width)になるようにタイムのlinear関数をいれます。
- シェイプレイヤーを作ってこの記事の要領で軌跡をパスにします。
以上です!滑らかさはロトベジェなのであまり再現性が高くないですが、案外できるもんですね。