Edited at

VVVVにInstance Noodlesを導入して手軽にGPGPUする

More than 3 years have passed since last update.


Instance Noodlesとは

Instance Noodles | vvvv

DirectX11のCompute Shaderを使ったGPGPU計算や、Geometry Shaderを使ったジオメトリ制御を、普通のVVVVのノード感覚で扱うためのContributions(ライブラリ)です。

VVVVにデフォルトで含まれているMapやGamma、Vectorなどの基本的なノードのCompute Shader版が大量に含まれているので、自分でシェーダを書かなくても手軽にGPGPUが使えます。

下に貼ったのは300000個のパーティクルをCurlノイズをかけてうねうねさせてみた感じのパッチと、その描画結果です。こんな感じで比較的シンプルなパッチで手軽にGPGPUできます。

下記のパッチで言うとBrownian, Curl, Vector3DSplit, Map, Vector3DJoin, Polar, SpriteBufferedはすべてInstance Noodlesに含まれるノードで、中身はシェーダを呼び出すだけのパッチになっています。

20160819_2016.08.24-22.02.59.png

20160819-Renderer_2016.08.24-22.02.23.png


インストール

前提として、DirectX11を使ってるのでDX11 packsが必要になります。

入れてない人は vvvvのインストールガイド[DX11対応] - Qiita を読んでDX11 packsの導入を済ませておいてください。

Contributionsページのdownloadからzipファイルをダウンロードし、解凍したフォルダをVVVVのインストールフォルダ内のpacksフォルダに置くと使えます。

...\packs\InstanceNoodles\girlpower\Compute\01_ComputeBasic.v4p を開いてうまく動いていれば導入は完了です。

導入後はgirlpowerと ...\packs\InstanceNoodles\nodes\modules フォルダ内を見て、どんなパッチが用意されてるのかと、ヘルプパッチで扱い方をひと通り確認しておくと良いです。


パーティクルを出してみる

まずは簡単なところから。

上のパッチでも使っているBrownianというノードを使ってみます。これはブラウン運動をシミュレーションするノードで、指定した数分のブラウン運動する座標値が取得できます。

Brownianの出力はSpriteBufferedPosition 3D Bufferにつなぎます。SpriteBufferedはパーティクルを表示するためのシェーダだと思えば良いです。

BrownianSpriteBufferedのSpread Countインレットにはそれぞれ描画したいパーティクル数を設定します。

SpriteBufferedの出力はDX11 Layerなので、あとはこれをDX11用のRendererに繋げばパーティクルが表示されます。

20160824_2016.08.24-22.59.22.png 20160824-Renderer_2016.08.24-22.56.41.png

表示できたらパーティクル数をどんどん増やしてみてください。

座標値をGPU側に転送してGPGPUで計算しているので、かなりパーティクル数を増やしてもあまり処理落ちしないはずです。

手元のGeforce 940Mだとパーティクル1000000個出しても48fpsぐらいは出る感じです。


CPU-GPU間の値の受け渡しについて

GPUで計算する場合、計算に必要な値は基本的にGPUのStructured Bufferに転送しておく必要があります。CPU→GPUへの転送はDynamicBufferというノードを使用します。

例えば、RandomSpreadで生成した100000 * xyzの値をInstance NoodlesのAttractorで使用したい場合、そのままSpreadを渡すことはできないので、DynamicBufferでGPUに転送したうえで渡すような使い方になります。

20160824_2016.08.25-00.30.23.png

また、計算結果に関してもGPUに保存されているため、Spreadとして取り出す必要がある場合はGPU→CPUへの読み出しを行う必要があります。これにはReadBackというノードを使用します。

0_2016.08.25-00.41.36.png


まとめ

だいたい基本的なところはこんな感じかな……?パッチはGitHubに置いておきました。

vvvv-sandbox/InstanceNoodlesSample at master · clomie/vvvv-sandbox

今回は触れなかったけど、他にもDX11.GeomFX系のGeometryにエフェクトかけられる感じのノードとかあって、そっちはそっちでめちゃめちゃ便利そうなやつが大量にあります。

現状でもBufferを扱えるノードはだいぶ充実しているので、たぶんInstance Noodlesを導入するだけでもかなりいろいろできるはずです。Damperがないのがちょっと痛いぐらい。

VVVVでDX11やるならpacksと一緒にとりあえずで入れておいていいぐらいだと思います。


DX9でGPGPUしたい場合

Vertex ShaderとPixel Shaderでテクスチャの各ピクセルの色情報をただのfloat値として扱って計算することになるっぽいです。

DirectX9でもGPGPUしたいという人は以下の記事が参考になります。

.ore, GPGPUする