This explanation is currently available in Japanese.
ひとことで
光が物質(水、ガラス、霧、煙)の中を通るとき、通り抜けた距離に対して指数関数的に弱まるという法則です。同じ厚みを通るたびに同じ割合ずつ減るので、1 m で半分になるなら、2 m で 4 分の 1、3 m で 8 分の 1 になります。弱まり方が色ごとに違うと、厚くなるほど残りやすい色が強調されます。
は透過率(届く光の割合)、 は吸収・散乱のしやすさ(消散係数)、 は通った距離です。
ゲームでの使いどころ
- 水の色と深さ:浅瀬は透明で、深くなるほど青緑になり、底が見えなくなる。水中の視界が遠くほど青くかすむ。
- 霧・煙・雲の透け具合:ボリュームレイマーチングの基本。雲の厚い部分ほど暗く、光を通さない。
- 色付きガラス・液体:ワインボトル、ポーション、宝石。厚い部分ほど色が濃くなる。
- 影の濃さ:半透明の物体や雲が落とす影の濃さ。
- 肌や蝋の透け具合:表面下散乱で、厚みに応じて光を弱める。
しくみ
薄い層 を通るとき、光は の割合だけ減ります。層を何枚も重ねると、
となり、指数関数になります。密度が場所によって違う場合は、通り道に沿った密度の合計(光学的厚さ)を使います。
色ごとの係数: を RGB で別々に持つと、色が変わります。
| 物質 | 吸収しやすい色 | 厚いと |
|---|---|---|
| 海水 | 赤 | 青緑になる |
| 紅茶・ウイスキー | 青 | 琥珀色になる |
| 煙・すす | 全色ほぼ同じ | 灰色のまま暗くなる |
指数関数の性質上、係数の小さな違いでも、厚みが増えると大きな色の差になります(デモのグラフの 3 本の曲線の開き方)。
実装のポイント
- 厚みの求め方:単純な形なら視線との交差から、複雑な形なら表面と裏面の深度の差、事前に焼いた厚みマップ、または距離場をたどって求めます。
- 乗算合成で安く:デモの水槽は、透過率を奥の画面に掛け合わせる(乗算合成)だけで描いています。追加のテクスチャ読み込みは不要です。
- 係数は「距離の単位」を意識: は「1 m あたりどれだけ減るか」です。シーンの単位(cm か m か)が変わると、見た目が大きく変わります。
つまずきやすい点
- 散乱を忘れる:ビール・ランバート則は「減る」ことだけを表します。霧や雲が明るく光るのは、途中で散乱されて目に向かう光があるからで、別に計算が必要です(ボリュームレイマーチング)。
- 線形に減らしてしまう:厚みに比例して透明度を下げる(線形)と、厚い部分が不自然に早く真っ黒になったり、薄い部分の変化が大きすぎたりします。
- 多重散乱:雲のような濃い媒質では、何度も散乱した光が奥まで届くため、単純な指数関数より明るくなります。雲の描画では補正を加えることがあります。
デモで試すこと
- 5 つの水槽は、厚みが 0.25 m から 3 m まで違います。海水では厚いほど赤が失われ、青緑が濃くなります。
- 右下のグラフは、厚みに対する各色の透過率です。赤の曲線が最も早く下がります。点は 2 m の位置です。
- 中身を「紅茶」にすると青が早く減るので、厚いほど琥珀色になります。「煙」では全色が同じだけ減るので、灰色のまま暗くなります。
- 「濃さ」を上げると、すべての曲線が急になり、薄い水槽でも色が付きます。