High Level Shading Language
開発経緯
編集プログラマブルパイプラインステージ
編集言語機能
編集コード例
編集// Shader Constants.
matrix TrWorldViewProj;
matrix TrWorld;
float4 LightPosition;
float3 EyePosition;
float4 DiffuseColor;
float4 SpecularColor;
float SpecularPower;
bool IsPhongModel;
struct BasicVSOutput
{
float4 Pos : SV_POSITION;
float3 WPos : TEXCOORD1;
float3 WNormal : NORMAL0;
};
typedef BasicVSOutput BasicPSInput;
// Vertex Shader Program.
BasicVSOutput BasicVS(float3 pos : POSITION0, float3 normal : NORMAL0)
{
BasicVSOutput output = (BasicVSOutput)0;
output.Pos = mul(float4(pos, 1), TrWorldViewProj);
output.WPos = mul(float4(pos, 1), TrWorld).xyz;
output.WNormal = mul(normal, (float3x3)TrWorld);
return output;
}
float4 CalcLambert(float3 light, float3 wnormal)
{
// Half Lambert.
float lambert = dot(light, wnormal);
lambert = lambert * 0.5f + 0.5f;
lambert *= lambert;
return lambert * DiffuseColor;
}
float4 BasicLambert(BasicPSInput input)
{
const float3 light = normalize(LightPosition.xyz - input.WPos);
const float3 normal = normalize(input.WNormal);
return CalcLambert(light, normal);
}
float4 BasicPhong(BasicPSInput input)
{
// Phong lighting with specular.
const float3 eye = normalize(EyePosition - input.WPos);
const float3 light = normalize(LightPosition.xyz - input.WPos);
const float3 halfway = normalize(light + eye);
const float3 normal = normalize(input.WNormal);
const float specular = pow(max(dot(normal, halfway), 0.0), SpecularPower);
return CalcLambert(light, normal) + specular * SpecularColor;
}
// Pixel Shader Program.
float4 BasicPS(BasicPSInput input) : SV_TARGET0
{
if (IsPhongModel)
{
return BasicPhong(input);
}
else
{
return BasicLambert(input);
}
}
対応環境
編集エフェクト
編集HLSL自体は、シェーダー関数および各シェーダーステージのエントリーポイント(いわゆるメイン関数)を記述するために使われるが、この複数のシェーダーステージをまとめて管理・適用する「エフェクト」と呼ばれる仕組みも存在する。つまり、例えば2つの頂点シェーダーエントリーポイントVS1(), VS2()と2つのピクセルシェーダーエントリーポイントPS1(), PS2()を単一のHLSLソースプログラムファイル(通例.fx拡張子が付けられ、エフェクトファイルと呼ばれる)に記述し、さらにVS1+PS1, VS2+PS2, VS1+PS2, VS2+PS1といったシェーダーステージの組み合わせ(パス)のほか、各種レンダリングステートの設定をエフェクトファイル中に記述して関連付けることができる。エフェクトを扱うAPIはDirect3D 10のコアライブラリもしくはDirect3D 9/11のエクステンションライブラリ(D3DX)に用意されており、レンダリングパイプラインの管理をC++コードから分離することができる。
WPFエフェクト
編集Windowsデスクトップアプリケーションフレームワークの1つであるWPFでは、グラフィックスのレンダリングにDirect3Dが使用されているが、GUIウィジェットにブラー(ぼかし)やドロップシャドウといったエフェクト(フィルター)を適用することが可能となっている。さらにWPFではユーザープログラマーがHLSLで作成したピクセルシェーダーを使用してカスタムエフェクトを適用することもできる[25]。
WPF 3.5まではシェーダーモデル2.0のピクセルシェーダーのみがサポートされていたが、WPF 4ではシェーダーモデル3.0のピクセルシェーダーも使用できるようになった[26] [27]。
Direct2Dエフェクト
編集DirectXファミリーの1つ、2次元コンピュータグラフィックスAPIであるDirect2Dでは、バージョン1.1にてエフェクト機能が実装されたが、HLSLによるカスタムエフェクトを作成・利用することも可能となっている[28]。
シェーダーモデル
編集D3DCREATE_S
OFTWARE_VERTEXPROCESSING
︶ため、固定機能ピクセルシェーダーと組み合わせることによりDirect3D 7以前の古いハードウェアでプログラマブルシェーダーを実行することも可能である。また、Direct3D 10.1以降では比較的高速なソフトウェアレンダリングエンジンであるWARPデバイスも実装されているため、GPUが対応していなくてもCPUにDirect3Dレンダリングを実行させることもできる。
Direct3D対応ハードウェア︵グラフィックスカード︶の世代によって、GPU上にてハードウェアレベルで実行可能なシェーダープログラムの仕様︵制約、機能など︶が異なる。この仕様はシェーダーモデルと呼ばれ、新しい世代のシェーダーモデルをサポートするハードウェアは基本的に古い世代のシェーダーモデルもサポートする[29]が、ベンダーごとに拡張された2.0a/2.0bなどの例外も存在する。
なおHLSLがDirect3Dに搭載されたのはバージョン9以降だが、シェーダーモデル2.0以降でないとHLSLを使えないというようなことはなく、HLSLを使用してシェーダーモデル1.xレベルのプログラムを記述することも可能である。また、Direct3D 10では、アセンブリ言語によるシェーダープログラム開発が廃止され、シェーダーの記述にはHLSLのみが使用できるようになった[30]。
シェーダーモデル3.0には頂点テクスチャフェッチ︵Vertex Texture Fetch, VTF︶と呼ばれる機能が存在するが、DirectX 9.0c世代で対応したのはNVIDIAのハードウェアのみで、ATIのハードウェアではサポートされなかった。逆に、浮動小数点バッファにおけるアンチエイリアス機能は、NVIDIAハードウェアではサポートされず、ATIハードウェアのみでの対応となっていた[31] [32]。他にも、︵DirectX 11で標準化される前の︶テッセレーション機能[33]がATIハードウェア上のみでサポートされる[34] [35] [36]など、シェーダーモデル3.0までは︵たとえDirectX 9.0c対応を謳っていても︶機能面において各社の足並みがそろわない状態にあり、これらの機能を利用するアプリケーション開発者は使用したい機能が実際にハードウェアでサポートされているかどうかをあらかじめDirect3DのCaps (Capabilities) 取得APIを使って一つ一つ調べなければならなかった。このようにベンダーごとに各機能の対応レベルがバラバラとなっていた悲惨な状況は、次のバージョンのDirect3D 10以降で要求仕様が厳格化されたことで、ある程度解消されることになる[37]。
なお、Direct3D 10.1 APIでは4.xプロファイルのシェーダープログラムに加えてダウンレベルの2.0プロファイルが使用可能であり、Direct3D 11/12 APIでは5.xおよび4.xプロファイルに加えてダウンレベルの2.0プロファイルが使用可能だが、いずれも3.0プロファイルに関しては使用できない[38] [39] [40] [41]。
DirectXバージョンと各シェーダーステージ
編集以下の表はハードウェアが対応しているDirectXバージョンと、そのハードウェアがサポートする各シェーダーステージの最上位バージョン(プロファイル)間の関係を示している。 後述するように、実行可能なシェーダープログラムの最大命令数やレジスタ数、リソーススロット数などは新しいバージョンのほうが大きくなり、より柔軟で長大なプログラムを記述することができるようになる。
DirectX Version | Pixel Shader | Vertex Shader | Geometry Shader | Hull Shader | Domain Shader | Compute Shader |
---|---|---|---|---|---|---|
8.0 | 1.0, 1.1 | 1.0 | - | - | - | - |
8.1 | 1.2, 1.3, 1.4 | 1.1 | - | - | - | - |
9.0 | 2.0 | 2.0 | - | - | - | - |
9.0a | 2.0a | 2.0a | - | - | - | - |
9.0b | 2.0b | 2.0 | - | - | - | - |
9.0c | 3.0 | 3.0 | - | - | - | - |
10.0 | 4.0 | 4.0 | 4.0 | - | - | 4.0 |
10.1 | 4.1 | 4.1 | 4.1 | - | - | 4.1 |
11.0-11.2 | 5.0 | 5.0 | 5.0 | 5.0 | 5.0 | 5.0 |
11.3, 12 | 5.1 | 5.1 | 5.1 | 5.1 | 5.1 | 5.1 |
12 | 6.0 | 6.0 | 6.0 | 6.0 | 6.0 | 6.0 |
ピクセルシェーダーの比較
編集PS 1.0-1.3 | PS 1.4 | PS 2.0 | PS 2.0a | PS 2.0b | PS 3.0[45] | PS 4.0[46], 4.1, 5.0 | |
---|---|---|---|---|---|---|---|
依存テクスチャ制限 | 4 | 6 | 8 | 無制限 | 4 | 無制限 | 無制限 |
テクスチャ命令制限 | 4 | 6*2 | 32 | 無制限 | 無制限 | 無制限 | 無制限 |
Position register | No | No | No | No | No | Yes | Yes |
命令スロット数 | 8 + 4 | 8 + 4 | 32 + 64 | 512 | 512 | ≥ 512 | ≥ 65536 |
実行命令数 | 8+4 | 6*2+8*2 | 32 + 64 | 512 | 512 | 65536 | 無制限 |
テクスチャの間接参照数 | 4 | 4 | 4 | 無制限 | 4 | 無制限 | 無制限 |
Interpolated registers | 2 + 8 | 2 + 8 | 2 + 8 | 2 + 8 | 2 + 8 | 10 | 32 |
命令予測 | No | No | No | Yes | No | Yes | No |
Index input registers | No | No | No | No | No | Yes | Yes |
一時レジスタ(Temp registers) | 2 | 6 | 12から32 | 22 | 32 | 32 | 4096 |
定数レジスタ(Constant registers) | 8 | 8 | 32 | 32 | 32 | 224 | 16x4096 |
Arbitrary swizzling | No | No | No | Yes | No | Yes | Yes |
Gradient instructions | No | No | No | Yes | No | Yes | Yes |
Loop count register | No | No | No | No | No | Yes | Yes |
Face register (2-sided lighting) | No | No | No | No | No | Yes | Yes |
動的フロー制御 | No | No | No | No | No | 24 | Yes |
ビット演算 | No | No | No | No | No | No | Yes |
整数演算 | No | No | No | No | No | No | Yes |
頂点シェーダーの比較
編集VS 1.1 | VS 2.0 | VS 2.0a | VS 3.0[45] | VS 4.0[46], 4.1, 5.0 | |
---|---|---|---|---|---|
命令スロット数 | 128 | 256 | 256 | ≥ 512 | 4096 |
最大命令実行数 | 不明 | 65536 | 65536 | 65536 | 65536 |
命令予測 | No | No | Yes | Yes | Yes |
一時レジスタ(Temp registers) | 12 | 12 | 13 | 32 | 4096 |
定数レジスタ(Constant registers) | ≥ 96 | ≥ 256 | ≥ 256 | ≥ 256 | 16x4096 |
静的フロー制御 | 不明 | Yes | Yes | Yes | Yes |
動的フロー制御 | No | No | Yes | Yes | Yes |
動的フロー制御の深度 | No | No | 24 | 24 | Yes |
Vertex Texture Fetch | No | No | No | Yes | Yes |
テクスチャサンプラーの数 | N/A | N/A | N/A | 4 | 128 |
Geometry instancing support | No | No | No | Yes | Yes |
ビット演算 | No | No | No | No | Yes |
整数演算 | No | No | No | No | Yes |