UnityやPost Processingで実装されているアンチエイリアシングとそれに関連する技術について調べたのでまとめます。
Unity2017.4.1
アンチエイリアシング?
例えばキューブをレンダリングするとき、エッジがスクリーンに対して斜めに描画されるとジャギーが生じます。
これはピクセル密度が低い環境ほど顕著です。
このようなジャギーを除去するための技術をアンチエイリアシングといいます。
SSAA
まず、シンプルな考え方で実装されるSSAAを紹介します。
SSAAはまず1ピクセル内に4つのサンプリングポイントを作ります。
そしてすべてのサンプリングポイントにおける色をそれぞれ計算して、計算結果を平均化したものをピクセルの色とします。
1ピクセルにつき4回計算が走ることになるので処理負荷が大きいです。
MSAA
SSAAの処理負荷が大きい問題を緩和したものがMSAAです。
MSAAでは1つのピクセルを描画する際に、ピクセルの色の計算のほかに4つのサンプリングポイントの深度を求めます。
そして深度が大きいポイントの数が多いほど、描画前の色をブレンドする率を高くします。
深度が大きいポイントが多いということは描画対象オブジェクトのエッジであると判断できるので、
描画対象の色を薄めることでジャギーが軽減された色を持つピクセル色を得られます。
色の計算は1ピクセルにつき1回なのでSSAAより高速です。
欠点として、テクスチャ自体にジャギーがある場合など、
深度により判別がつかないケースではアンチエイリアシングが効きません。
UnityとMSAA
MSAAはGPUでサポートされている機能です。
そのため、Unityでは下記の通り設定するだけで簡単に適用することができます。
- Edit > Project Settings > Quality > Anti Aliasing でサンプリングポイントの数を選ぶ
- Camera > Allow MSAA をチェック
ただしMSAAはDeferredレンダリングとの相性は悪いという特徴を持っています。
そのため、UnityでもDeferredレンダリングではMSAAを使うことができません。
FXAA
FXAAはSSAAやMXAAと違い、ポストエフェクトとして処理するアンチエイリアスです。
上記の記事によると、FXAAは次のような考え方で実装されます。
- 各ピクセルとその周辺ピクセルとの輝度の差を求める
- 輝度の差の情報からオブジェクトのエッジを推定する
- エッジにあるピクセルにどれだけオブジェクトが被っているかを推定する
- ピクセルにオブジェクトが被っている比率に応じて周囲の色とブレンドする
この手法は処理負荷が比較的小さいようです。
TemporalAAの説明
TemporalAAもFXAAと同じくポストエフェクトによるアンチエイリアスです。
TemporalAAは次のような考え方により実装されます。
この手順により、エッジにあるピクセルのみ色がブレンドされるためアンチエイリアスが掛かります。
また上記の手順では簡略化してしまいましたが、必ずしも前フレームのみとの合成ではなく、
直前の数フレーム分を合成してレンダリング結果とする実装もあります。
ただ直前数フレームを合成するということは、カメラが激しく動いているとブレた結果となってしまいます。
これはモーションベクトルを使うことで防げるようです。
もんしょの巣穴blog [UE4] ResponsiveAAの挙動
t-pot『DirectX 11: Temporal Anti-Aliasing』
TemporalAAは品質は高いものの、処理負荷も大きそうです。
AAにこだわりが強い、かつ他のポストエフェクトでもモーションベクトルを使う環境であるならアリなのかもしれません。
参考
もんしょの巣穴blog [UE4] ResponsiveAAの挙動