2012年07月05日一覧

NVIDIAのシェーダー言語とか その2

前回の続きです。

結局、NVIDIAの配布するライブラリ(Cg Toolkit)に依存してしまうけど、DirectX/OpenGLで共通のシェーダーソースコードを使用することが可能になります。Cg言語は HLSL と大分似ているのでコードは書きやすいと思われます。 OpenGLに純粋に従うのであれば、 GLSL にてシェーダーを記述することになりますが、DirectX版も用意しなければいけない環境だと HLSL & GLSL の2種類を書かなくてはいけなくなり、ちょっと手間です。

(HLSL2GLSLや HLSL2GLSLfolk といったトランスレータを用意して何とかのりきる手もあるにはあると思いますが)

そこで NVIDIAが用意している強力なOpenGL拡張があります。
GL_EXT_Cg_shader というものです。とても奇妙な、でも強力な拡張機能です。
現時点ではほとんど情報が出てこないので、このブログでちょっと取り上げてみようと思った次第です。

この機能で何ができるかを列挙します。

  • GLSLにはないが、Cg言語で備えている組み込み関数が GLSLで使用できる。litとかlerpとか。
  • #include ディレクティブが使える
  • vec2,vec3といったGLSLの型の代わりに、HLSL(Cg)の float2, float3 といった馴染みの型が使用できる
  • GLSLシェーダーソースコードの代わりに、Cgシェーダーソースコードを渡してOpenGLのシェーダーを生成できる

一番最後の項目が、とっても奇妙で、すごすぎる機能です。
NVIDIA限定とはいえ、CgランタイムなしでCgコードをコンパイルできるわけですから。
これを前提とすれば、ほぼHLSLで書いておけば、OpenGL版に移行するときも楽ちんということです。

あとは、#include でしょうか。 「GLSLには #include がない!」とはよく騒がれたりする人がいるようですし。これが使えるという点は、結構大きなポイントかもしれません。

なお、使い方は簡単で、
glCreateShader 関数の引数に、GL_VERTEX_SHADER / GL_FRAGMENT_SHADER を渡す代わりに、
GL_CG_VERTEX_SHADER, GL_CG_FRAGMENT_SHADER をセットして、Cg言語で記述されたソースコードを与えてあげるだけです。

※ わかりにくいという指摘がありましたので、修正しました。