Vulkanのシェーダーコードは、GLSL、HLSLなどの人間の読み取れる構文ではなく、バイトコード形式で指定する必要があります。このバイトコード形式は、SIR-Vと呼ばれVulkanとOpenCLの両方で使用するように設計されています。
バイトコードを使用する利点
バイトコードを使用する利点は、シェーダコードをネイティブコードに変換するためにGPUベンダーが作成したコンパイラーの複雑さが大幅に軽減されることです。GLSLのような人間の読める構文では、一部のGPUベンダーでは、動作できても、他のドライバーでは、実行を拒否したり、コンパイラーのバグのために異なったシェーダーを実行されたりする可能性があります。SPIR-vのような単純なバイトコード形式を使用することで回避することができる場合があります。
バイトコードを作成するには、GLSLをSPIR-Vをコンパイルする方法があります。KhronosはGLSLをSPIR-Vに変換する独自のコンパイラをリリースしました。すでにVulkanSDKに含まれているため追加のダウンロードは、必要ありません。
GLSL
GLSLには、C言語スタイルの構文を持つシェーダー言語です。そこで書かれたプログラムには、すべてにmain関数があります。入力に引数と、出力に戻り値を使用します。C言語との違いは、グローバル変数を使用して、入出力を取り扱います。もちろんグラフィックスプログラムを支援する様々な関数を用意しています。
vertex-shader 頂点シェーダ
頂点シェーダは、各頂点を処理します。ワールドの位置、色、法線、テクスチャの座標などの属性を受け取ります。出力には、クリップ座標の位置と、色やテクスチャ-の座標など、フラグメントシェーダに渡す必要がある属性です。これらの値は、ラスタイザーによって、フラグメント上で補完され、滑らかになります。
座標軸は、次のように見える中心をゼロとした[-1,1][-1,1]座標系にフレームバッファをマッピングする同次座標です。
最初に作成する三角形では、3つの頂点位置を直接指定して以下の形状を作成します。
通常これらの座標は、頂点バッファーに格納されますがVulkanで頂点バッファーを作成し埋めることは、簡単では、ないので画面に三角形をポップアップするまで直接シェーダー内で座標を決定します。
コードは、次のようになります。新しくshader.vertファイルに以下を書き込みます。
コードの記法は、GLSLの記法にのっとりコーディングしていきます。
#version 450
vec2 positions[3] = vec2[](
vec2(0.0, -0.5),
vec2(0.5, 0.5),
vec2(-0.5, 0.5)
);
void main() {
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
}
- vec2 position[3]
これに三角形の頂点の座標(x軸,y軸)を指定している。
- main 関数
main関数は、すべての頂点に関して呼び出されます。gl_vertexIndexには、現在の頂点インデックスが含まれています。これは、通常頂点バッファーのインデックスですが、今回は、直接定数で定義され,ダミーのz,w,座標と統合されクリップ座標の位置を生成します。組み込み変数gl_Positionは、出力となります。
コンパイル
コマンドプロンプトもしくは、パワーシェルで以下のように入力します。
シェーダファイルはたくさんできると思いますのでできる方は、batファイルを作成すると楽にコンパイルできるかもしれません。
VulkanSDK内のglslangValidator.exeに-vのオプションをつけてコンパイルするファイル名を指定します。
C:\VulkanSDK\1.1.82.1\Bin32\glslangValidator.exe -V shader.vert