UnityでLightmapを綺麗にBakeする!

こんにちは、MinaFrancescaです。
今回は、UnityでLightmapを綺麗にBakeする方法を記事としてまとめていきたいと思います。
以前、FANBOXでも同様の記事を投稿し、多くの驚きの声をいただいたのですが、今回は、それを復習しながら、繋がっていく関連作業についても簡潔にまとめていきたいと思います。
なお、この記事はあくまでも、「Lightmapを綺麗にBakeする」ことを目標とし、作業の内容についてはそこまで深くは掘り下げません。こういうふうに設定すると焼けます、というラインで進めていきます。
VRChatでワールドを作成するにあたっての重要な情報も散りばめていきますので、これからワールド制作をやってみよう!と考えている方は必見です。
それではいってみましょう!

この記事でご紹介すること

  • Lightmapを綺麗に焼くためのモデルの読み込み設定
  • PointLightを使ったライティングとBakeの設定
  • Reflection ProbeとPPSの設定
  • Lightmapデータの圧縮
  • Unity2018から実装されたGPU Bakeを試す

Lightmapを綺麗に焼くためのモデルの読み込み設定

まず、今回の投稿用に、お部屋を準備しました。
このお部屋をUnityにもってくる際に、モデルのインポートの画面でいくつの設定を行う必要があります。モデルとは、拡張子が「fbx , obj , skp」などのファイルですね。
UnityのアセットストアやBoothからダウンロードしてきたものであれば、皆さん迷わずPrefabフォルダを探すことと思います。Unityのアセットストアの場合は、たいていモデルのインポート設定はだいたい既にされていますが、LightmapをBakeする場合は、必ず確認しておかなければならないことがあるので、Prefabではなく、モデルデータが格納されたディレクトリを探して、モデルのファイルをクリックした時にインスペクタに表示される、こちらのような画面を探してください。

注目すべきところに赤枠を付けました。まずはこのように設定をしてください。

一番上の「Generate Back Face」は、オブジェクトの面の裏側の描画を行うかどうかのチェックですが、裏面が表示されていなくておかしな部分がある場合にチェックを入れると良いでしょう。

「Mesh Compression」をHighに設定していますが、これはVRChatのワールド制作におけるワールド容量の軽量化の手法です。Highの最高圧縮設定でも、見た目はほとんど悪化しません。軽量化はわずかな程度ですが、最高に軽いワールドを創りたい時には有効でしょう。

「Generate Colliders」のチェックはここでは外れていますが、例えば、大量のオブジェクトが含まれていて、あとでいちいちコライダーを設定するのが面倒だと予想される場合は、ここにチェックを入れましょう。自動的にコライダーコンポーネントを入れてくれて楽が出来ます。

「Legacy Blend Shape Norr…」は必ずチェックを入れましょう。これはVRChatのワールド制作における軽量化の手法のひとつです。これのチェックが外れていると、このモデルについてのファイルサイズが肥大化するようです。どうやらUnity2018のバグのひとつでもあるようです。
そして「Normals」を「Calculate」に設定します。これがかなり大事です。

最後に「Generate Lightmap UVs」にチェックを入れます。UnityのBake記事でよく説明されているところで有名ですね。


さきほどのタブ群の一番右「Materials」というところも確認しましょう。
Unityのアセットストア製のものであればたいてい問題ありませんが、自前のモデルや他の3Dモデル販売サイトからのインポートの時は、ここの設定は大切です。

「Location」を「Use External Materials(Legacy)」に設定します。
このあと、右下の「Apply」をクリックします。これで完了です。
モデルデータに組み込まれているテクスチャ、マテリアルが、フォルダにまとまってプロジェクトに展開されます。


PointLightを使ったライティングとBakeの設定

では、実際にライティングをしていきたいと思います。まずはこちらの画像をご覧ください。

天井からぶら下がった電球、それぞれにPointLightを設定しました。
この設定を見ていきましょう。

PointLightの設定としてまず、「Mode」を「Bake」に設定します。
これで、このライトがLightmapを焼くライトになります。
「Range」で照らされる距離を広げ、「Intensity」で、照明の強さを設定します。
電球なので、「Color」はオレンジにしました。

「Shadow Type」を「Soft Shadows」に設定しました。すると、「Baked Shadow Radius」という項目がすぐ下に出現します。この場合、状況によって違いますが、だいたい「10」が良いところです。もし、「No Shadows」にした場合は、この光による影は生まれません。
時々、影はいらないけれど光は欲しい、ということもありますので、そういう時に利用します。

ここでの照明の強さ「Intensity」は、ちょっと眩しいかな、ぐらいの感じに設定するのがおすすめです。ここで加減すると、Bakeしたあとに、なんか光が足りなかったかな?と感じることが多いです。


ちなみに、PointLightを複数置いていくと、何故だかライトを置いているのに光が出ていないんだけど・・・?ということに必ずなると思います。そんな時は、「Project Settings」の「Pixel Light Count」を数を大きく設定します。これが小さい数値である意味はないので、適当に50くらいに設定しておいてください。これで正しくライティングされることと思います。


次に「Directional Light」の設定を考えます。LightmapをBakeする際に、ライトを焼き付けるのだからといって、この「Directional Light」の「Mode」をBakeに設定してしまうと、いろいろと大変なことになります。このあたりはそれぞれ考え方があるところなので、これが絶対正しい、と強くは書けないのですが、一応、私なりの見解をここに書いておきましょう。

基本的に「Directional Light」はBakeするべきではありません。

「Directional Light」は「Realtime」に設定しておきましょう。
何故かというと、「Directional Light」とは、言い換えれば太陽です。夜の場合は、月でしょう。
その光を焼き付けると、どうなるかというと、以下のようなことが起こります。

・樹々が揺れているのにその影は揺れない
・水シェーダーが機能しなくなる
・VRCでアバターが真っ黒に表示される
・そもそもBake出来ない、あるいはものすごい時間を要する

このようなことが考えられます。
影を焼き付けてしまうので、当然、樹の葉が風で揺れても影が動かず、不自然になってしまいます。また、多くの水シェーダーが機能しなくなります。光あってこその水。覚えておきましょう。
VRCでアバターが真っ黒に見えてしまったことがありませんか?多くがこの「Directional Light」をBakeしていることが起因しています。
ワールドにTerrainで樹や草を置いている場合、そもそもBake出来ない、あるいは、Bakeにものすごい時間を要する場合があります。

一定の時間を何度も何度も繰り返すような状況になっている場合、「Directional Light」を焼いている、あるいは、草や樹がBakeする対象「Static」設定になっていると考えられます。
Bakeする際に、Terrainや、置いた樹々は非表示にしておきましょう。

しかし、「Directional Light」を焼くことでメリットもあります。
それは、パフォーマンスが向上する、ということです。Realtimeのライティングが無くなれば、当然負荷は低くなります。大人数が集まる会場の作成の際には有用であると考えられます。
しかし、VRChatも日々改良が行われ、現在「Directional Light」をRealtimeで使用していても、ある程度のPCスペックで90FPSを実現することは十分に可能です。このことから、そもそも「Directional Light」はBakeするべきではないと考えています。参考まで。


PointLightを設置する時のお話ですが、上の画像のように、PointLightは、電球のオブジェクトのちょっと下あたりに配置するのが良いでしょう。
電球の中にPointoLightを隠してしまうと、Bakeした際に変になってしまいます。
PointLightはオブジェクトに埋もれない、隠れない位置に置きましょう。


お部屋にある照明器具すべてに、PointLightを設定しました。

天井にある一番大きな照明のPointLightの設定で、「Shadow Type」が「Soft Shadows」に設定されているため、天井に不思議な影が出来ています。これは「No Shadows」に設定すると解消されますが、このあともう少しこのことについて掘り下げていきますので、まずはこのままBakeしてみます。結果は以下のようになってしまいます。
おそらく、こんな感じになって悩んでしまい、この記事に辿り着いたのではないでしょうか。

あるはずのライトが消え、不気味な境目が生まれ、UnityのLightmapとは一体・・・と絶望する瞬間です。
では、こんな状況から抜け出すためのいくつかの手法をご紹介していきます。


まずは、Bakeを始める際に誰もが見る画面です。こちらの設定を、この画像のようにしましょう。
また、これはProjectを立ち上げた際にすぐに設定してほしいのですが、この画像の一番下「Auto Generate」のチェックを外しましょう。とても快適になります。
また、「Lightmap Parameters」がここではまだこのように設定できないと思います。いったん飛ばしてください。

ここで注意するのは、「Lightmap Resolution」と「Lightmap Size」の項目です。
画像では、それぞれ5と512に設定されていますが、これは開発段階の数値です。この数字が高いほど、Bake処理に時間がかかると思ってください。なので、開発段階はこの画像のように設定し、最後に仕上げのBakeをして完成、としたい時に、
「Lightmap Resolution」を40、「Lightmap Size」を1024とかにすると、とても綺麗にBake出来ます。

ここまでは、検索で出てくる多くの記事で紹介されていることです。
しかしこれだけではまだ不十分なのです。次に進みましょう。

右クリックをして、「Lightmap Parameters」を作成します。多くの方がまったく触れたこともないものでしょう。出来たファイルをクリックすると、このような画面に辿り着きます。

ここで重要なのは、最下部の「Backface Tolerance」を0に設定することです。
これ以外は特にいじる必要はありません。
ここまで来たら、さきほどのBakeの画面をまた出します。


さきほど飛ばした、「Lightmap Parameters」の設定で、今作成した、「New LightmapParameters」が選択できるようになっています。これを選択しましょう。

まだあります。次の作業に移りましょう。

配置したオブジェクトには必ず「Mesh Renderer」というコンポーネントが付いています。
このコンポーネントの「Scale In Lightmap」を10に設定しましょう。

とはいっても、めちゃめちゃたくさんオブジェクトをおいたのに、今からヒエラルキーを辿って全部設定していくのは面倒すぎる!っていうこともあると思います。

ヒエラルキーの上部に「MeshRenderer」と打ち込むと、「MeshRenderer」が設定されているオブジェクトがズラッと絞り込み検索されます。こうなるととても楽です。出てきたオブジェクトをすべて選択し、先ほどの「Scale In Lightmap」を10に設定しましょう。一瞬で終わります。

一応書いておきましょう。Bakeしたいオブジェクトは、「Static」に設定する必要があります。
しかし、闇雲にすべてをStaticにするのではありません。
例えば、開く予定のある扉、動く予定のあるなんらかのオブジェクトは、Staticに設定してしまうと、その場所から動かなくなってしまいます。
Bakeしたい対象のオブジェクトは、上の画像のように、「Lightmap Static」にチェックが入ってさえいれば、Bakeの対象となります。
また、開く予定の扉であれば、「Occluder Static」と「Occludee Static」はチェックを外しておくと良いでしょう。このあたりはオキュリュージョンカリングの話になるので、割愛します。

さて、これでBakeをすると、こちらの画像のようになります。見違える出来栄えです!

ライトはしっかりライトとして機能し、不自然な感じはありません。


部屋全体を広く照らすPointLightで「Shadow Type」を「Soft Shadows」あるいは「Hard Shadows」で影を出していると、そのPointLightによって、部屋全体が、良く言えば「味が出る」感じに仕上がります。この画像では、天井の中央の大きめの電球に設定したPointLightがそれにあたります。これによって、部屋の右奥の隅が、ボソボソとした味のある暗がりが表現されています。
もし、そういう「味のある」感じが不要であれば、このPointLightの「Shadow Type」は「No Shadows」に設定すると良いでしょう。
どのように結果が異なってくるかは、こちらをご覧ください。

左は、Bakeする前です。PointLightは「SoftShadows」に設定しているため、傘の影が後ろに出来ています。
中央は、PointLightを「SoftShadows」のままBakeした結果です。ボソボソとした味のある仕上がりで、どことなくサイレントヒル的な雰囲気が漂います。
右は、PointLightを「No Shadows」に設定してBakeした結果です。すっきりと清潔感のある壁に仕上がりました。ほとんどの方はこちらのほうがお好みでしょう。

作りたい空間の雰囲気に合わせて、「SoftShadows」か「No Shadows」を選択しましょう。


Reflection ProbeとPPSの設定

ライティングの仕上げとして、Reflection ProbeとPPSの設定をしていきましょう。
Reflection Probeは、表面が鏡のように反射するオブジェクトが正しく反射するようにするものです。窓ガラスや、ビンなどがそれにあたります。まずはReflection Probeを設定しましょう。

特に難しいことはありません。Reflection Probeを生成したら、作った部屋を囲むように範囲を設定し、「Type」は「Bake」になっていることに注意して、最後に「Bake」のボタンを押すだけです。
上の画像では、「Resolution」が512になっていますが、窓ガラスに映るものをもっと鮮明に見せたいときは、この数値を高くしてください。

次にPPSの設定に移ります。
PPSとは、Post Processing Stackの略で、画面効果のことです。眩しく見えるはずのものを眩しくし、色合いの調整などが出来ます。

Package Managerという項目から、Post Processing Stackをインストールします。

VRChatから特に告知がない限りは、最新版で大丈夫でしょう。上の画像のように、Post Prossesingの項目から「Install」を押してインストールします。

まず、すでにある「Main Camera」に、「Post Process Layer」を設定します。
「Layer」を「TransparentFX」に設定します。なんでもよいのですが、これがおそらく誰しもあいてる都合のよいレイヤーだと思います。

次に、PPS(名前はなんでも大丈夫です)という空オブジェクトを作り、そこに、「Post Process Volume」を設定します。赤枠部分の設定を行ってください。
上の画像はオススメの設定ですが、昼夜でその設定値は異なりますし、光るオブジェクトの光り具合の好みもそれぞれあると思います。調整が楽しいところなので、いろいろいじってみると良いでしょう。

このPPSが適用されている実際の画面は、Gameタブで確認できます。

Sceneタブでは見れないので、気を付けてくださいね。

さて、ここまで作業が終わると、このような仕上がりになります。

うん、いいですね!電球は良い感じにボヤァっと光り、色合いがなんだかドラマチックに感じられます。
最後に、自分のアバターを置いて、どんなふうに自分が見えるかを確認してみましょう。

DirecrtionalLightや、PPSの設定がおかしいと、アバターの見え方が不自然だったりするかもしれません。自分の好みの見え方になるよう、調整を頑張ってみましょう。

天井から部屋全体を照らすPointLightの設定を「NoShadows」にしてBakeした場合はこちらのようになります。明るく清潔感のある仕上がりとなります。


VRChatのワールド制作ではあれば、VRCworldというPrefabをヒエラルキーに入れているでしょう。
PPSを設定したら、必ず、VRCworldの設定で、「Reference Camera」に、MainCameraを設定しましょう。これをしないと、VRChatで確認した時に、設定したはずのPPSが適用されていません。


Lightmapデータの圧縮

焼き付けたLightmapのデータは、そのままではファイルサイズが大きいです。このままでは、ワールドの容量が増えてしまいます。

シーン名のフォルダの中に、今回BakeしたLightmapのデータが保存されています。これらを複数選択します。

上の画像のように設定し、最後に「Apply」を押します。Crunch圧縮がかかるので、かなり軽くなります。その違いを確認してみてください。もっと軽くしたい場合は、「Max Size」をもっと下げると良いでしょう。

また、LightmapをBakeするということは、パフォーマンスが劇的に向上することでもあります。こちらの画像を確認しましょう。

LightmapをBakeする前の状態です。右上のSetPass callsが、1336と、とても高い数値になっています。これは、VRChatでいうところのFPSが10くらいのパフォーマンスです。これではとても居心地が良いとは言えません。

LightmapをBakeしたあとです。SetPass callsが、265まで下がっています。これであれば、VRChat上でも、70~90FPSが期待できます。陰影の具合も自然になっていますし、LightmapをBakeすることの重要さがわかると思います。


Unity2018から実装されたGPU Bakeを試す

Unity2018より、PCに搭載されたGPUを使ってLightmapをBake出来るようになりました。
これにより、Bake時間が大幅に短縮される場合がありますが、では、Bake結果はどうなのでしょうか。すべて試してみましたので、その仕上がりを見比べてみましょう。

GPUでBakeすると、やや色合いが濃い感じがしますね。
また、部屋全体を照らすPointLightを、SoftShadowsにしてGPUでBakeすると、ちょっと壁が汚すぎる感じになってしまいます。これはちょっと使えませんね。
少しアンティーク感のある洋館などを表現する時は、CPU BakeのSoftShadowsを。
現代的で清潔感のある部屋を作る時は、GPU BakeのNoShadowsを。
というふうに、シーンによって使い分けるのが良さそうですね。


今回省いた内容

今回、MeshBakerやBakeryの内容は省かせていただきました。というのも、VRChatでのUnityが2018となったため、Unityの標準機能として、GPUでBakeすることが可能になったため、Bakeryの必要性が薄れました。確かにBakeの結果は異なりますが、Unity標準のBakeでも十分に戦える状況にありますので、今このタイミングでBakeryを購入する必要性はあまりありません。

そしてMeshBakerについてですが、MeshBakerを通してまとめあげたMeshは、必ずしもLightmapが綺麗に焼けるとは限りません。焼ける時もありますが、残念な結果に終わる場合もあります。
MeshBakerを通す場合は、焼く予定の無い、光が及ばないオブジェクト、または、マテリアルでメタリックに振りまくっているものです。綺麗に焼けた時はラッキー!ぐらいな感じです。
やはり、正しくLightmapを確実に綺麗に焼きたい時は、そのモデルの作成の段階で、ある程度まとめあげてUnityにもってくる必要がある、ということです。


最後に

さて、長々とした記事となってしまいましたが、何か有力な情報はありましたでしょうか?
ここまで習得していれば、VRChatでライティングを駆使したワールドが作れることでしょう。
ぜひぜひたくさんの方に、まずは自分のHOMEワールドの作成をお奨めしたいところです。
覚えて、綺麗にBake出来れば、ライティング作業はとても楽しいものです。光があるだけで、味気ない3Dモデルもいっきに輝いて見えます。
なんでこの設定をするのか、みたいな、難しいことまでは考える必要はさほどありません。
この記事で紹介しているとおりに設定さえすれば、たいていのものはうまくLightmapがBake出来るはずです。ぜひぜひお試しくださいね。

それでは、長々とお付き合いいただきありがとうございました。
MinaFrancescaでした。