ITmedia NEWS >

DirectX9リアル対応3Dゲームが出てこない理由(その2)(2/3 ページ)

» 2004年02月13日 16時54分 公開
[トライゼット西川善司,ITmedia]

 「遅くなる」原因は明らかだ。一つは、現行のDirect X 9世代GPUでは、浮動小数点実数演算のスループットがそれほど優秀ではないため。もう一つは、1ピクセルあたりのデータ量が多くなるため、描画時のメモリ帯域の消費が激しく、GPUとしてのトータルパフォーマンスが出にくくなるためだ。

 例えば、αRGBがそれぞれFP32で表現される「D3DFMT_A32B32G32R32F」では1ピクセルあたり128ビット、すなわち16バイトも必要になる。この場合、1024×768ドットの解像度で1バッファあたり12MBにもなる。

 以上の事情から、整数レンダーターゲットでありながら、ちゃんとHDRレンダリングができて、さらに3Dゲームでも利用できそうなバッファとしては「D3DFMT_A2R10G10B10」「D3DFMT_A16B16G16R16」が有望なのだが、これらもGeForce FXでサポートされていないのだ。ちなみにDeltaChromeは「D3DFMT_A2R10G10B10」だけサポートしているあたりが興味深い。

 さて、前段で紹介したDirect X 9 SDKに含まれるHDRレンダリングデモのすべてが、GeForce FX系、DeltaChrome、Volariでは動作しない。正確に言うと、実際には動作するが、リファレンスラスタライザが採択されて、ほとんどハングアップ状態に陥ってしまう。これはRADEON9500以上以外では、レンダーターゲットとして浮動小数点実数バッファが使えないためだ。

 マイクロソフトが用意したDirect X 9のサンプルプログラムが動作するDirect X 9世代GPUは、ATIのRADEON系のみという現状。このような状態では、3Dゲーム開発者はDirect X 9で提供された新技術に手を出せるはずがない。

 Direct X 8.1時代、プログラマブルピクセルシェーダ1.4は事実上、ATI RADEON8500の限定仕様であった。そういう意味では、Direct X 8.1で起こった異常事態が、Direct X 9時代にも持ち越されてしまっている、といってもいい。

RADEON9700用のHDRレンダリングデモとして発表された「Rendering with Natural Light」(http://www.ati.com/developer/demos/r9700.html)では、HDRシーン生成に多ビット整数レンダーターゲット「D3DFMT_A16B16G16R16」を活用している。

HDRレンダリング的表現はDirect X 8世代のテクニックでも実現は可能だが

 結果論から言えば、ユーザー数が多く影響力の強いGeForce FXのために、3DゲームにおけるHDRレンダリングテクニックは、Direct X 8世代のプログラマブルシェーダ1.Xのレベルにとどまることになった。

 これはαチャネルに強輝度情報を格納する形でシーンをレンダリングする手法。最近の3Dゲームでは頻繁に活用されており目にする機会も増えている。具体的にはRGBの各色を正規化(のような感じで圧縮)し、αチャネルを浮動小数点でいうところの指数部のような感じで利用してレンダリングする。この手法はαRGB各8ビットといった従来の32ビットカラーのレンダーターゲットでもHDRレンダリングが行えるので互換性が高い方法だ。

 しかし、大きな弱点もある。

 この手法では、レンダリングのときに、いわば数値表現のエンコードとデコードを行わなければならない。このエンコードとデコードの処理系にはプログラマブルピクセルシェーダを使うことになり、これが非常に重い処理系となる。このため、フレームレートは上がらない。ダイレクトにHDR値が書き込める浮動小数点実数バッファや多ビット整数バッファならば、エンコードデコードは不要になるのだ。

 また、レンダリング先のバッファ自体がαRGB各8ビットのままである。ここに無理矢理、指数表現を導入してダイナミックレンジを強引に広げている弊害で、数値そのものの精度はその分低下してしまう。例えるならば、このような処理系では、0から100の数値表現において、扱える値が1から100の100段階でなく、「10」「20」「30」「40」「50」……「100」の10段階になってしまうイメージだ。ここでは、「14」は「10」として表現されてしまい「15」は「20」と表現されてしまう。

 このように数値の精度が低くなると、グラデーション表現などではマッハバンド(二次輪郭)が思いっきり出ることになる。

 この弱点が体感出来るサンプルを紹介しよう。

 

 下の2枚の画面は、Masaki Kawase氏によるHDRレンダリングデモ(http://www.daionet.gr.jp/~masa/)をRADEON9500以上とGeForce FX系で動作させた結果だ。なお、DeltaChromeやVolariの結果も実質的にはGeForce FX系の結果と同じになる。このデモは非常によくできていて、動作させたハードウェアに適したHDRレンダリングモードを選択する設計になっている。RADEON9500以上では「D3DFMT_A16B16G16R16」が使えるので、これを使って正しいHDRレンダリングを行う。一方、GeForce FX系ではDirect X 9で新設されたバッファが使えないために、上記で説明したようなDirect X 8世代の「D3DFMT_A8R8G8B8」を使ったHDRレンダリングを行う。

 実際に実行してみると分かるが、GeForce FX系ではHDR値のエンコード/デコード処理が重いためにフレームレートはRADEON9500以上と比べて異常に落ち込む。しかも、GeForce FX系では上で説明したようなHDR値精度の問題で、微妙なグラデーション表現でマッハバンドが発生してしまうのだ。

RADEON9500以上では「D3DFMT_A16B16G16R16」を利用したDirect X 9的HDRレンダリングが行われる
GeForce FX系ではDirect X 9レンダーターゲットが使えないので「D3DFMT_A8R8G8B8」を使ったDirect X 8的HDRレンダリングしか行えない
RADEON系のHDRレンダリングで□を4倍に拡大。滑らかなグラデーション表現になっている
同様にGeForce FX系HDRレンダリングで□内を4倍に拡大。ダイナミックレンジだけを広げた弊害で値の精度が失われてしまい、このようにグラデーション部でマッハバンドが出てしまう

 現行の3Dゲームでは、低解像度レンダーターゲットにHDRレンダリングを行い、この強光度部分にプログラマブルピクセルシェーダを活用してブルーム効果(強い光が溢れて見えるような効果。グレア効果ともいう)を付加してから通常レンダリング映像に重ね併せて表示する、というような処理系を採用している。

Copyright © ITmedia, Inc. All Rights Reserved.