今回はUnityのライトプローブについて見ていきたいと思います。
ゲームでは様々なライトを設置してゲーム内のゲームオブジェクトを照らしています。
ライトでゲームオブジェクトに当たる光、またその反射光等をゲーム中に計算処理を行っているわけです。
そんな計算をしているのがグローバルイルミネーションシステムです。
ライトプローブについて見ていく前にこのグローバルイルミネーションについて少し見ていきます。
グローバルイルミネーション
Unityではグローバルイルミネーションシステムを使って光の反射をシミュレートします。
光の反射を考慮するには事前に静的なオブジェクト(ゲームオブジェクトのインスペクタでLightmap Staticにチェックしたもの)
に対して光を当てて計算し、光の反射を考慮したオブジェクトの面の色をライトマップ(ライトの光を考慮したゲームで使うゲームオブジェクトの面のUVMap)にベイクしておいて動作を軽くするBakeGIと、
事前計算したデータを元にリアルタイムに光の反射を考慮するPreComputed RealtimeGIがあります。
静的なゲームオブジェクト(動かない建物等のゲームオブジェクト)は、事前にライトマップを生成しておくと光の計算をゲーム中にする必要がないので、ゲームの動作が軽くなります。
しかし動的なゲームオブジェクト(キャラクター等の動くゲームオブジェクト)には反射光の影響を及ぼすことが出来ません。
また複雑なゲームの舞台を事前にライトマップにベイクすると何時間もかかる可能性もあります。
ベイクの時間を最適化するにはUnityのチュートリアルの
を見ると最適化の方法がわかります(英語ですが・・・(^_^;))。
ライトマップに事前に光の反射を考慮したUVMapを保存し利用すればゲームの動作が軽くなりますが、静的なゲームオブジェクトから動的なゲームオブジェクトに反射光の効果を与えることが出来ません。
BakeGIとPreComputed RealtimeGIはゲームオブジェクトがLightmap Staticでなければいけませんので、これらの静的なゲームオブジェクトからの反射光を取得出来ません。
グローバルイルミネーションについて詳細かつ正確に知りたい方は、記事の最後に記載する参考サイトのUnityマニュアルを参照してください。
ライトプローブ
静的なゲームオブジェクトの反射光を動的なゲームオブジェクトに適用する事が出来ないのはグローバルイルミネーションの項目でやりましたが、
それを可能にするのがライトプローブで、シーンのライティングに関する空間のベイクしたライト情報を保持し、静的なゲームオブジェクトから動的なゲームオブジェクト、動的なゲームオブジェクトから静的なゲームオブジェクトにも光の効果を加えることが出来ます。
ライトプローブ概要
ヒエラルキー上で右クリック→Light→Light Probe Groupを選択します。
すると、
上のように黄色い丸いポイントとそれを繋ぐ線がシーンビュー上に表示されます。
この黄色い丸いポイントが光の情報を持っているポイントでゲームオブジェクトを囲むようにこのポイントを増やしたり移動させたりして光の情報を保持出来るようにします。
上のようにEdit Light Probesボタンを押すと下の編集ボタンが有効になります。
Add Probeは新しいポイントの追加、Select Allは全てのポイントを選択、Delete Selectedは選択しているポイントの削除、Duplicate Selectedは選択しているポイントを複製します。
ポイントはシーンビュー上でマウスで選択可能で、オブジェクトハンドルを操作する事で移動、Ctrl+Dで複製、Deleteキーで削除等も出来ます。
ライトプローブのポイントの数は出来るだけ少なくし、光の変化が激しい所や狭い所に多く配置した方が良いようです。
ゲームオブジェクトがライトプローブのどのポイントの四面体に入っているかを調べ、そのポイントのライトの情報を取得します。
ライトプローブを使ったサンプルの作成
説明だけ見ても分かり辛いと思いますので、実際にライトプローブを使ってみましょう。
サンプルの舞台の作成
まずはサンプルの舞台を作成します。
ヒエラルキー上で右クリック→3D Object→Planeを選択し、インスペクタのTransformでScaleのXYZを5にし、右上の下向きの矢印からLightmap Staticを選択します。
ヒエラルキー上で右クリック→3D Object→Cubeを選択し、Lightmap Staticにチェックを入れます。
ヒエラルキー上で右クリック→Light→Spotlightを選択し、Cubeに光が当たりように角度や位置を調整します。
SpotlightのModeをBakeにしライトをベイクに使用します。
Cubeを照らすスポットライトは
上のような感じにしました。
既に自動でライトマップを生成するような設定にしている場合はライトマップが作成されていると思いますが、Lightウインドウ(Unityメニュー→Window→Rendering→Lighting Settings)で自動と手動を切り替えることが出来ます。
Auto Generateの横のチェックを外すと手動でGenerate Lightingボタンを押さないとライトマップをベイクしません。
またGenerate Lightingボタンの横の下矢印を押すとBake Reflection Probesでリフレクションプローブだけベイクしたり、Clear Baked Dataでベイクしたライトマップを削除できます。
グローバルイルミネーションはキャッシュに保存され、UnityメニューのEdit→PreferencesのGI Cache項目で設定が出来、Clean Cacheでキャッシュをクリア出来ます。
先ほどのClear Baked Dataを選択した場合はベイクしたライトマップは消えますがキャッシュは残るようです。
Generate Lightingボタンを押してライトマップをベイクしてください。
ベイクしたライトマップデータはシーンフォルダの中にシーンと同じ名前のフォルダが作成されその中に作成されます。
そしてスタンダードアセットのThirdPersonControllerをヒエラルキーにドラッグ&ドロップしてキャラクターを配置し、動かしてみます。
ここまででライトマップをベイクしましたが、ライトプローブは配置していません。
実際にキャラクターを動かしてライトの近くに動かすと、
上のようにキャラクターがライトに当たっているにもかかわらず、暗いままです。
これはスポットライトがベイク用のライトでライトマップに焼きこんでいますが、リアルタイムに光を当てない為です。
ライトプローブの配置
次にヒエラルキー上で右クリック→Light→Light Probe Groupを選択しライトプローブをCubeを囲むようにポイントを作成していきます。
今回は上のような感じでポイントを作成しました。
ライトプローブの設置が終わったら再びLightウインドウのGenerate Lightingボタンを押してベイクします。
ベイクが終わったらキャラクターを動かして確認してみます。
上のようにライトプローブによってスポットライトの光の情報をキャラクターに与えることが出来るようになりました。
ここで注意しておかなければいけないのは動的に動くゲームオブジェクト(この場合キャラクター)のMesh RendererやSkinned Mesh RendererのLightingのLight ProbesでBlend Probes等のライトプローブを使う設定をしておく必要があります。
Light ProbesをOffにするとライトプローブの効果が得られません。
発光するゲームオブジェクト
ゲームオブジェクト自体が発光し、動くゲームオブジェクトにその光の効果を与えたい時にもライトプローブが使えます。
先ほど作ったスポットライトのインスペクタで名前の横のチェックを外し無効化してからGenerate Lightingを押します。
ヒエラルキー上で右クリック→3D Object→Capsuleを選択し、Lightmap Staticにチェックを入れます。
Assetsエリア内で右クリック→Create→Materialを選択し、名前をMyMaterialとして、先ほど作成したCapsuleに設定します。
MyMaterialのEmission項目をチェックし、発行色を設定して、Global IlluminationをBakedにします。
LightingウインドウのGenerate Lightingボタンを押してベイクします。
実際に試してみると以下のようになります。
上がライトプローブなしの場合で、下がライトプローブありの場合です。
ライトプローブありの場合はキャラクターに赤みがかかった光が当たっているのがわかります。
終わりに
ライトの設定は色々な要素が絡んでくるので難しいですね・・・・(^_^;)