今回は7月のお題企画でs.TAHARA賞を受賞した美坂さんの「Potsu-Jin」で実装されている時間経過ギミックを美坂さんが前後編に分けて解説します!
後編ではライティングについて解説。前編では、背景、空などの表現について解説しています。
ワールドに時間の流れが取り入れられると一気に実在感が高まるので、興味のある方はぜひ試してみてください!前編はこちら。
皆様こんにちは、美坂と申します。

こちらの記事ではclusterワールド「Potsu-jin」のライティング関連について説明していきます。
ライトの基本設計・配置
Unityでクオリティの高いライティングを実現するにはライトベイクは欠かせません。このワールドでも基本的にライトベイクして細かな陰影をつけつつ、時間による光の変化を表現するためにリアルタイムなDirectional Light(長いので以下DLと表記)を足す、みたいな方針で組んでいます。
ちなみに「何でもとにかくライトベイクすれば良い」という訳でもなく……ちゃんと設定されていないライトベイクはむしろ焼かないほうがマシって状態になる場合もあります……かなしい。

素の状態。なんか安っぽさが感じられるというか……。

ライトベイクした状態。陰影が足されてちょっといい感じに。

更にDLを追加した様子。
時間経過でDLの色・向きを調整して朝焼けから昼、夕方に。
DLの影響でだいぶ印象変わってきます。clusterのリアルタイムDLでは影ができず、かつライトベイクによる影は動かないので厳密に見ると様子がおかしいのですが、まあそこまで違和感ないのでヨシ!
ライトベイク切り替え

夜は灯りとかつけてかなりワールドの印象を変えてます。
同一のライトベイク設定でこれを表現するのは無理があるので、昼と夜2通りのベイク結果を切り替え表示しています。
とはいえ通常cluster上ではこのような切り替えは不可能です。
で、何をどうやっているかというとこんな感じ。

まずシーン内に「昼」のオブジェクトと「夜」のオブジェクトをそれぞれ重ならないようにStaticで配置します。それぞれ「ライトベイク対象のもの」と「Reflection Probeに映したいもの」だけ配置しています。

そしてシーン全体にBakedなDLを真上から照らし昼の明るさ・陰影をつけます。ここで夜側オブジェクトは「蓋」のオブジェクトを付けて光を遮蔽、真上からのDLが当たらないようにしています
なんか斜め上な力技ですがこれで昼側だけにDL当たります。
冷静になって見てみるとたぶんDLのCulling MaskとオブジェクトのLayerで分ける、とかのほうが良さそうな気がしますね……。
他にも昼と夜で微妙にオブジェクトを変えたりしています。
オブジェクトの明るさ変えたり光源足したりとか。

実は駅名表示をひっそりと意味深に変えたりしてますが現在全く意味はありません。雰囲気だけの要素。
ここで小技。
ベイク用にしか使わないオブジェクト(DL遮蔽用の蓋とか追加した光源とか)は、実行時には不要です。

そのようなオブジェクトはTagを「EditorOnly」にすることで、clusterアップロード時にシーンに含まれないオブジェクトにする事ができます。
本番環境で見えてほしくない物とか不要なものとかに設定すると便利。
配置が終わったらライトベイクかけます。

ライトマップテクスチャとUV2の様子は現状こんな感じ。サイズは2048x2048pxでもうちょっとオブジェクト足す予定なのでまだスペースに余裕を持たせています。
このライトマップテクスチャのサイズ、地味に容量食うので注意が必要です。
ちなみに私個人的にはここの配置、つまり3DモデルのUV2配置によってライトベイクのクオリティは決まる、と思っています。モデルのUV2、雑に扱われがちですけどたぶんとても重要です。

ベイクが終わったらに昼夜2つのオブジェクトを同じ座標に重ねます。ベイク後なら移動してもベイク結果はそのままなので。
しかしこの手法、ライトベイク毎に座標戻さないといけないので更新時ちょっとめんどくさいです……。

あとは時間経過とともに昼の間は「昼オブジェクト」、夜は「夜オブジェクト」を表示するようAnimationでActive状態を切り替えてやれば擬似的にライトベイクを切り替えることができます。
Staticなオブジェクト(正確にはBatching Staticなオブジェクト)は実行時に座標を移動させることはできませんが、Active状態を切り替えることはできるようです。
ただこの手法、私の知見が不十分ですのでもしかすると何か良くない影響があるかもしれません。自己責任!
Reflection Probe

Reflection Probeも昼夜2つ用意して、更にその座標を動かすことで昼夜で映り込みを無理やり切り替えています。

こんな感じに昼は昼用を地上・夜用を地下に配置、時間経過でそれらを入れ替えるように動かすことで2つのReflection Probeのオブジェクトへの影響度が変わります。
- 昼→ 昼用Reflection Probe 100% : 夜用Reflection Probe 0%
- 夕→ 昼用Reflection Probe 50% : 夜用Reflection Probe 50%
- 夜→ 昼用Reflection Probe 0% : 夜用Reflection Probe 100%
みたいな感じ。
ただこれリニアに影響度(weight)が変わってくれるかと期待したんですが、そう上手くは行きませんでした。結果を見た感じ段階的に切り替わってますね。
ここはちょっと雑にやってるのでもっと良い設定がありそう。
最後に
とまあこんな感じにかなり力技で実装されています。
通常のUnity環境ならもうちょっとうまい方法もあるかもしれませんが、cluster環境で頑張ってみた感じこうなってしまった、といった所です。
ある種の縛りプレイ的なやつかもしれない。
あとこちらのワールドは容量と負荷をできるだけ抑える作りを目指しています。
現状で容量18M程度、メモリ消費量・描画負荷も抑えてあります。
一般的にあまり目立たなくかつ評価されづらい地味な要素ではあるのですが、clusterのようなスマホ対応したプラットフォームでは結構重要な要素です。
ワールド制作の際には容量・負荷などを考慮しておくとユーザーに優しい作りになるかもしれません。