Japanese memo of "Ambient Obscurance Baking on the GPU"
概要
- Destiny での AO ( Ambient Obscurance : 距離減衰を考慮した AO ) の話.
- 論文へのリンク
- 下は AO の結果の図.
距離減衰する AO, カーネルサイズは 2m・300m の 2 種類.
- AO(p) = (1 / PI) ∫ rho( d(p, ω) ) cos θ dθ
- p は位置座標, d(p,ω) は ω方向の最近傍のブロッカーまでの距離, θはωと法線間の角度.
- rho(x) = 1 - exp(a * x)
- a = log(0.5 / d), d はメートル.
- カーネルサイズ(レイを飛ばす範囲)は 2m と 300 m の 2 種類で計算.
(A) 建物と地形 : 頂点 AO
- Least Squares Vertex Baking[Kavan 2011] を利用.
- ポリゴンの面単位で, 最大のサンプル数を制限している.
- サンプルから飛ばしたレイの 25% が裏ポリゴンにヒットしている場合, そのサンプルは捨てる.
- 木や低木による遮蔽は半透明扱いで AO を計算.
(B) 装飾用のオブジェクト : 頂点 AO (ローカル AO)とグローバル AO の組み合わせ
- 下のような装飾用のオブジェクトはインスタンス化している.
- 大きいオブジェクト : 木, プレイエリア外でインスタンス化したオブジェクト
- 小さいオブジェクト : 茂み, 低木
- インスタンスごとに別々の頂点 AO データを持つとデータサイズが大きくなってしまう.
- そこで, インスタンス化するようなオブジェクトの AO はローカル AO (オブジェクトごと)とグローバル AO(オブジェクトのインスタンスごと)の組み合わせを使う.
- ローカル AO
- そのオブジェクト自身による頂点 AO.
- グローバル AO
- 下図の左側で木はグローバル AO のみの結果. 中央は グローバル AO + ローカル AO. 右側は参照用の正しい AO の値.
- 木の AO の計算の工夫
- 木の法線がいまいちだったり, 複雑にポリゴンが交差してたり, ビルボードを使っているので計算用に飛ばしたレイが裏ポリゴンに当たる問題がある.
- 従って, ツール側では以下のように, AO のボリュームテクスチャを作る.
- まずは 木を 2 階層の疎なボリュームテクスチャで表現する.
- 各ボクセルで 2 種類の AO (カーネルサイズが2m・300mの場合)を計算して, その結果をそれぞれ 4 つの float で表現した SH(0,1次) として保持する.
- AO の結果を必要な場合は, AO のボリュームテクスチャの結果をトライリニア補間して利用する. ( この AO のボリュームテクスチャはランタイムでは使用しない )
- ランタイムでの頂点 AO の利用
- 2m の AO を 3%, 300 m の AO を 97% としてブレンドして, 頂点 AO として保存する.
- それは頂点シェーダで参照して, G-Buffer に 5 bit のデータとして書き込む. ディザリングも利用する.
(C) 動的なオブジェクト向けの AO : AABB を小さく分割して AO の情報書き込んでおく
- ゲームで使っている可視性のシステム
- AABB とそれらの接続性を表現しているグラフで, 粗く可視性を判定できる.
- ランタイムのレンダリング時のカリング用などに使う. Umbra を利用.
- 上の可視性のシステムで使っているデータに, 動的なオブジェクト用の AO の情報を書き込んでおく.
- さらに, AABB 同士の接続性を考慮して, AO が急に変化しないように正規化しておく.