27
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SilentClubを作る過程で得たワールド制作に関する知見

Last updated at Posted at 2018-12-09

この記事はVRChat Advent Calendar 2018の9日目の記事になります。

昨日の記事は@kleus_balutさんによる、VRChatで使われている3Dオーディオ技術でした。

はじめに

SilentClubのオーナーのryouです。
今回のアドベントカレンダーではSilentClubを作る過程で得た知見、使用した技術、細かいTips等を雑多に書こうと思います。

SilentClubとは

キャプチャ2.JPG

基本的に毎週土曜日の21:00~、Friend+で開いているボイスチャット強制ミュートワールドになります。

運営はryou(技術担当。主にUnity)とsilinder(デザイン担当。主にBlender)の二人でやっています。

PostProcessingStackのBloomに関して

Unlitアバターが光らないよう調整する

Bloomですが、何も考えずに使用してしまうとUnlitシェーダーを使用したアバターが通常より明るくなってしまいます。一部ワールドでUnlitなアバターを使うと発光して見える経験をした人は結構いるはずです。

例を挙げましょう。以下画像はUnlitなUnityちゃんとEmissionを設定したQuadになります。

img_bloom_02_01.JPG

これにBloomを設定してみます。(わかりやすいようにIntensityを強めにしています。)

img_bloom_02_02.JPG

Quadが光ったのと同時に、Unityちゃんも光ってしまいました。このように、Bloomは設定に気をつけないとUnlitアバターが光るようになってしまいます。

では、どのように設定すれば光らないかと言うと、

img_bloom_02_03.jpg

Bloomの設定項目内Brightness Responseに濃いグレーの範囲があると思うのですが、これの左端がグレーの縦線より右側になるようにしましょう。

濃いグレーの範囲の位置はThresholdの数値を大きくすることで右に移動します。Soft Kneeがデフォルトの数値の場合は、1.375程度にしておけば良い感じの位置に来ると思います。

img_bloom_hogehoge.jpg

こう設定すると次の画像のようにアバターが光らなくなります。

img_bloom_02_04.JPG

Thresholdを調整した影響でQuadの光も弱くなっていますが、それはQuadのEmissionを強くすることで調整しましょう。

設定は控えめにする

Bloomに関する補足ですが、設定は基本的に控えめにしたほうがいいと思います。これは別に「Bloomマシマシだと初心者っぽくてダサい」といった理由ではありません。

Bloomの設定を強くしてしまうと、ユーザーのアバターが想定より輝いてしまい、結果的に周囲のユーザーに迷惑をかけてしまう、気まずくなってしまう状況が出てしまうからです。

当然Bloomが控えめであれば、「ちょっと光り方が物足りないな」という状況は多くなりますが、周囲に迷惑をかけて気まずくなってしまうよりよっぽど良いと考えています。

なので、ワールドのエフェクトをより輝かせたい場合は基本的にBloomを強くするのではなく、エフェクト自体のEmissionを強めにする等で対応するのがベターかと思います。

RealTimeReflectionProbeを使用した動画・エフェクトの反射

20181208021659_1.jpg

画像のように、ダンスホール内のステージに動画とエフェクトがリアルタイムに反射するようにしています。

これはReflectionProbeをRealTimeにして実現しています。ゴーストクラブでも動画が反射しているスクリーンショットを目にしましたが、おそらく同じ方法だと思います。ReflectionProbeを利用して動画の反射を表現することで、アバターの金属部分にも動画が反射するようになり、そこはかとなくイケてる感じになります。

ただ、RealTimeなReflectionProbeはかなり重い機能なので、単純に配置してしまうとめちゃくちゃ負荷がかかってしまいます。

そのため必要最小限の物のみを反射させるようにして、負荷を抑えています。

具体的には、反射させるオブジェクト用のレイヤー(今回はDanceHallDisplayという名前)を追加し、Culling Maskでそのレイヤーを指定しています。

img_reflection_01.JPG

この方法で必要最小限のオブジェクトのみ反射するようにして、RealTimeReflectionProbe負荷を出来るだけ抑えましょう。実装の際は負荷計測もしっかりして、処理負荷が許容範囲内に収まっていることも確認したほうが良いかと思います。

負荷の計測

負荷軽減作業をする際、まず鉄則として「CPU/GPU/Memory/Network等のどこがボトルネックになっているのか調べる」という事をしなければなりません。

その理由に関しては、まろんさんがツイートされていた以下の動画でわかりやすくまとめられています。

動画で言われているように、例えば「CPUの処理が追いついていないせいでFPSが下がっているのに、GPUの負荷軽減作業をしても意味がない」という事になります。負荷計測をしないとこういうことが頻繁に起こってしまいます。

また負荷計測を行わなかった場合、行った作業が効果を発揮したのか、発揮したのであればどの程度負荷が軽減されたのかといったことがわかりません。「実はほとんど負荷が減っていないのに作業にめちゃくちゃ時間がかかった」や「負荷が大して減らないのにワールドのクオリティがかなり下がる」などといったパターンが結構あります。負荷計測を行いそのような作業がわかれば、次に活かすことが出来ます。

他にも例えば、アバターの負荷に関する話になりますが、DynamicBoneのGravityが処理負荷に影響しないということも負荷計測によって判明しました。以前はちらほら「DynamicBoneのGravityはめちゃくちゃ重い」という噂が立っていたのですが、負荷計測をきちんと行うことで噂に惑わされずに済みます。

計測方法

CPU/GPUの負荷に処理時間に関してはSteamVRのフレームタイミングという機能を使う事で計測が出来ます。

SteamVR > 設定 > 動画フレームタイミングを表示というボタンがあるので、それをクリックすることでCPU/GPUの処理時間を確認することが出来ます。

img_frametiming_01.JPG

img_frametiming_02.JPG

グラフの横軸は時間(フレーム)、縦軸は各フレームにおけるCPU/GPUの処理時間になります。90FPSを実現するにはグラフが11ms以下、45FPSの場合は22ms以下に収まってる必要があります。

左下のヘッドセットに表示にチェックを入れると、アバターの右腕にこのグラフが表示されるようになるのでHMDをつけてVRChatをプレイしながら処理負荷を確認することが出来ます。

フレームタイミングを利用して、CPU/GPUどちらの処理がボトルネックになっているのかを調べ、その負荷を減らすような負荷軽減作業をするようにしましょう。

音楽がこもったりこもらなかったりを切り替える

SilentClubに来て頂いた方であれば気づいた方もいるかもしれませんが、ダンスホール周辺では音がこもって聞こえるようにしています。

どう実装しているかと言うと、AudioSourceにAudio Low Pass Filterというコンポーネントを付けることで実装しています。

img_lowpass_01.JPG

ダンスホールの入り口にこのコンポーネントの有効・無効を切り替えるトリガーを配置することで、ダンスホール内外でこもったりこもらなかったりするようにしています。

音のこもり具合はCutoff Frequencyを弄ることで調整出来るので同じことをする場合は良い感じに調整して下さい。(数値を下げるほどこもります)

ジャンプしたり物を投げたりした際によく飛ぶようにする

基本的にジャンプする、物を投げる等の動作をした場合は若干大げさなくらい飛ぶようにしたほうがユーザーとしては気持ちがいいです。

デフォルトの設定では全然飛ばないのでSilentClubでは以下のように重力設定を弱めに、VRC_Player ModsのjumpPowerを高めに設定することでよく飛ぶようにしています。

img_jump_01.JPG

img_jump_02.JPG

ダンスホールの前方でぐるぐる回ってるエフェクト

これ。シェーダー書いて実装してます。

GitHubにプロジェクトとUnityPackageを置いてますので、もし使用したい場合はそちらをどうぞ。

リアルタイムライトを使わない事で、Cubedシェーダーのアバターの顔に陰が出来ないように

この一連のツイートが全てなのですが、SilentClubでは一部を除きリアルタイムライトを使っていません。ワールド全体を照らすディレクショナルライトもありません。

これは負荷軽減的な意味もあるのですが、ツイートの通り当時大きなシェアを占めていたであろうCubedシェーダーでリアルタイムライトによる強い陰影が出来なくなるというのが一番の理由になっています。

img_face_shadow_02_01.JPG

この画像はかなり悪いパターンですが、似たような状況は目にしたことがあると思います。これはCubedシェーダーのFlatLitToonのデフォルト設定を適用した状態のマテリアルにIntensityが1.0のディレクショナルライトを当てた状態になります。リアルタイムライトを配置するとこのように「折角写真を撮ったけど顔に変な影が入ってしまった」という状況に結構な頻度で遭遇してしまいます。

img_face_shadow_02_02.JPG

こちらの画像は、ディレクショナルライトをBakedにしてLightProbeを置いたパターンです。顔の陰影が無くなっています。同時に、ライトによる体の陰影も消えています。

リアルタイムライトによる顔の影対策としてはFlatLitToonのShadowを0にする、陰影対策がされているシェーダーを使う等あるのですが、そういう対策法を知らない人でも変な影が出ないようにワールド側で対策したいということでこういう形にしています。

もちろんリアルタイムライトが無いと床に影が落ちなかったり、体の陰影が出来なかったり、スペキュラが出なかったり等デメリットも多いため、そこはワールド製作者のポリシーによりますし絶対にこのやり方が良いとは言えません。こういう方針もあるよという参考にして頂ければと思います。

あとがき

そのうち(約4ヶ月後)。

今回記事にしていない内容でも、SilentClubで「これどうやって実装してるんだろう?」みたいな物があれば気軽に聞いてもらえればと思います。

明日のVRChat Advent Calendarは@nyakome306さんです。お楽しみに!

27
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?