1 / 4 HLSL入門
HLSL(High Level Shading Language)は、GPU上で実行されるシェーダープログラムを記述するための高水準言語です。
C言語に似た構文を持ち、GPU上での頂点変換やピクセル処理などを効率的に記述することができます。
HLSLの概要と歴史
初期のGPUは頂点変換や光源計算などの処理のプログラミング能力を有しておらず、固定機能パイプラインがハードウェアに固定されていました。
後にプログラマブルシェーダーが導入され、頂点シェーダーやピクセルシェーダーといった個別の処理単位をGPU上で自由に記述できるようになりました。
当初プラグラマブルシェーダーは限られた機能しか持たず、記述にもアセンブリ言語が必要でした。
これにC言語に似た高水準言語であるCgが登場しました。
HLSLは、Cgを引き継ぎつつMicrosoftとNVIDIAの協力のもとで開発された高水準シェーダー言語です。
DirectX環境での利用を前提としており、CgよりもDirectXとの親和性が高く、現在ではDirectXベースのグラフィックスプログラミングにおける標準的な言語となっています。
Shader Graphとの違い
グラフィカルにシェーダーを組み立てるShader Graphとは異なり、HLSLではコードベースでシェーダーの処理を記述します。
文法はC言語に似ており、変数宣言、条件分岐、ループ、関数定義などが可能です。
例えば最小限の頂点シェーダーは以下のようなコードになります。
// 頂点シェーダーの例
struct VS_INPUT
{
float4 Pos : POSITION;
float4 Col : COLOR;
};
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float4 Col : COLOR;
};
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT output;
output.Pos = input.Pos;
output.Col = input.Col;
return output;
}コードベースのシェーダー記述は、Shader Graphに比べてやや難解であり、初心者には敷居が高いという欠点もあります。
しかし柔軟性が高く、複雑な処理や最適化を行いやすいという利点があります。
本来HLSLは特定のゲームエンジンに依存しない汎用的なシェーダー言語ですが、Unityからの利用ではShaderLabを介して組み込む形が一般的です。
Compute Shader
Compute Shaderは、GPU上で汎用的な計算を行うためのシェーダーです。
HLSLを用いて記述され、頂点やピクセルの処理に依存しない計算を効率的に実行することができます。
Unityからの利用の際にHLSLを直接記述するのは、通常このCompute Shaderのような特殊な場合に限られます。
HLSLの利点と難点
利点
- 高い柔軟性: HLSLではShader Graphでは表現しにくい複雑なシェーダー処理や最適化を行うことができます。
- 高いパフォーマンス: GPUの特性を活かした効率的なシェーダー記述が可能であり、パフォーマンスの向上が期待できます。
- 高い移植性: HLSLはDirectX環境で広く利用されており、異なるハードウェア間での移植性が比較的高いです。
特にHLSLで扱えるループは、Shader Graphでは表現しにくい複雑な繰り返し処理を効率的に記述することができます。
難点
- 高い学習コスト: HLSLはShader Graphに比べて文法や構造が複雑であり、初心者には習得が難しい場合があります。
- デバッグの難しさ: GPU上で実行されるため、CPU上でのデバッグに比べて問題の特定や修正が難しいことがあります。
Shader Graphとの併用
Shader Graphのカスタムファンクションを利用することで、Shader GraphからHLSLの処理を呼び出すことができます。
Shader Graphは非常に強力なビジュアルシェーダー作成ツールですが、標準ノードだけでは任意のループを扱えないなど一部に制約があります。
また、複雑な処理のためには大量のノードを配置しなければならず、記述性に難があります。
一方でHLSLはShader Graphでは表現しにくい複雑な処理や最適化を平易に扱うことが可能です。
利便の点ではShader Graphが優れていますが、一部単独では扱えない処理があり、また複雑な処理は記述自体が困難です。
こうした場合、HLSLのカスタムファンクションを利用することで制約を補うことができます。
シェーダーのすべての処理をHLSLで記述することも可能ですが、Unity固有の機能やマテリアルシステム、マルチプラットフォームを扱うためには複雑な手順を理解し実装しなければなりません。
Shader Graphとの併用により、視覚的な編集の利便性とHLSLの柔軟性を両立させることができます。
カスタムファンクション
Shader Graphのカスタムファンクションノードを使用することで、HLSLで記述した関数をShader Graph内で呼び出すことができます。
例えば、以下のようにHLSLで関数を定義し、Shader Graphのカスタムファンクションノードから呼び出すことができます。
float4 MyCustomFunction(float4 input)
{
// 任意の処理
return input * 2.0;
}HLSLはテキストファイルで記述してShader Graphのカスタムファンクションノードから参照する形で利用します。
あるいは、カスタムファンクションノード内に直接HLSLコードを記述することも可能です。
是非活用してください。
https://docs.unity3d.com/Packages/com.unity.shadergraph@17.7/manual/Custom-Function-Node.html