[UE4]LightのMobilityを整理しよう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/8c881c6a-e054-30ec-d988-7ef1f8c981c4.png)

今回はLightingのMobilityの効果についておさらいしようと思います。プロの人達でも、なんとなくでLightのMobilityを設定していることがたまにあります。

例えば。。。

- Static: 焼き付けるから軽いけど動くオブジェクトには当たらないライト
- Movable: 重たいけどキャラクタの影も全部つけてくれるライト
- Stationary: よくわからないけど軽いらしいから置いておこうライト

のような感覚でライトを設定されていることがあります。が、残念ながら上記の理解は間違いといえる部分もあり、ライティングの質や処理負荷を向上させるためには、より具体的に各Mobilityの内容を理解する必要があります。ということで、今日は各LightのMobilityを整理しようと思いますが。。。まずは免責事項です。今回の説明では以下の部分は省きます。

- Light MobilityによるShadow Map生成の違い
- Directional Light や Sky Lightの、各Mobilityによる挙動の違い
- (ライトではなく) MeshのStationary Mobility
- 半透明

なんだよほとんど喋らねえじゃねえか！と思うかもしれませんが、UE4のLightingは非常に複雑で色々な例外があります。今回はそれらを省き、まず大まかなLightのMobilityに対するメンタルモデルを形成してほしくこちらを記載しています。

それではまずはLightのMobilityのおさらいです。

## LightのMobilityのおさらい
まず、各ライトのMobilityがシーンのオブジェクトに対してどのような影響を及ぼすか、簡単に表にしてみました。これはオブジェクトがMovableであろうがStaticであろうと、計算手法はそれぞれで変わりますが以下の挙動になります。下の絵は、マネキンがMovable、ほかはStaticなObjectに対して、緑のポイントライトを一個照らした際の挙動です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/72fe5dcf-a531-b38b-c3e3-2d3d612fb9ed.png" width=75%>

**↓Static Light = Diffuse + Specular + Indirect Lighting**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/de3780d5-dc2e-7db4-8cdd-9e8592c7cfc4.png" width=75%>

**↓Stationary Light = Diffuse + Specular + Indirect Lighting**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/a891c1bb-1715-1688-90cf-cfbf333328d4.png" width=75%>

**↓Movable Light = Diffuse + Specular**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/f63996ae-0615-8fb5-6c99-a40fda5eefbb.png" width=75%>


StaticとStationaryはどちらも全てにチェックが入っていますが、それでも内部での計算方法は大きく異なります。では、各ライトはどうしてこのような挙動の違いが生じるのでしょうか？それはもちろんそれぞれの計算手法が違うからです。今度はその実装方法と注意点を見るために、各ライトがStatic/Movableのそれぞれのオブジェクトにどのように影響を与えるかをまとめてみます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/f1959455-020d-d56f-d9ed-daf470fcac76.png" width=85%>

一つ一つを理解していくように番号を振りました。以下でそれぞれについて簡単に見ていきたいと思います。

## 1. Static LightがStatic Objectに与える影響

```
Static Lightの直接光も間接光も事前に計算されStatic Objectのライトマップに焼き付けられる
```
以下の様に、一つのStatic SkyLightでもライトベイクすることで間接光も取り入れたライトマップを作成することができます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/38a11750-f891-b876-092c-183882dba8be.png" width=50%>

ではどのようにライトマップが作成されるかですが、この詳細に関しては過去に書いた記事がございます。こちらを参考にしていただけますと幸いです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/5529f7a0-dc74-cc2e-0bc8-f0f22ccc0e8d.png" width=50%>
[Lightmass Deep Dive 2018 Vol.1: Lightmass内部アルゴリズム概要(Lightmap編)](https://www.slideshare.net/EpicGamesJapan/lightmass-deep-dive-2018-vol1-lightmasslightmap)
[Lightmass Deep Dive 2018 Vol. 2: Lightmap作成のためのLightmass設定方法](https://www.slideshare.net/EpicGamesJapan/lightmass-deep-dive-2018-vol-2-lightmaplightmass)

ライトマップに格納されるのはDiffuse成分のみで、Specular成分は別のところに格納されるのですが、それは、次で説明いたします。


## 2. Static LightがMovable Objectに与える影響
```
 2. Static Lightの直接光も間接光も、空間ボリュームデータに事前に焼き付けられ、
MovableなObjectはそのボリュームデータをリアルタイムで参照してライティングを計算する
```
このため、**Static LightingはMovable Objectに影響を与える**と言えます。
ですので、下図の様なStatic Lightingが一個置かれてるシーンでも。。。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/3d187d28-9882-cbb1-4da0-f7b0024cd1bf.png" width=50%>

ライトベイクを行えれば、動的なキャラクターもライトで照らされます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/b5809664-c5d9-ad26-2bad-a11807bf79b2.png" width=50%>

これはStatic Lightingがライトベイク時に空間に分布するボリュームデータに直接光と間接光をどちらも格納するからです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/96c86a07-6ba4-14f7-c6e9-3b168d795b84.png" width=50%>

このボリュームデータはUE4.24の現在2種類用意しており、Persistant毎に切り替えることができます。設定はWorld SettingsのLightmass内部、Volume Lighting Methodです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/48be7a4a-411b-a61d-a3e6-eae3b3a5f522.png" width=50%>
- Voluemetric Lightmap
- Sparse Volume Lighting Samples (Precomputed Light Volume: 通称PLV)

下記のSparse Volume Lighting Samplesに関しては以下のSlideShareでこちらも詳細をまとめていますので、ご参考になれば幸いです。
[Lightmassの仕組み　~Precomputed Light Volume編~](https://www.slideshare.net/EpicGamesJapan/lightmass-deep-dive-part2-pub)

Volumetric Lightmapに関しても詳細をまとめておりますので、いずれ資料を公開できればと思います！

ただし、このボリュームデータから参照されるのはDiffuse成分のみだけです。ではSpecular成分はどこに格納されるでしょうか？

### 2.5 Static LightのSpecular成分はReflection Captureに格納される
Static LightのSpecularはReflection Captureに保存されます。ですのでReflection Captureから擬似的にPoint Lightの鏡面反射成分を受け取ることになります。

**ReflectionCaptureなし**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/5c877636-2393-715e-dd5c-74c541506a9c.png" width=75%>

**ReflectionCaptureあり**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/c21d86f2-1992-0f32-64fa-86e66ce32ee4.png" width=75%>

ただし、これはライトからの輝度を正しく計算したというわけではなく、Reflection Captureにライトをレンダリングして映り込ませるという擬似的なものです。ですので、Light Source Radiusを上げると、映り込みの形も大きく変わります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/fcef26a2-b14f-d9ee-4ec2-90ea6b623dea.png" width=75%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/055702c9-0b06-4b9a-1b74-58bf692acffd.png" width=75%>

また、明示的にCubemapを指定していると、このライトの映り込みは考慮されないので、ライトからの擬似的なSpecular成分の様には映らない点も注意が必要です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/457b4471-d1de-2ccb-2481-5464cc8f345a.png" width=75%>


この様にStatic Lightが及ぼす鏡面反射成分は非常に擬似的なため、最初に説明したマトリクスではStatic Light * Specular の組み合わせを△としました。



## 3. Stationary LightがStatic Objectに与える影響
```
Stationary Lightの直接光は動的に計算され、
間接光はStatic Objectのライトマップに格納される
```
Stationary LightはStatic ObjectらのShadow Mapを事前計算し、ライティングは動的に行います。この詳細はスミオさんが書かれている以下の記事が参考になるかと思います。
[Stationary Light の影について](http://darakemonodarake.hatenablog.jp/entry/2015/12/16/UE4/Stationary)

ShadowMapは固定されますが、ShadowMapを壊さない様なライトの変更を動的に行うことができます。例えば、ライトの強度や色を変更できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/500f749a-f7de-22d8-4262-0b0d9bb7b881.png" width=75%>

ただし注意点が必要です。上記の様に**間接光はライトマップに格納される**ということです。動的に変更できるのは直接光の成分だけなので、**間接光成分は変更されません。**そのため、ライトの色や強度を動的に変更すると以下の様にライティングが破綻することがあります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/95f78933-af8e-202f-45be-21cd0ca2d104.png" width=75%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/620afd9a-3dbc-1cba-b53f-560b838d9343.png" width=75%>

このため、Stationary Lightの設定を動的に変更する際はこの点を理解し、例えば、ライトの`Indirect Lighting Intensity`を0にして、間接光成分を最初から計算させないなどの対応が必要かもしれません。その分、間接光の恩恵も受けれなくなりますが。。。


## 4. Stationary LightがMovable Objectに与える影響
```
Stationary Lightの直接光は動的に計算されますが、間接光は空間ボリュームデータに事前に焼き付けられ、
MovableなObjectはそのボリュームデータをリアルタイムで参照してライティングを計算する
```

上記、Static Objectへの影響と全く同様の問題がMovable Objectでも起きます。Stationary Lightは間接光データを事前計算Volume Dataに格納します。それにより、Stationary Lightからの間接光の成分を受け取ることができるのですが。。。Stationary Lightの設定をかえても、事前計算の間接光の値は変わりません。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/6f9e8d3b-dfea-5c7e-3e74-8dd7803e456b.png" width=75%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/934ee585-6c9f-df33-b2e5-6e6455d606ae.png" width=75%>


## 5. Movable LightがStatic/Movable Objectに与える影響
```
全て動的に計算される
```
Movable Lightは簡単で、全てを動的に計算します。なので事前ライトベイクを必要としません。ただし、上記で述べたように間接光成分がありません。
**↓Movable Light = Diffuse + Specular**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/bcb70083-369e-442f-a7ae-e5c0bc52d8ca.png" width=75%>


この様なGIを動的に生成する方法はUE4.24の現在UE4では以下の２つを用意しております。
- Screen Space Global Illumination (SSGI)
- Ray Tracing Global Illumination

**↓SSGI ON**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/c242fad9-c61d-5d73-e48b-ee9e8e8e0c9a.png" width=75%>

SSGIはフェイクではりますが、擬似的にでも照り返しの効果が見て取れます。ただし、あくまでScreen Space。擬似的であり例えば、画面ないに映るものしか反映しないため、もしもカメラの後ろに強く照り返すオブジェクトがあったとしても、それらは反映されません。これは洞窟などのシーンで致命的になりえます。

Ray Tracing GIに関してはすみません！ここでは割愛します！ちゃんとGIが反映される最強メソッドではありますが、動的に沢山のレイを必要とするため、負荷などの観点からも注意が必要です。こちらはUE4.24でかなり改善されましたが、引き続き改善をすすめています。

## まとめ
以上です。簡単にですが各Mobiltyがオブジェクトに対して与える影響と、その注意点を羅列してみました。ご参考になれば幸いです。