拙訳
以前のデカール・レンダリング
- デカールごとに、カリングして、カメラ範囲内にあれば、ボックスをレンダリングして、Gバッファにブレンドする
- 実装が簡単だったり、カリングが高精度だったり、などの利点があった
- ドローコールがデカールごとに必要だったり、Gバッファにブレンドする必要があったり、などの欠点があった
バインドレス・テクスチャリング
- すべてのテクスチャをまとめたデスクリプタ列を作る
- バッファから読み出した値を配列のインデックスにするときには
NonUniformResourceIndex()を使うことに注意- または、wave命令のballotでもできる
Clustered Deferred Decals
- Clustered deferred rendererにデカール描画を追加した
- デカールのブレンドはGバッファに書き戻さずにレジスタ内で行う
- register pressureに注意して、CU使用率が低下しないようにすること
- 高レベルの最適化
- softなフェードアウトによって、距離でカリングする
- 距離に応じて簡易なものに切り替える
- 低レベルの最適化
- VGPR使用率が最大のボトルネックなので、スカラ化がうまく機能する
- クラスタのインデックスをスカラにすると、関連データもまとめてスカラになる
- デカールとマテリアルの機能を別個のブロックに分ける
- 機能をまとめ直すことで、レジスタを空ける
- VGPR使用率が最大のボトルネックなので、スカラ化がうまく機能する
バインドレス・デカールの制限事項
- デカールが他のパスから可視でなくなる
- SSAOやSSRなどでは、アルベドやノーマルがデカールによって修正されたか分からない
- マテリアルIDが更新されないので、TAAでゴーストになったりする
一般的なデカールの問題#1:法線ブレンディング
- 線形ブレンド
- 雪や砂の層のような厚みを重ねる場合には最適
- 法線が打ち消し合って、平坦化してしまいがち
- Re-orientated normal mapping [Barré-Brisebois and Hill 2012Barré-Brisebois, C. and Hill, S. 2012. Blending in Detail. Self Shadow. https://blog.selfshadow.com/publications/blending-in-detail/.]
- 大抵のデカールでうまく機能する
- デカールの法線が表面の法線に常に沿う
一般的なデカールの問題#2:スクリーン空間のUV勾配
- UVやZの勾配はスクリーン空間では正確に導出できない
- ddx/ddyが使えない
- ミップマッピングがなく、境界付近でのUV勾配がうまくいかない
- 解決策
- 固定のミップレベルでサンプリングする
- シェーダで勾配を計算する
- boundsの勾配を使って近傍の位置を計算して、そこからデカールの勾配を求める
- デカールとマテリアルのスケールを適用する
一般的なデカールの問題#3:スクリーン空間のZ勾配
- 深度が不連続な箇所では勾配が大きくなる
- 勾配が大きいと低ミップが選択されるので、色が繋がって見えなくなる
- 取り得る方法:
- Z勾配をGバッファに格納する
- または、深度不連続性をチェックして修正する
- 検出したエッジ部分でLOD0をサンプルする
- 深度バッファからGatherRedでquadを2つサンプルして、十字の近傍との距離を比較する
- 今度は、ミップのチラツキが発生するが、気づきにくいし、TAAなどで緩和されるので問題ない
一般的なデカールの問題#4:リークとオブジェクト分別
- デカールは含めたくない場所に漏れ出すおそれがある
- デカールとマテリアルの両方に“DecalGroup”ビットマスクを用意して重なるかチェックする
Dirty decal tricks #1
- コーナーやエッジをなめらかになるようにデカールの法線を調整する
- デカールの方向に向かって表面の法線を補完する
- 泥などの、平坦でないジオメトリに覆われている場合に有効
- 一方で、ジオメトリの法線を上書きするのは難しい
Dirty decal tricks #2
- 浅い水たまり
- 黒のデカールアルベドをブレンディングすることによって表面のporosityを真似る
Dirty decal tricks #3
- triplanar mappingでUVフリーなテクスチャリング
- triplanarのコントラストは法線によってブレンディングの”steepness”を定義する
- triplanar + 傾斜依存のブレンディング
- デカールの方向と下地の表面との傾斜に応じてブレンドマスクを生成する