15
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TouchDesignerAdvent Calendar 2017

Day 17

TouchDesignerでGPGPU Particle Systemを作る Vol.2 応用編

Last updated at Posted at 2017-12-16

TouchDesigner Advent Calendar 2017の12/17の投稿となります。
ここでは、TouchDesignerでのGPGPU Particle Systemの作り方を2回に分けて書きます。今回はその2回目。
今回の完成ソースはここ。
ある程度分かっている人は完成したソースを見ながら、初心者は空のProjectから作るぐらいが良いかもしれません。

前回のコードをベースに動きをつける

前回の投稿でGPGPU Particle Systemの表示部分が完成しました。
今回は動きの部分を実装していきます。
ポイントは基本的な入力を全てTOPにすること。
こうすることで各particleに個別のパラメータを持たせることが可能になります。

初期位置と移動量を持たせる

前回制作したときは、TOPは『Particleの絶対座標を記したもの』として扱いましたが、今回は『Particleの初期位置を記したもの』と『Particleの移動量を記したもの』に分けます。
こうすることで任意の座標にparticleを配置し、そこから動かすことができます。

1. 初期位置を作る

今回は座標中央、XYZ=(0,0,0)の座標からParticleを飛ばします。
Constant CHOPで(0,0,0)の黒を指定し、16bit floatに変更します。
01_constant01.PNG
02_constant02.PNG

2. 移動量を作る

速度はNoise Topで作りましょう。
移動量なので値は小さめにします。こちらも16bit float。
03_Noise01.PNG
04_Noise02.PNG

3. 初期位置と速度を足す

Composite SOPのAddを使ってConstant TOPで作った初期位置にNoise TOPで作った速度を足し合わせます。

05_Comp.PNG

4. 移動し続けるようにする

このままだと一回しか移動しないので、移動し続けるためにFeedback TOPを使います。
初心者の頃はFeedback TOPの挙動がよく分からなくて困ったりするのですが、要するに「一発目だけ左の接続元の絵を利用し、それ以降は参照元の絵を使う」というシンプルなTOPです。
Composite TOPの後にNull TOPをつけ、Constant TOPとComposite TOPの間にFeedback TOPを設置し、Null TOPをFeeback TOPに参照させます。
うまく組めるとComposite TOPが加算されて派手な色になっていくと思います。

5. 確認する

前回作ったNoise TOPを取り外し、今回のNull TOPをnull_posとnull_colorに接続します。
この状態でFeedback TOPのResetを押すと、画面中央から放射状にParticleが飛んでいくと思います。
05_settings.PNG

Particleに寿命を持たせる

上でできたParticleはひたすら進んでいくので、feedbackのresetを押して定期的に初期位置に戻す必要があります。
そこで応用性を広げるために、Particleに寿命を持たせて、寿命が来たら初期位置に再度出現するようにします。
今回は白、つまり1.0になると寿命が来た、と判定させるため、黒から段々明るくなって、白になってまた黒に戻るループを組みます。

1. 寿命の初期値を決める

上の初期位置同様、Constant TOPの黒、16bit floatで組みます。
今回は1chしか使わないのでmonoで作っていますが、GPUが圧迫されていないのであればRGBを設定しても問題ないでしょう。

2. 寿命の進行速度を決める

こちらもNoise TOPで作ります。寿命の進行速度が固定だと絵がイマイチなので absTime.seconds を使って動的に変化させます。
08_Noise01s.PNG
09_Noise02.PNG

3. 加算し、年齢が進行しつづけるようにする

ここは上と全く一緒です。
Composite TOPでaddを設定して加算し、Null TOPとFeedback TOPで加算しつづけられるようにする。するとComposite TOPがどんどん白くなっていくと思います。

4. ループを作る

白、つまり値が1になるとリセットして黒になるようにしたいので、ここでGLSL TOPを使います(もしかしたらTOPでうまく書けるのかもしれませんが・・・)。

glsl2_pixel.dt
out vec4 fragColor;
void main()
{
    vec4 color = texture(sTD2DInputs[0], vUV.st);
    fragColor = TDOutputSwizzle(fract(color));
}

記述は見ての通り簡単でピクセルの値は0から1の間で動いてるので、fract関数を使って整数部分を切り捨てて返すだけです。つまり、1.0以下だと普通に値をそのまま利用して、1.0になったら0.0として返すだけ、という関数です。
これで寿命側のComposite TOPが変な動きのループする砂嵐になってるとおもいます。
06_settings.PNG

5. 3つの画像から今回利用する位置情報を生成する

今回、Particleは寿命の値が1かどうかによって、位置情報のComposite TOPを利用するか、あるいは位置情報の初期値であるConstant TOPを使うかを決めます。
つまり、Particleの移動量を足した位置情報であるComposite TOP、Particleの初期位置であるConstant TOP、Particleの現在の寿命であるComposite TOPの3つの画像を入力し、新たな「寿命による判断を加えて、Particleによっては初期位置に配置しなおした位置情報」のTOPを作ります。
これももしかしたらTOPのみで作れるかもしれませんが、今回はGLSLMulti TOPを使い、shaderを書きます。
GLSLMulti TOPに、「1. 位置情報のComposite TOP」「2. 初期位置のConstant TOP」「3. 寿命のComposite TOP」の順に繋ぎます。
そしてコードは以下。

glslmulti1_pixel.dat
out vec4 fragColor;
void main()
{
    vec4 recentPos = texture(sTD2DInputs[0], vUV.st);
    vec4 originalPos = texture(sTD2DInputs[1], vUV.st);
    int life = int(texture(sTD2DInputs[2], vUV.st).r);
    
    recentPos = mix(recentPos, originalPos, life);
    
    fragColor = TDOutputSwizzle(recentPos);
}

これも見ればある程度分かるのではないでしょうか。
1つめの入力画像から移動後の位置を、2つめの画像から初期位置を、3つ目の画像から寿命を取得しています。
lifeは0であればまだ寿命は来てない、1だと寿命が来ている、ということになります。
そしてこのシェーダで参照後、寿命のほうで書いたシェーダによって0に戻されてまた年を重ね始めます。
CPU側で書く場合はif文で判定するのですが、Shaderでif文を書くと遅い、という話なのでmix関数を利用しています。
mix関数はこちらにある通り、線形補完の関数ですが、今回0か1かしか入れてないのでrecentPosを採用するか、originalPosを採用するかの2択的な処理となっています。
できあがったノードのレイアウトはこんな感じ。

07_settings.PNG

まとめ

いかがでしたでしょうか。
openFrameworksをもりもりやってた頃はGPGPU Particleって敷居が高いイメージがあって、やらなかった口なのですが、TouchDesignerだと勘所抑えると意外と書くところ少なく実装できてしまうし、全体も把握しやすいように思います。
また、TOPが殆どGPU最適化しているため、リアルタイムにバリバリ使える、というのもShaderを書く箇所を少なくできている理由だと思います。

読んでも『わからんかった...』という人のために

知り合いのモーションデザイナ、CGアーティストにGPGPU Particleでデザインをしてもらうためコンテナ群を製作してます。
そのうち公開すると思います。

15
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?