vvvv gammaでたぶんいちばん簡単なcompute shader

2024/02/27に公開

vvvv gammaでGPUパーティクルを出すサンプルは、Help BlowserのLearn > Documentation > Fuse に参考になるものが多くあるように思えます。一方、シンプルに計算をしたり、strideとfuseの役回りについて理解するのが難しく感じたのでこのドキュメントを書きます。

環境は以下のとおりです。

vvvv gamma 5.2
VL.Fuse Version 1.0.2

StrideだけでComputeShaderを動かす

公式サンプル

VL.Stride本体と関連パッケージをinportするとノードブラウザでComputeBufferが表示できるようになります。
このとき HelpBrowser の Learnタブ の NodeInfo、FOLLOW MODEのチェックにチェックを入れておくと関連情報を確認できます。
この中の Write a Shader を選択します。

Compute Shaderのサンプルを確認することができます。

このサンプルでは長さ1024のfloatのbufferが使われているのを確認することができると思います。
実際に動いているshaderのコードを見るには、MyComputeShader のノードを右クリックしOPENすると確認できます。

strideのshader言語sdsl で書かれています。

[Summary("Increments values in a buffer.")]
shader MyCompute_ComputeFX : ComputeShaderBase
{
	float Increment = 0.01; // Incrementのpinから渡ってきた渡ってきた数値
	RWBuffer<float> Values; // Valuesのpinから渡ってきたBuffer

    override void Compute()
    {
        uint index = streams.DispatchThreadId.x;  // ThreadId を取り出す
        
        float value = Values[index];  // Bufferに入っていた値を取り出す

        value += Increment + (index / 10.0); // おそらく適当な計算をしている

        Values[index] = value; // Bufferに新しい値を書き込む
    }
};

このノードの出力を Renderer類(RenderEntity、RendererScheduler、RenderWindo) などにつなぐことでGPUを使った計算ができます。
ReadBackFloat のノードが出力しているのは、GPUで計算された結果の値です。

同様の例を作ってみる

左上をクリックして New > Shader をすると、新しいshaderを作ることができます。
ComputeFXを選択するとそのまま使えるComputeShaderのテンプレートで作成してくれるので便利です。

こんな感じにノードを繋げます。
このサンプルでは長さ1のfloatのbufferを使って、実行ごとに +1をする計算をしています。

[Summary("")]
shader MySample_ComputeFX : ComputeShaderBase
{
	RWBuffer<float> Values;

    override void Compute()
    {
        uint index = streams.DispatchThreadId.x;
        
        Values[index] += 1; // Bufferの値に +1 するだけ
    }
};

F9キーを押すとリロードが行われるので挙動の確認に便利そうです。

sdslをfuseのnodeで置き換える

先程はComputeShaderの処理をsdslのコードで記載しましたが、fuseのノードでこれを置き換えることができます。

GetItemDispatchThredIdXから渡ってきたThreadIdを使い、Bufferから値を取り出しています。そしてその値を +1 したあと、SetItemで Bufferに書き戻します。

こうすることで sdslのコードを書かずに、ノードだけでcompute shaderを記述することができました。

描画したい

https://zenn.dev/spiqua/articles/07e1db68575ed3

Discussion