見出し画像

【VRChat】ワールドのQuest対応はとても大変……

追記:最後にちょっとテクニカルな話をおまけとして追加→記述が間違えてたので修正、思い付きで文章を増やしてはいけない……

2024/12/01 追記:とみーさんからQuestの同期ギミックについての知見を頂き、掲載の許可を頂いたので追記しておきました。

今回はワールド製作者の間で時折話題になるQuest対応について、小ネタということで雑談っぽい感じで多少書きます。

本当は今月はテクスチャについての記事を書きたかったのですが、事前の想像通りとても長い文章になりそうです。しっかりと時間をかけて書こうと思います。

では、さらっと普段の恨みつらみ……もといQuest対応の難しさについて語っていきたいと思います。

余談:『毎月更新止めたとか言ってなかったっけ?』と思うかもしれませんが、正確には無理がない程度に続けると言っており、さりげなく継続してて現在32ヵ月めになります。まぁ無理はしないということであっさり目とかにしてますが、なるべく続けたいですね。

ベースとして

サックーさんの記事が古いですけど、今でも全然通じるので是非読んでみてください。

ここからQuest対応で私がしんどいな~と思っていることについて喋ろうと思います。

①色がUnity上とQuest上で異なる

PC版とQuest版の違いの中で、個人的に最もつらいもののうちの一つです。

基本的にQuest対応をするときというのはUnity側で作業をするわけですが、UnityとQuest上で色が違います。

当然エスパーじゃないので、Quest側の色味がどうなっているかは分からないままUnity上で調整し、アップロードしてQuestを被ってからUnityとは異なるその見た目にとてもガッカリします。わざわざQuestを被らないと分からないので凄く手間がかかります。

以前これについて調査した記録があるので、興味があれば一読してほしいのですが、原因としてはデバイス依存の問題で、そもそものQuest自体の色空間が異なっているからみたいです。

特徴としてはまず赤がとても赤いです。他の2色は微妙に持ち上がってるもののまぁ無視できる範囲。そして、上記記事には書いてないですが、シェーダーの処理によっては別の影響を受けている気配があります(全体的に輝度が持ち上がって、黒が浅くなっているイメージを受けます)

上記記事から持ってきた設定した輝度値と実際に表示される画素値の比較です

筆者はQuest2とQuest3両方持っていますが、体感的にはどちらも同じような色味の異なり方をしています。なのでMetaが意図的にそう設計しているのでしょう。おのれMeta……。

ちなみにデバイス特有の問題なので、Questを使用したPCVRでも同じ色味です。ですので、普段からQuestしかHMDを持っていない人は、この問題に気づきにくいです。

ただし、VRChat内で撮影する写真はUnityの正しい色合いと同じなので、見てた景色と何か違う!?って思う形で気づくユーザーはいるかもしれませんね。
(余談:Quest自体のスクリーンショット機能を使うと、見たままの色が撮れます)

一応Virtual Desktopには色補正みたいな機能があるようですが、Quest単体ではVirtual Desktop挟まないのであまり関係のない話になります。

まぁ対策?としては
①細かいことは気にしない(一番楽です)
②Unity上の見た目をQuest側に寄せて調整(上記記事でやってます)
③使用しているShader全てにQuest版のみ色味を変えるコードを入れる(あまり現実的ではない……が過去にやったことはあります)
④視界ジャック的手法で色味を調整する(悪くはないのですが、エフェクト掛けられる側が使用しているシェーダーによって結果がばらつく気がします。あと余計なパフォーマンスを食います)
⑤影響の少ない青や緑をメインでワールドを作る
くらいですかね。

仮にVirtual Desktopみたいに補正する機能があったとしても、ユーザー全員がやってくれるわけではないので、根本的には意味ないんですよね。

Unity⇔Questをひたすら行き来しなければならない苦しみと、求めている色がドンピシャでQuest版で出せない苦しみが、ワールド製作者を責め立てます(補足:PC版は色味が同じなのでUnity上だけで完結して楽です)

先にPC版を作っているとなまじ"正解"を知りすぎてる分、Questに持って行って劣化すればするだけため息が出てきちゃいそうになるんですよね。

気持ち的にはQuestの民にも、綺麗なワールドを見せてあげたいと思うんですが、そのための労力で心が折れてしまう人も居るでしょう。

まぁ大変なんだなぁということを知っておいてくれると嬉しいです。
ちなみに見た目にこだわらなければ、そんなに大変でもないです。こだわればこだわるほど苦しみが深くなります。

あとは少し別の細かい話をするとQuestはLDR(Low Dynamic Range)で0~255の輝度値しか扱えませんが、PCは255以上の輝度値を扱えるHDR(High Dynamic Range)なのでリッチです。
(補足:赤緑青のRGBすべてが0だと黒色、全てが255だと白色です)

PC版でPostProcessのBloom機能を使うと、255を超えた輝度値をぼかして、周りににじんだ状態で表示してくれます。
(ようは輝いている感じのエフェクトになる)

QuestはそれがないのでPostProcessのBloomに頼りすぎていると、違いに苦しむことになるでしょう。バリバリにHDRの色味にしていると255の壁でスパッと切られて味気の無い感じになるでしょう。

②超Z-fightingする

先ほど紹介した①と同列一位くらいの苦手ポイントです。

Z-fighting自体の説明を軽くすると、2つ以上のオブジェクトが全く同じ位置に重なっている時、
『俺が前だ!!』
『いや、私が前だよ!!』
という醜い戦いが起こり、チラチラします。凄く目立ちます。
(Zは奥行きなので、奥行き方向の戦いという意味でZ-fighting)

ところがQuest版はPCVRに比べて精度が半分と言われています。
そのためZ-fightingが起こりやすくなっています。

具体的には0.01m(=1cm)も離れてたら、別の座標にあると思いますよね?
Quest版では残念ながら同じ座標になってしまうんですね~。

一応、プレイヤーが参照するカメラのNearとFarの間を縮めると、精度が縮めた分だけ細かくなり、Z-fightingしづらくなる……のですが、その分至近距離と遠くが見えなくなるので悲しくなります。

そして、何故かここら辺の一般的なZ-fighting対策をしても、QuestのZ-fightingはピンピンしていることが多いです。

私がよくしんどいなと良く思うのは水面です。
大体、水面があると地面があって、接しているじゃないですか?

こういうの

その境界がちらつきます。おしまいです。
マジでどうしろと言うんだ……。しかもかなり遠くから視認できるんですよね、このチラつき。

最近のワールドだと水面が遠景にあることをいいことに、水底をガッと削り取り、水の位置の位置を地面の下に下げることで地面と接しないようにしたり、そもそも水を消してしまったりと、そういう"誤魔化し"を沢山しています。

ただ最近、知り合いのワールド製作者たちとこの話題になった時に、『Quest2の機種依存問題』らしいという話を聞きました。

確かに昔Z-fightingしていたところを見に行ったところ、微妙に上下に動いて不安定な感じに見えるけど、fightingしているようなちらつきは無くなっていました。

なので
『みんな早くQuest3になれ~~~~~~~~~~~~~~~~』
って気持ちになってます。

ですが、それは数年後の話だと思うので、しばらくは頑張って何とかするしかないですね……ぐったり……。


①と②はひどく労力を割いても、かなりしんどい問題でしたが、ここからは気を付けていればどうにかなる話をしていきます。

③パフォーマンスが低い

軽量化、ワールド製作者の腕の見せ所となります。

とはいえQuestはそもそものスペックが低いので、あまり贅沢なことはできません。

PCVRで90FPSサクサク軽量ワールドでも、Quest単機だと30FPSとかってケースはまぁまぁあります(というかPC版先行で作成すると、30FPSでも出てるほうって言われるQuest単機のスペックよ……)

一般的な軽量化技法は勿論通用しますし、フル活用するのですが、Questでの特殊なポイントとしては、PCVRでは全く問題ないポリゴン数でパフォーマンスが落ちていることが多いです。

そこで私が良くやることとしては、最近アバターの軽量化で有名になったMantis LOD Editorを使用して、ポリゴンをガリガリ削ることです。

内緒にしてたテクニックなんですが、アセットが有名になっちゃったので教えてもいいか……と思っていましたが、LilさんがlilNDMFMeshSimplifierとかいう非破壊でポリゴンリダクション出来るやつを出したそうです。
……無料上位互換か?(筆者は相変わらずMantisLODEditor使ってます。非破壊アドオン別に出している人も居ますからね)

目安的にはやっぱり画面内に表示されるポリゴン数が、100万ポリゴン切れると落ち着いてくるイメージがあります。

バッチ数は少なければ少ないほどいいですが、300くらいまでなら結構FPS出せる余地はある気がします。

あと半透明はかなり厳しいので、模様とかの無い目立たないガラスはすっぱり非表示にしたりします。思い切りは大事。

④同プロジェクトでQuest対応しようとすると、PC版の設定をうっかり破壊しやすい

これよく、『みんなどうしてるんですか?』と話題にはなります。

PC版と同じプロジェクトでAndroid(Quest)プラットフォームにSwitch Platformするとその時点では問題ないのですが、Quest用にマテリアル等をそのままいじっては駄目です。複製していじる必要があります。

複製せずにさわって、Quest用にマテリアル等を整えてしまうと、後でPC版に戻したときにマテリアルがQuestの時の見た目になってしまっていて、頑張ってPC版で調整した時設定は失われてしまう……という悲しい悲劇が起こります。

私はどうしているのかというと、『PC版これで100%完成!もう調整するところない!!』ってレベルまで持ってって、プロジェクトごと複製して、複製したほうをQuest版プロジェクトとします。これなら絶対安心です。

デメリットは『あ、あれ追加し忘れてた……』ってなった時に両方で作業しないといけないのと、それが同期するオブジェクトだった時に結構めんどくさくなります(networkIDというのでPC⇔Quest間の同期が図られているので、プロジェクトを分けてそれがズレたりするとキチンと同期してくれなくなります)

あとは頻繁にアップデートしたいワールドとかはとっても困ると思います。

ですので人によってはVCCで導入できるEasyQuestSwitchを使うって人も結構多い気がしますね。
(まぁこれもうっかり追加し忘れることあるので、私はそれでプロジェクト分ける派閥ですね)

⑤アップロード制限100MBまで

Questがダウンロードできる容量を考えると100MBが精一杯なのかもしれませんが、これ結構きついです。

軽量化テクニックも割と『負荷を減らすために、計算結果を事前保存しておく』ということをします。

つまり、容量に余裕があれば軽量化出来る部分は増えるんですが、100MBの制限があるということで、残念ながらそんなに沢山のデータを保存しておくことができません。世知辛いですね……。もう50MBくらい増やしてもらえないかな~チラッ……って感じ。

⑥綺麗な水シェーダーがない

難しいポイントというか、私は結構水が好きなので、超個人的な不満ポイントですね。Questで満足できるくらいのクオリティの水シェーダーがありません。

PC版は影付きのリアルタイムライトで有効化された深度由来の贅沢なエフェクトを使っていて、かなりリッチな見た目になっているケースが多いです。

ところがQuest版は影付きリアルタイムライトが禁止されているので、
『奥行きに応じて水の色を濃くなる』
『水底にコースティクスの模様ができる』
『水を通して映っている景色がボケたり歪んだりしているのが揺れる』
『地形と接している部分が泡立つ』
といった、”水らしい”要素が一気に削られます。

よってQuestではこれらをごまかしたり、別の形で実装したりする必要があります。

例えば、『奥行きに応じて水の色を濃くなる』は深いところほど地面テクスチャに水の色を付けるとかですかね。水面上から見た時はごまかせます。

『水底にコースティクスの模様ができる』は水底に直接模様をUVスクロールさせちゃう感じですね。これら二つはUnlitWFというシェーダーに機能があります。

一方で、『水を通して映っている景色がボケたり歪んだりしているのが揺れる』は残念ですが、これは諦めですね。代替は私の知る限りではないです。

『地形と接している部分が泡立つ』はモデル側に深さ情報を仕込んで、シェーダーで呼び出せばある程度それっぽくなります。
(やっているシェーダーはちょっと知らないです。自分は自作で星々のとまり木というワールドで泡ではないですが模様を付けてます。あと、あそこでは水面の色も深さ由来にしてた気がしますね)

⑦Questの同期の限界(2024/12/01 追記)

とみーさんからQuestの同期の限界について知見を頂いたので、追記という形でまとめて置こうと思います。

とみーさんのことを軽く紹介しておきますと、PC/Questの両対応ゲームワールドを沢山手掛けていらっしゃる方で、他にもBoothでUdonSharpやParticleSystemの解説本やUdonのギミックを販売なさっている方です。
(個人的には『VRChat ワールドギミック 100サンプル集』がイチオシですね)

ゲームワールドは一般のワールドに比べて、同期するものが非常に多いため独自の知見が大量にありそうですが、そのようなワールドを数多く手がけているとみーさんに教えて頂いた知見は、以下のツリーになります。

通信速度が間に合わないというのはどういうことなんだろうと思いましたが、掘り下げてお伺いさせていただいたところ、以下のような知見を頂きました。

これ、なるほどな~って思いました。

確かにQuestの人って、全体のどれくらいを占めているのかは分かりませんが、5Gルーターによる無線化をしている人が多そうなイメージがあります。

ですので、その通信量でギリギリまで圧迫されていれば、Udonの通信がQuest/ルーター間で詰まっちゃうのはかなりありそうな話だな、と非常に納得できました。
(まさかのUdonのネットワーク通信量制限以前の問題とは……)

というかそこまでいくと、一般のゲーム開発じみてきて恐ろしい話ですね。

筆者的には、Questでは大抵のUdonギミックは互換性を持ってキチンと動く気がしていたので、通信量に対する知見はほぼなかったのですが、中々思いもよらないところで問題が発生するのだな~としみじみ思いました。

この場を借りて、お礼を申し上げます。
とみーさんありがとうございます!!

Quest対応するメリットについて

まぁあんまり辛いポイントの話しすぎてもあれなので、良い点についてもお話ししておきましょう。

基本的には訪れる人が倍くらいになるといった感じでしょうか?対応していないと対応しているケースでVisit数はそれくらい異なるイメージがあります。倍増はぶっちゃけ魅力的ですよね。

やっぱりQuest単機の人から見た時にNewカテゴリに結構長い間ワールドが乗っているのも、Visit数が増える理由なんでしょうね。

ただしそれがFavorite数に結びつくかと言われるとまぁそうではないですね。

個人的には上手く対応できているワールドは伸びている気がしますが、Quest対応を上手くやるには、『ワールドの構想時点からQuest対応を視野に入れてPC版を製作している』必要があるので、それ相応の経験値が必要になる気はしています。

Quest2の人へ、Quest3オススメです

ワールド作ってQuest対応している時の対応時に体感していることとして、パフォーマンスが2倍近いです。

FPSがほぼ倍近く出ている時があるので、スペック的にはかなりアップしている気がします。

もちろん②で説明したように、Z-fightingのチラつきもかなりマシになっている感じがあります。

みんなQuest3になってくると、若干贅沢なことしても十分なFPSが確保できるようになるので、ワールド製作者的にはユーザーがQuest3になってくれると嬉しいことばかりです。

Quest2ぼろぼろでそろそろ乗り換えなきゃなってなっている人は是非検討してみてください。

最後に

まぁこんな感じで色々苦労しつつQuest対応版を作成しているんだよ~って話でした。

例えば私のワールド製作に5ヵ月とかかかったワールドでは、Quest対応のために約2週間くらいが割かれています。

ここら辺の苦労を知らずに、軽率にワールド製作者に対して『Quest対応しろ』とか言ってると、全くQuest対応してくれなくなるかもしれないので気を付けてくださいね。

現在VRChatのロードマップには『Build & Test on mobile devices』とありますが、おそらく①のQuestの色味問題まで考慮はしてくれないと思うので、それが来てもしんどいままでしょうね。

いつの日かもっと簡単にテストできる環境が出来てくれたらいいなぁと思いつつこの文章を締めたいと思います。

読了ありがとうございました。



おまけ(2024/12/01 記述が間違っていたので修正、申し訳ない…)

折角なので少しだけ技術的な話をします。

PCはDirectX、QuestはOpenGLというAPIで動いています。
この二つではUVの上下や、Normalmapの緑チャンネルの反転、深度のレンジの違いなど、差異があります。

Unityではこの差異をイイ感じに埋めるようにビルド時変換してくれます。なのでUnity上はDirectXOpenGL方式でデータを取り扱えばOKです。
(逆だったので修正、大変失礼いたしました。UnityはOpenGL方式です)

ところがランタイム……すなわちゲーム実行中に作成したデータはその方式での取り扱いをされ、変換が挟まりません。PCであればDirectX仕様、QuestであればOpenGL仕様で扱われます。

それによりちゃんとした結果が出ないことがあります。特にRenderTextureを取り扱う場合や、持ち込みのカメラで無理矢理深度(Depth)を取り扱う場合などは特に注意する必要があります。

Shader使いや3DモデラーでNormalmapを作る人などは少しだけ頭に入れておくとよいかもしれません。

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