Alpha to Coverage

長く続いた Direct3D 9.0 の時代、GPUベンダーは 9.0 +α の機能を独自に開発してきました。

それは従来のシェーダでは対処できなかった課題を解決するもので、Direct3D 10 の機能を先取りしているものもあります。

今回取り上げる「Alpha to Coverage」は Direct3D 9.0 で「アルファテストに対するAA(アンチエイリアシング)」を可能にする技術です。

(NVIDIA はこれを "Transparency AA" と呼んでいますが、ここでは両方を含んで Alpha to~ と言うことにします)

後述しますが、Direct3D 10 で、この機能は正式に Direct3D の仕様に採用されました。

Direct3D 9.0 の マルチサンプリングAA(MSAA) はプリミティブの境界にしか適用されないので、

ポリゴン内部に生じた描画されない(=アルファテストで破棄された)ピクセルの境界に対しては効果を発揮しません。

そのため、金網や植物など、アルファテストで切り抜いて描画するものにジャギーが生じるのが悩みのタネでした。

こ の問題に対する従来の解決法は、原始的なスーパーサンプリング(高解像度のレンダーターゲットに描画後、

縮小してフィルタリング)しかありませんでした が、Alpha to Coverage 技術によってアルファテストに対する

マルチサンプリングが可能になり、パフォーマンスを改善できるようになりました。

この機能、GeForce は 7シリーズ以上、Radeon は X1000 以上が対応していますが、両者はそれぞれ異なる実装をしています。

☆ GeForce で Alpha to Coverage を有効にする方法

GPUベンダー独自規格である Alpha to Coverage のための D3DRENDERSTATETYPE は Direct3D 9.0 には存在しないので、

普段使われることのない D3DRS_ADAPTIVETESS_Y をオーバーロードすることになっています。

(ちなみに、本来 D3DRS_ADAPTIVETESS_Y は テセレーション関連のステートですが、GeForce 7 はテセレーションに対応していないので問題ありません)

まず Alpha to Coverage が利用可能かを調べ、SetRenderState で有効にします。

もちろん、アルファテストも有効にしていなければいけません。

こうすることで、アルファテストに対するマルチサンプリング、Alpha to Coverage が適用された描画ができます。

if(pd3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,D3DFMT_X8R8G8B8,0,D3DRTYP_SURFACE,

(D3DFORMAT)MAKEFOURCC('A','T','O','C')) == S_OK)

{

pd3dDevice->SetRenderState(D3DRS_ADAPTIVETESS_Y,(D3DFORMAT)MAKEFOURCC('A','T','O','C'));

}

無効にするときはこうします。

pd3dDevice->SetRenderState(D3DRS_ADAPTIVETESS_Y, D3DFMT_UNKNOWN);

マルチサンプリングによる Alpha to Coverage とは別に、スーパーサンプリングによる Alpha to Coverage もサポートしていますが、品質とパフォーマンスは劣ります。

pd3dDevice->SetRenderState(D3DRS_ADAPTIVETESS_Y,(D3DFORMAT)MAKEFOURCC('S','S','A','A'));

☆Radeon で Alpha to Coverage を有効にする方法

Radeon の場合は D3DRS_POINTSIZE をオーバーロードします。

有効にする。

pd3dDevice->SetRenderState(D3DRS_POINTSIZE,(D3DFORMAT)MAKEFOURCC('A','2','M','1'));

無効にする。

pd3dDevice->SetRenderState(D3DRS_POINTSIZE,(D3DFORMAT)MAKEFOURCC('A','2','M','0'));

Radeon の実装では、この機能が利用可能かをチェックする方法がありませんが、

[AMD09]には "All ATI cards supporting the DirectX9 feature set expose alpha to coverage." と書かれているので、

pd3d->GetAdapterIdentifier で Radeon を識別できたら使用することにしましょう。

Diretct3D 10 では AlphaToCoverageEnable というステートが新しく作られ、どのGPUでもこの機能を利用することができるようになりました。

参考

-

[NV08] GeForce の実装での Alpha to Coverage(ムービー、サンプルデモ、ホワイトペーパー)

http://www.nvidia.co.jp/object/transparency_aa.html

*Radeon の実装での Alpha to Coverage(サンプルデモ、ホワイトペーパー)

http://developer.amd.com/gpu/radeon/pag ... ments.aspx

*Direct3D 10 での Alpha to Coverage(下のほうに解説、サンプルは DirectX SDK内)

http://msdn.microsoft.com/en-us/library ... 85%29.aspx

[AMD09] (PDF)

http://developer.amd.com/gpu_assets/Adv ... 0Cards.pdf

- 2010 Reputeless -