コンテンツにスキップ

High Level Shading Language

出典: フリー百科事典『ウィキペディア(Wikipedia)』

これはこのページの過去の版です。Ertyupoi (会話 | 投稿記録) による 2015年1月17日 (土) 05:07個人設定で未設定ならUTC)時点の版 (Ertyupoi がページ「High Level Shader Language」を「High Level Shading Language」に移動しました: High Level Shading Languageが現在の正式名称)であり、現在の版とは大きく異なる場合があります。

High Level Shading Language(ハイレベル シェーディング ランゲージ、略称: HLSL)はマイクロソフトによって開発されたDirect3Dで使われるプログラマブルシェーダのためのプロプライエタリシェーディング言語である。MSDNの日本語版では上位レベル シェーダ言語(じょういれべるシェーダーげんご)という訳語を使用している[1]。かつては High Level Shader Language という呼び方もされていた。

HLSLはOpenGLで使われるシェーディング言語であるGLSLと(機能的には)類似の物である。また、NVIDIAと協力して開発されたことから、言語文法がCg(C for Graphics)言語に非常によく似ている。

開発経緯

Direct3D 7まではグラフィックスカードに実装された固定パイプラインおよびハードウェア機能を駆使して3Dグラフィックスシーンを構築していたが、グラフィックス表現の柔軟性を向上させるべく、Direct3D 8ではプログラマブルシェーダーが搭載された。これによって、グラフィックスアプリケーション開発者がグラフィックス描画アルゴリズムをソフトウェアによってカスタマイズすることが可能となった。しかし、Direct3D 8で使用できるシェーダー言語はアセンブラ低級言語)であったため、開発効率やプログラムコードの再利用性に限界があった。それを解消するべく、C言語風の宣言文や制御文などの記法を可能とした高級言語HLSLが開発されることとなった。

プログラマブルパイプラインステージ

HLSLによってプログラム可能なグラフィックスパイプラインステージは、対応するDirect3Dのバージョン(シェーダーモデル)によって異なる。

頂点シェーダーはアプリケーションによって提供(入力)される頂点それぞれについて実行され、主にオブジェクト空間から視空間への頂点座標変換やテクスチャ座標の生成、また頂点の接線や従法線や法線ベクトルのような光線の係数の計算などの処理を担当する。頂点シェーダーを通して頂点のグループ (三角形であれば通常は3個) が入力された時、出力座標はその領域内で画面上のピクセルを決めるために補間される。この処理はラスタライゼーションとして知られている。これらのピクセルそれぞれがピクセルシェーダーを通ることで、結果としてスクリーン上の各点の色が計算される。

また、Direct3D 10/11対応ハードウェアにおいてDirect3D 10/11インターフェイスを使うアプリケーションは、頂点シェーダーステージの後にジオメトリシェーダーを指定することもできる。ジオメトリシェーダーはラスタライズの前にプリミティブの増減を行なうことができる。

なお、HLSLで使用可能なパーリンノイズ生成関数であるnoise()は、テクスチャシェーダーと呼ばれる特殊なシェーダーステージでのみ利用が可能となっている。

コード例

以下にDirect3D 10/11向けHLSLを用いた、単純なHalf Lambert照明モデルおよびPhong照明モデル(Blinn-Phong)の頂点シェーダーおよびピクセルシェーダーのプログラムを示す (動的分岐によって照明モデルを切り替える例であるが、これはいわゆるウーバーシェーダー(uber-shader)なので、実行速度効率などは考慮していないことに注意されたい)。

// 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);
	}
}

例のように、ピクセルシェーダーによってピクセル単位の正規化法線ベクトルを求めることにより、Direct3D 7以前の固定機能シェーダーでは実現が難しかったPer-Pixelライティングが容易に実装可能となっている。 もちろん、使用するシェーダーモデルおよび対応するハードウェアによっては、より複雑で長大なアルゴリズムを実装することもできる。単純な局所照明(ローカルイルミネーション)だけでなく、より厳密な物理ベースのレンダリング方程式に基づいた、大域照明(グローバルイルミネーション)モデルをHLSLによるプログラマブルシェーダーで実装することで、より現実に近いリアルタイム3Dコンピューターグラフィックスを実現することも可能となる。さらに、Direct3D 11ではコンピュートシェーダーを使って、GPUにグラフィックス用途以外の汎用計算を行なわせるGPGPUプログラムをHLSLで記述することも可能となる。

対応環境

HLSLプログラムは主にホストとなるC++アプリケーションプログラムコードからDirect3D APIを使って入力と出力を管理する必要があるので、単体で動作させることはできない。なお、単体のコンパイラはマイクロソフトから無償提供されているDirectX SDK(あるいはバージョン8.0以降のWindows SDK)に付属する。HLSLコンパイラfxc.exeによって出力されるのは、グラフィックスハードウェアのベンダに依存しない共通バイトコードであるため、一度コンパイルしておけば異なるハードウェアであっても動作させることができる。HLSLプログラムをサポートするのはDirect3D 9以降をサポートするシステムに限られるため、2013年4月現在ではWindows OSおよびXbox 360が主な動作環境である。

エフェクト

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++コードから分離することができる。

シェーダーモデル比較

ハードウェア(グラフィックスカード)の世代によって、実行可能なシェーダープログラムの仕様(制約、機能など)が異なる。この仕様はシェーダーモデルと呼ばれ、新しい世代のシェーダーモデルをサポートするハードウェアは基本的に古い世代のシェーダーモデルもサポートする[2]が、ベンダーごとに拡張された2.0a/2.0bなどの例外も存在する。

なお、Direct3D 10.1 APIでは4.xプロファイルのシェーダープログラムに加えてダウンレベルの2.0プロファイルが使用可能であり、Direct3D 11.x APIでは5.0および4.xプロファイルに加えてダウンレベルの2.0プロファイルが使用可能だが、いずれも3.0プロファイルに関しては使用できない[3] [4] [5] [6]

ピクセルシェーダーの比較

  PS_1.0から1.3 PS_1.4 PS_2.0 PS_2.0a PS_2.0b PS_3.0[7] PS_4.0[8]
依存テクスチャ制限 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
  • PS_2.0 = DirectX 9.0のオリジナルのShader Model 2の仕様である.
  • PS_2.0a = NVIDIA GeForce FXに最適化されたモデル。
  • PS_2.0b = ATI Radeon X700, X800, X850のシェーダーモデル, DirectX 9.0b.
  • PS_3.0 = Shader Model 3.
  • PS_4.0 = Shader Model 4.

実行命令数において"32 + 64"というのは"32のテクスチャ命令と64の算術命令"を意味する。

頂点シェーダーの比較

  VS 1.1 VS_2.0 VS_2.0a VS_3.0[7] VS_4.0[8]
命令スロット数 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
  • VS_2.0 = DirectX 9.0のオリジナルのShader Model 2の仕様である.
  • VS_2.0a = NVIDIA GeForce FXに最適化されたモデル。
  • VS_3.0 = Shader Model 3.
  • VS_4.0 = Shader Model 4.

脚注

外部リンク