バイラテラル・アップサンプリング(Bilateral Upsampling)のメモ

概要

参考文献

特徴

  • まず,「オフスクリーンパーティクル」とはパーティクルだけ低解像度のカラーバッファに対してダウンサンプリングしたデプスバッファを使ったレンダリングをして, 後でフル解像度のバッファと合成する手法です.

  • これによって フィルが少なくなって GPU 処理が軽くなるメリットがありますが, 一方で低解像度に対してレンダリングするため情報が欠落してアーティファクトが発生するというデメリットも起きます.

  • 下図の左はフル解像度でパーティクルのデプステストを行った場合です. 一方で下図の右のオフスクリーンパーティクルではダウンサンプリングしたデプスバッファを使ったデプステストを行っているため, 結果をそのままアップサンプリングするとギザギザのアーティファクトが発生しています.

  • 上では「オフスクリーンパーティクル」というようにパーティクルの話でしたが, スクリーンエフェクトについても低解像度のバッファに対して処理してアップサンプリングする方法が同様に使えます.
  • 下図は 球にする AO の処理(Sphere AO)を適用していない状態です. ( "Sphere AO" について)

  • これに対して Sphere AO をフル解像度(1280x960ピクセル)で行った場合, 62 FPS でした.

  • 一方で, Sphere AO を 1/2 * 1/2 解像度 ( 640x480ピクセル)で処理してから, 後述するバイラテラル・アップサンプリングで参照した場合, 絵のクオリティがそんなに変わらないにも関わらず, FPS が 62 -> 135 と 2 倍近く速くなっています.


  • 低解像度でレンダリングした結果をそのままバイリニアフィルタでアップサンプリングすることもできます.

  • バイラテラル・アップサンプリングを使うと, 法線やデプスが不連続なところについては重みを弱くすることでギザギザのアーティファクトを和らげます.

  • バイラテラル・アップサンプリングでのフィルタ処理によって一定コストでアーティファクトを和らげることができますが, 細かい特徴のアンダーサンプリングや低解像度のバッファのオーバーサンプリングが起きます.


図による説明

  • 下図の左がバイリニアフィルタによる重み, 下図の真ん中はデプス差分による重み, 下図の右側は法線の違いによる重みです.


  • 実際に下図のようなデプスの差分や法線の向きによる違いがある場合についてです. 下図の右側の上からバイリニアフィルタによる重み, デプスの違いによる重み, 法線の違いによる重みです. 実際に低解像度のバッファを参照するときにはこの 3 つの重みを乗算して利用します.


  • 下図の左側の列はバイラテラル・アップサンプリングをした場合で特に問題ないのですが, 下図の右側の列はバイリニアフィルタのみでアップサンプリングした場合でシルエットに白い線が出てしまっています.


  • 更に拡大したのが下図です. 下図の右側の列はバイリニアフィルタのみでアップサンプリングした場合でシルエットに白い線が出てしまっています.


実装

  • まず, 低解像度バッファの 4 テクセル分のバイリニアフィルタ相当の重み(vBilinearWeights)を用意しておきます.

  • 下のコードではフル解像度バッファの法線(vNormalHiRes)と 低解像度バッファの 4 テクセル分の法線(vNormalCoarse[0][1][2][3])との比較をして, 重み(vNormalWeights[0][1][2][3])を求めています.
  • この時点で, フル解像度バッファの法線バッファへのテクスチャフェッチ1 回と, 低解像度バッファの法線バッファへのテクスチャフェッチが 4 回発生します.

  • 下のコードではフル解像度バッファのデプス(fDepthHiRes)と, 低解像度バッファの 4 テクセル分のデプス(fDepthsCoarse[0][1][2][3])を比較して, 重み(vDepthWeights[0][1][2][3])を求めています.
  • さらに, フル解像度バッファのデプスバッファへのテクスチャフェッチ1 回と, 低解像度バッファのデプスバッファへのテクスチャフェッチが 4 回発生します.

  • 最後に低解像度のバッファの結果の 4 テクセルをサンプリングし, それに対して求めた重みを乗算した結果を加算することで, アップサンプリングを行います.
  • あと, 係数を正規化する処理も入っています.
  • ここで, 低解像度バッファの結果へのテクスチャフェッチが 4 回発生します.


まとめ

  • そのまま実装するとテクスチャフェッチ数が多くなるので, コストに見合った場合に使った方が良さそうです.
  • あるいはテクスチャの RGBA にパックしてフェッチ数を減らしたり, 使うシーンであまり効果のない判定処理は飛ばしてしまう方法もあると思います.