超久々に投稿します。初めましての方ははじめまして。
今回はTouchDesignerという映像表現に強いノードベースプログラミングのソフトを使ってスプライトアニメーションを作ってみました。
なんでTouchDesignerの記事なのか
あまりに日本語の記事がなさすぎるのと、英語読むの辛いのと、こういったロジックを組み込みたいって思ったときに超困ったので、ちょっとでも助けになったらいいなぁと思い書きました。その為ちょろちょろロジックごとにこうやって作って見ましたな感じで書いてあります。何分触り始めたばっかり過ぎて超初歩的なことしか書いてなかったりしますが、そのうち色々書けるといいなぁと思います。
あとは自分の備忘録も兼ねてます。というかこれがほぼメインです。
ちなみにTouchDesignerを使おうとした理由はFleXが使えて流体表現ができるっていうのを見てそれをやりたくなったからです。でもあれWindowsでしか動かないんですねー・・・
全体の構成
一旦こんな感じで作ってみました。Containerの中に基本的に全部突っ込んでます。Movie file In TOPは外から指定してもいいかなぁと思いました。
Containerの中身
それではこれからざっくり説明していきます。
スプライトアニメーションの作り方
スプライトアニメーションを行うにあたって、TOPで行なったこととCHOPで行なったことを分けて書いていきます。
TouchDesignerでスプライトアニメーションを行う際にTOPで行なったのは、1,画像を読み込む、2,TouchDesignerの座標系に変換、3,表示するフレームの画像にcrop、4,背景を透過、5,アニメーションが再生中か終了しているかで表示画像の差し替えを行なっています。
CHOPでは、1,ボタンから信号受け取り、2,LFOのリセットとTimerのスタート、3,LFOを横軸と縦軸用のステップに変換、4,表示する座標を算出、5,Crop TOPにExportといった感じで行なっています。
TOP:1,画像の読み込み
これはMovie File Inで指定してるだけなので省略します。
TOP:2,TouchDesignerの座標系に変換
TouchDesignerの座標系は左下が0となっています。今回使用したスプライトアニメーション用の画像は左上が原点になっているため、上下を逆にする必要がありました。
上下逆にするためには、Transform TOPを使用し、ScaleのY軸に-1を指定することで実現しました。
TOP:3,表示するフレームの画像にCrop
これはそのままCrop TOPを使用しています。Cropする位置については、CHOPで指定しています。
TOP:4,背景を透過
使用した画像がpngではありましたが、黒背景を使っていたため、Subtract TOPを使用し、Cropした画像からConstant TOPで作成した黒画像を排除することで背景を透過しました。
元から背景が抜けていればここは特に何もする必要はないかと思います。
TOP:5,再生中か否かで画像の切り替え
画像の切り替えにはSwich TOPを使用しています。切り替え先の画像にはConstant TOPを使い、Alphaが0の透明な画像を使っています。Swich TOPの切り替えにはTimer CHOPのRunningパラメータを使用しました。
次はCHOPについてです。
CHOP:1,ボタンからの信号受け取り
Containerの外から中に信号を受け取るためにIn CHOPを一番初めに設置しています。ボタンはButton COMPを使っており、Button typeをMomentaryに変更しています。トグルスイッチではなく、クリックタイプのボタンにすることが出来ます。
CHOP:2,LFOのリセットとTimerのスタート
まずLFO CHOPについて。
LFO CHOPは周期的に決められた線形を出力し続けるものです。Sin波とかPulseを出したり出来ます。詳しい種類については公式のドキュメントに書いてあります。
今回はその中でRampを使います。Rampは0から1まで線形に増加していくのを繰り返すCHOPになります。1秒間のスプライトアニメーションを表示したいため、Frequencyを1にすることで、1秒間で0から1に変化する値を取得する事ができます。この設定をしたLFOに対し、In CHOPからの入力を中央に接続します。LFO CHOPの中央はリセットなので、1が入力されるとLFO CHOPの値が0からリスタートします
次に、Timer CHOPについてです。
Timer CHOPはその名の通りタイマーとして動作します。動作中や、終了時に値を更新する事ができます。今回はアニメーション中のみ画像を切替えたかったので、OutputsにRunningを設定しています。これはTimerが動作中のときは1、それ以外は0を出力します。この値をSwich TOPのIndexに出力しています。In CHOPからの値は下段につなげており、これはStart Triggerとなっているので、1が入力されることによりタイマーがスタートする用になっています。
3,LFOを横軸と縦軸用のステップに変換
LFOから出力される値は1秒間に0から1に変化するものでした。このままではCrop用の座標として使うことは出来ないので、0から1までを0から64に変更した値を8で割った余りを算出したものと、0から1までのレンジを0から8に変更したものを作ります。
まず、8で割る方法ですが、Math CHOPのTo Rangeを使用し、0から1を0から64に変更します。64の理由はスプライトアニメーションが64枚あるためです。また、この時OPのIntegerはFloorに設定し、切り捨てて整数にしています。この64までの数字を8で割るには、Limit CHOPを使用します。Limit CHOPのTypeをLoopにし、Minimumを0、Maximumを8にすることで、入力は0から64でありながら、0から8への値の変化を繰り返します。これにより8で割った余りを算出することが出来ます。
次に0から8までにレンジを変更する方法ですが、0から64に変化させたときと同じように、To Rangeを0から8に設定し、OPのIntegerをFloorに設定することでレンジを変更出来ます。
4,表示する座標を算出
表示する座標とは、スプライトアニメーション用の画像のどこをCropするのかということになります。Cropするための座標は、Left,Right,Bottom,Topの座標となります。座標ではなく0から1のフロートでも指定出来ますが、一旦画像の座標のほうがわかりやすいと思ったので今回は座標で指定しています。
やっていることは簡単で、先程算出した数値とConstant CHOPに64を入力したものを、Math CHOPを使い掛け合わせているだけです。Math CHOPにConstant CHOPと先程のMath CHOPをつなげ、繋いだMath CHOPのOPのCombine CHOPsをMultiplyにすることで、2つの入力をかけ合わせたものを出力することが出来ます。
これでLeftとBottomは指定することが出来ますが、RightとTopは更に64足したものである必要があります。その為、Math CHOPのMulti-AddのPost-AddにConstant CHOPの値をExportすることで、LeftやBottomと同じ用に算出したものに、64を足した数値を算出する事ができます。
これでCropするための座標を算出することが出来ました。ちなみに、Math CHOPで算出した値は全てNull CHOPへ出力しています。
Crop TOPにExport
それぞれのNull CHOPをそのままCrop TOPのLeftやTop等にExportするだけです。これで毎フレーム表示するアニメーションにCropされた画像がCrop TOPから出力されるようになります。
完成
完成したものはこのような感じになりました。
おわりに
今回はTouchDesignerを使ってスプライトアニメーションを作ってみました。最近書籍が出たので、それを元にサンプルを作ったりしていますが、やはり実際に自分でロジックを考えて作っていかないとなかなか習得出来ないと改めて思いました。
TouchDesignerの記事はこれが初めてなので、かなり冗長的に書いてありますが、そのうちもうちょっとシンプルにしつつ、ロジックの組み方のTips的な感じの内容になっていくのかなぁと思います。最近はUnreal Engine等でノードベースプログラミングが流行ってきているので、しっかり習得していきたいです。
ちなみに次の内容は未定です。アニメのOPやEDで使われてる面白いアニメーションを再現するとかやってみたいなぁとぼんやり考えてはいます。
では、また