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 -