GPU/Shader Language
Graphics | Compute | ||
---|---|---|---|
HLSL (DirectX) | Y | Y | 独自, C++言語ベース |
GLSL (OpenGL) | Y | Y | 独自, C言語風だが細部は異る |
Cg (NVIDIA) | Y | ? | 言語上はほぼ HLSL だが DirectX 以外でも使えるため細部は異なる |
Mantle (AMD) | Y | Y | |
Metal (Apple) | Y | Y | C++言語 (LLVM) |
CUDA (NVIDIA) | N | Y | C言語 (LLVM) |
OpenCL | N | Y | 独自 |
RenderScript (Android) | N | Y | C言語 (LLVM clang) |
SPIR-V (Vulkan) | Y | Y | Binary 中間言語 (GLSL or C++等から変換) |
- C言語タイプ : リソースはポインタ表現が可能、LLVM (clang) ベース
- HLSL タイプ : ポインタ表現は使わないが構文は C言語の拡張
- GLSL タイプ : function, statement は C言語だが、データタイプ (配列,Vector,Matrix) やデータの初期化、型変換などは独自仕様
- data type (vector, matrix 等) とその演算子、組み込み関数などは基本的に互換性なし
LLVM/clang を使った C言語タイプはコンパイラが明確かつメジャーなので、構文上のバグ発生率が極めて低いという利点があります。 GLSL のようにドライバ毎にコンパイラが異なっている場合は、同じ言語でも実装が GPU によって異なるため、初歩的なバグが残っていることも少なくありません。
GLSL が一番方言が強いですが、Smartphone からブラウザまで最も多くのプラットフォームで走るシェーダー言語でもあります。
Shader File
プラットフォームによって Shader File に記述可能な情報が異なっています。
- GLSL : Entry は必ず main() 、そのため VertexShader, FragmentShader 等は個別に別ファイルにしなければならない。(pre processor で分岐するなどの工夫は可能)
- HLSL : コンパイル時に Entry 関数名を指定可能。そのため複数のシェーダー関数を 1ファイルに記述できる。
シェーダーの入出力を定義するのは描画命令を発行するアプリケーション (エンジン) 側の役割なので、 同じ言語の ShaderFile でも他の環境でそのまま使えるわけではありません。
In/Out (attribute/varying) , Constant (Uniform) , Buffer, texture (resource) 等、アプリケーション側で決めている仕様に合わせた変更が必要となります。
FX
FX は、 VertexSahder, PixelShader など複数のシェーダーを組み合わせて、パイプラインや基本的なステートも同時に記述できる複合フォーマットです。 DirectX HLSL の fx ファイル、CgFx が有名。
FX に記載された情報を解釈するのは描画エンジン (CPU側) の役割なので、描画エンジンが対応していない情報は記述しても無視されます。
HLSL, CgFx 以外は明確な標準型が存在しないため、多くの場合は描画エンジン依存であり互換性はありません。
SAS
同じシェーダー言語だったとしても入出力のインターフェースに互換性がないと、そのまま再利用することが出来ません。 入出力の記述を共通化するために定められたフォーマットが DirectX HLSL の SAS です。
ただし厳密に SAS に従った実装は多くなく、部分的な流用が多いものと考えられます。 決められたルールだけでは不足するので、実際の描画時は何らかの独自拡張が必要となっていることも問題です。
また SAS 自体も途中で仕様を完全にリセットしたことがあります。 これは互換性が全くない仕様変更であり、初期の実装が無駄になっています。 それゆえ信頼性の面でも不安が残り普及を妨げることとなりました。
GUI との相性が良いためツールではよく利用されていますが、 やはり完全な互換性が確保できているわけではありません。