【Unity】Unityでのグローバルイルミネーションの基礎知識

Unityでグローバルイルミネーションを使う上での基礎知識を簡単にまとめました。

Unity2018.2.0

物体に当たる光の種類

物体に当たる光は「光源からどのような軌跡をたどってきたか」によって下記の通り分類できます。

名前 説明
直接光 ライトから直接届く光
間接光 ライトから出た光が1回以上反射してから届く光
環境光 Skyboxによる光

直接光と間接光についてはわかりやすいです。

環境光についてはSkyboxによる光と書きましたが、より正確には
「ライトの影響ではないが物体に届く光のこと」であると言えます。

現実世界では必ずどこかに光源があるのですべて直接光か間接光であるはずですが、
CGではライトで全ての光源を表しているわけではないため、環境光という考え方があります。

ライトの影響の計算方法

あるライトから出た光の影響は以下のいずれかの方法で計算されます。

名前 説明
リアルタイム シェーダでライトの情報を使って計算
ベイク GIを使って事前計算したライトの影響をテクスチャ(ライトマップ)に描く
ランタイムではそのテクスチャをサンプリングする
リアルタイムGI 何とか頑張ってGIの計算を軽くしてリアルタイムにGIを計算する

リアルタイムというのはシェーダでディフューズやらスペキュラやらを計算するアレです。
リアルタイムでライトの位置や強さなどを変えられますが、その分クオリティは低いです。
この場合、間接光は計算されず無視されます。

これに対してベイクは事前計算するので計算にいくらでも時間を掛けられます。
放射してから何回か反射して物体に届くような間接光の影響(光が回り込む表現)もいい感じになります。
ただし事前計算なのでリアルタイムでライトを動かしたりはできません。
また、スペキュラは視点に依存するためベイクされません。

間接光をいい感じに表現したいけどリアルタイムでライトを動かしたい、という要望に応えたのがリアルタイムGIです。
具体的には以下のような工夫をして処理負荷を抑えているようです。

  • ライトマップの解像度を大幅に落とす
    • 間接光はぼやけているものという前提で細かい表現はリアルタイムライトに任せるという考え方
  • clusterと呼ばれる、staticなジオメトリをローポリにしたものを作る
  • レイトレーシングの際に行う計算の重い部分を事前計算として切り出す

リアルタイムGIはモバイルにはまだ時期尚早なのかな?という感じがするので、とりあえずこれ以上詳しくは調べません。
下記の記事に詳しく書かれているので興味がある方は参照してください。

unity3d.com

Lighting SettingsでGIを有効にする

ベイクやリアルタイムGIを有効にするにはWindow > Rendering > Lighting Settingsを選択してウィンドウを開きます。
そして有効にしたいものにチェックを入れて有効化します。

  • ベイクを有効にするためにはMixed LightingのBaked Global Illuminationにチェック
  • リアルタイムGIを有効にするためにはRealtime LightingのRealtime Global Illuminationにチェック

f:id:halya_11:20181203233821p:plain

ベイクとリアルタイムGIを同時に使うこともできますが、両方の処理負荷が乗ってくるとのことです。

さてこれでベイクやリアルタイムGIが有効にはなりますが、これだけではまだ効果はありません。
「このライトはリアルタイムに使う」「このライトはベイクに使う」といったライト毎の設定が必要です。

LightのMode

LightコンポーネントにはModeというフィールドがあります。

f:id:halya_11:20181203235132p:plain

これは「このライトの直接光や間接光のうち、何をリアルタイムで計算して何をベイクするか」を設定する項目です。

設定項目名 説明
Realtime 直接光はリアルタイム計算される
間接光は無視される
Dynamic/Static両方のオブジェクトに影響する
Baked 直接光も間接光も事前計算されてライトマップにベイクされる
Staticなオブジェクトにのみ影響し、Dynamicなオブジェクトには影響しない
Baked GIが有効なときのみ有効(Baked GIが無効だと強制的にRealtimeになる)
Mixed DynamicなオブジェクトにはRealtimeと同じように振舞う
StaticなオブジェクトにはRealtimeとBakedのいい所取りができる
例えば「直接光はリアルタイムで計算しつつ間接光だけベイク」とかができるようになる
Baked GIが有効なときのみ有効(Baked GIが無効だと強制的にRealtimeになる)

3点目のMixedについてはLighting Settingsと絡んできて複雑なので次節で説明します。

また上記の説明では、Realtime GIには触れていませんが、
Realtime GIが有効かつIntensity Multiplierが0じゃなければ、Realtime のライトの間接光の影響も計算されます。
(本記事ではRealtime GIは詳しくは触れません)

ライトモードをMixedにした時の設定について

Lighting SettingsウィンドウのMixed LightingにはLighting Modeという設定項目があります。

f:id:halya_11:20181204002134p:plain

前節のLightのMode設定をMixedにした状態でこのLighting Modeを切り替えると、
ライトの直接光と間接光がどう影響するかをさらに細かく設定できます。

設定項目名 説明
Baked Indirect Staticなオブジェクトに対しては直接光はリアルタイム計算され、間接光はベイク
(Dynamicなオブジェクトは直接光のみRealtime計算)
Subtractive Staticなオブジェクトに対しては直接光も間接光もベイク
Dynamicオブジェクトの影の色を指定する必要がある
処理負荷は小さいが品質は低い
(Dynamicなオブジェクトは直接光のみRealtime計算)
Shadowmask Staticなオブジェクトに対しては直接光はリアルタイム計算され、間接光はベイク
ただしシャドウマップの範囲外にあるStaticオブジェクトは影をベイクしたテクスチャから取得する
リソースに最も負荷が掛かるが、結果は一番良い
(Dynamicなオブジェクトは直接光のみRealtime計算)

まずSubtractiveは全てをベイクしてしまうので、Staticなオブジェクトの影は動きません。
場合によってはこれは不自然なので、Baked Indirectにして直接光だけリアルタイム計算します。

これで影はライトに反応して動くようになりますが、シャドウマップの範囲を外れると当然影が生成されなくなります。
よって、近くはリアルタイムで計算して遠くはベイクしたものを使うShadowmaskが必要になってきます。

上記の設定のうちどれを使うかはケースバイケースではありますが、
Shadowmaskはモバイルでも検討すべき良い機能だと思います。

参考

docs.unity3d.com

unity3d.com