This explanation is currently available in Japanese.
ひとことで
煙や霧の板が床や壁と交わる部分を、奥にある物体との深度差に応じて薄くすることで、板が刺さった硬い直線を消す手法です。Depth Fade とも呼ばれます。深度バッファを 1 回参照するだけの安価な処理で、地面を這う霧、足元の砂煙、水面の湯気などが一気に自然になります。
ゲームでの使いどころ
- 地面の霧・砂煙・土煙:着地や爆発で舞い上がる煙が地面に刺さって見えるのを防ぐ。
- 水面や溶岩の湯気:水面と交わる境界を柔らかくする。
- 光の筋・グロー:壁の手前に置いた光の板が壁に切り取られるのを防ぐ。
- 水しぶき・泡:水面付近のパーティクル。
しくみ
通常の不透明物体を描いたあとの深度バッファには、各画素に写っている一番手前の不透明物体までの深さが入っています。粒子の画素を描くとき、
- :その画素に描かれている物体の深度(深度テクスチャから読む)
- :いま描こうとしている粒子の画素の深度
を比べ、差が小さいほど透明にします。
は「どのくらいの距離でフェードさせるか」です。深度バッファの値は非線形(透視投影)なので、比較する前にビュー空間の距離(線形深度)に変換する必要があります。three.js なら perspectiveDepthToViewZ が使えます。
実装のポイント
- 深度テクスチャの準備:粒子を描く前に、不透明物体を深度テクスチャ付きのレンダーターゲットに描いておきます。多くのエンジンではこの深度が標準で使えるので、マテリアルの設定だけで済みます(Unity の Soft Particles、Unreal の DepthFade ノード)。
- フェード距離は粒子の大きさに合わせる:大きな霧の板なら 0.5〜1m、小さな火花なら数 cm。粒子ごとに変えることもあります。
- カメラへの近さでもフェード:カメラが煙の板の中に入ると板が画面いっぱいに映って不自然です。カメラとの距離でもフェードさせるのが定番です(Near Fade)。
つまずきやすい点
- 深度を書かない物体:半透明の水面など深度バッファに書かれない物体とは比較できません。
- MSAA と深度の解像度:アンチエイリアス付きの描画では、深度テクスチャの解決方法によって縁に線が残ることがあります。
- 板全体が薄くなる:フェード距離を大きくしすぎると、地面から離れた部分まで透明になり、霧自体が見えなくなります。
デモで試すこと
- 「ソフトパーティクル」をオフにすると、霧の板が床や柱と交わる部分に、くっきりとした直線が現れます。オンに戻すと境界が溶け込みます。
- 「薄めている量を色で表示」をオンにすると、深度差が小さいために薄めている部分が赤く表示されます。床や柱の近くが赤いことを確認してください。
- 「フェードする深度差」を大きくすると境界がよりなだらかに、小さくすると硬い線に近づきます。