SMAAの組み込み

SMAA

スクリーンスペースのアンチエイリアスとして,FXAAを組み込みました。 今回は,もう少し綺麗になるらしい,スクリーンスペースのアンチエイリアスであるSMAAを組み込んでみます。

http://www.iryoku.com/smaa/
https://github.com/iryoku/smaa

UnityのPostProcessingStack v2にも組み込まれているようです。

SMAAの組み込み

f:id:hikita12312:20180324122235p:plain:w600

SMAAは3つのパス(エッジ検出パス,ブレンド重み決定パス,ブレンドパス)と,テーブルとして利用されるテクスチャ2つ(AreaTexture,SerchTexture)が必要となります。 上記githubから,次のファイルを持ってきます。

  • smaa/SMAA.hlsl
  • smaa/Textures/SearchTex.h
  • smaa/Textures/AreaTex.h

SMAA.hlslはシェーダー本体で,SearchTex.h,AreaTex.hはテーブルとして利用されるテクスチャのバイナリ定義です。 SearchTextureはRG8フォーマット,AreaTextureはR8フォーマットとして,先に読み込んでおきます。

SMAA.hlslをインクルードして,3つのパスを定義しますが,この時,次のマクロを定義します。

  • SMAA_RT_METRICS :
    zwにスクリーンサイズ,xyにスクリーンサイズの逆数の入ったfloat4
  • SMAA_THRESHOLD :
    エッジ検出の閾値
  • SMAA_MAX_SEARCH_STEPS :
    ブレンド重み計算時のstep数
  • SMAA_MAX_SEARCH_STEPS_DIAG :
    ブレンド重み計算時のstep数。SMAA_DISABLE_DIAG_DETECTION定義で無効
  • SMAA_CORNER_ROUNDING :
    ブレンド重み計算時の角の丸め率? SMAA_DISABLE_CORNER_DETECTION定義で無効

実際の組み込み例は次のような感じです。

エッジ検出パスでは,輝度ベースでエッジ検出を行うSMAALumaEdgeDetectionPSパスか,Color値のそれぞれの要素の差分から検出を行うSMAAColorEdgeDetectionPSパスを選択できます。 また,Depthテクスチャを渡してエッジの誤検出を防ぐような仕組みもあるようです。 今回は利用していませんが,TAA的に履歴バッファを利用してさらにサンプル数を稼ぐようなパスも用意されています。

結果

SMAA.hlslのクォリティ定義SMAA_PRESET_HIGHにあたる設定で適用してみました。

f:id:hikita12312:20180324122424p:plain:w600
f:id:hikita12312:20180324122508p:plain:w300
SMAA OFF
f:id:hikita12312:20180324122526p:plain:w300
SMAA ON
f:id:hikita12312:20180324122633p:plain:w600

以前実装したFXAAは,エッジ部分がボケた形になってしあう弱点があるのですが, SMAAだとそのような事はおきず,綺麗にエッジのギザギザが無くなっています。 FXAAと比べてもかなり高品質な印象です。

ただし,FXAAだと0.14ms程度掛かっていた処理が,SMAAだと0.442ms程度まで増加しています。 やはり処理が複雑であることと,3つのパスを利用していることが効いているのでしょうか。