シェーディング言語

シェーディング言語（）は、プログラマブルシェーダー向けのプログラミング言語のこと。この種の言語は色や法線のような特別なデータ型を持っている。C言語やJavaのような汎用言語とは異なり、標準入出力機能を持たないなど、特定領域に特化したドメイン固有言語の一種である。3次元コンピュータグラフィックスの様々な市場に対応するため、複数の異なる言語が開発されている。以下にその概略を述べる。
プロダクションでのレンダリング.
この種のシェーディング言語は最高画質を目指して開発されている。材質特性は全体的に抽象的で、プログラミングスキルはほとんど要らないし、ハードウェアの知識は全く必要ない。この種のシェーダーは、アーティスト達がテクスチャマッピングやライティング、その他の作業を行って見たそのままに得られるように開発されている。
この種のシェーダーの処理は、たいてい時間がかかる。シェーダーが行う処理に必要な計算能力は、写実的な結果を得るためにより高価になり得る。大部分は巨大なコンピュータクラスター上で実行される（グリッド・コンピューティング、分散コンピューティング）。例えばShadeではShadeGridと呼ばれるネットワークレンダリングシステムを備えている。
RenderMan Shading Language.
RenderManシェーディング言語 (しばしばRSLないしSLと省略される) は、RenderManインタフェース仕様で定義されており、プロダクションレンダリングを行うのに最もよく使われているシェーディング言語である。また、この言語は最初に実装されたシェーディング言語でもある。
この言語は6つの主要なシェーダーのタイプを定義している。
Houdini VEX Shading Language.
Houdini VEX (Vector Expressions) シェーディング言語 (略してVEXと呼ばれる) は、RenderManシェーディング言語に非常に似たものとして作られている。この言語は完全な3Dグラフィックスのパッケージ製品とに統合されているけれども、シェーダー開発者は、普通はレンダリング処理上不可能なシェーダ内部の情報へアクセスすることができる。RSLとVEXの間の言語の違いは主に構文の違いである。2、3のシェーダー命令の名前が異なっている。
Gelato Shading Language.
Gelatoのシェーディング言語はHoudiniのVEXのように、RenderManシェーディング言語に非常に似たものに作られている。Gelatoシェーディング言語とRSLの違いは主に構文の違いである。Gelatoは関数定義中の引数を区切る方法としてカンマの代わりにセミコロンを使用している。また2、3のシェーダー命令の名前とパラメータが異なっている。
リアルタイムレンダリング.
まで、開発者は複数のビデオカードのグラフィックスパイプラインからの出力を同じレイヤで制御することができていなかったが、今やリアルタイムレンダリングにシェーディング言語を用いる方法が広く使われている。このことにより、以前のハードコードされた変形方式やシェーディング方程式を用いた方法と比較して、ハードウェアの抽象度を高めつつより柔軟なプログラミングモデルを取ることができるようになった。この結果、プログラマはレンダリング処理全体をより詳細に制御することができるようになり、小さなオーバーヘッドでより高品質なコンテンツを開発することができるようになった。
驚くべきことに、これらのシェーダーは最高のパフォーマンスを得るために、パイプライン上の適切な時点においてGPU上で直接実行されるように設計されており、またそのストリームプログラミングモデルのため、汎用処理（GPGPUなど）においても成功を収めている。
この種のシェーディング言語は通常グラフィックスAPI向けであるが、いくつかのアプリケーションでは機能制限付きではあるもののエンドユーザー向けの組み込みシェーディング言語として提供されている。
ARB 低レベルアセンブリ言語.
OpenGL Architecture Review Boardは2002年にグラフィックスプロセッサ向けの標準低レベル命令セットとしてARBを策定した。
ローディングと実行を行うために、高レベルOpenGL"シェーディング言語"はARBにコンパイルされる。高レベル"シェーディング言語"とは違い、ARBアセンブリはフロー制御や分岐をサポートしていない。しかしながらその移植性の高さから様々なGPUで使われ続けている。
OpenGL シェーディング言語.
GLSL、"glslang"としても知られている。言語文法はC言語がベースとなっている。これはOpenGL API用の高レベルシェーディング言語として、まずバージョン1.5の拡張機能として導入されたのち、バージョン2.0にて標準化された。本家OpenGLの他、OpenGL ES、WebGLといったサブセットや派生規格でもサポートされている。この言語は単一命令セットで頂点処理とフラグメント処理を統合し、条件ループと(より一般的な)分岐をサポートしている。歴史的に、GLSLの機能はARB_vertex_programやARB_fragment_programのような様々なOpenGL拡張によって先行して開発されてきた。これらの拡張には制限があったり、低レベルであったり、アセンブリのような言語であって、それらの使い勝手は今やよくない。これらの拡張自身も今や新しいバージョンには生き残っていない他の拡張提案によって先行開発されてきた。
DirectX アセンブリ言語.
Direct3D 8で初めて搭載された。アセンブリ言語とはいえ、ハードウェア非依存の中間バイトコードにアセンブルされるため、Direct3D対応であれば実行ハードウェアを問わない。Direct3D 9でもこのアセンブリ言語は使用可能だが、Direct3D 10以降は使用できない。
DirectX 高レベルシェーディング言語.
正式名称はHigh Level Shading Languageだが、HLSLの略称で呼ばれる。Direct3D 9で初めて搭載された。言語文法はC言語およびC++がベースとなっている。。主にマイクロソフトからの多大なサポートによる所もあるが、それと同時にリアルタイムレンダリング用途として最初のCスタイルシェーディング言語でもある。が、その機能はGLSLの機能と合わせるために異なるリビジョンが後にリリースされた。
OpenGL/Direct3Dで利用可能なシェーダープログラムのステージと機能はOpenGL/Direct3Dのバージョンによって異なる。また、GPUメーカーによって独自拡張された機能や、未実装の機能が存在するため、完全に互換性のあるシェーダープログラムを記述するのが困難になっているのが実情である（Direct3D 10においては、最低限すべての機能を満たすことが仕様として要求されているため、この問題は解消されている）。
GLSLおよびHLSLはともにC言語に似た構文を採用しており、さらにベクトル演算を記述しやすいようにC++言語風の拡張を行なっているが、両者に互換性はない。
Adobe Flash シェーディング言語.
アドビシステムズは Adobe Flash 11 以降用に Adobe Graphics Assembly Language (AGAL) と、C言語風の Pixel Bender 3D を開発した。
PlayStation 4 シェーディング言語.
ソニーは PlayStation 4 用に PSSL (PlayStation Shader Language) を開発した。PSSLはHLSLをベースとしている。
Metalシェーディング言語.
AppleはiOS 8で導入した独自のローレベルグラフィックスAPI「Metal」用に、Metal Shading Language (MSL) を開発した。
NVIDIA シェーディング言語.
NVIDIAによって開発されたこの言語は、簡単かつ効率的にプロダクションの作業パイプラインを統合できるようにデザインされた。この言語の特徴はAPI独立であることと素材管理を改善する非常に多くのフリーなツールからなっていることである。
CgはOpenGLおよびDirect3D両環境で動作するプログラムを記述できる。2012年4月を最後にバージョンアップは終了し、開発者へのCgランタイム自体の提供自体は継続されるものの、将来の新しいハードウェア機能をサポートしないため、新規開発での採用は推奨されていない。なお、CgはNVIDIAがMicrosoftと緊密に協力して開発した言語であるため、HLSLと似た構文になっており、ある程度の互換性も確保されている。
最初のCg実装はハードウェア部を抽象化するが故により制限が多かったが、それ以前の方法に比べても革新的であった。Cgという言語自体は、、より新しいシェーディング言語へのつなぎとして生き残っており、Adobe Photoshop、MayaやLightWaveでの採用など、主にデジタルコンテンツ作成現場では一定の地位を確立している。なおPlayStation 3の標準シェーディング言語はCgであり、他にもAAAタイトルWindowsゲームやUnityのようなゲームエンジンでも採用実績がある。
Cgの特徴としては「コネクタ」、つまり様々な処理ステージを結びつける特別なデータ構造として使われることである。ここでのコネクタとは、アプリケーションから入力されたデータを頂点処理ステージに受け渡し、フラグメント処理への入力する際に補間を行う。