Post processing

Screen-Space Reflections / SSR

画面空間反射

画面に見えている情報で反射を近似する。

9 / 10

Interactive demo

Preparing the demo…

Screen-Space Reflections / SSR

Drag to orbit, Ctrl/⌘ + scroll to zoom. Use two fingers on touch screens.

This explanation is currently available in Japanese.

ひとことで

濡れた路面、磨かれた床、水たまりへの映り込みを、描き終えた画面の色と深度だけを使って近似する手法です。反射する面の各画素から反射方向へ光線を少しずつ進め、深度バッファと比べて「画面上のどの物に当たるか」を探し、その画素の色を映します。すでに描いた画面を再利用するので、シーン全体をもう一度描く(鏡のためにカメラを反転して描き直す)よりずっと安く済みます。

ゲームでの使いどころ

  • 濡れた路面・雨の夜の街:ネオンや街灯が地面に映り込む、サイバーパンクな街並み。
  • 磨かれた床:大理石の床、体育館、ショールーム。
  • 水たまり・水面:近くの物の映り込み。
  • 金属やガラスの近景の映り込み:環境マップでは表せない、近くの物の正確な映り込み。

しくみ

  1. 反射させる画素の 3D 位置 p\mathbf{p} と法線 n\mathbf{n} を、深度と法線のバッファから求める。
  2. 視線を法線で反射した方向 r\mathbf{r} へ、光線を一定の歩幅で進める。
  3. 各地点を画面に投影し、その位置の深度と比べる。光線が画面上の物の奥に入ったら、そこで当たったとみなす。二分探索で当たりの位置を細かく詰める。
  4. 当たった位置の画素の色を、反射として加える。

これは画面上で行うスフィアトレーシングのようなもので、距離場の代わりに深度バッファを使っています。

画面空間の限界:画面に描かれていない物は映せません。

  • 画面の外にある物(カメラの後ろ、画面の端の外)
  • 手前の物に隠れた物の裏側
  • 画面に映っている物の見えていない面

光線が画面外に出たり、当たる物がなかったりした場合は、反射をなめらかに消して、環境マップの反射で補うのが一般的です。

実装のポイント

  • 画面の端でなめらかに消す:当たった位置が画面の端に近いほど反射を弱めると、画面外で反射がぷっつり切れるのが目立たなくなります。
  • 粗さへの対応:粗い面では反射をぼかす必要があります。粗さに応じて光線の方向をばらつかせ、時間方向に平均するのが現代的な方法です。
  • 厚みの仮定:深度バッファには表面しかないので、物の奥行き(厚み)を仮定して、当たりかどうかを判定します。
  • [フレネル](/keywords/graphics/lighting/fresnel/):浅い角度ほど反射を強くすると、濡れた路面らしくなります。

つまずきやすい点

  • 反射の消失:カメラを下に向けると、映るべき物が画面外に出て反射が消えます。これが SSR の最大の弱点で、プレイヤーにも気づかれやすい問題です。
  • ちらつき:歩数が少ないと、細い物を飛び越えて反射が途切れたり、ちらついたりします。
  • 負荷:画素ごとに数十回の深度の読み込みが必要です。低解像度で計算することが多いです。

デモで試すこと

  1. 濡れた床に、ネオン、柱、像、球が映り込んでいます。「SSR なし」と比べると、空間の雰囲気が大きく違います。
  2. 「反射だけ」で、床のどこに何が映っているかを確認してください。
  3. 視点を下に向けたり回したりすると、画面外に出た物は映らなくなり、反射が途切れます。「画面の端でなめらかに消す」をオフにすると、途切れ方がはっきり分かります。
  4. 「光線の歩数」を減らすと、遠くの物が映らなくなったり、映り込みがちらついたりします。

References

Unreal Engine Post Process Effects ↗

A general reference for this subcategory.