この記事は、TouchDesigner Advent Calendar 2017 23日目の記事です。
はじめに
何の打ち合わせもなしに、前日の記事と内容が丸被りしました。(そんなことあるんですね...)
書き直すの面倒なので、そのまま掲載します。
ごめんなさい!!!
TouchDesignerでは、GLSLフラグメントシェーダを用いた画像の生成が可能です。
上記画像のように、単一のGLSLフラグメントシェーダであれば、GLSL TOPノード1発で済むのですが、
人間とは欲深いもので、前フレームの計算結果を利用して次のフレームの描画をしたくなる時があります...
つまるところ、このLorenz Attractorのように、
バッファを用いた描画をどうやってTouchDesigner上で実現するのか気になって夜も眠れませんでした。(昼寝てたけど)
本記事では、これを実現する方法を雑に解説します。
実装する内容
今回は、Shadertoyに掲載されている2次元波動シミュレーションをTouchDesigner上に移植します。
Wave Simulation #touchdesigner #glsl pic.twitter.com/MudSzoOI4l
— Kodai Takao 🌊 (@m1ke_wazowsk1) 2017年12月10日
— Kodai Takao 🌊 (@m1ke_wazowsk1) 2017年12月22日
リリースはこちらです。(CC License) [WaveSimulationForTouchDesigner - GitHub](https://github.com/kodai100/TD_WaveSimulation/releases/tag/TD_WaveSimulationSample) (TouchDesigner099 2017.15400)
波動シミュレーションの仕組み
波動シミュレーションの解説は、うしお先生の記事が非常にわかりやすいため、
こちらを参照していただきたいと思います。
過去にUnityで実装した例も掲載しておきます。
Wave Simulation for Unity
ただし、今回の内容は波動シミュレーションを理解しなくても問題ありませんので、読み飛ばしていただいても結構です。
TouchDesignerでのバッファの作り方
一度Shadertoyプロジェクトを見てみましょう。
BufAのGLSLコードは、BufAとBufBの計算結果を参照しており、
BufBのGLSLコードは、BufBとBufAの計算結果を参照、
TouchDesignerで同じバッファ機能を実現するためのキモは以下2つのノードを利用することです。
- GLSL Multi TOP (GLSL TOP)
- Feedback TOP
GLSL Multi
GLSLコードを書くためのノードです。
複数の画像を入力に受けることができます。
今回の例はGLSL TOPでも同じ効果が得られますが、僕は宗教的にこちらを使います。
Feedback
「指定されたノードの現在のフレームバッファを消去せず次のフレームに受け渡す」機能を持ったノードです。
つまり、これをうまく利用することで次フレームに現在の計算結果を引き継ぐことができます。
つなぎ方
ShadertoyプロジェクトのBufAを実装する例を示します。
はじめに、Feedback TOPにConstant TOPを接続します。
このときのConstant TOPは、解像度を指定するためだけの機能を持っています。(Feedbackは接続元がないとエラーを吐くため渋々...)
次に、Feedback TOPのTarget TOPに、BufAのコードを実装したGLSL Multi TOPを指定します。
最後に、Feedback TOPの出力と、
画像には映っていませんがBuf BのFeedback TOPの出力を
GLSL Multi TOPの入力に接続します。
BufBや最終的な描画についても同様に接続すればOKです。
最終的なノード
I/Oなどの雑多な処理を除けば、以下のように単純な構造になります。
詳しい内容は配布した.toeプロジェクトを参照していただけると助かります。
結果
終わりに
この手法の応用例としては、森岡さんの記事と組み合わせて、
バッファだけGLSLで書き出し、
その結果をパーティクルシステムで取り出して利用するといった使い方ができるかと思います。
(俗にいうVTFですね。)
時間が確保できず適当な解説になってしまいましたが、質問等あればお気軽にTwitter経由でご連絡ください。
明日は一番楽しみにしていた比嘉先生によるOpenCL講座です。
よろしくお願いします!