This explanation is currently available in Japanese.
ひとことで
空間を満たす霧に、ライトの光が当たって散乱する様子を計算し、光そのものが空間に見えるようにする表現です。普通の霧(距離で色を混ぜるだけ)とは違い、スポットライトの円錐、窓から差し込む光の筋、影で区切られた光の帯、懐中電灯の光線が見えるようになります。ホラーゲームやダンジョン、教会や廃墟の雰囲気作りに欠かせません。
ゲームでの使いどころ
- 光の筋・光の帯:窓やステンドグラスから差し込む光、木漏れ日、雲の切れ間の光。
- 懐中電灯・ヘッドライト:暗闇の中で光線そのものが見える。ホラーゲームの定番。
- 雰囲気・空気感:ほこりっぽい倉庫、湿った洞窟、ライブ会場のスモーク。
- ゲームプレイの手がかり:光の筋で出口や目的地を示す。
しくみ
ボリュームレイマーチングの一種で、画面の各画素について、カメラから(不透明な物体の手前まで)霧の中を進みます。各地点では次の 3 つを調べます。
- 光が届くか:スポットライトの円錐の内側か、距離による減衰はどれくらいか
- 影になっていないか:ライトのシャドウマップを読み、その地点がライトから見て物体の陰にあるかを調べる。これが光の筋を柱や窓枠で区切る
- どれだけ目に向かって散乱するか:霧の密度と位相関数
は影の判定(届くなら 1、影なら 0)、 はカメラからそこまでの透過率です。最後に、奥の景色を透過率で弱めて、散乱光を足します。
フロクセル方式:実際のゲーム(Frostbite、Unreal Engine の Volumetric Fog など)では、画面を奥行き方向にも分割した粗い 3D グリッド(視錐台のボクセル = フロクセル、例:160×90×64)を作り、各セルに届く光と密度を計算してから、奥行き方向に積算します。画素ごとにレイマーチするより安く、複数のライトや半透明物の霧にも対応できます。
実装のポイント
- 深度バッファで打ち切る:不透明な物体の奥の霧は見えないので、シーンの深度から物体までの距離を求め、そこで積分を止めます。
- ジッターと時間方向の平均:少ない歩数で縞が出ないよう、開始位置を画素ごと・フレームごとにずらし、TAA で平均します。
- ムラのある霧:密度に 3D ノイズを掛けて時間でゆっくり動かすと、光の中を漂う霧の空気感が出ます。
- 低解像度で計算して合成:霧は低周波なので、画面の半分〜4 分の 1 の解像度で計算し、深度を考慮して拡大します。
つまずきやすい点
- 負荷:画素ごとに数十歩、各歩でシャドウマップとノイズを読むので重い処理です。解像度と歩数の調整が必要です。
- 影の解像度:シャドウマップが粗いと、光の筋の縁がギザギザになったり、ちらついたりします。
- 強すぎる霧:密度を上げすぎると、画面全体が白っぽくなり、コントラストが失われます。光の筋を見せたい場所だけ密度を上げる(局所的な霧のボリューム)のが効果的です。
デモで試すこと
- 暗い広間に斜めにスポットライトが差し込み、柱の影で光の筋が区切られています。視点を回して、光の円錐が空間に見えることを確かめてください。
- 「影で光をさえぎる」をオフにすると、光の円錐全体が一様に光り、柱を突き抜けた不自然な光になります。
- 「濃さのむら」をオンにすると、光の中を霧が漂います。オフにすると均一でのっぺりした光になります。
- 「視線方向の歩数」を下げると、ざらつきが増えます。これを時間方向に平均して消すのが実際のゲームの方法です。