This explanation is currently available in Japanese.
ひとことで
周囲の景色を、全方向を写した 1 枚の画像(環境マップ)として用意し、その画像のあらゆる方向の明るさを「光源」として使って物体を照らす手法です。点光源や平行光源を 1 つずつ置く代わりに、空、地面、周りの建物、ネオンの看板など、景色全体からの光と映り込みを一度に与えられます。物体がその場所に「なじむ」かどうかは、ほとんどこの照明で決まります。
ゲームでの使いどころ
- 屋外の空の光:昼の青空、夕焼け、曇り空など、空全体からの柔らかい光と、金属や水への空の映り込み。
- 屋内・場所ごとの映り込み:部屋ごとに置いた反射プローブ(リフレクションプローブ)で、その場所の周囲を映す。
- キャラクターの見栄え:ライトを細かく置けない場面でも、環境マップだけで立体感のある照明になる。
- 製品ビューア・キャラクター選択画面:スタジオ照明の環境マップ 1 枚で、素材を美しく見せる。
しくみ
PBR の反射方程式は、あらゆる方向からの光の積分です。環境マップを使う場合、これを画素ごとに毎回積分するのは重いので、事前計算で 2 つに分けます。
1. 拡散反射(放射照度マップ)
拡散反射は、法線を中心とした半球全体からの光の平均です。環境マップを非常に強くぼかした画像(放射照度マップ)、あるいは数個の係数(球面調和関数)に事前計算しておけば、法線の向きで 1 回読むだけで済みます。
2. 鏡面反射(事前フィルタ済み環境マップ)
鏡面反射は、反射方向の周りの、粗さに応じた範囲の光の平均です。粗さごとにぼかし具合を変えた環境マップを、ミップマップの段として事前計算しておきます(three.js の PMREM など)。
は視線の角度と粗さだけで決まる値で、これも小さな表(BRDF の積分表)として事前計算します。この分け方は Split-Sum 近似と呼ばれ、Unreal Engine 4 以降のゲームで標準的に使われています。
粗い面ほどぼかした段を読むので、映り込みがにじみます。デモの粗さ 0 の球は景色をくっきり映し、粗さ 0.9 の球はほとんど色の付いた柔らかい光だけになります。
実装のポイント
- HDR で持つ:太陽のような強い光を表すには、1 を超える明るさを保存できる HDR 画像(EXR、HDR 形式)が必要です。8 ビットの画像では、太陽も空も同じ白になってしまいます。
- 反射プローブの配置:ゲームでは場所ごとに環境マップ(プローブ)を撮影し、物体の位置に応じて近いプローブを使ったり混ぜたりします。部屋の形に合わせて反射の位置を補正する(パララックス補正)と、室内の映り込みが正確になります。
- 直接光と組み合わせる:太陽のようにくっきりした影を落とす強い光は、通常のライトとして別に置き、環境マップは空や周囲の柔らかい光と映り込みを担当させるのが一般的です。
つまずきやすい点
- 遮蔽を考えない:環境マップは「無限に遠くの景色」なので、物体の内側や隙間にも光が入ってしまいます。AO(遮蔽)を掛けないと、隅や口の中まで明るく光ります。
- 位置が合わない:室内で環境マップを使うと、映り込む景色の位置が物体の位置とずれます。パララックス補正やスクリーン空間反射で補います。
- 動的な変化:時間帯が変わるゲームでは、環境マップも作り直す必要があります。リアルタイムで更新するか、複数の時間帯を補間します。
デモで試すこと
- 「環境」を切り替えると、ライトを 1 つも置いていないのに、同じ球と像がスタジオ・夕暮れ・ネオンの夜それぞれの雰囲気に一瞬でなじみます。
- 手前の列(金属)で、粗さ 0 の球は景色をくっきり映し、右へ行くほどにじんで柔らかくなります。これが粗さ別に事前にぼかした環境マップです。
- 「環境を回す」で景色を回転させると、映り込みも一緒に回ります。
- 「直接光(ステージの照明)も使う」をオンにすると、通常のライトによる影とハイライトが加わります。