見出し画像

ライトベイクに慣れてきたころに読むと良いかもしれない記事

(2023/11/01追記 裏面ポリゴンの話と無効テクセルの話を追加)
(2024/06/13追加 Bakeryの罠、SkyLightについての部分に、Environment Lightingが標準ライトベイクシステムの結果に加算された状態で無効化される話を追加)

はじめに

前回、ライトベイク初心者向けの記事を書きましたが、今月のワールド製作者向け記事では、引き続きライトベイクの話をします。

今回はライトベイクの手順に既に慣れた人を対象にしていますので、基本的な用語説明などはあまりありません。

今回はよく引っかかりがちな罠の話や、知ってると知らないとで最終的な品質や容量に影響してくる話などの、小技を中心にお話ししたいと思います。

前半は共通の話、後半はBakeryに限定した話になります。
それでは参りましょう。

(追記:この記事はUnity2019での検証内容ですので、Unity2022になって変わっているところがあるかもしれません。もし変わってるところがあればコメント等で教えて頂ければ、検証・修正します)

ライトマップのテクスチャ設定

前回のライトベイクの記事で、ライトマップはテクスチャだというお話をしました。

Unityのテクスチャは、容量を減らすために圧縮を行う初期設定となっています。しかしながら、データの圧縮というのは基本的には何かを犠牲にして、容量を削減しているケースが大半です。そして、時には圧縮時にノイズのような模様が発生してしまうことがあります。

突然ですが、『ライトベイクされた、テクスチャのない白いワールド』を作ったり、見に行ったりしたことはありますか?

そこで、このような色のついた沁みを見たことはないでしょうか?

これ、実は『ライトマップの圧縮によって発生したノイズ』らしいです。
(私は、このようなノイズになるまでの流れが頭の中で整理できていないので、ふわっとした言い方になりますが)
意図的にライトマップを非圧縮の形式にすることで、このノイズが消えてくれます。

テクスチャの圧縮形式は、テクスチャを選択した時に一番下に出てくる項目で出来ますが、タブを切り替える必要があります。PCとandroid(つまりQuest)用の設定があるので、必要に応じてチェックを入れて、設定を上書きします。

私は「RGB9e5 32 Bit Shared Exponent Float」を選択することが大半ですが、色々試して比較検討してみるのも良いと思いますが、そもそもライトマップ向けのHDRのテクスチャ形式がほぼないので、これ一択な気がします。

当然ながら非圧縮にするとデータ容量は大きくなってしまいますので、トレードオフしてでも綺麗さを優先したい場合の選択肢ではあります。

例えば、私が良く使ってる形式だとデフォルト設定(BC6H)の4倍の容量になるので、例えば4Kのライトマップだと1枚で64MBになってしまいます。気を付けましょう。

個人的にたまにやるのが、綺麗に見せたい部分だけ1枚のライトマップに格納し、そのライトマップの形式だけ、非圧縮のものにして、それ以外の重要でないものはデフォルトの形式にするという手法です。

ライトマップを指定してまとめる機能としては、Unity標準ならSystemtagやBakedtag、BakeryならBakeryLightmapGroupがあります。
(しかしながら、Unity標準の方は完璧に制御するのが難しいらしいというのを聞いたことがあります。試したことはないです)

(2023/10/30 追記 WhiteFlareさんから『BC6Hのブロックが4x4なのでPaddingを8にすれば隣接アイランド間の色の混合を抑えられるはず』という貴重な情報を貰いました。

標準ライトマッパーではLightmap Paddingという項目があり、そこでPaddingを調節すればこの色付きのノイズを消せるかもしれません。

問題はBakaryを使ってベイクする場合です。Paddingの調整方法がないか探したのですが、数値を指定できるような場所はなさそうでした。

したがってBakeryでは、Asset UV ProcessingをDon't Changeにして、以下の二つの方法のいずれかでPaddingを調整するしかなさそうです。
・自作でUV2を制作している場合は展開中にPaddingを大きめに取る
・UnityのGenarate Lightmap uvsを利用している場合はPack Marginを大きく設定する

もしBakeryのPaddingの調整方法に心当たりがあって、教えてもいいよって方は是非コメントください)

自身にライトベイクせず、他オブジェクトに影を落としたい時

MeshRendererで、Staticフラグにチェックを入れている時に出てくる、Scale in Lightmapの値を0にすることで、この状況にできます。

これにより、ライトマップに自身の影の影響を出しつつ、自分はライトベイクされないので、ライトマップ容量を節約し、余った部分で他のオブジェクトのライトマップUVを大きくして綺麗に焼いたりすることができます。
ライトベイクの影響を受けにくいオブジェクト(例えば金属など)に対して、この手法を使うと良いです。

他のテクニックとしては、凹凸の少ない(=陰影がなく、明るさが一定な)オブジェクトに対して、Scale in Lightmapの値を0にした状態で、自分自身の明るさをLightProbeで確保することで、疑似的にライトベイクしたかのように見せることです。

Unity2019になってからは、Recieve Global Illuminationという項目でLightProbeを選択すると同様の挙動が出来るようになりましたが、Bakeryはこれを考慮してくれないらしいです(未検証)

また別の注意点としては、Mixed Lightを利用している場合は問題が起こることがあるようです。詳しくは黒鳥さんの記事を読むと良いです。

ライトベイクは軽い?Static batchingについて

ワールド制作に手慣れてきた人の中には、
『よし、広いワールドを作ってみよう!』
と決意して、チャレンジする人が一定数居ると思います。

『ライトベイクすれば、軽くなるからヨシッ!』
と思って、大量のオブジェクトをベイクした結果、数百MB単位でワールド容量が激増し、宇宙猫のような顔をしたクリエイターも居ることでしょう。
少なくとも昔の私はそうでした。

どうしてこういうことが起きるのか?

それを説明するには、Static batchingについて語る必要があります。

ライトベイクをする時、ゲームオブジェクトのStaticフラグにチェックを入れると思いますが、その右側の下三角形を押すと下のようにドロップダウンが表示されます。真ん中あたりにBatching Staticという項目があるのが分かると思います。

これにチェックを入れて、ライトベイクを実行するとStatic batchingが有効化されます。

なので、よく「ライトベイク」をすると軽くなると捉える人が多いですが、正確にはこのStatic batchingのおかげである部分もあります。前回説明したようなライトベイクの働きは同じ欄にあるContributed GIという項目のほうです。

Static batchingはゲーム中に自動でメッシュを結合してくれる機能です。メッシュが結合されると描画命令の回数が減って、その分軽くなります。

しかしながら、UnityのStatic batchingのリファレンスページの最後にも書かれていますが、同一の3Dモデルであっても複製されたメッシュで結合します。

(DeepLにより翻訳) スタティックバッチングを使用すると、結合されたジオメトリを保存するために追加のCPUメモリが必要になります。複数のGameObjectが同じメッシュを使用する場合、UnityはGameObjectごとにメッシュのコピーを作成し、それぞれのコピーを結合メッシュに挿入します。つまり、同じジオメトリが複数回結合メッシュに表示されます。Unityは、GameObjectをスタティックバッチ処理するために準備するためにエディタまたはランタイムAPIのどちらを使用しても、これを行います。メモリフットプリントを小さくしたい場合は、レンダリングパフォーマンスを犠牲にして、いくつかのGameObjectのスタティックバッチ処理を避ける必要があるかもしれません。たとえば、密林環境で樹木を静的にマークすると、メモリに深刻な影響を与える可能性があります。

https://docs.unity3d.com/ja/2021.3/Manual/static-batching.html

この場所の記述では、結合メッシュデータはCPUメモリ上に格納されるという記述になっています。なのでゲーム中に結合されたメッシュがCPUメモリ上に乗るだけ……のように思えます。

ですが、私の認識上ではそれだけではなく、アップロード時のワールドデータにも、そのメッシュ情報(あるいはそれ以外の何か)が格納されています。

これについての記述はリファレンスどころか、ネット上にも『ライトベイクをやめると容量が減る』くらいの情報しかない超絶ニッチな情報ですが、以前私が実験を行って確認しました。
(見つけられないのは、私の探し方が悪いのかもしれませんが)

今回も、実際に検証してみましょう。

まず約3000ポリゴン程度の球をモデリングしました。何故3000ポリゴンかというと、経験上これくらいのオブジェクトが沢山ある時にベイクすると容量が爆発するからです。

等間隔に百個ほど並べて、まずはベイクしない状態でアップロードして、その時のアップロード容量の内訳を確認してみましょう。

アップロード容量の内訳はVRWorld Toolkit……ではなく、エディターログを確認します。何故ならVRWorld Toolkit自体はこのエディターログのデータを簡易表示してるにすぎず、肝心なstatic batchingで増えている容量というのはこの簡易表示には乗ってません。

エディターログはConsoleのタブ上で右クリックして、Open Editor Logで見ることが出来ます。

さて、エディターログ上では以下のようにアップロード容量の内訳が表示されます。
まずはベイク前の容量です。

次にベイク後の容量です。

比較して何が増えているでしょうか?
Textureはいいですよね?ライトマップ分の容量が増えてますから。
何故かMeshesが0kbになってます。そして一方でLevelsが約7MBも増えています。

仮に重複してメッシュが保存されているとしたら69.4KB×100 = 6940KB ≒ 7MBとみることが出来ます。

このことから重複問わず、複製されたメッシュデータがLevelsに保存されていることが推測できます。代わりにMeshesは0kbになっているものの、増えた量のほうが多いです。

ではbatching Staticのチェックを外して、ベイクをしてみましょう。

御覧の通りLevelsの値はほぼベイク前の値に戻りました。またMeshesも元通りになっています。

以上のことから、私はこの保存されている容量というのが、結合されたメッシュだと思っています……が、きちんとしたリファレンスが無いのであくまで推測止まりです。

ですが、Static batchingによって、容量が増えていることはこれで実証できたと思います。

ちなみにこの容量はベイクする・しないに関わらずbatching staticにチェックが入っているだけでこの容量は増えるようです(検証中に気が付きました)
なので必要が無いのであればbatching staticのチェックは外したほうが良いかもしれません。

ちなみにこの話を聞いて
『Quest対応する気ないし、いくらでも容量増えてもいいから、軽量化は全部Static batchingでいいでしょ!』
って思っている人も居るかもしれません。

小さいワールドならそれでいいかもですが、Unityリファレンスで触れられているようにCPUメモリ上にStatic batchingのメッシュ分のデータが乗るので、それを考えるとCPUメモリが少ないユーザーに何かしらの悪影響はあるかもしれません。
(余談:よく考えるとこのことに気が付いたワールドで、突然映像だけ同期されなくなって、喋れはするけど映像だけフリーズする状態になることがあったのですが、何か関係あるかもですね)

さて、以上を踏まえて、私なりの『広いワールドを作るにはどうしたらいいか』というお話を少ししましょう。

私がお勧めしているのは
『同じメッシュ・マテリアルのオブジェクトはGPU Instancingを使うこと』
をなるべく優先し、その上で
『一つしかないユニークなオブジェクトにだけStatic batchingを使うこと』
です。

GPU Instancingは同じメッシュ・マテリアルの時に、同じオブジェクトを使い回してくれる機能です。それによって同じオブジェクトであれば描画命令がオブジェクト1個分で済みます。

Static batchingと同時に使おうとするとStatic batchingのほうが優先されるので二者択一の機能です。

またGPU Instancingは条件次第(Reflection ProbeやLight Probeの影響下など。詳しくはUnityリファレンス参照)では機能しなくなることもありますが、基本的には簡単かつ超強力な機能です。積極的に使っていくといいでしょう。

GPU Instancingしたからといってライトベイクが出来ないわけではありません、Contributed GIにチェックマークを入れ、Batching Staticのチェックを外した状態でベイクすればOKです。

あとはワールドの構造次第ではありますが、オクルージョンカリングを上手く使って、遮蔽されているものの描画を省いていくことで、かなり負荷を抑えられるはずです。

大雑把な指針としてはこんな感じになりますが、時折聞かれる程度に需要があると思うので、そのうち『大規模なワールドの作り方』的な記事をそのうち書こうと思います。

余談が長くなってしまいましたが、Static Batchingの利用には気を付けましょうという話でした。

ライトベイクに非対応のShader

これについてはタイトル通りですが、ライトベイクに非対応なシェーダーが存在します。

アバター向けのシェーダーは一部を除いて非対応なので、注意が必要です。

また対応しているShaderでも、作者さんによりますがワールド向けのシェーダーを別途用意していたり、以下の画像のようにオプションを有効化しないとライトベイクできなかったりと、色々注意が必要です。

liltoonの場合、"ライトマップを使用"オプションがあります

ライトベイクに対応しているシェーダーとしては、StandardシェーダーやAutodeskシェーダーなどは間違いないです。そのほかでワールド製作者の中でいうと、Boothで配布されているFillamented ShaderやGithubで公開されているmochie shaderなどは人気があるように思えます。

シェーダーについて、あまり詳しく知らない人向けにちょっと説明すると、シェーダーはマテリアルに割り当てて使う、オブジェクトの見え方を決めるためのプログラムです。

シェーダーはプログラムですので、中で定められていない処理はできません。

そしてその処理の一つに、ライトベイク用の処理も存在します。つまり、ライトベイクに対応していないシェーダーというのは、その処理がないシェーダーなのです。

無駄な処理があればあるほど、当然ですが重たくなるので、特定の目的に特化したShaderも結構あります。例えば水面用のシェーダーにライトベイク機能は不要ですよね?

VRChatが用意してくれてるシェーダーも、ワールド用プロジェクトを作成するとインポートされていて、そのシェーダーの中にもライトマップに対応したQuest向けシェーダーが存在しています(Bumped DefuseとかStandard Lite辺りがベイクできます)

ですが、結論的に言えば、良く分からなければStandardシェーダーを使っても問題ありません。ワールドではQuestでもシェーダーの制限はないので、Standardでも大丈夫です。

一度bakeしたライトについて

RealtimeライトをBakedに切り替えて、ライトベイクを行うと、もう一度Realtimeにしてもすぐには戻りません。一度Realtimeに戻した状態でライトベイクする必要があります。

これは私見ですが、ライトベイク周りは『ライトベイクを実行する』という行為を行わない限り、切り替わらないものが多い気がします。つまり、項目を切り替えた瞬間反映してくれるものが少ないということです。

状態を切り替えたはずなのに反映されない場合は、一度その状態でライトベイクを挟むと良いでしょう。それで直るはずですが、それでも戻らない場合はそのゲームオブジェクトを一度作り直すのが最終手段です。

DirectionalLightmapについて

ワールド向けのシェーダーでは凹凸情報をノーマルマップ(法線マップ)という画像で表現しているものが多いです。この凹凸情報と光の向きの二つの情報によって、光と影が計算されています。

リアルタイムライトでは、きちんと向きがある光ですので、凹凸情報が考慮されたうえで、光と影ができます。

リアルタイムライト使用

ところがライトベイクでは、ノーマルマップの凹凸情報は考慮されないため、折角のノーマルマップ情報が無駄になってしまいます。

ライトベイク結果(Directional Mode = Non Directional)

そこで、ノーマルマップを考慮したライトマップを生成するモードとして、Directional Modeというものが用意されています。これをDirectionalに指定することで、ノーマルマップの凹凸情報を保持することが出来ます。

ライトベイク結果(Directional Mode = Directional)

しかしながら、追加の情報を保持するためにライトマップと同じ容量の画像が一枚増えてしまい、シェーダーの処理もその分重くなってしまうというデメリットもあります。

左が追加の画像データ

したがって使いどころを見極める必要はありますが、クオリティに直結するかなり重要な機能です。

Unityの標準ライトベイクシステムではデフォルトでオンになっているようですので、気を付けるべきはBakeryを利用している人でしょう。ウィンドウの上から3つ目にあります(Settings mode = Experimental)

Bakeryのほうは選択肢が多く、なんと5つもありますが、お手軽に試せるのは『Baked Normal Maps』か『Dominant Direction』の二つくらいです。
前者は追加テクスチャを生成せずに行う代わりにデメリットがいくつかあるタイプ、後者はUnity標準で行われてるDirectional Modeと似ているものです。どちらもシェーダーを気にせず利用できます。

『RNM』や『SH』は非常に高品質な結果が得られますが、対応したShaderが必要であり、またライトマップ1枚当たり、3~4枚の追加テクスチャを生成・使用するため、負荷・容量ともに高いです。
またMaterialPropertyBlockを利用する必要があるため、それ用のUdonが必要になります(Merlinさんが公開しているVRCBakeryAdapterなど)

『MonoSH』は対応したShaderが必要ですが、追加テクスチャが2枚と『SH』の半分で済み、『SH』に近い品質を得られます。またMaterialPropertyBlockも不必要なため、最近ではこちらのほうがよくワールドで使われる傾向にあるようです。詳しくはtktkさんの記事を読むと良いでしょう。

ちなみに上で言っている『対応したShader』については、Bakery側で用意してくれているBakery Standardというシェーダーがあり、Bakeryをインポートすると利用できます。

ライトマップの解像度調整

前回の記事で、ライトマップの解像度周りの話をしましたが、その調整方法についてです。ありがたいツイートを引用させて頂きます。

Draw Modeの変更はシーン画面左上のShadedの部分を、変更することで可能です。チェッカーの間隔が細かいほど、ライトマップの解像度が高くなっているので、適切に変更しましょう。

UV2の重複の可視化

UV2は重複しないことが望ましいのですが、Unity標準のGenerate Lightmap UVsを利用したりしていると、たまに重複した状態になってしまうことがあります。

1つ上の話でも出てきたDraw ModeをUV Overlapにすると重複している場所が赤く表示されるので、原因の特定がしやすいです。

対策としては、Generate Lightmap UVsのPack Marginを大きくするか、前回の記事で紹介したライトマップの解像度を上げる系のことをすると解消できる可能性があります。

裏面に当たる光はライトベイクできない(2023/11/01追記)

表題の通りなのですが、裏面に当たる光はベイクできません。
ここでいう裏面というのはポリゴンの裏面です。

といっても分からない人もいると思うので簡単に説明します。

実はポリゴンには裏表があります。そしてちょっとややこしいのですが、この裏面を描画するかどうかはShaderによって規定されるので、Shaderによって見えたり、見えなかったりします。

Standardシェーダーはポリゴンの裏面を描画しないシェーダーなので、Standardシェーダーにしてみるとどこが裏面なのかが分かるはずです。

ポリゴンの裏面は、ライトを当てても明るくならず、またベイクも出来ません。なぜなら裏面の描画は表面のコピーでしかないからです。

その証拠に、両面描画のシェーダーで表面をベイクしてると、裏面も同じように明るくなるはずです。

何故か真っ黒のままベイクできないなと思ったときは、ポリゴンの裏面かどうかを疑ってみましょう。

ベイクしたら変な模様が出たり、部屋の隅が明るくなったりする(2023/11/01追記)

(ここの話は、WhiteFlareさんにTexel Validityについても記載が欲しいというコメントを頂いてから、自分なりに勉強した話なので、誤りがあったら指摘してください)
1つ上で、ポリゴンには表面と裏面があって、裏面に当たる光は意味ないよ……という話をしました。

ここで、壁の中に完全に埋まってるポリゴンを考えてみましょう。

UV2が展開されている場合、この埋まってるポリゴンにも領域が割り当てられていますが、光が当たらないことが確定しているこのポリゴンのライトベイクに関わる計算コスト……無駄になりますよね?

Unity標準ライトベイクではこのような領域を判定して、無効化する機能が自動で動いているみたいなのですが、時にこの機能が悪さをして、変な模様が出たり、部屋の隅が明るくなったりします。

何故でしょうか?

という話をするには、ライトベイクの仕組みについての話をする必要があります。

先ほど二つほど上の話で、このようなチェッカー模様を見たと思います。

これはテクセルと呼ばれていて、テクスチャ上の1ピクセルが3Dモデル上でどれくらいの面積を示すかを表していて、つまりこのチェッカーのマス目一つ一つがテクスチャの1ピクセルに該当します。

ライトベイクではこの各テクセルから、沢山のレイ(光線)を出して、周りの光源からの光(直接光)や、周りのオブジェクトから反射・透過されてくる光(回折光)の情報を集めます。

そして集まった情報を元にそのテクセルの色や強度を決定する……ということがライトベイクで行われています。

さて、話を戻します。Unityの標準ライトベイクシステムは無駄なテクセル領域を検知して、テクセルを無効化するという処理を行っています。

どのようにして無駄なテクセル領域を検知するかというと、テクセルから放たれた光線の内、どの程度が裏面にぶつかっているかを割り出して、ある一定の割合以上だった場合に無効化を行います。
無効化された場合、付近にある有効なテクセルの値をそのまま持ってきます。

例えば最初に例に挙げた壁の中のポリゴンについて考えてみると、このポリゴンから放たれる光は全て裏面に激突しますので、確実に無効化されるわけです。

ちょっと聞いただけだと、賢そうな機能に聞こえますが、そんなことはありません。上手くいかないケースがあるからです。

例えば床があったとして、その上の空中に片面しかないゲームオブジェクトを置いた場合、どうなるでしょうか?

床のテクセルからレイが放たれても、大部分が空中の片面メッシュの裏側に吸い込まれていくので、片面メッシュの下の大部分の面積が無効なテクセル領域になってしまいます。結果としてこのような変な模様が出てきます。

無効なテクセル領域はScene画面左上のShadedとなってるところをTexel Validityに切り替えることで、赤色に表示されます。上の画像と比較してもらえると、変な模様になっている部分が丁度、無効なテクセル領域であることが分かりますね(なお、Texel Validityを初め、ライトマップ関連のビューモードはBakeryとかでは正しく表示されませんので注意)


また別のケースとしては、一つのゲームオブジェクトに他のゲームオブジェクトを突っ込んでいる場合について考えてみましょう。部屋のような構造を作ってみました。この時に隅っこについて着目してみましょう。

もしテクセルが以下の画像のように中途半端にはみ出ていたら、どうなるでしょうか。試しにベイクしてみましょう。

部屋の隅であるのに明るくなりましたね。Texel Validityで見ても、隅が無効化されていることが分かります。

このようにテクセル無効化で不本意な結果を得ることがあることがあります。これに対する対応策は大きく二つあります。

まず一つ目は無効化の判定を行うしきい値に相当するBackface Toleranceを小さくすることで、レイのほとんどが裏面に当たった時のみ無効化するようにすることです。

このパラメータは0~1の値を取ります。0にするとレイの全てが裏面にヒットしない限りは無効化されません。1の場合は1つでもレイが裏面にヒットすると無効化されます。デフォルトは0.9が採用されていますので、かなり厳しい値であることが分かります。

このパラメータはLighting Settingsにあるわけではなく、Lightmap Parameters Assetと呼ばれる、設定用アイテム内にあります。

この設定アイテムはMeshRendererにセットしてオブジェクトごとに適応したり、Lighting Settingsにセットして全体に適応したりできます。Lighting Parametersと書かれている項目が該当します(画像下のほうにあります)

新しく作ってみましょう。

左クリックすると、New Createという項目があるのでクリックすることで新規作成できます。

最初はNew Lightmap Parametersという名前なので、適当に名前を付けて、各種パラメータを設定します(各種パラメータについての説明は割愛します)

先ほど左クリックしたところを再びクリックすると、適当につけた名前で先ほど作ったパラメータが作られています。なのでそれを選択しましょう。

パラメータを調整した場合、適当なベイク用のライトを1つ、位置を少しだけ動かしましょう(重要)
これをやらないと、どうもキャッシュで処理されてしまうらしく、パラメータが反映されません(キャッシュについては後ろで解説)

試しにBackface Toleranceを0にしてみると、先ほどの部屋の隅がキチンと暗くなってくれました。

これで無効化されたテクセルによって引き起こされる問題は最小限になるはずですが、SNSで情報を探してみるとエミッションとかで上手くいかないケースがあるらしいですが未確認情報です。そういう時はもう一つの方法を試してみると良いかもしれません。

もう一つの方法は、裏面がないメッシュのマテリアルでDouble Sided Global Illuminationにチェックを入れることです(大体一番下にあるはずです)

これはようは、ライトベイク時に裏面も表面と同じように扱うオプションになります。ですので、このマテリアルが適応されているオブジェクトの裏面にレイが当たっても、有効なレイだと判断されて無効化されなくなります。

こちらのほうが推奨されていることが多い気がするので、基本的にこちらを使っても良いかもしれません(なんか色変わってる気がするので、うん?って思わないでもないですが)

これにチェックを入れたからと言って裏面がベイクできるようになるわけではありませんので、それは注意してください。

上の話は全てUnityの標準ライトベイクシステムの話で、Bakeryだと以下のような記述がマニュアルにあるので、裏面も全て表面として扱われているようですので、おそらく気にする必要はなさそうです。
(代わりに、たまたま壁の中に飛び込んだ光が壁の中で乱反射して、別の変なところから飛び出してくるようなことは起こりそうだなと思っていますが)

(DeepLで翻訳済み) シェーダでどのようなカリングモードが使用されていても、Bakery はすべてのバックフェー スを不透明として扱います。つまり、直接光線はフロントフェイスを通らないのと 同様に、バックフェイスを通りません。ただし、バックフェース GI を使用する場合、バックフェースは、フロントフェースによって受光された照明を部分的に放出することができます。

https://geom.io/bakery/wiki/index.php?title=Manual
試しにBakeryで焼いてみましたがこの通りです

ライトベイクのキャッシュ情報

ライトベイクを行うと、その計算結果はキャッシュとして保存され、次回以降のライトベイクの時間の短縮に使われます。

毎回、ライトベイクに時間がかかる人はこのキャッシュ領域が少なくなっている可能性があるかもしれません。

[Edit]→[Preferences]→[GI Cache]の項目で保存場所やキャッシュ容量の上限を指定したり、キャッシュの削除などができます。

自分は100GBほど設定していますが、9.78GB使用にとどまっているみたいです。

[Preferences]にある設定項目は基本的にプロジェクトを跨いで、適応されるので、一度設定しておけば大丈夫です。


以下Bakeryの話。

Bakeryの罠、SkyLightについて

Bakeryは環境光が無効化されるので、BakerySkyLightというコンポーネントを追加して、環境光のベイクを行う必要があります。

そのため、このことを知らないと、標準ライトベイクに比べて何故か影が暗かったり、色が真っ黒だったりと想定していない結果になったりします。

標準の環境光は、デフォルトではSkyboxの色と明るさを参照しています。Unity標準のライティング用のウィンドウの一番上らへんにある、[Environment Lighting]という項目をいじると変えられます。

この環境光が、ライトベイクを行うと無効化されますので暗くなってしまうということが発生します。気を付けましょう。この記事用に作った、極端な例ではありますが、Enviroment Lightingを色々弄ってるとこんな差異が出ることもあります。

標準ライトベイク
Bakery

(2024/06/13追記
Unityの標準ライトベイクシステムではライトベイク時にEnvironment Lightingの色や明るさを加算した状態でライトベイクを行い、ライトベイクされている間はEnvironment Lightingは無効化されます。つまり、ライトベイク時のEnvironment Lightingの色に固定されます。一方、Bakeryはそもそもこの加算自体を行いませんので、無視する形になります)

そして、記事を作成中に発見して、思わず「えっ」って声出ちゃったんですけど、Scale in Lightmapsが0のオブジェクトでは、Enviroment Lightingの設定が無効化されずに復活するようです……そんな馬鹿な……。

どうやらライトベイクにそのゲームオブジェクトが含まれてるか否かで、Enviroment Lightingの設定の無効化が決まるらしいです。ライトベイクに含めないことでもEnviroment Lightingの設定が復活しました。

Bakeryでライトベイク中に、Enviroment Lightingを変な値にしてる場合は気を付けましょう。

BakerySkyLightコンポーネントの色設定を、Enviroment Lightingの色設定に近似させないと、ライトベイクに含んでるオブジェクトとそうでないオブジェクトで差異が発生しそうです。

Scale in Lightmapsが全て0
端っこの一つだけ、ライトベイクに含めていない

Bakeryのベイクデータを消すとき


一度Bakeryで焼いたデータを消して、アップロードしたい時にUnity標準のLighting SettingsタブのBakeボタンの横にあるClear Bakeで消すのはよくありません。

何故ならBakeryによる紐づけが完全にとかれていないので、アップロード時にベイク結果が復活してしまうからです。

BakeryのベイクデータはAssetsフォルダー内のBakeryLightmapsというフォルダに格納されています。一度ベイクをやり直したい時とかに、このフォルダに中途半端にデータが残っていると悪さをすることがあります。

Unityの上のメニューで、[Bakery]→[Utility]→[Clear Bake]を押すと、ベイク情報を一括で削除できるタブが出てくるので、一括で削除したい場合はこれで消すといいでしょう。

Delete Lightmap filesのチェックは入れなくても、ビルド時に復活しないことを確認したので、一応消しておきたい人だけチェックを入れれば良さそうです。

Clear from scenesはNothingにしておかないと、ライトマップに関する情報が格納された"!ftraceLightmaps"という名前のゲームオブジェクトが生成されます。NothingにしてからClearボタンを押しましょう。
(もしかしたらこれを残して置けば、次ベイクする時にこの情報を使って時短ベイクする無害なやつなのかもしれませんが、アップロード時に変なことされる可能性はあるので消しといたほうが無難でしょう)

ライトベイクの分割

あまりにも広すぎるシーンなどでベイクを行うと、高品質な設定ではライトベイクに時間がかかりすぎて、話にならないこともあると思います。

よくあるのは、最初は低品質で素早くベイク・確認して、本番は高品質で……っていう話がありますが、ぶっちゃけ最初から高品質で確認したいですよね。

BakeryではBakery Lightmap Groupという機能があり、ゲームオブジェクト単位でライトベイクを分けてすることが出来ることが出来ます。これにより分割しながらベイクができます。

Bakery Lightmap Groupについては何度か紹介していますが、落雷さんの記事を見るのが一番良いです。

これは標準機能にはないので、これはBakeryを買う一つのメリットです。
(ShaderやUdonを使えばできなくはない気がしますが、色々と労力に見合ってない気がします)

Bakeryで綺麗に落ち影を出す方法について

(2024/02/21 追記)

折角記事を書いていたのに関連付けるのを忘れていました。
以下に調査結果をまとめています。

おわりに

こうして雑に書き出してみても1万字超えるあたり、結構色々あるなぁという感じがしますね。

以上で小ネタ系は大体書き終えた気がするので、これでライトベイク関係の話はいったん終わりです。パラメータや具体的な使い方については、無数にある他の記事を参考にすれば十分だと思いますので。

もし小ネタ系で何か思い出したら、またこの記事に追記していく形で書いていこうと思います。これらの情報がお役に立てば幸いです。

長文の読了、お疲れさまでした。

いいなと思ったら応援しよう!