Club Belkaというクラブワールドを作りました。パブリック化してるので使ってみてね。
クラブワールドならやっぱり動画プレイヤーの色がアバターとかに反映されると楽しいよね。ということでiwaSyncの色を取ってLightVolumeTVGIで光らせています。LTCGIは使っていません。
このワールドは2台のiwaSyncがあり、DJとVJがそれぞれ接続するという方式が使えます。VJ Separationと呼んでいますが、この状態でももちろん色反映が出来ます。
ちなみにクラブワールドを作ったということはつまりDJをやっているということです。ブッキング待ってます!気が向いたときに増えるhearthis.atはこちら。
さて宣伝はこのくらいにして本題に移りましょう。LightVolumeTVGIの使い方を説明します。
目次
バージョン等
以下の環境で説明します。
- Unity - 2022.3.22f1
- VRChat SDK - 3.8.1
- VRC Light Volumes - 1.0.0
- Filamented - 1d1b8321905dc0b12f6c14b8b110be49d4486a75
- Unity Lightmapper
Light Volumeの設置
基本的にはマニュアル通りなので適宜参照してください。まずはQuick World Setupの部分を進めましょう。
とりあえずワールドを準備します。今回はSingle Bedroom Free VRChat Worldを利用させて頂き、小物を退かして適当にiwaSyncを置きました。
一旦Light Volumeをポン置きしてライトベイクします。特に理由は無いですが折角なので解像度(Voxels Per Unit)を上げてみました。
なおBakeryでベイクする場合は、Light Volume ManagerからBaking ModeをBakeryに切り替えてください。
わかりやすいように部屋全体は少々暗めにしておきました。
これで一旦テストビルドして、lilToon 1.10.1以降に更新してあるアバターで確認するといい感じに光ってると思います。いい感じですね。
とりあえずワールドの簡単なVRCLV対応は出来ました。お手軽!
シェーダーの変更
この時点ではアバターにVRCLVは適用されますが、対応するシェーダーに変更しないとワールドのオブジェクトには反映されません。Filamentedがさいつよなので可能な限り全部置き換えちゃいましょう。
StandardとAutodesk Interactiveを置き換えるといい感じになると思います。あとはVRCLVを反映させたいマテリアル全てに対してVRC Light Volumes Supportのチェックを入れます。この項目はSettings ModeをFullにすると出てきます。
シーンの複製と適用範囲の調整
ではここからLightVolumeTVGIを適用していきます。まずはマニュアルのAdditive Light Volumesの部分の作業をします。
新たにLightVolumeを設置し、動画プレイヤーの光を適用させたい範囲を指定します。今回はわかりやすいように部屋の1/4程を残して光らせようと思います。
範囲を決めたらシーンを保存し、そのシーンを複製します。シーンファイルのコピペで大丈夫です。
複製したシーンを開き、ライトを全て排除してください。発光するもの全てを光らないようにするという意味です。放出(Emission)のあるマテリアルも全てなんでもいいので光らないものに置き換えます。
Light Volumeは残したままで問題ありませんが、必要なのは先程光らせる範囲を指定したLight VolumeとLight Volume Managerだけなので他は消しても大丈夫です。
外から入ってくる光も邪魔です。ライティングの環境設定からリアルタイムのシャドウカラーを#000000にしたり環境ライティングの強さ乗数を0にしたりしてとにかく光を排除します。
光るものを全て排除したら次は動画プレイヤーのスクリーンを光らせます。スクリーンのある場所にエリアライトを置くとかでいいです。
エリアライトの範囲とか強さとかを調整したらライトベイクします。スクリーンからの光だけがいい感じになっていれば大丈夫です。
一体何をしているのかというと、TVGIを使って追加で光らせる範囲を生成しています。ここで生成されたライトマップの情報を使って光るため、他の光源があったらそこにも色が乗って光ります。
つまり環境光やデスクライトの光などがスクリーンの色に合わせて光ることになるわけですね。よってすべての光源を排除してスクリーンの光のみでライトベイクする必要があるわけでした。
この通りTVGIで光る強さと範囲が今回の場合はエリアライトの設定そのものになるため、この光らせ加減の調整がわりと結構かなりダルいです。要するにライトベイクしまくり大会です。
今回はUnity Lightmapperでやっていますが大きいワールドだとベイクが非常に長くてダルいので、Bakeryがあるならそっちを使った方が相当早いので楽です。
メインシーンに適用
メインシーンに戻り、光らせる範囲のLight Volumeの設定をします。
Volume SetupからDynamicとAdditiveにチェック、Baked Dataに先ほどのテクスチャを設定、Baking Setupからベイクのチェックを外します。
必要に応じてColor Correctionを調整してください。
ベイクのチェックを外すことにより、このシーンで再度ライトベイクを行ってもここにセットした3つのテクスチャは更新されなくなります。というか更新されてしまうと困るので。

実はメインのシーンであらかじめ範囲を決めてから複製する必要はなく、複製側のシーンからLight Volumeオブジェクトをコピペしてきても問題ない(はず)ですが、仕組みの理解のためにこのような方法としています。
Light Volume Managerの設定に移ります。Light Volumeが複数あり、かつ範囲が重複する場合においてはWeightが大きいものが優先されます。今回はTVGIの光を優先したいので、Weightを他より大きくしておきます。あとはAuto Update Volumesにチェックを入れます。
最後にその下にあるPack Light Volumesボタンをポチ!(あるいはライトベイク)すると適用されます。これで光らせる範囲の準備は完了です。複製シーン側で再ベイクした場合もPack Light Volumesボタンをポチ!でシーンに適用されます。とりあえず困ったらCtrl+Sくらいのノリで押しとけばいいと思います。
スクリーンの色を取得
色情報はレンダーテクスチャから取得するため、動画をレンダーテクスチャに書き出す必要があります。無改造なiwaSyncの場合はLIVEモードだとそれができないので、色々と汎用的にできるパワープレイな方法でレンダーテクスチャに書き出します。
適当にレンダーテクスチャを新規作成、スクリーンを撮影するカメラを設置してターゲットテクスチャに作成したレンダーテクスチャを指定します。色を取るだけなので、この時作成するレンダーテクスチャの解像度は16x9みたいな小さいもので問題ありません。その分負荷も下がります。極論1x1でいいです。
なお、このレンダーテクスチャはミップマップを有効、およびミップマップの自動生成も有効にしておいてください。
カメラのカリングマスクをスクリーンのレイヤーと合わせ、かつクリップ面をスクリーンギリギリに調整することでスクリーン以外が映り込む可能性をできるだけ排除します。ついでに負荷軽減です。
画像では説明のためスクリーンより広い範囲が映っていますが、実際にはスクリーンだけが映るようカメラ位置やFOVを調整してください。よって本来この時点でのカメラプレビューは真っ黒になるはずです。
映り込みを断固として阻止したいなら部屋の外とかに色取得用に別途スクリーンを設置してそれをカメラで映すといいと思います。
ともかく、これでレンダーテクスチャに映像の色を落とし込めました。この方法ならどんなモノにでも柔軟に対応できるので万能のパワープレイかと思います。
TVGIの設定
適当なオブジェクトにLight Volume TVGIコンポーネントをアタッチします。空のオブジェクトを作ってそこにアタッチでいいと思います。
Target Render Textureに先ほど用意したレンダーテクスチャを、Target Light Volumesに色を反映させる対象のLight Volumeを指定します。
動作テスト
これで設定は完了しているはずです。テストビルドしてみましょう。
めちゃくちゃ光っていますね。これで導入完了です。
あとは光る範囲とかを気合で調整しましょう。
ちなみに気づいたと思いますが、発光範囲の小物を動かしたり増やしたりとかするとシーン複製の段階からやり直しです。気合ですね。
というわけでLightVolumeTVGIの導入方法を説明しましたが、未来の自分のための備忘録のようなものです。ここが違う!とかこのほうが良い!とかその他なんかあれば教えてください。
Unityなんもわからん。