「 2012年07月 」一覧

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言語で記述されたソースコードを与えてあげるだけです。

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


NVIDIAのシェーダー言語とか


NVIDIAはHLSLによく似たCgというシェーダー言語をサポートしている。
Cg Toolkitという名前でランタイムとツールとを用意していて、これを用いればNVIDIAだけに限らず AMD RadeonでもCg言語を用いたシェーダーを使えるようだ。

このCgは非常に検索性が悪い(笑)ので何とかしてほしいところですね。”Cg”って用語がもはや一般的すぎて・・・。

で、NVIDIAのボード環境に限っていえば、HLSL, Cg, GLSL と3種類のシェーダー言語をサポートしていることになります。
DirectX なら HLSL、OpenGLならGLSLといった具合に。Cgはどちらの環境でも使えるようにランタイムがきちんと整備されている。NVIDIA環境ならCgをつかっておけば問題ないという感じ。
そういえば、PS3の環境も Cg を使っているんだっけ。

今回はこの3言語をNVIDIAがサポートしている点でのお話です。
NVIDIAはこの複数の言語をサポートするために、Unified Compiler Architecture (UCA) という構造をとっているようです。これは、どの言語であれ同じコンパイラエンジンを通ることになり、出てくる結果もほぼ同じようなものに仕上がるということだと推測される。Microsoftの VisualBasic.NetやC#らで作った成果物が MSIL として出てくるのと同じなんじゃないかと思う。

このおかげで複数のエンジンを積まず、シンプルさをある程度維持しつつ、複数の言語をサポートできるのだと思う。そもそも GLSLはドライバ内部にシェーダーコンパイラを持つことを要求されているので、そこにCg用が入っていたとしてもなんの問題もなく、むしろ合体させてしまうのは都合がいいことだろう。

個人的には、OpenGLのこの仕組みはあまり好きではないですが。DirectXのように一度、共通のバイナリ化してほしい。シェーダーのソースコードは確かにプラットフォームを越えて持って行きやすいが、中身がそのまま見えてしまうのはうれしいことではなかったりするので。4.1のBinaryShaderの拡張も、ベンダー依存のバイナリが出てくるようなので、この点については望み薄のような気がします。

NVIDIAが3つのシェーダー言語をサポートしているという点と、構造を話したところで、続きはまた次回に。