※この記事は2019/6月時点での情報です。Quest対応ワールドを増やしたい?増やしたくない?「OculusQuestがVRChat用端末に割といいぞ。RedFlagを作る間に得たtipsを適当に書きます。いっても、このワールドは当初からQuest対応するつもりはなかったんだけど、適当にポチポチしたらわりかしQuestで動いてしまい、見栄えもまあまあできたという経緯。基本的にQuestをターゲットに書いているが、基本すべてのことはPC版でも有効になるはずなので軽量&イカしたライティングのワールドを作るときの参考になるかもしれない基本コンセプト。Quest用に作る、PC向け表現を分ける。公式ドキュメントに書いてある通り「PC向けを先に作って、Quest向けに軽量化する」よりは「Quest向けに作って、そのあとPC向けに最適化する」方が楽、と思われる。「PC用/Quest用プロジェクトを作って云々...、って大変そう。オブジェクト類は全部同じ配置じゃないといけないんでしょ?プロジェクト2つをちゃんと同じにそろえるのって大変じゃん」と思うかもしれないが、Quest用Avatar開発で言われてるのと同様、「どっちかのプラットフォームで作って、UnityプロジェクトのSwitchPlatformする」だけで2環境を切り替えて開発でき、オブジェクト配置は同じにできる。最終的には、PC用でアップ→switchPlatform→Quest用でアップ(PC/Questは逆でもよい)、の3ステップでCrossplatformなワールドがパブリッシュできるPostProcessingStackのようなPC専用機能は、Quest向けにそのままアップロードしても無効化されるのでわざわざ切り替える必要はない。テクスチャについては、Unityのプラットフォームごとのオーバーライドという機能を使えば、自動で環境ごとにリサイズして出力ができる。Quest用シェーダーはPCでも動く、のでQuest向けシェーダーでPCワールドを構築してしまえばそのまま両対応なワールドが出来上がる。Quest基準で全部作ってしまえば、例えば透明マテリアル(Transparent)や特殊な表現シェーダー、VideoPlayerまでPCで使えなくなってしまう。そこについては切り替えるしかない。PCで作っておいてQuestでアップロードするときは該当GameObjecetのEnableを切るとか。PCのガラス表現は別メッシュにしておいて、Quest側ではMeshRenderをDisableにしておく、とかということでPCとQuest用ワールドの差異をQuestに揃えてできるだけ減らす、または自動処理に任せてしまうことで、やるべきことを単純化しておくと案外できる実際作るときの作業フローは、PC/Questどちらかの環境向けでビルドして編集/確認をし、適度に途中/最後でPC/Quest両方をアップロードして最終確認することになる自分の動作チェックは主にPCでやっているが、Questでの検証が捗るならそちら基準でもよい。UnityのSwitchPlatform操作はAssetの量によるが数分PCが使えなくなるので、頻繁に切り替えたくはないだろう。基本はPC/Questどっちかで開発をすすめ、いい感じの出来になったところで、Switchしてもう片方で動作チェックするのが良いと思われるQuest向けセットアップをする。公式ドキュメントに従う。SwitchPlatformをしようとすると、UnityAndroidSDKのダウンロード&インストールが促されるのでそれに従う。インストールしUnityを再起動すると、SwitchPlatformが押せるようになるあとは普通にワールド作成をする。prefabをD&Dしてもいい。各種有志が公開しているワールド作成キットもいいぞ。ナルさんのStarterKitにはお世話になりました。SDKにVRChat/Mobile/xxxxx系シェーダーがあるので、それを使う。ベストはDiffuseあたりのだと思われるが、色指定ができないのでStandardから移行しようとしている人は大変だ。やるなら、色テクスチャを用意して必要に応じてモデル側にUV割り当てたりとかして、マテリアル統合とかするべきとは思うが、しんどい。そこでVRC公式は移行しやすいよう、StandardLiteシェーダーを用意してくれたので、とりあえずはそれを使ってしまうが楽だ*1。Cube並べ勢にはこのシェーダー追加は朗報だった。パフォーマンス改善は悪くなってから考えても遅くない*2(PC含め)Questでもイケるイカしたライティングをする雰囲気をよくするにはライトを使え、ということでざっくりお勉強してきましょう。Unityで一般的なライトの把握。QiitaQuest版VRChatではDirectionalLightぐらいしかリアルタイムライトは使えません。あと、Environment(Ambient)も行ける(と思う)。いっても影要らなかったらDirectionalLightも要らんPointLightやEmission付きオブジェクトをばらまいて、ベイクすると(レンダリング軽いのに)シックでエモくなる。オススメLightprobe付けると、アバターとかにちゃんと明るさが反映される。オススメPC用ならReflectionProbeを置くとテカテカした人たちが良い感じになるのでこれをやっていく。やっていき!ライトをベイクしろ?公式は言っている「ベイクは必須です。リアルタイムライトは激重だ。Lightmapとprobe使え。Lightmapも低解像度で十分綺麗だから」「大丈夫だ。一般的にライトをリアルタイム処理すると重い。光の当たり方を事前に計算して、テクスチャに"焼き込んで"おくと、リアルタイムじゃないのにそれっぽい陰が作れる!というのがベイク処理(bake:焼く)。ベイク」とか「アンビエントオクルージョン」とかググってLightingウインドウ*3を開いて。これでリアルタイムライトは機能しなくなり、負荷が軽くなる動かないオブジェクトのinspectorを開いて、右上のstaticをチェックする。ライトは全部Modeをbakedにする。これによって、オブジェクトやライトがベイクの対象になる。逆に動くオブジェクト、PickupやAnimatorで動くものはチェックしないこと。Lightmapを押そう。するとちょっと待たされた後、ベイクされる。Sceneウインドウのワールドがシックになってるはずだ。Unity便利ですごいAmbientOcclusionをオンにしてもいいだろう。凹みとかの陰が追加されるが、Lightmap解像度が低いと陰が回り込んでしまって、却って汚くなるかもしれない。この辺は様子を見て選ぼう内部的には影のテクスチャ画像を生成して持つため、データサイズが大きい。雑にベイクするとあっさり10MBオーバーのワールドになる。しょうがないにゃあ...とりあえずできたがQuest用は汚いし、データサイズもデカくてひどい*4。ベイク情報(Lightmap)を軽くする&&縞々で汚いのを対処する。LightmapSettingsを詰めよう。なんで縞々かというと、画像の圧縮ノイズだ。ASTC形式にすればマシのようだ)ようで、今回ほしいベイクテクスチャ(Lightmap)では特性が合わず、いい見た目にならないようだ*5。圧縮Compressionのチェックを外す。これは未圧縮になるためデータサイズが大きくなるので、併せて以下も行うなんでサイズが大きいかというと、Unityがめっちゃ細かい影テクスチャを吐いていることに他ならない。なだらか~に明るい/暗いのが付けば雰囲気として今回はいいので、解像度を下げよう*6。resolutionを40→10とした。これでサイズは理屈の上では1/16になるはずだなお、影解像度の低下が目立つ場合は、目立つGameObjectのLightmapだけ解像度を上げる手がある。lightmapを大きくすると、そのRendererだけLightmapの解像度があがる、とのこと。ほどほどに小さい方が細切れになってメモリを効率よく使えそうだが、収まるなら少ない枚数のテクスチャに収まった方がいい気がする*7。極端に小さかったり大きかったりしなければいいのかな?最初に比べて解像度は1/4、Lightmapテクスチャは1/16になったが、なだらかできれいな影が付いた。データサイズも半分になり快適。ぶっちゃけ、PCでもこの解像度でいいやと思う程度には十分な品質だ*8*9LightProbeって何?LightProbe/LightProbeGroupというのは、Quest版VRChatでは「その空間明るさ情報」を事前計算した点、とそれをまとめたグループ。これがあると、ワールドの明るいところにいるアバターやモデルは明るく、暗いところにいるアバターやモデルは暗くなる*10。色が付いたライトがあればその色が付く。probeから離れた場所では、周辺のrobeから平均をとって明るさを計算してくれる。テラシュールブログあたりで詳細を内部的な話をすると、データはprobeごとに色情報の数値として保存されるらしく、データサイズは非常に小さい。極端に多くなければ、ぽこぽこprobeを置いてやって良いと思われる。*11基本的には「周辺の光がつよいところ(光源の近くやEmission付きマテリアルが光ってる近く)」と「暗いところ」と「光の強さが急に変わるところ(光線が遮蔽されてる壁)」に置くといいらしい。自動化ツールもあるらしいので、それを使うのもよさそうだ(が、自分は手配置した)Unity上ではLightProbeごとに線が引かれ、LightProbeの範囲が表示される。この空間内/近くなら、それっぽく明るさが決まるということだReflectionProbeって何?(Quest不要/PC専用)ReflectionProbeはReflection、つまり反射の表現に使われる。鏡のように磨かれた鉄球に周囲の風景が映る、みたいなのをそれっぽく表現するための技術。これがあると、ワールド内に反射するものがあるか、反射するシェーダー付きのアバターがいるときにちゃんと風景が映って見える。フルフルにこれも計算すると重いので、ワールドの一部領域ごとに事前に360°撮影したテクスチャを用意しておき、その場所に来た時反射物にペタっと張ってそれらしく表現する。これはシェーダー制限によってQuestにはないはず。内部的には、前述のように360°画像テクスチャを持っているのでデータサイズは大きくなりがち。いっても、らしく反射すればいいのでそんな大きな解像度は割り当てなくていいんじゃないかな。部屋などの、周辺の風景がガラッと変わる場所ごとにProbeを設置する、ことが重要と思われる。反射オブジェクトがなければ作らなくてもいいモノだが、中には反射マテリアルを付けたアバターがあなたのワールドを訪問するかもしれない。いう時はとりあえず1個置いてあると、極端に変にならないのではないか?(消極的対応)ちなみにReflectionProbeがない場合、反射マテリアルはSkyboxなどの背景を使うようだ。Probeがないと「部屋の中にいるのに、反射マテリアルには空が写ってる」ということが起きうるオクルージョンカリングって?まだ自分は手を出せてない。詳しくはUnity公式説明を読んで。視界外かどうかを事前計算しておいて、GameObjectごと消すことで処理を軽くする。広いワールドや、部屋がたくさん分かれたワールドを作るときに思い出すとよさそうだが、現行小さめのワールドが多いQuestでそういうワールドが来る機会はあるのだろうか?探索して遊ぶワールドとかにはいいかもしれない?モデルのテクスチャサイズをプラットフォーム毎に自動的に縮小する&&テクスチャ圧縮をASTC形式にするUnityのプラットフォームごとのオーバーライドという機能を使えば、自動で環境ごとにリサイズして出力ができる。Androidを押すと、環境ごとに自動で設定が切り替える機能が有効になる。あとはSizeなりFormatなりCompressionQualityをいじる。一つ、ASTC形式にする話はページを分けた。ETC/ETC2と比べてかなりキレイなので何も考えずFormatはASTC*12にしてよいと思う最終的にどうなる基本的にはシェーダーをQuest用にするだけでQuest不可なものを除いて、Questワールドは動くはず加えてライトをベイクする。RedFlagは当初10MB程度あったものが、4MB以下になってる。モデルでのテクスチャ利用がほとんどないマップだったとは言え、Lightmap改善だけで半分以下になった。見栄えをそこまで犠牲にせず、ロードも早くなって実によい。VRC_xxx系コンポーネントはVideoPlayer以外制限が緩いそう、気づいてる人はそれなりにいそうだが、VRC_xxxx系コンポーネントや許可されたUnityコンポーネントはだいたいが動く。そこにチャンスはある、と思う。ギミックやゲーム作る人には朗報ではないだろうか?というか今作ってる。当たり前だが、QuestにVRCミラーは重い*13。Questは現状自撮りができないのでミラーは欲しい。離れたら消えるミラー、ON/OFF切り替えできるローカルミラー等を配置しようレンダーテクスチャを使うカメラ(例・ナルさんのStarterKit付属のSimpleCameraなど)は割とすんなり動く。Quest相手にテクスチャサイズはあまり大きくない方が良いだろう。自分は1024pxにしているQuestでは距離に応じてテクスチャ解像度が切り替わるため、細かい文字を遠くから見る場面はつらい。配置するときは注意、近づいて読めるようにしよう他、CrossplatformAvatarワールドや、あたらしいHubやHomeなどVRChat運営が作ったワールドを見て、何となく察する(ミラーの挙動とか解像度とか)究極的にはQuest買って自分で見に行く。いいぞ↑はPC版での見栄え、背景のLightmap書き込みも悪くない質感だが、これでもQuestあわせの低解像度。カメラのフラッシュを見るとPostProcessStackの効果でぼやっとしているのがわかる。これもポチポチするだけで視界がエモくなるので、オススメだぞいかがでしたか?StandardLiteシェーダーをはっつけたCubeを並べ、Lightばらまいて綺麗で軽量なベイクができるだけで、なんかそれらしいQuestワールドは作れる。