WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

Unity 5でGI(グローバル・イルミネーション)を触ろう

こんにちは、エンジニアの成田です。

今回はUnity 5に新たに搭載されたEnlightenと呼ばれるGI(広域照明)を試してみようと思います。
ss22

1.Enlighten

Enlightenは半導体の設計などで有名なARM社の傘下であるGeomericsが開発しているGIのミドルウェアです。内部的にはラジオシティ法を使って間接照明を計算していて、プレイステーション3、4、Xbox 360やPCのゲーム等で採用実績があるようです。今回Unity 5にこのミドルウェアが統合されたことで簡単にGIを使ったゲームを制作することが可能になりました。

2.触ってみよう

それではさっそくいじってみましょう。まずはUnity 5を起動して新しいプロジェクトを作成します。
特に設定は変更せずにPlaneとCubeを置いてみました。
ss1
シャドウは行われているものの、GIは……効いてなさそうですね。実は静的ゲームオブジェクトにしないとGIの事前計算は行われないのです。すべてのオブジェクトをStaticにしてみます。
ss2
今度はオブジェクト間の色がお互いに影響し合っています(カラーブリーディング)のでGIが機能しているようです。
でも正直GIの影響は大きくありません。これはなぜかと言えばLightがシーン全体に当たっていて間接光よりも直接光が支配的なためです。GIは閉所など間接光が重要なシーンで大きな効果が得られると言われます。

というわけでコーネルボックスのようなものを作ってみました。
天井には穴が開いていて外側からDirectional Lightの光が差し込むようになっています。
ss3
しかしこれは明らかに違和感のある絵です。Sphereを見るとよく分かりますが、南半球がなぜか茶色くなっています。これはデフォルトではシーン全体のGIのAmbientとReflection成分にSkyboxが適用されているためです。
今はこれらを無効にしてしまいましょう。

WindowメニューからLightingを開きます。
ss4
Environment LightingのAmbient IntensityとReflection Intensityを0にします。
ss5
ss6
するとシーンが真っ暗になってしまいました。
ss7
しかしこれはある意味正しい結果と言えます。AmbientやReflectionなど想定外の要素の影響を受けていないことと、天井からの光が奥の壁に反射して側面や天井の壁がぼんやり照らされていてGIが機能していることが確認できます。

しかしやはりどうにも暗すぎますね。今度は光源の光を強くしてみましょう。
LightingウィンドウでObjectタブを選択しLightボタンを押し、ヒエラルキービューからDirectional Lightを選択します。これがGIの光源に関する設定になります。LightのIntensityとBounce Intensityを変更することで、照明の強度とオブジェクトに反射した時の強度を変えることができます。
Intensityを3、Bounce Intensityを2くらいにしてみましょう。
ss8
シーンはこのようになります。
ss9
だいぶGIっぽい絵になってきました。ちょっと明るすぎてリアルではないかもしれませんが今はこれでいきましょう。

今度はCubeの上に乗ったSphereを金ピカにしてみましょう。
少し話は逸れますが、Unity 5は物理ベースシェーディングを採用しており、Unity 4までのマテリアルの設定とは設定パラメータが異なっています。これについてはまたの機会に書きたいと思います。
今回はUnityのこのページを参考にして金のマテリアルをこんな感じで作ってみました。
ss10
マテリアルを適用してみましょう。
ss11
上で設定したようにアルベドが黒、スペキュラが黄色のマテリアルですので、ご覧のようにSphereが真っ黒になっています。これを金色っぽく見せるためには周りの環境が映り込んだキューブマップを設定して反射しているように見せると良いです。
SphereにReflection Probeコンポーネントを追加します。
ss12
Reflection Probeはオブジェクトを中心に全方向の環境をキャプチャし、その画像をキューブマップとして利用することができます。
注意点として、Reflection Probeはデフォルトでは周囲環境を無限遠まで映り込むものとして計算していますので、今回のような閉所の絵では映り込むオブジェクトがおかしくなることがあります。
こういう場合にはBox Projectionを有効にします。
ss13
シーンは次のようになります。
ss14
Sphereに金色の周囲環境が映り込むようになりました。しかしSphereの下のCubeや右の壁がReflection Probeを追加する前よりも明るくなってしまっているのが気になります。これはReflection ProbeのSize内に入っているメッシュも影響を受けるためです。
そこでSphere以外のすべてのオブジェクトがReflection Probeの影響を受けないように変更します。各オブジェクトのMesh RendererのReflection ProbesをOffに変更します。
ss15
Reflection Probeの反射も強すぎるのでIntensityを0.8に下げます。
するとこうなります。
ss16

それでは最後にStaticでないオブジェクトをシーンへ置く方法を見てみましょう。
最初にも言いましたが、事前計算GIはStaticなオブジェクトに対してのみ行われます。白色マテリアルでdynamicなオブジェクトを配置するとまたもや真っ黒になってしまいます。
anim1
dynamicなオブジェクトを事前計算したGIのシーンへ混ぜる方法としてはLight Probeが一般的でしょう。いずれかのオブジェクト(Staticなものが良いでしょう)にLight Probe Groupを追加します。
ss17
ss18
Light Probe Groupを追加すると上のような8つの球(Probe)が出てくると思います。これらのProbeはPlay時には表示されません。空間内にこれらのProbeを配置することでその地点の照明が事前計算され、実行時にはdynamicなオブジェクトはこれらProbeの照明計算結果を補完することで事前GIと親和性の高い結果を得ることができます。

またProbeは、Add Probeで数を増やしてサンプル地点を増やすことができます。
ss19
今回はこのように配置してみました。
ss20
黒かったCubeがシェーディングされていることが確認できると思います。
ただしdynamicなオブジェクトからの反射光をStaticなオブジェクトに影響させることはできません。(と思います……)

もう少し調整しましょう。先ほど作成した金色のSphereを見てください。
反射にCubeが映り込んでいないことに気づきましたか?Reflection Probeに関してもデフォルトでは事前計算でベイクされるため、dynamicなものは映らないのです。
dynamicなもの、さらに今回のように毎フレーム移動するようなものを映り込ませたい場合は、Reflection ProbeのTypeをRealtime、Refresh ModeをEvery frameに変更します。
ss21
ただしReflection Probeに毎フレーム計算させると当然処理が重くなるので使いどころは考えた方が良いでしょう。
ではPlayしてみましょう。
anim2
dynamicなCubeが動いて壁に近づいたり離れたりするにつれて、壁の色の影響も増えたり減ったりしていること、またSphereの反射にCubeが映っていることが分かると思います。

いかがでしたでしょうか。UnityにEnlightenが統合されGIが大変身近になりましたので、今後この辺りの知識も増やしていきたいですね。
ss22