カラープロパティを色相ぐるぐるしたい

はじめに

「カラー」プロパティは色相ぐるぐるがやりにくい。頑張ってキーフレ打てばできなくはないけど修正を考えると現実的でない。

カラーピッカーの「H」(Hue:色相)にキーフレームを打つイメージ。これが実現できる方法を考える。

カラーピッカー

「色相/彩度」や「コロラマ」エフェクトでやってみる?

例えば「4色グラデーション」を適用した状態。これを色相ぐるぐるしたいとき、誰しも思いつくのが「色相/彩度」エフェクト。これで簡単にできる。

「4色グラデーション」を適用した状態

「4色グラデーション」+「色相/彩度」で色相を90°回した状態

上の例では全体の色が変わった。じゃあ黄色だけ変化をさせたいときどうするか。「色相/彩度」エフェクトの「チャンネル制御」「チャンネル範囲」プロパティを使用して、適用する範囲の指定をしてからぐるぐるする? でも調整しにくいし、多分思ってる結果が返ってこない。

適用範囲を黄色あたりだけに絞る

他の色との境ですごい色相の変化が...。コレジャナイ感...。

カラープロパティにキーを打つ?

このカラープロパティ自体にキーを打ちたい。そう思えてくる。だから打ってみる。

打ってみた。

「カラー3」はRGB(色相0°、120°、240°)だけに打った。キーフレ間の補完で明度彩度が変化しているし論外。数値を調べればわかるが色相もきれいに補完されてない。

「カラー4」はRGBに加えてYCM(色相60°、180°、300°)のキーを打った。タイムラインのインジケーターをキーフレームの間に持ってきてカラーピッカーをだすとわかるけれど、明度彩度の変化がなく色相だけが変化している。

成功!!ヤッター!!!・・・で済むのか。済む場合もあるでしょう。そのときはこれでいい。

じゃあこれ修正したくなったらどうするのか。逆回転にしてくれと言われたらキーフレーム全部移動するのか。あほらし。触るキーフレームはいつでも少ないほうがいいのである。

「角度制御」と連動させたい

色相環をイメージする。わからない人はSAIとかのUIで見るあれ。色相は角度で表せるので「角度制御」と連動させたい、という考えに至る。(ここまで0.1秒)

角度制御と色をどう関連付けるか。

「エクスプレッションで色拾って、角度足せばいいのでは?」と思う。間違ってない。でも思った結果にならないはず。ここではもうあえてやらないが。

試しにテキストレイヤーのソーステキストにエクスプレッションで色を拾って、それを表示してみる。

エクスプレッションで色を取得して、テキストレイヤーに表示してみる

この色をエクスプレッションで拾う

拾った値はRGB値であることがわかる

RGBと一致した。RGBの値は拾えることがわかった。

(エクスプレッション内で調整しているので上図テキストレイヤーの表示は[0-255]で表示されてるが、内部的にはRGBを[0-1]の範囲で拾っている。)

RGBに「色相」を示す値はない。ゆえにRGBにいくら「角度制御」を加減乗除しても意味はない。

今やりたいのは、カラーピッカーに表示されている「HSB」の「H」を直接触りたい、ということ。

「HSL」「HSB」「HSV」といろいろ表記があり、表している意味も微妙に違う。どれであってもH(色相)は同じなのでここでは違いは気にせず進める。あとは自分で調べて。

RGBとHSLの変換

RGBは「赤・緑・青」の割合を表している。HSLは「色相・彩度・明度」を表している。全く異なる要素で色を表しているこれらだが、お互いRGBとHSLは変換できる。

決まった変換式があるが、AfterEffectsのエクスプレッションにも用意されているのでそれを使う。

  • rgbToHsl(rgbArray)

  • hslToRgb(hslArray)

意味は見たまま。説明の必要もない。手順は次のよう。

  1. rgbToHsl でRGBをHSLに変換

  2. Hue(色相)を操作する

  3. hslToRgb でHSLをRGBに戻す

エクスプレッションで色を拾った場合、4つの要素の入った配列が返ってくる。4つめはアルファなのでここでは無視する。つまり[R,G,B]が返ってくる。先のエクスプレッションで変換した場合、[R,G,B]の配列が[H,S,L]の配列になる。またその逆もしかり。

そしてHSLの取りうる範囲はすべての要素で[0-1]である。一般的に角度は[0°-360°]で表すものであるが、ここでは[0-1]で与える必要があることに注意。180°とか2°とかそのままぶちこんでも全て1(=360°)として扱われてしまう。この辺が初心者が陥りやすい。

[0-360]とか[0-255]とかそれらは人間がわかりやすいための表記であって、パソコンくんには[0-1]がわかりやすいのである。

実際やってみる

まずは「4色グラデーション」エフェクトを適用。そして色相をいじるためのコントローラーとして「角度制御」エフェクトを適用する。わかりやすくするため、エフェクトの名前を「色相オフセット」に変えた。

「カラー1」プロパティにエクスプレッションを書いて、「色相オフセット」と連動するようにする。

■カラープロパティに書くエクスプレッション

rgb = value;

hue = effect("色相オフセット")(1);


hue = (hue%360/360) + (hue < 0);

hsl = rgbToHsl(rgb);

hsl[0] = (hsl[0] + hue)%1;

hslToRgb(hsl);

これで「色相オフセット」をいじると色相だけが変化する。

少ないキーフレームで色相サイクルが作れた!

「カラー」にキーを打たずに、「角度」のキーだけでぐるぐるできる。途中で逆回転になったりなんでも来い。どんとこい!

もとのカラーもそれはそれでキーフレ打てる。

今回は「もとの色を基準に、色相を何度回すか」という式にした。

イメージしやすさのために「色相オフセット」の値をカラーピッカーで色を決めるときの値と一致させたい!というときは、元のカラーの色相を0°にするとよい。もとが0なので「色相オフセット」の値がそのままH(色相)になる。

エクスプレッション解説

●1行目

rgb = value;

このプロパティ自身のエクスプレッション適用前の値を変数rgbに格納。

●2行目

hue = effect("色相オフセット")(1);

このレイヤーのエフェクト「色相オフセット」の「角度」の値を変数hueに格納。もし別のレイヤー(コントロール用のレイヤーとか)から拾うときはレイヤーの指定も忘れず。

●3行目

hue = (hue%360/360) + (hue < 0);

hueはそのままだと周回も足した角度を表している。角度のプロパティは「0x+0.0°」という表記になっていて「0x」は周回、「+0.0°」は[-360~360]の角度を表している。例えば値が「2x+90°」だとすると1周360°だから「2*360+90」=で、hueには810という値が入ることになる。反時計回りだと負の値を取るので、「-2x-90°」となれば-810となる。

この値を前述の通り[0-1]に収めないといけないのでその計算をしている。角度としてはマイナス値は間違っていないが、今回色相に与える値としては適切でないので[0°-360°]の範囲を示す[0-1]に変換しないといけない。

色相に周回の考えは要らないので「0x+0.0°」の「+0.0°」の部分だけほしい。

hue%360

これでhueを360で割った余り、つまり周回を無視した「+0.0°」の部分だけを取り出せた。hueがどんな値であってもこれで[-360-+360]の値に変換された。さらにそれを360で割ることで[-1-+1]の範囲に収めることができるので、

(hue%360/360)

となる。前述の通り角度は負の値の可能性もある。正の場合はそのままでよいが。負の場合、hueに360°分プラスして正の値に戻す。先の計算ですでにhueは[-1-+1]に収めているので、1周分の加算で[0-1]に収まる。hueが正か負か判断するので

(hue < 0)

とすると、hueが0か正の場合「false」、負の場合「true」が返ってくる。「true」「false」は計算式中でそれぞれ「1」「0」に自動変換される。結果、負のときは +1、正のときは+0となる。

以上の計算でhueを[0-1]に収めることができた。

●4行目

hsl = rgbToHsl(rgb);

最初に格納したRGB値をHSLに変換したものを変数hslに格納。

●5行目

hsl[0] = (hsl[0] + hue)%1;

hslは[H,S,L,A]4つの要素をもつ配列。その1つ目が色相の値になるので、hsl[0]に先ほど求めたhueを足す。ここで足した結果、値が1を超える可能性がある。越えた分は周回として3行目と同様、捨ててしまっていい。小数部分だけほしいので、

%1

で、1で割った余り、つまり小数部分のみ抜き出している。これでhsl[0]はもとの色から「色相オフセット」分だけ色相が調整された[0-1]の値になった。

●6行目

hslToRgb(hsl);

求めたHSL値をRGBに変換する。これでプロパティに調整後の値がぶちこまれる。

も少し調整してみる

色相オフセット」エフェクトをOFFにしているときは色相調整されない、とう風にしてみるには、2行目をこうする。

hue = effect("色相オフセット")(1) * effect("色相オフセット").enabled;

エフェクトの有効無効をenabledで判断。TRUE/FALSEが返ってくる。前述の通り、これらは「1/0」に暗黙の変換がされるのでOFFの場合は自動的にhue自体が0になり、エクスプレッションで色相オフセットの計算がなされても変わらずもとの色を保ったままになる。

おしまい。間違いあったらごめんぽよ。