テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】マルチシーン編集する際に知っておきたい、複数のシーンに跨ったライトマップを操作した時の挙動について

今回はマルチシーン編集(Multi Scene Editing - MSE)による複数シーン編集とライトマップについてです。

Unity 5.3より複数のシーンを同時に編集可能になりました
これにより広大なシーンを複数のシーンに分割し段階的に構築する事や、屋根や壁といった編集しないシーンと編集するシーンを分けて、オブジェクトを並べる事に集中する・・・といった事が可能になりました。

f:id:tsubaki_t1:20160208020125g:plain

で、複数のシーンに分けて編集できるのは良いのですが、複数のシーンを構築した際にライトマップが幾つかのシーンに跨っていた場合はどのようになるのでしょうか。
確認してみました。

複数シーンに跨ってライトマップを焼くには

複数のシーンに跨ってライトマップを焼くには、マルチシーンエディティングを活用します。
つまり、複数のシーンをHierarchyに登録した状態、マルチシーンエディティング中にライトマップを焼けば、結合した状態でライトマップが焼かれます

f:id:tsubaki_t1:20160208001712g:plain

これで各々のシーンをロードした場合も、ちゃんと別シーンのライトの影響を受けた状態でロードされます。

ライトマップのベイクをスクリプトから実行する

ライトマップ用にシーンを一々並べるのは正直面倒くさいので、スクリプトでライトマップを一括で並べてくれて焼く方法を考えます。

ここで思いつくのがLightmapping.BakeMultipleScenesなのですが、どうやら現状(Unity 5.3)このAPIは動作しないらしく、変わりにこんな感じのを用意しました。

gist.github.com

使い方は、Assets>Create>LightmapBakerでアセットを作成して、Main Sceneにメインとなるシーン、Scensに結合するシーン一覧を放り込んでBakeボタンを押す感じです。

f:id:tsubaki_t1:20160208004725j:plain

f:id:tsubaki_t1:20160208005011j:plain

やってる事は単純で、シーンを並べてベイクしてるだけです。実際にはエディタ拡張でライトマップベイクをバッチ処理する事になると思うので、任意のフォルダからLightmapBakerを一覧取得してかたっぱしからベイクする感じになるかなと思います。

ライトマップが保存されるのはアクティブなシーンと同名のフォルダ

まず単純に複数のシーンをベイクした場合、ライトマップはアクティブなシーンに保持されます。
このアクティブなシーンとはHierarchy上にあるシーン一覧で名前が太字のシーンです。例えば下のシーンでは「Light」がアクティブなシーンに当たります。

f:id:tsubaki_t1:20160207232823j:plain

アクティブなシーンは一番最初に開いたシーンが該当しますが、Set Active Sceneでも切り替えることが可能です。

f:id:tsubaki_t1:20160207233011j:plain

マルチシーン編集の状態でライトマップを(Autoのチェックを外して)ベイクすると、アクティブなシーンと同名のフォルダが作成され、フォルダの下にLighting Dataが出力されます
このLighting Dataは複数のLighting Data Assetを保持しており、この個数はマルチシーン編集時でロードされているライトを焼く関連の情報を持つシーンの数と概ね一致します。
例えば下の図の場合、3つのシーンにレンダラーもしくはライトがあるシーンが3つあるので、3つ表示されています。

f:id:tsubaki_t1:20160207233318j:plain

ライティングの基本設定はアクティブなシーンが保持

ライティングの基本的な情報、例えばSkybox(空)やAmbient Light(環境光)・Reflection Source(環境マップ)の設定は、アクティブなシーンが保持します。
なので、アクティブなシーンを切り替えたり、アクティブなシーンをアンロードした場合、他のシーンの設定が使用されたりします。

f:id:tsubaki_t1:20160207235135j:plain

各シーンのライトマップは必要な時にロードされる

問題となるライトマップですが、これは各シーンが保持していました。例えばライトマップに使用するテクスチャであったり、Precomputed Realtime GI等です。つまり、ライトマップのテクスチャはシーンが必要な時にロードされ、不要になった状態でUnloadUnusedAssetsを実行すれば破棄されます。

ライトマップとは無関係のシーンからライトマップを含むシーンをロードすると、追加でライトマップの設定にテクスチャが読み込まれるのが分かります。

f:id:tsubaki_t1:20160207235917g:plain

但し若干面倒なのが、Lightprobeはライトマップを焼くタイミングで結合され、関連シーンを読み込んだ際に全てロードされる事です。

元々Lightprobeは一部読みが出来ないので*1このように関連処理を取得する際に一括で取得するような仕様になっているのかなと。
例えば下のシーンにはLightprobe Groupが一つもありませんが、一緒にライトマップを焼いたシーンに含まれていたので、結合されLightprobegroupが表示されています。

f:id:tsubaki_t1:20160208000821j:plain

焼く時に含まれないシーンのライトマップは破棄される

少し厄介なのが、ここで「以前ライトマップを結合して焼いたが、今回保持していなかったシーン」がある場合、ライトマップが破棄されます

例えば「Stage1とStage2とLight」というシーンでベイクした後「Stage1とLight」のシーンだけでベイクすると、Stage2のライトマップが破棄され、ロードした際にStage 2の部分だけライトマップ無しで表現されます。

f:id:tsubaki_t1:20160208005912j:plain

つまり、基本的にライトマップを焼く時は単体で焼くか、結合して焼くかの2択となります。が、単体で焼く場合はシーン間の接地面がどうしても不自然になるので、注意が必要です。

上が「結合して焼いたライトマップ」、下が「個別に焼いたライトマップ」です。個別に焼いたライトマップは、境目が分かりやすく出ています。

f:id:tsubaki_t1:20160208002132j:plain

f:id:tsubaki_t1:20160208002139j:plain

関連

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

*1:Unity 4では出来たが、Lightprobe間の補完で何か問題があったとか何とか