テクスチャとサンプラーステートの関係


テクスチャとひとことで言った場合、この中には2つの要素が含まれていると思います。
1つは、ポリゴン表面に貼りたい画像のデータ。
そしてもう1つは、その画像に適用するフィルタ設定やUV設定といったの各設定情報。このうち後者はテクスチャフィルタやラッピングモード(アドレッシングモード)とも言われるため
テクスチャの情報としてまとめられてしまうことが多いと感じます。
特に昔からのOpenGLではテクスチャオブジェクト内にラップモードとフィルタ設定を行っておき、
テクスチャの使用時にはその設定が有効になるという挙動を示します。

DirectX9においては後者の設定はテクスチャの処理するステージに対して設定するものとなっています。
SetSamplerStateメソッドのヘルプを見てみても、サンプラー番号といわれる部分はサンプラステージインデックスと表記されています。
HLSLシェーダ内にレジスタ指定できますが、そのときの register(s0);という”s”の部分については、おそらくステージの意味合いなのではと思います。

しかし近年、DirectX10(D3D10)以降これらの関係がAPIの上から変わりました。
前述の各設定情報がサンプラーオブジェクトとして分離されました。
ハードウェアの面から考えると、画像が置いてある部分の内容と、そこから読み出すときのフィルタ設定は確かに分離でき
こちらのほうが自然な印象を受けます。
この時代においても、レジスタ指定の部分では従来どおり register(s0); ですが、
このときの”s”の意味合いは、サンプラーの意味を持つ”s”へと変わっていると思います。

また、OpenGLのほうでもテクスチャの設定関連が見直され、
新しいOpenGL*1では、テクスチャとサンプラーとそれぞれ別のオブジェクトとして使うことが可能になってきました。
これらにおいては、glGenSamplers, glBindSamplerといった生成、割り当ての関数が追加されています*2

新しいものだけを見れば、DirectXもOpenGLも同じ流れになっていてすっきりしました。
しかし、気になる点も1点あります。
それはこのサンプラーの設定はサンプラーの番号に対して設定するという方法しかないという点です。
HLSLのエフェクト(.fx)を使う上では、サンプラーステートと参照するテクスチャを結びつけて記述が出来ますが、
それぞれのシェーダーを別々に設定するような機構では、この設定は出来ないようです。
まだ見つけられてないだけかも知れませんが、OpenGL(GLSL)ではそういった機構すらないように思えます。

これらの点から、テクスチャの割り当てとサンプラの割り当ての番号は一致するように実装しておくのがいいのかなと思いました。
テクスチャの割り当ての番号自体は、シェーダーリフレクションを使えば求められます。
DirectX9については、そもそも同一のステージ番号に閉じ込められていますし、
旧OpenGLではテクスチャオブジェクト内にまとまってしまっています。
全てにおいて統一の取れたものにするには、この方法しかないのでは?と考えています。

*1 : OpenGL3.2以降だと思われる

*2 : GL_sampler_objects

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする


コメント

  1. tueda より:

    OpenGLのテクスチャー周りの仕様はサンプラー・オブジェクトが使えるようになって格段にきれいになりましたね。初期設定さえ済ませればglActiveTexture(),glBindTexture(),glBindSampler()の3行ですから。
    いい加減古いOpenGLは捨ててモダンな(3.3以降の)OpenGLに移行してほしいです。