ライトベイクに挑戦する前に読むと良いかもしれない記事
今月のワールド製作者向け記事は、ライトベイクについてです。
ライトベイクについては基本的ではあるものの、覚えるべきところがかなりあるため、沢山の記事があります。そのためやり方を覚えるだけなら、それらの記事を参考にしつつ、なぞっていけば出来ます。
しかしながら、色々な設定項目が何を意味しているのかを理解するためには、根本的なところ……すなわちライトベイクとは何なのかを理解する必要があります。
この記事では、ライトベイクに挑戦する初心者の方が挫折しないように、『ライトベイク』について解説したいと思います。
前提知識:VRCの映像が出来るまで
まずは『VRCの映像が出来るまで』の話をかいつまんでしたいと思います。後々のライトベイクの話に関わってくるので、お付き合いください。
私たちは一般的に、デスクトップユーザーであればPCモニター越しに、VRであればHMDのレンズ越しにVRChatの映像を見ています。
テレビなどの映像の仕組みがパラパラ漫画……と知っている人は結構多いと思います。VRCのようなゲームでもそれは一緒です。
1秒間に数十回という速い速度で、画面上の絵が更新されることで、滑らかに動いているわけです。
そして、1秒間の映像が何枚の絵で構成されているかを示す単位が『FPS(frames per second)』になります。フレームレートとも呼ばれています(フレームは漫画とかで言う「コマ」を意味しますので、意訳すると「コマの更新速度」になります)
VRChat内でメニューを開くと、メニューの左上にFPSという数字がありますが、これがまさしくそうです。例えばFPSが90であれば、一秒間に90枚(=90フレーム)の絵が描かれ、更新されているわけです。
しかしながら、この値が低いと、動きがガクガクになる……というのを体感的に理解している人は多いと思います。そう、このFPSという値は固定の数字ではないのです。
FPSが低くなる状況、それは絵を作る処理、描画処理が何らかの理由で間に合っていない時です。
漫画や小説であれば〆切に間に合わなければ出版が遅れることがあると思いますが、ゲームでそれをやると一瞬真っ暗になってしまうという事故状態になってしまいます。
ですので、途中のコマを抜くように、絵の更新間隔を自動で下げることで対応する必要があります。つまり、FPSが下がるということです。
そして、「フレームレート(FPS)が下がる」ということは、「1秒間を構成する絵の枚数が少なくなる」ということになりますので、途中のコマが抜けた漫画状態になり、動きがカクカクする……というわけです。
また絵を表示する側のHMDやモニターにも、画面の更新速度があり、こちらはリフレッシュレートと呼ばれています。こちらは単位がHz(ヘルツ)になっていますが、FPSと似ていて90Hzであれば、1秒間に90枚更新されます。
大体のHMDでは設定から変更可能ですが、Quest2では72Hz、Valve indexなどでは90Hzが初期設定となっているはずです。デスクトップであればモニターの更新速度がそのままリフレッシュレートになります。
仮にPCのスペック的に余裕があって、1秒間に200枚くらい絵を描けるとしましょう(つまり200FPSということです)
しかし、絵を表示する側が50Hzだとすると、FPSは50しか出ません。つまり絵を表示する側の性能に、足を引っ張られてしまっている形ですね。
このような形でFPSには上限が付くこともあります。
(ゲーム側でFPSの上限を設けることもありますが)
話が長くなってきたので、一旦まとめると
『VRChatのようなゲームでは一秒間に数十枚という絵が作られ、更新されている』
ということを頭に入れておいてください。
ライトベイクのいいところ
現実世界であれば、光源と、光に照らされた物体があれば、当然ながら明るくなるところと、影になって暗くなるところがありますよね?
Unityではライトコンポーネントのついたゲームオブジェクトを置くことで、光源を作ることが出来ます。
ですが、ちょっと考えてみてください。
光と影をシミュレートするのは果たして簡単なことなのでしょうか?
例えば自分の部屋をUnity上で再現したかったとしましょう。
部屋の中には色々な光を放つものがありますよね?窓から差し込む太陽光、天井の照明、パソコンのモニターや各種LEDランプなどなど、実に色々な光源があります。
またそれらの照明は部屋の中にある沢山の物体によって反射されたり、物陰に回折して回り込んでいったりします。
この状態で、
『はい、これら全ての光と影を計算してください……目標は1秒間に90回。ええ、90FPS出てほしければ、一秒間に90枚分の絵が必要になりますから』
と言われれば、まぁ途轍もない計算量になることを想像してもらえたと思います。当然、オブジェクト・光源の数が多ければ多いほど、負荷は増大します。
負荷が上がるほど、FPSは下がっていき、ガクガクしますので、皆さんの快適なVRChatワールドとは程遠くなっていくわけです。
まともにはやっていられないので、何とかするための工夫が必要になります。
ここで、ようやっと『ライトベイク』の考え方が出てきます。
その内容を端的に言うと以下の通りです。
『静止している光源については、光と影が動くことはない。だから、事前に計算をして、その結果を保存しておけばいい。絵をかくときに、その計算結果を呼び出して、光と影をつけてしまおう!』
実に賢い考え方ですよね。計算結果については、ライトマップと呼ばれるテクスチャ(=画像)で保存されます。
『ライトベイク』、直訳するなら「照明を焼く」ですが、要は光と影を画像として焼き付けているわけです。これにより沢山の計算が省略されます。
Unityではこの『ライトベイク』のための機能が用意されていて、誰にでも『ライトベイク』が出来ます。いや~、お手軽でいいですね…………。
とはならずに、多くの人が『ライトベイク』で挫折します。
「綺麗に焼けない」「そもそも影が出ない」「謎の線が出る」などなど……、色々な悲鳴をよく聞きますし、それを解決するのにひどく苦労している様子を見かけます。
原因は何でしょう?
『ライトベイク』の結果に影響する要素が多すぎるから、と答える人も居ると思います。
私もそれには頷くところはあるのですが、もっと根本的なところかなと考えていて、
「影響する各要素の関連性が見えていないから」
だと思っています。
「このパラメータを触ると、どうなるのか」
「なぜこれが必要なのか」
「どういう仕組みなのか」
といった関係性を理解できてないまま、やり方のみを知っている。
それでは、失敗した原因を探し出すことは、当然難しいですよね?
そこで、今回の記事では『ライトベイク』という行為の裏側で、何が起こっているのかを解説していきたいと思います。
ライトマップが出来るまで
『ライトベイク』をすると、その結果がライトマップと呼ばれる画像として焼き付けられることはお話ししたと思います。
この章では、このライトマップが作られるまでに何が行われているのか、について順を追って説明したい……のですが、その前に事前知識が必要になるので、ちょっと別のお話をします。
みなさんが知っているアバターには、テクスチャ(=画像)が貼り付けられていることはご存知ですか?
肌や服の色や模様、質感などがテクスチャで表現されていますので、仮にテクスチャが無いとただの白い人形のようになってしまうわけです。現実世界の粘土で出来た人形みたいに、直接色を塗っているわけではありません。
ところで、画像は2D(平面)で、モデルは3D(立体)ですよね?
どうやって平面を立体のものに対応付けているのでしょう?
実は、UVと呼ばれる3Dのモデルを平面に展開した、要は展開図のようなものが用意されています。その展開図に対して、画像を重ねているわけです。
小学校の図工の時間などに、サイコロを作った経験がある方は多いと思います。サイコロの展開図でいうと、以下のような感じのものを目にしたことがあると思いますが、これもある意味UV図といえるかもしれません。
ちなみになぜUVという名前なのかについては、このUVというのは数学でいうXYと同じでただの座標軸です。UV展開図は、とどのつまり横軸U軸と縦軸V軸がある図で、基本的にはこの0~1の領域に展開図が作られてるものです。
このUV座標が3Dモデルの各頂点に格納されていることで、『3Dモデルのこの頂点は、平面画像上のここに来るよ!』という対応付けが出来るわけです。
ここまでの話でピンと来てない方は以下の記事を読むと良いと思います。UVについてイラスト付きで解説されていて、非常に分かりやすくてお勧めです。
一旦まとめると、
『2Dのテクスチャを3Dのモデルに対応付けるために、UVというものがある』
というのを頭に入れておいてください。
その上でライトマップの話に戻ります。
先ほど、『ライトマップはテクスチャとして保存される』というお話をしたと思います。
ライトマップも当然ながらただのテクスチャですので、3Dモデルに対応するためにはUVが必要になります。そのためのUVはライトマップを作る時に同時に作られる特別製のものになります。
(注意:より正確には、特別製なUVがあるというのは間違っており、ライトマップ用の特別な管理システムがあるだけです。ですが、同じような働きをしていることには間違いないので、理解しやすさを優先しています)
何が特別製かというと、1枚のライトマップで複数の3Dモデルを担当するために、複数の3DモデルからUVを集めてきて、ライトマップを作ります。
つまり1枚のライトマップの中には、複数のオブジェクトの光と影の計算結果が詰め込まれています。これにより、沢山のオブジェクトがあってもライトマップの枚数は少なくて済みます。
ただし、ここからが重要なのですが、この時に収集されてくるUVは、Unity上ではUV2と呼ばれる2枚目のUVになります。
なぜ1枚目のUVを流用できないのかというと、色々付随して説明する必要が出てくるので、まず先にライトマップが作られるまでの流れを説明したうえで、次の章で説明させていただきます。
とはいえ、ここに対する公式の解説はないため、あくまで私が『こういうことをやっているんだろうな』と推測しているにすぎないので、間違っている可能性はご了承ください。
簡単に説明すると、以下のような流れになっていると推測しています。
①Staticフラグが付けられているオブジェクト群からUV2の情報を集めてくる
②集めてきたUV2を敷き詰めることで、ライトマップ用のUVを作成する。
③最終的に出来上がったライトマップ用UVを元に、ライトマップを計算・生成する。
この3つの工程を見てもらえば分かると思いますが、UV2というものが必須であることが分かっていただけると思います。
しかしながら、この3つの工程はUnity上では[Bake]と書かれたボタンを一つポチっと押すだけで行われますので、ライトベイクに初めて挑戦する人には一切分かりません。
だから、何故UV2が必要なのか理解できないままのことが多いです。
逆にUV2が必要なことを分かっていれば、
『もしかして上手く焼けなかったのはUV2がないのでは!』
と、気が付くことが出来ます。
この記事を読んだ方々には
『ライトマップ用UV(正確にはUVのようなもの)を作るのに、UV2というものが必要』
ということを覚えていってほしいです。
UV2に求められている制約について
UV2は、普通のテクスチャ用である一枚目のUVと比較して、特殊な制約を求められます。
(だからこそ、別枠の2枚目になっていると思ってもらっても大丈夫です)
それは主に以下の3つです。
・UV展開図に重なりが無いこと。
・UV展開図の展開されたパーツ間に十分な隙間があること。
・UV展開図が0~1に収まっていること。
これらの制約が求められる大きな理由は、先ほど説明した工程②の『集めてきたUV2を敷き詰めることで、ライトマップ用のUVを作成する』にあります。
ではなるべく分かりやすく説明していきます。
1つ目の性質『UV展開図に重なりが無いこと』についてですが、これは比較的シンプルです。重なった場所があると、そこに光と影の計算結果が2重に保存されてしまうのでおかしくなってしまうということです。
ちなみに1枚目のUVは、仮に重なっていたとしても同じ模様が複数の場所で使われるだけなので、重なっていても問題はありません。1枚目のUVと違い、計算結果を保存するという特殊な使い方をしているUV2ならではの話ということですね。
2つ目の性質『UV展開図の展開されたパーツ間に十分な隙間があること』についてですが、これについては絵の具と紙のキャンパスを想像してもらうと良いかもしれません。
水に溶けた絵の具をたっぷり含んだ筆先を、キャンパスに載せると色がにじんで、広がっていきますよね?一般的には、キャンバスは一枚なので気にする必要はありません。
ですが、今回はUV2を敷き詰めている……つまり複数のキャンバスが隣り合って繋がっている状態です。
そんな中、たまたま真っ暗な絵と明るい絵が隣り合ってしまったら?
絵の具がにじんでいき、真っ暗な絵の中に明るいところが出来たり、その逆が起きたりしてしまいますよね?
簡単には、同じようなことが起きていると思ってもらって大丈夫です。それを回避するために隙間(Paddingと呼ばれます)を用意する必要があります。
3つ目の性質『UV展開図が0~1に収まっていること』は、上でしたキャンバスの話になぞらえると、キャンバスの外にはみ出て絵が描かれている状態と言えるでしょう。
したがってUV2を集めて、一つの地続きのキャンバスを作る時に困ってしまうわけです。
以上、3つの性質を満たしていないと、そもそもベイクできなかったり、計算結果がおかしくなったりします。
なので、上手くいかない時に、UV2が正しいかどうかを確認することも非常に大事なことになります。
さて、怒涛のように解説されて、疲れましたでしょう?
書いてる私も疲れてきました(笑)
残念ながら、もうしばらく記事は続きますので、一息入れてもらえればと思います。
もう大丈夫ですか?では続きに参りましょう。
ここまで、ライトマップにおけるUV2の重要性についてお話してきましたが、そもそも3DモデルにUV2がない場合というのもあります。
そう、ライトベイクさえしなければ、UV2はなくてもいいんです。
UV2はただのデータですので、UV2があることによって3Dモデルのデータ容量は増加します。つまり、ライトベイクしないのであれば無いほうが、容量的には軽い、ということになります。
UV2を制作するかどうかは3Dモデル製作者に委ねられていますので、購入しようとしている3DモデルにUV2があるかどうかは、販売ページに書かれてなければ、購入前には分かりません。
では、Unity上で3DモデルにUV2があるかどうかを確認する方法を教えます。
まず確認したいオブジェクトのメッシュデータを探してください。MeshRendererと一緒にあるMeshfilterのところにあるアイテムをクリックするのが分かりやすいと思います。
クリックすると基本的には以下の画像のように、一つのアイテムから中身が展開されているようなものが表示されるはずです。このアイテムはFBXと呼ばれる3Dモデルの保存形式の一つです。
Unityの3Dモデルは、大体がFBX形式で取り扱われています。FBXを構成するパーツの一つとしてメッシュ(=形状)データがあります。大体後ろ側にあります
メッシュデータを選択すると、右下にプレビューが表示されます。もしかしたら折りたたまれていることもあるので、その場合は広げてみてください。
そこを見ると以下のようにメッシュのプレビューと、メッシュに格納されている色んな情報について書かれています。UV2は格納されているとuv2と表記されていますので、これによってUV2があるかを確認できます。
ちなみにないと以下のように、uv2という表記がないです。
余談ですが、私はUV2がどんな形で展開されているかも確認したいので、Unityアセットストアの有料アセット『UV inspector』を利用しています。約5.5ドルです。新しいバージョンのUnityだと標準機能でついているので、購入する必要はないかもしれません。
さて、これでUV2の有無が確認できるわけですが、問題はUV2がない場合ですよね?ライトベイクが出来ないわけですから。
『えっ!? じゃあBlenderとかのモデリングツールで、UV2作らないといけないってコト!?』
と思った方、ご安心を。
それについては、Unityがある程度救いの手を用意してくれています。
FBXを選択した時に、modelタブの一番下辺りにgenerate lightmap uvsという項目があります。
これにチェックを入れることで、UV1(1枚目のUVの別名)の情報をもとにUnityがUV2を自動生成してくれます。ですがここにいくつか罠があります。
まずUV2が既にある場合にこの項目をオンにすると、Unityが自動展開したUV2で上書きされます。折角綺麗に作られたUV2が既にある場合は、オフのままにしましょう。
次にUV1の情報をもとに……という点がなかなか危険です。つまりUV1が滅茶滅茶な状態だと、UV2も滅茶滅茶になる可能性があります。UV1の状態によっては、上手くUV2が自動生成されない可能性があることを覚えておいてください。
(大体は何とかなるのですが、下手すると、項目をオンにしてApply押してから全然終わらないこととかあります)
あと、曲線が多いモデルは基本的に、細切れになって敷き詰められた残念なUV2が生成されます。
ちょっとこれについては詳しく説明します。
まず、事前知識として、UV全般の話ですが、3Dモデルのポリゴンに沿っていれば、どこにでも切れ目を入れて展開することが出来ます。ただし、変な切れ目の入れ方をすると、先ほどUV2の制約の時に説明した色にじみを誘発しやすいです。
なので、自然とUV2の展開図というのは、基本的に整列された綺麗な状態になる傾向にある気がします(これは私の所感にすぎませんが)
ところが、generate lightmap uvsは、細切れにしてとにかく詰め込むような感じの展開をします。試しに上の綺麗なUVのモデルで、Generate Lightmap uvsを押してみるとこんな感じです。
基本的にこのように細切れにされます。UV1やモデル形状にもよる気がしますが、曲線が多いモデルは大体がこんな感じです。悲しいですね。
「いやいや、それはパラメータの調整ができてないだけだよ!」
とおっしゃる方がいるかもしれませんが、今回の私の検証ではそのパラメータ、ほとんど仕事をしていなさそうです。過去の実体験でもいい仕事をした覚えがありません。
とはいえ、この話は脱線するので、この下らへんにあとで検証用の別記事を作って貼っておきます。興味があったら読んでみてください。
2023/12/13 追記:遅くなりましたが、記事を仕上げました。簡単に結論を言うとパラメータの調整で良い結果を得られるパターンもありそうです……がUnityのリファレンスにあるパラメータの説明と結果があまり一致してない感じなので、仕事してない印象があったみたいです。
Unity2022での移行でパラメータが増えて、そのパラメータがかなり罠っぽいので、Unity2022で作った新プロジェクトでGenerating Lightmap UVsを利用する場合は読んでおいたほうが良いと思います。
ということで、generate lightmap uvsは最低限ベイク出来る状態を作ってくれますが、品質までは保証されませんので気を付けましょう。
とはいえ、救いがないわけではなく、十分なライトマップの解像度さえ確保できれば綺麗に焼けるはずです。次の章で詳しく説明します。
ライトマップの解像度について
さて、大分お疲れかと思いますが、この話で最後になりますので、もう少し頑張ってください。
みなさんは画像や動画に解像度というものがあることはご存じだと思います。最近だと4Kとか8Kとかよく言うあれです。
そして解像度が高いほど、鮮明に見えることも体験上分かっていると思います。
ライトマップも画像ですので、当然ながら解像度があります。
ですが、一般的な画像に比べて、より解像度に気を使う必要があります。
なぜなら、ライトマップ一枚の中には沢山のUV2が敷き詰められているからです。ライトマップの解像度が低くなると、各UV2の解像度も自然と低くなるということです。
仮に、解像度が低かったらどうなるでしょうか?
当然ながら、不鮮明になりますので、光と影がぼかされて、なんだかよく分からない状態になってしまうでしょう。そして、ライトベイク初心者の目から見たときに『何か上手くいかなかった』結果だけが残ります。
以下はちょっと前に別の記事用に作成した3枚のライトベイク例で、下に行くほど解像度を高くしています。
解像度をキチンと確保することによって、これだけ結果が異なります。
では、解像度を確保するにはどうしたらいいでしょうか?方法は大きく分けて3つあります。
①ライトマップ自体の解像度を上げる
シンプルにはライトマップ自体のサイズを大きくしてしまうのが、まず一つの手になるでしょう。ただしその分ライトマップの容量は大きくなってしまいます。
Unityでは「Lightmap Resolution」と表記されているパラメータです……がUnityのデフォルトの値は既にかなり大きいです。合わせて「Lightmap Size」を1024→4096にすると、ライトマップが4Kサイズになってくれます。
②各モデルごとに割り当てられるUV2の領域を変える
他には、各UV2ごとに、敷き詰められる時のサイズを変えることもできます。MeshRendererにあるScale in Lightmapという項目がそうです。
(補足:ベイクする前には隠れていて、Contributed Global Illuminatorという項目にチェックを入れるか、Staticフラグにチェックを入れると出てきます)
一般的にはオブジェクトの大きさに比例して、敷き詰める時の初期サイズは大きく割り当てられます(上限有り)。それに対してこのScale in Lightmapというパラメータが掛け合わされて、最終的な領域が決まります。
重要ではないオブジェクトの割り当て領域を小さくして、重要なオブジェクトに領域を割くなどの工夫をすれば、容量を節約しながら綺麗に見せることも可能です。
③UV2を作り直して、再展開する
そして最後に、Blender等のモデリングソフトでUV2を展開・編集するという手もあります。これは各モデルのUV2に対して行います。
ようはUV2の中における面積が大きければ、解像度が大きくなりますので、そうなるようにUV2を作り直すことで綺麗にベイクすることが出来ます。
ただし、UV2の制約のところで書いたように、ある程度隙間が必要になりますので、最低限の隙間は確保しつつ、最大限敷き詰めるのがUV2の基本方針になります。
また自分で作ることによって、プレイヤーの目にあまり触れない部分のUV2は小さく作り、重要な部分の面積は大きく取る……といったコントロールも可能になります。
既存のモデルのUV2を編集するだけだと考えれば、1からモデリングするのと比較して、ハードルはかなり下がりますが、Unityと別ソフトで3Dモデルをやり取りする必要があるのが難しいところです。
ですが、私は綺麗に焼けなくて困ったときはこれをしています。
Unityのgenerate lightmap uvsと比較すると、遥かに綺麗になり、容量も節約できますので、余裕があればぜひ試してみてください。
Blenderであれば、有料アドオンとかで自動展開用のツールがいくつかありますので、そういうものを導入すると簡単に展開出来て楽かもしれません。
(筆者はHoudiniという別ツールを使用しているので、詳しくありませんが)
VketのページでBlenderでの作り方について解説しているページがあったので貼っておきます(UV画面上での編集のやり方については『いつも通りにUVを展開するだけ』と割愛されているので、別途調べる必要があるかもしれません)
以上3つがライトマップの解像度問題を解決する方法になります。モデリングツールの使用経験が無い方は①か②の方法になりますが、③が出来るようになるとUV2絡みの問題からは解放されます。
ここでのまとめとしては
『ライトマップの解像度をしっかりと確保することが重要』
です。
まとめ
さて、最後にまとめておきましょう。
『VRChatのようなゲームでは一秒間に数十枚という絵が作られ、更新されていて』、その絵を作成するときの、光と影の計算を省略するために「ライトベイク」という技術があります。
ライトベイクの結果はライトマップに保存されますが、ライトマップは2Dの画像なため、3Dのモデル達に対応付ける必要があります。
『2Dのテクスチャを3Dのモデルに対応付けるために、UVというものがあり』、ライトベイクの時にライトマップ用の特製UVが作られます。
『ライトマップ用UV(正確にはUVのようなもの)を作るのに、UV2というものが必要』になるため、各3DモデルにはUV2を用意する必要があります。
またライトベイクの結果はライトマップの解像度に依存しているため、『ライトマップの解像度をしっかりと確保することが重要』です。
おわりに
以上、長い長いライトベイクの話でした。大変お疲れ様でした。
一般的なライトベイクの記事では、
『とりあえずやってみましょう!』
の精神で、やり方メインで書いている記事が非常に多いです。
まぁ上のような文章を書いて、それにプラスしてやり方まで、みたいな記事があったら、とんでもない長さの記事になってしまいますからね……。
ですが、どうでしょう?
この記事を読む前までは
『ライトベイク ≒ 得体のしれないもの』
だったのが、少し親しみやすくなったのではないでしょうか?
もしそう感じて頂けたのであれば、頑張って書いた甲斐があります。
恐らく、実際にライトベイクに挑戦すると色々な躓きがあると思います。
その時は、この記事を見返して、ライトベイクってどんなやつだったっけ?と思い出していただければ幸いです。
ではここまで読み終えたあなたの辛抱強さに敬意を表して、この文章を締めさせていただきます。
長文の読了、お疲れ様でした。
2023/10/29追記:発展編を執筆しました↓
おまけ
・ベイクのエラー原因を探してくれるツール
・オススメ記事
この記事が気に入ったらサポートをしてみませんか?