今も疑似HDRテクスチャと併用するのが主流
HDRテクスチャも、DirectX 9世代/SM3.0対応以降のGPUであれば、普通に浮動小数点テクスチャを活用すれば問題はない。FP16-64ビットテクスチャであれば、テクスチャフィルタリングもバイリニアから異方性までの全てを適用できる。DirectX 10世代/SM4.0対応GPUでないとFP32-128ビットテクスチャへのフィルタリングは出来ないが、一般的な3DグラフィックスのレンダリングでここまでのHDRテクスチャを必要とする局面は少ないだろう。
しかし、FP16-64ビットテクスチャの汎用性そのものは高いのだが、大きな問題もある。それはビデオメモリの占有量と読みだし時の帯域消費が大きいと言うことだ(レンダーターゲットの時と同じ問題)。
αRGB各8ビットのint8-32ビットの従来のLDRテクスチャであれば、DXTC(DirectX Texture Compression)と呼ばれるテクスチャ圧縮メソッドが利用できる。DXTCで圧縮されたテクスチャは、圧縮された状態のままGPUコアが直接アクセスできるため、活用すればかなり省ビデオメモリに貢献できるのだ。しかし、浮動小数点のHDRテクスチャになると、最新のDirectX 10世代/SM4.0対応GPUであっても、その圧縮メソッドはサポートされていない。
3Dゲームグラフィックスにおいて、全てのテクスチャをHDRテクスチャで賄うには、ビデオメモリ予算、帯域予算があまりにも厳しすぎるため、DirectX 9世代/DirectX 10世代においても、LDRテクスチャを疑似HDRテクスチャ的に活用することが多いようだ。
疑似HDRテクスチャは、フォーマットとしてはLDRテクスチャなので、DXTCを効かせて圧縮することが出来る。
ポイントとなるのは、どうやってLDRテクスチャにHDR情報を格納するかなのだが、これについては様々なテクニックが考案されている。
ここでは「ロストプラネット」(カプコン,2007)で採用された方法を紹介しよう。
この方法で用いるのはα値とRGBの全てが1/4の圧縮されるDXT5モードのDXTCだ。
HDRからLDRへの変換(エンコード)は、まず、{R,G,B,1.0}のうち最大値Mを選択し、その逆数1/Mをαに格納する。続いて{R,G,B}の全てをMで割ったものをRGBに格納する。
元に戻すデコード処理は{R,G,B}={R,G,B}÷αだけで求められる。
これで、分解能は低下してしまうものの、HDRのダイナミックレンジは維持され、それなりにRGBのカラーも保持されるのだ。
HDRテクスチャであっても、高輝度なHDR値のテクセルよりは、RGBが0.0~1.0のLDR値のテクセルの方が多いはずだ。この方法は、その計算アルゴリズムの特性上、その大半を占めるであろうLDR値のテクセルの保持品質が高くなるのが特徴だ。
また、エンコードすれば、HDR値に戻るのでFP16-64ビットのHDRテクスチャとの混用も容易だといえる。さらに、この方法は、高圧縮率なDXT1で圧縮したLDRテクスチャを同一シェーダで取り扱えるというメリットもある。
DXT1はα=0かα=1のどちらかでしか利用できないが、α=1としてLDRテクスチャをDXT1で圧縮しておけば、先ほどのDXT5の疑似HDRテクスチャを{R,G,B}={R,G,B}÷αにてデコード処理したとしても{R,G,B}={R,G,B}÷1であり、つじつまは合う。(続く)
(トライゼット西川善司)