コンピュート シェーダ は,通常のレンダリング パイプラインと異なって,グラフィックス カード上で動作するプログラムです。これは超並列 GPGPU アルゴリズム,またはゲームレンダリングの一部を加速させるために使用できます。効果的に使用するためには,しばしば GPU アーキテクチャおよび並列アルゴリズム,さらには DirectCompute , OpenCL ,または CUDA に関する深い知識が必要です。
Unityでのコンピュート シェーダ は DirectX 11 DirectCompute テクノロジーにもとづいて作られていて,現在は Windows Vista 以降 かつ シェーダモデル 5.0 を利用可能な GPU が必要です。
通常のシェーダ と似て,コンピュート シェーダ はプロジェクト上で *.compute
拡張子のついたアセットファイルです。DirectX 11 スタイルの HLSL 言語で記述されていて,最小限の #pragma
コンパイル ディレクティブ 用いてどの関数がコンピュート シェーダ カーネルを用いるか指定します。
コンピュート シェーダ を使用するための最低限のサンプルを示します:
// test.compute
#pragma kernel FillWithRed
RWTexture2D<float4> res;
[numthreads(1,1,1)]
void FillWithRed (uint3 dtid : SV_DispatchThreadID)
{
res[dtid.xy] = float4(1,0,0,1);
}
上記のサンプルでは際立って面白いことはやっておらず,ただ出力テクスチャを赤で埋めます。
言語は標準的な DirectX 11 HLSL であり,例外として #pragma kernel FillWithRed
ディレクティブを使用しています。ひとつのコンピュート シェーダ アセットは最低限ひとつの実行可能な “コンピュート カーネル” を含む必要があり,その関数はe #pragma ディレクティブにより指定します。ファイルの中に複数のカーネルを含むことが可能であり,複数の #pragma kernel
行を追加するのみです。
#pragma kernel
行はオプションとして,カーネルをコンパイルしている間に複数のプリプロセッサ マクロを後に続けて定義することが可能です。サンプルとしては:
#pragma kernel KernelOne SOME_DEFINE DEFINE_WITH_VALUE=1337
#pragma kernel KernelTwo OTHER_DEFINE
// ...
スクリプトのなかで, ComputeShader
型の変数を定義して,アセットに対する参照を割り当てて,その後は ComputeShader.Dispatch 関数を用いて実行することが出来ます。詳細についてはスクリプト リファレンスの ComputeShader を参照下さい。
コンピュート シェーダ と密接に関連しているのが ComputeBuffer クラスであり,任意のデータバッファを定義します (DirectX 11 用語では “structured buffer”)。 Render Texture も, “random access” フラグ (DirecX 11用語では “unordered access view”) がセットされていれば,またコンピュート シェーダから書き込むことが出来ます。 RenderTexture.enableRandomWrite を参照下さい。
テクスチャおよびサンプラはUnityで別オブジェクトではないため,コンピュート シェーダ で使用するためには Unity 特有のルールに従う必要があります:
Texture2D MyTexの場合, SamplerState samplerMyTex
) のいずれかにします。"SamplerState MyLinearClampSampler"
- これにより フィルタとして Linear ,かつ, Wrapモードとして Clamp が使用されます。