プログラミングで格好いい映像を作りたいと始めた『TouchDesigner』。
いろいろググっていると、
大量のパーティクルを生成できる『GPGPUパーティクルシステム』なる方法があるそうで。
1からGPGPU Particle Systemを作ることにしました。
〜中略〜
オフィシャルのParticle SOPは勿論、PalleteのparticlesGpuよりも低負荷です。
私の持っているGTX 1060の載ったRazer Bladeでは200万Particleまで行っても60FPSをキープできました。
参考記事1:TouchDesignerでGPGPU Particle Systemを作る Vol.1 基本編
『GPGPU』とはなんぞやとググってみると、
- GPGPU(General-purpose computing on graphics processing units・・GPUによる汎用計算)
だそうで、並列処理が得意なGPUを、映像以外にもゴリゴリ使う方法で、
最近では『Python』などで実施される『機械学習』にも応用されているようです。
他にも、nvoid社の資料にもGPUパーティクルシステムの記載がありました。
英語なので意訳すると、
GPUパーティクルシステムは『ParticleSOP』よりめっちゃ優秀よ。
全部の計算をGPU上のGLSLでやっちゃうからね。
GLSLは100万以上のパーティクルでも動かせまんねん。
的なことが書いてあって。
This tutorial will be focused on creating a GPU based particle system using TouchDesigner and GLSL shaders. This has many benefits compared to using the built-in Particle SOP, because all the computations inside of GLSL shader are performed on the GPU. GLSL shaders allow for the creation of particles systems with extremely large particle counts (in the multi-millions and more), with customized behaviour, that still compute quickly.
参考記事2:nvoid社 Introduction to Touch Designer
他にも、GLSLなしで『GPUパーティクル』作る方法もあるようですが、
参考記事3:TouchDesignerでGLSLを書かずにGPU Instancingしてみる
今回はとても丁寧に書かれていた参考記事1をベースに、
補足する形でまとめていこうと思います。
GPGPUパーティクルシステムを試してみた
参考記事1をベースに『GPGPUパーティクルシステム』をつくるとこんな映像になります。
パソコンのスペック次第では、
200万以上のパーティクルでも60FPSでるそうで、
それはそれはゴージャスなパーティクルがパーリーピーポーになる予感がプンプンしております。
GPGPUパーティクルシステムを試してみる 4つの構成
『GPGPUパーティクルシステム』の構成は以下。
大きく4つに分かれているので、1つずつざっくり解説してみます。
GPGPUパーティクルシステムその1 3D描画なら定番
まずはAグループ。
『TouchDesinger』で3D描画するならおきまりの、
- Geometory COMP
- Camera COMP
- Render TOP
- Out TOP
をつなげています。
『Geometory COMP』内の『Torus SOP』を『In SOP』に変更しています。
GPGPUパーティクルシステムその2 頂点をつくる
続いてグループB。
構成は、
- Grid SOP
- Convert SOP
- Attribute SOP
『Grid SOP』で 256 x 256 のPoint(頂点)をつくって、
『Convert SOP』でパーティクルに変更しています。
TD099では、Particles Per vertex と表示されていました。
GPGPUパーティクルシステムその3 色と座標をつくる
続いてグループC。
『GPGPUパーティクルシステム』では、
パーティクルの位置や色の情報を、
画像から取得する必要があるそうです。
『Noise TOP』を使って画像を作っています。
- Noise TOP
- Null TOP (null_pos)
- Null TOP (null_color)
『Noise TOP』を2つのNullに分離させて、
『GLSL MAT』にそれぞれuniformで取り込んでいるのが重要なのかなと思います。
参考記事
GPGPUパーティクルシステムその4 GLSLちょっと書く
最後にグループD。
『GLSL MAT』を生成して、
『GLSL MAT』->Samplers1→TOPに、
先ほど作っていた null_pos と null_color を紐付けつつ、
『GLSL MAT』->Samplers1→SamplerNameに、
- uPosMap
- uColorMap
という変数名で取り込めるようにしています。
『GLSL MAT』まずは頂点シェーダ(バーテックスシェーダ)側。
/// glsl1_vertex.dat uniform sampler2D uPosMap; // null_pos側の変数 uniform sampler2D uColorMap; // null_color 側の変数 out Vertex{ // 構造体 フラグメントシェーダへの受け渡し用 vec4 color; }vert; void main() { int id = gl_VertexID; // 0-65535までの頂点のユニークID取得 vec2 res = textureSize(uPosMap,0); //uPosMapの縦横の解像度取得 vec2 uv = vec2(float(id % int(res.x)), float(floor(id / int(res.x)))) / res; // uv座標に変換 vec2 texCoord0 = uv + (1.0 / res) * 0.5; //座標を真ん中にもってくる vec3 newP = texture(uPosMap, texCoord0.st).xyz; // uPosMapの値を座標値として取得 vec4 worldSpaceVert =TDDeform(newP); // この2行を書かないとカメラ動かしても gl_Position = TDWorldToProj(worldSpaceVert); // パーティクルが動かない vert.color = texture(uColorMap, texCoord0.st); 構造体に値を流し込む }
続いてフラグメントシェーダ(ピクセルシェーダ)側。
/// glsl1_pixel.dat in Vertex{ // 頂点シェーダから受け取り vec4 color; }vert; out vec4 fragColor; void main() { TDCheckDiscard(); //お守り vec4 color = vert.color; //お守り TDAlphaTest(color.a); //お守り fragColor = TDOutputSwizzle(color); // 最終出力に色指定 }
『GLSL』描く分ちょっとハードルはあがりますが、
『GLSL』単独で全部書くよりもだいぶ楽につくれるんじゃないかと思います。
最後に『Geometory COMP』->Render->Material に
『GLSL MAT』をドラッグドロップして紐づければOKです。
GPGPUパーティクルシステムを試してみる まとめ
かっこいい映像をゴリゴリ動かそうとなると、
CPU単独ではどうしても処理が重くなって厳しくなるので、
並行処理・映像処理特化の『GPU』をうまいこと使いこなすことで、
より今ドキなかっこいい映像がつくれるんだろうなと思います。
球体や四角など形が決まっているものは『ジオメトリインスタンス』で、
参考記事
とにかく大量のパーティクルなら『GPGPUパーティクルシステム』でと、
うまいこと役割分担しながらつくっていけるといいなと思います。
『TouchDesigner』関係ではこんな記事も読まれています。
1. 【GLSL】プログラムでかっこいい映像をつくりたい! 〜『TouchDesigner』を見据えて2. 【TouchDesigner】で『GLSL』を使う方法まとめ【画像あり】
3. 【TouchDesigner】『GLSL MAT』の使い方 3次元でぐりぐり動かしてみる
4. 【TouchDesigner】GPUを使う方法の一つ ジオメトリインスタンス
5. GPGPUパーティクルシステムを試してみた【TouchDesigner】
6. 【TouchDesigner】パーティクルの出し方をまとめてみる
7. 【TouchDesigner】で『GLSL』を使う方法を動画で学んでみる その1
アオキのツイッターアカウント。
この記事へのコメントはありません。