CgはNVIDIAが開発していた、リアルタイム3次元コンピュータグラフィックス(3DCG)におけるプログラマブルシェーダーのためのシェーディング言語である。2012年を最後にバージョンアップは終了している。GPUプログラミングのために特化・最適化されており、CG描画に向いている。この言語名の由来は「グラフィックスのためのC言語」(C for Graphics) であり、C言語 (ANSI C) をベースとした文法を持つ。また、C++言語の類似機能も一部取り入れている。
GPUの技術的な発展にともない、アプリケーションソフトウェアのプログラマーが陰影計算処理(シェーディング)をプログラミング可能なハードウェアが開発・提供されるようになった。しかしDirect3D 8.xやOpenGL ARB拡張における最初期のGPUプログラミングは低水準言語(アセンブリ言語)をベースとしたもので、APIの実装が提供するランタイムライブラリおよびデバイスドライバーに含まれるアセンブラが解釈可能なニーモニックを利用してプログラムを記述する必要があったため、開発が難しく生産性や可搬性も低かった。そのため、GPU向けの高水準言語が必要とされるようになり、Cgが開発された。Cg Toolkit 1.0のベータ版は2002年6月に公開された[1]。
なお、類似のGPU用高水準言語として、OpenGLネイティブのGLSL(2003年にOpenGL 1.5の拡張機能としてリリース)およびDirectX(Direct3D)ネイティブのHLSL(2002年末にDirectX 9.0の標準機能としてリリース)が存在するが、Cgはどちらかというと(マイクロソフトとNVIDIAが共同開発した)HLSLにより近い文法となっている。
GLSLはOpenGL専用であり、またHLSLはDirect3D専用であるが、Cg言語およびCgランタイムライブラリは両方のAPIに対応しているという特徴を持っている。つまり、OpenGLおよびDirect3Dの両方を、Cgシェーダープログラムを実行する基盤として利用することができる。
NVIDIAのGPGPU開発・実行環境であるCUDA用に拡張されたC/C++では、Cgによく似たデータ型や組み込み関数が実装されているなど、Cgは後発の言語にも影響を及ぼしている。
int
のサポートは任意であり、プロファイルによってはfloat
として扱うこともある。unsigned
を付けることで符号無し整数型とすることができる。
char
、short
、long
sizeof(char) < sizeof(short) < sizeof(int) <= sizeof(long)
Cgは配列(固定長配列)や構造体もサポートする。ポインタをサポートしない代わりに、配列は第一級オブジェクトである[2]。また、配列にpacked
型修飾子を指定することで、packed array型[2]を定義することができる。基本数値型に関して、例えばfloat4
やfloat4x4
のように、4次元までのベクトル型と4×4次元までの行列型のエイリアスがあらかじめ定義されている。これらはベクトルや行列そのものを扱う型として、3次元のコンピュータグラフィックス計算において多用される型である。
CgはC言語で用いられる算術演算子や論理演算子をサポートしている。算術演算子はベクトル型や行列型にも適用できるものがあり、(C++言語の演算子オーバーロードのように)プログラムの可読性を高め、直感的に理解しやすいグラフィックスプログラムを書くことができるようになっている。
CgはC言語と同様の制御構造を記述するための構文を持つ。関数を定義することもできる。パラメータは既定で値渡しであり、in
/out
/inout
/uniform
の修飾子を指定することもできる。
C言語と同様に、CgにはGPUプログラミングのための標準ライブラリがある。abs()
やsin()
など、C言語の標準ライブラリと共通の数学関数がある一方で、テクスチャマッピングのためのtex1D()
やtex2D()
など、GPUプログラミングに特化した関数も用意されている[3]。
Cgによるプログラムは基本的に頂点やピクセルのシェーディングを行うためのものであり、そのほかのレンダリングプロセスや入出力を扱うためのC/C++ホストプログラムを必要とする。CgはOpenGLやDirectXのAPI基盤上で動作させることができるが、Cgシェーダープログラムを各APIと連携・バインドさせるためのライブラリがNVIDIAから提供されている。
Cgで使用可能なシェーダープログラムのプロファイル、すなわちOpenGLやDirectXにおけるシェーダーモデルのバージョンは、2012年2月リリースのCg Toolkit 3.1時点では、リファレンスマニュアルによると下記のようになっている。
なお、OpenGLはバージョン4.3で、DirectXはバージョン11でCompute Shaderを導入しているが、結局Cgは最終バージョンである3.1時点でそれらに対応しなかった。
Cg言語は複数のシェーダープログラムを組み合わせた一連の処理パイプライン(Pass)およびそれらの入出力をまとめてひとつの「Technique」として管理することのできるEffectフレームワーク「CgFX」も同時に備えている。これはDirect3D 9やDirect3D 11の拡張ライブラリ(D3DX9、D3DX11)およびDirect3D 10のコアライブラリでサポートされているEffectフレームワークとよく似ており、個別にパイプラインステージごとのシェーダープログラムおよびその入出力を管理するよりもずっとシェーダープログラムのパイプラインを構築しやすくなる。 Effectには複数のTechniqueを含むことができ、Techniqueには複数のPassを含むことができる。
// input vertex
struct VertIn {
float4 pos : POSITION;
float4 color : COLOR0;
};
// output vertex
struct VertOut {
float4 pos : POSITION;
float4 color : COLOR0;
};
// vertex shader main entry
VertOut main(VertIn input, uniform float4x4 modelViewProj) {
VertOut output;
output.pos = mul(modelViewProj, input.pos); // calculate output coords
output.color = input.color; // copy input color to output
output.color.z = 1.0f; // blue component of color = 1.0f
return output;
}
Cgを使ったシェーダーオーサリングツールとして、FX Composerと呼ばれるソフトウェアがNVIDIAによって開発・提供されていたが、DirectX 10に対応するv2.5を最後に開発が終了している[4]。
Cgは2012年4月リリースのバージョン3.1.0013を最後に更新がなされておらず、開発が終了している。 なお開発者へのCgランタイム自体の提供自体は継続されるものの、将来の新しいハードウェア機能をサポートしないため、新規開発での採用は推奨されていない[5]。 後継のクロスプラットフォームなシェーダーエフェクトフレームワークとして、NVIDIAによってnvFXが開発されている [6][7]。 nvFXはHLSLやGLSLをバックエンドとするが、OpenGL ESもサポートし、モバイルなどの組み込み機器もターゲットとなる。