HLSL
[Wikipedia|▼Menu]

High Level Shading Language(ハイレベル シェーディング ランゲージ、略称: HLSL)[1]マイクロソフトによって開発された、Direct3D (DirectX) で使われるプログラマブルシェーダーのためのプロプライエタリシェーディング言語である。High Level Shader Language という呼び方もされている[2][3][4]。ただしMSDNの日本語版ドキュメントでは、英語版の原文が「High Level Shader Language」となっている箇所だけでなく「High Level Shading Language」となっている箇所でも、上位レベル シェーダー言語(じょういレベルシェーダーげんご)という訳語を使用している[5][6]

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

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

GDC 2016ではDirectX 12の今後の発展、そして新たな次期DirectXとシェーダーモデル6の開発に関して言及があり、HLSL言語仕様にも大きな機能追加が予定されていることが発表された[8]。シェーダーモデル6.0ではWaveと呼ばれるSIMT(英語版)スレッドグループの概念と各グループ内でのデータ交換(シャッフル)のための組み込み命令が導入され、NVIDIA GPUのWarpおよびAMD GPUのWavefrontを標準化した[9]
プログラマブルパイプラインステージ

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

Direct3D 9の場合(シェーダーモデル1.x-3.0)は、
頂点シェーダーバーテックスシェーダー)およびピクセルシェーダー(OpenGLにおけるフラグメントシェーダーに相当)の2つである。

Direct3D 10.xの場合(シェーダーモデル4.x)は、頂点シェーダー、ジオメトリシェーダー(OpenGLではプリミティブシェーダーとも呼ばれる)、そしてピクセルシェーダーの3つである。

Direct3D 11.x/12の場合(シェーダーモデル5.x)は、頂点シェーダー、ハルシェーダー(OpenGLにおけるテッセレーション制御シェーダーに相当)、ドメインシェーダー(OpenGLにおけるテッセレーション評価シェーダーに相当)、ジオメトリシェーダーピクセルシェーダー、そしてコンピュートシェーダー(計算シェーダー、演算シェーダー)の6つである。ただしコンピュートシェーダーだけはグラフィックスパイプラインとは独立して動作させることができる。

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

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

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

Windows 10 October 2018 Update (version 1809) では、DirectX Raytracing(英語版) (DXR) と呼ばれるリアルタイムレイトレーシング技術が実装された[11]。DXRにハードウェアレベルで対応するGPU上では、シェーダーモデル6.3のレイトレーシングパイプラインを記述するためのHLSLシェーダーが利用可能となる[12]
言語機能

HLSLの基本的な文法はC/C++に準ずるが、グラフィックスプログラムを記述するのに適した専用のベクトル・行列型や関数を備えている。数学関数の中にはC/C++標準ライブラリと同様のものも含まれる。また、Direct3D 10ではAPIの大幅な設計変更が行なわれたこともあり、Direct3D 9用のHLSLと比較して、Direct3D 10以降用のHLSLではオブジェクト指向に基づいた言語仕様の再設計がなされ、多数の仕様変更が加えられている[13]

Direct3D 10以降ではHLSLにてクラスを定義し、C++のようにデータ(メンバー変数)と振る舞い(メンバー関数)を関連付けることが可能だが、アクセス指定子によるカプセル化継承および仮想関数といった機能は備えていない。

Direct3D 11ではシェーダーの組み合わせ爆発問題を解消するべく、HLSLにてインターフェイスの定義と実装によるポリモーフィズムを疑似的に実現する「動的シェーダーリンク(Dynamic Shader Linkage)」と呼ばれる機能が追加された[14]
コード例

以下に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 (DirectCompute) ではコンピュートシェーダーを使って、GPUにグラフィックス用途以外の汎用計算を行なわせるGPGPUプログラムをHLSLで記述することも可能となる。

なお、HLSLソースファイルには通例.hlsl拡張子が付けられ、ヘッダーファイルには.hlsli拡張子が付けられる[15]
対応環境

HLSLプログラムは主にホストとなるC++アプリケーションプログラムコードからDirect3D APIを使って入力と出力を管理する必要があるので、単体で動作させることはできない。なお、単体のコンパイラはマイクロソフトから無償提供されているDirectX SDK(あるいはバージョン8.0以降のWindows SDK)に付属する。プロプライエタリなHLSLコンパイラfxc.exeによって出力されるのは、グラフィックスハードウェアのベンダーに依存しない共通バイトコード中間表現)であるため、一度コンパイルしておけば異なるハードウェアであっても(コンパイル時に想定されていた機能を満たす限り)動作させることができる[16]。HLSLプログラムをサポートするのはDirect3D 9以降をサポートするシステムに限られるため、かつてはWindows OSおよびXbox 360以降のXboxシリーズが主な動作環境であったが、Vulkan向けのシェーダープログラムを事前コンパイルして中間表現SPIR-V(英語版)を生成するコンパイラglslangValidator[17]がGLSLとHLSLの両方に対応したことなどもあり、クロスプラットフォームでのHLSLの活用が進んでいる。


次ページ
記事の検索
おまかせリスト
▼オプションを表示
ブックマーク登録
mixiチェック!
Twitterに投稿
オプション/リンク一覧
話題のニュース
列車運行情報
暇つぶしWikipedia

Size:56 KB
出典: フリー百科事典『ウィキペディア(Wikipedia)
担当:undef