縮小バッファによる半透明パーティクル描画についてのメモ

縮小バッファに描いたものを合成するというフローについて.

別バッファ半透明描画と直接描画の結果一致の確認

METAL GEAR SOLID 4の記事などで紹介されている方法の確認をあらためて

  1. 半透明用バッファを(0,0,0,1)でクリア
  2. 半透明描画
    • アルファブレンドの場合
      • RGB : Dst*(1-SrcAlpha) + Src*SrcAlpha
      • Alpha: DstAlpha * (1 - SrcAlpha)
    • 加算ブレンドの場合
      • RGB : Dst + Src*SrcAlpha
      • Alpha: DstAlpha
  3. 半透明バッファを最終合成
    • RGB : Dst * SrcAlpha + Src

3回の半透明描画の例で計算確認
c[i]はアルファ乗算済みRGB
a[i]は対応する出力アルファ値{ 半透明アルファ値 : アルファブレンド, 0.0 : 加算合成 }
としてアルファブレンドと加算合成が任意に混在するものとする

// c0に直接3回の合成(c1, c2, c3 の順)
cd=c3+(c2+(c1+c0(1-a1))(1-a2))(1-a3)
ad=(1-a0)(1-a1)(1-a2)(1-a3)


// ---------------------------------------------

// cs_, as_へ3回の半透明を合成してから最後にc0と合成
// 疑似コードの通り初期値として c0=0, a0=1 とすると c1,c2,c3 の合成は
c_temp=c3+(c2+c1(1-a2))(1-a3)
a_temp=(1-a1)(1-a2)(1-a3)

// c_tempをc0へ合成
cd=c0*a_temp+c_temp
=c0(1-a1)(1-a2)(1-a3)+( c3+(c2+c1(1-a2))(1-a3) )
=c3+(c2+(c1+c0(1-a1))(1-a2))(1-a3)

c0直接合成とc_tmpを介した合成で式が一致した
アルファブレンドと加算合成が任意の数と順序で混在していても, 別バッファ半透明の結果は直接描画半透明と一致する(゚∀゚)

(だいぶ前の記事を整理)




Lost Planet

西川善司の3Dゲームファンのための「ロスト プラネット」グラフィックス講座

  1. シーンカラーとシーンデプスの縮小版生成, 縮小解像度のアルファバッファも生成
  2. パーティクル群を縮小バッファへ描画,この時縮小アルファには最終合成時用のマスクを書き込む
  3. 縮小アルファを元にフル解像度シーンカラーへ合成

半透明の奥側は縮小シーンであるため, フル解像度との合成で解像度のズレが見える.
加算合成等の場合は縮小アルファにどのような値を書き込むのかわからない.
縮小アルファへの書き込みさえなんとかなれば加算減算乗算も可能に思える.

METAL GEAR SOLID 4

西川善司の3Dゲームファンのためのゲームグラフィックス講座
アルファブレンドと加算合成の混在でも動作する処理

Tales of ARISE

CEDEC2019: 『Tales of ARISE』におけるレンダリング技術と高速化
UE4改造して複数解像度による多段階の半透明描画をしている

  1. 低解像度で半透明描画 (MGS4と同様で, 縮小シーンではなさそう?)
  2. 低解像度バッファの勾配情報等から低解像度高周波マスク生成
  3. シーンへの低解像度バッファ合成と, フル解像度高周波ステンシルバッファ生成
    • ステンシル出力有効にして高周波マスク値からステンシル値出力している?
  4. ステンシルバッファを利用してフル解像度で部分的に半透明再描画
    • 詳細部分のみパーティクル描画をフル解像度で実行する

低解像度で描画して, 詳細が必要な部分だけステンシルマスク利用のフル解像度描画.
資料の情報からはMGS4ブレンドバッファと同様にシーンの縮小バッファではなくクリアされた縮小バッファに描いている?.
ブレンドバッファ方式の場合は乗算等は不可能そうに思えるがどうか?
earlydepthstencilでピクセル処理を早期棄却しつつ部分的にフル解像度描画できる.
高周波判定する閾値を変化させることで負荷のコントロールができそうな点も面白そう.