Narazaka::Blog

奈良阪という人のなにか

VRChatで10000ポリゴン以内アバター持ちが超雑にOculus Quest対応する方法(素人)

☆2019年11月17日に最新事情に合わせて色々更新しました

4000ポリゴンのふんわりローポリアバター1体自作しただけの素人ですが、ローポリの時代が来た(?)と言うことで書いてみました。

f:id:narazaka:20190412155720p:plain
プレステっぽいってよく言われます

Oculus Questが来た!

VRChatがOculus Questに対応するとのことで、そのときのアバター・ワールド要件が発表されました。 docs.google.com

条件についての詳細はこっち docs.vrchat.com

解説はこちらに詳しい vrmizunana.hatenablog.com

アバターについてざっくり要点をまとめると

  • PC用とQuest用のアバターは別データ
  • PC用のみしかない場合QuestにはVRChatデフォルトアバター(ロボットの胸にアバターサムネイルが出るもの)が表示される
  • Quest用アバターはUnityでAndroidビルドの設定にし、PC用と同じblueprint IDでアップロードする必要がある
  • Quest用アバターは以下の制限がかかる

コンポーネントの制約

カテゴリ 制約
容量 10MB以内(ビルド時圧縮後の状態において)
シェーダー VRChat/Mobile以下にあるもの(ただしLightmappedとSkyBoxを除く)のみ
Dynamic Bone 使用不能
Cloth 使用不能
カメラ 使用不能
ライト 使用不能
Post Processing 使用不能(v1、v2とも)
オーディオソース 使用不能
Rigidbody・Collider・Joint系 使用不能

パフォーマンスランク制約

カテゴリ Excellent Good Medium Poor VeryPoor
見え方 必ず見える 見える 見える(デフォルトの制限値) 見える(設定で制限緩和必要) 一応見える(アバターごとに逐一選択して表示させるというアクションをとる)
ポリゴン数 5000 5000 7500 10000 (制限無し)
メッシュ 1 1 2 2 (制限無し)
マテリアル 1 1 2 4 (制限無し)
Animator 1 1 1 2 (制限無し)
ボーン数 75 90 150 150 (制限無し)
パーティクルシステム 0 0 0 2 (制限無し)
合計アクティブパーティクル 0 0 0 200 (制限無し)
メッシュパーティクルアクティブポリ数 0 0 0 400 (制限無し)
パーティクルトレイル・パーティクル衝突 無効 無効 無効 有効 (制限無し)
トレイルレンダラー・ラインレンダラー 0 0 0 1 (制限無し)

その他努力目標

カテゴリ 努力目標
容量 5~8MB以下にするべき
ドローコール 3以下にするべき
メッシュ(Skinned Mesh Renderer)数 1つのみにすべき。アニメーションやその他動きはシェイプキーかボーンで実装するべき。
マテリアル GPU Instancingを有効にするべき。
テクスチャ 1K(1024x1024)以内にするべき。
ボーン数 66(Standard Humanoidの数)以下に少なくするべき。そもそもDynamic Bone不可なので増やす必要がなく不要なのは削除するべき。

現時点では明確に制限付きなのはDynamic Bone等コンポーネント全面禁止が主で、ポリゴン数等各種値は実は単に努力目標です。

恐らく明確な制限の内で一番強いのは、Dynamic Bone等よりも、シェーダーがVRChat組み込みのみという所。 つまり日本コミュニティの人型アバターで使われるArkToonとかReflexとかUTSとかまんまるとかが軒並みアウト。 多くのアバターにとって恐らくこれが最大の苦労ポイントになると思います。

また一方で、逐一表示アクションをとってもらう必要はありますが、VeryPoorでも一応表示は可能であるというのが重要なポイントです。 なのでつまり実はPCアバターポリゴン数等を全く減らさずにシェーダーだけ変更してQuest用アップロードするという手段でも、なんとか無理矢理Quest民に見てもらうことは可能です。

ちなみにQuestの人と実地検証したところ、アニメーションオーバーライド有効(表情変えられる)、エモートスイッチ有効、コライダージャンプ有効という感じらしいので、本当に制約があるのはシェーダーと各種コンポーネントだけの模様です。

なおQuestの人はQuest用があるワールドのみにしか行けないので、既存のPCオンリー用ワールドでプレイするときに知らない間にQuestの人が来てデフォアバターとして表示されるってことはないっぽいです。

つまりそういう不意なコミュニケーションミスを避けるためにQuest用アバターをアップロードしないといけないって話ではなさそうで、Quest対応ワールドに行くときにあると良いかもねって言う温度感な気がしますね。

超雑にQuest用アバターにする

明確な制限がないとは言え、好き勝手アップロードしてQuestユーザーを落とす激重アバターにしては意味がないので、おおむね制約内に作るのがよさげでしょう。

とりあえず自分がblenderで元々4000ポリゴン自作アバター(ポリ数少ないだけで最適化はしてない)を作ってたので、ポリ数制約を満たしている既存アバターがあるところからQuest用アバターを作る手段をメモっとこうと思います。

シェーダー表現やダイナミックボーン他諸々を潔くざくっと切り捨ててとりあえず対応する雑な感じですが、まあ今後の参考になれば……。

目指すのは

  • 10000ポリゴン以内(達成済み)
  • メッシュが一つ
  • テクスチャも一つ
  • マテリアルも一つ
  • ローポリに嬉しい裏面描画可能なUnlit系シェーダー
  • その他の設定はとりあえずなし

といった雑な感じのアバターです。

アバター1つ作っただけの初心者素人が調べつつ書いたやつなので、間違いの指摘やよりよい手段の提案があればコメントしてください。

あとこの記事が「超雑」と冠する理由の一つでもあるんですが、筆者はOculus Questを持ってないので、これが本当に問題なく表示されるか確認してない(できない)です。

あくまで仕様制約に乗っ取ってやってみた系記事なので、ダメだったらコメントください。

とはいえある程度一般的な最適化手順等を踏んでいると思うので、最適化してない雑アバターをPC用でも最適化しとくかーという話にも使えると思います。 そのレベルでは確認してるので、そこまで巻き戻りはないと信じたい……。

なお全体的にうっかり保存すると巻き戻しが難しい作業になるので予め別名保存しておくのが良いと思います。

裏面メッシュを作る(必要なら)

blender(2.79前提)作業です。

Questで使えるVRChat/Mobile以下のシェーダーは両面描画(Cul Off)をサポートしません

1枚のポリゴンで両面を描画する手法を使っている場合は、Questでは裏面が表示されず意図した表示ができなくなるので対応が必要となります(ローポリアバターでポリ数節約のためにしばしば使われる)。

(両面描画は行っていない、もしくは行っていてもあまり気にならないので対応不要だと思う場合はこの項目はスルーして、メッシュを統合するに進んでください。)

今回自分のアバターでは髪の毛で両面描画を行っていたので、裏面メッシュを作りたいと思います。

f:id:narazaka:20191117143139p:plain

とりあえず当該のオブジェクトを選択してShift+D→Enterで同位置に複製オブジェクトを作ります。

f:id:narazaka:20191117143316p:plain

複製後のオブジェクトを編集モードで裏面がいらなさそうなメッシュを削除します。

f:id:narazaka:20191117143516p:plain
裏から見えなさそうな所はポリ数削減のために削除

さてここから「面の反転(法線の反転)」という作業を行います。

3Dモデルの面は「表裏どちら向きの面か」という情報(法線)を持っています。これを逆向きの面にすることで裏面メッシュにします。

法線が分かるように表示を変えましょう。まずは編集モードで3Dビューの右上の+マークをクリックしてパネルを出します。

f:id:narazaka:20191117143645p:plain
右上の+マークをクリック

そのパネルを下の方にスクロールしていくと法線の項目があるので、面っぽいやつを有効にします。

f:id:narazaka:20191117144248p:plain

f:id:narazaka:20191117144329p:plain
面ぽいやつを有効

その状態でaキーでメッシュ全選択するとこのようにとげとげが外向きに出ている図になると思います。

f:id:narazaka:20191117144459p:plain
とげとげが「法線」

そのまま全メッシュを選択した状態で「W」キーを押して出るメニューから

f:id:narazaka:20191117145106p:plain
面を反転

「面を反転」を行うと面が反転されます。これで裏面対応は完了です。

f:id:narazaka:20191117145158p:plain
とげとげが内向きになった

メッシュを統合する

blender作業です。

一つのメッシュにするためにオブジェクト分かれてるのを一つに結合してしまいます。 元々一つの場合はスキップ。

まずミラー(モディファイアー)を使っているオブジェクトと使っていないオブジェクトが混在している場合、モディファイアーを適用してから統合しましょう(モディファイアーはオブジェクト単位なので、これをやっとかないと変にミラー適用されたりされなかったりして見た目が壊れます)。

f:id:narazaka:20190412113837p:plain

アバターを構成するオブジェクトを全部選択して

f:id:narazaka:20190412051358p:plain
オブジェクトのツリーからShiftおしながらクリックで選択できます

Ctrl+Jで結合します。

f:id:narazaka:20190412051641p:plain
メニューからだとこれ

オブジェクトを結合しても統合前それぞれに設定していたUVやテクスチャは特に問題なく1つのオブジェクトに複数設定される形になって、元と変わりなく見えるみたいです。

なんか表示されないとか変になった場合は以下が参考になったりするかも? iruyi.blogspot.com

テクスチャ・マテリアルを統合する

blender作業です。

テクスチャ・マテリアルも複数に分かれているのを統合してしまいます。 元々一つの場合はスキップ。

「ベイク」と呼ばれる方法を使うようです。(素人なので伝聞形)

以下の記事ほぼそのまんまやったら上手くいきました。

www.wwwmaplesyrup-cs6.work

Mesh BakerというUnityツールもあるみたいだけど、微妙に値がはるし元々blenderだしそっちでやります。

なお上記記事は英語UIですが、この記事は以下の感じで設定済みの日本語UIでやります。

blender-cg.net

(0) 先にオブジェクトを統合しておく

前項の感じで統合しておきます。

基本的に編集モードでUVをまとめるので、オブジェクトが一つじゃないと出来なさそうな感じがあります。 (調べていないのでもしかしたら複数オブジェクトでも出来るのかも知れませんが、今回はメッシュもマテリアルもテクスチャも一つにするのが目標なのでどのみち関係ないです。)

(1) 既存テクスチャに「UVマップ」を設定

統合したいテクスチャが設定されてるオブジェクトのテクスチャタブ→マッピング→マップに「UVマップ」を設定します(下の方にあるのでスクロールすると出てくると思います)

f:id:narazaka:20190412112242p:plain

(2) UVを一つにまとめる

オブジェクトデータタブから

f:id:narazaka:20190412112533p:plain

+ボタンを押して新しいUVマッピングを作ります(名前は適当)

f:id:narazaka:20190412112703p:plain

(元記事の手順に従っているだけなので)この項目がどういう物なのかはいまいち把握していませんが、結果から推察すると、 マテリアルに指定されたテクスチャをオブジェクトのどこに表示するかというUV展開のセット(1オブジェクトにマテリアルが複数定義可能なので複数のUVがある)を、あるオブジェクトに対して複数定義できる機能っぽい……?です。

上記手順はその定義する領域の追加処理で、テクスチャが分かれた状態の既存のUVマッピングセットとは別に統合テクスチャに対しての新しいUVマッピングセットを作るといった感じですね(たぶん……)。

さて、この新しいUVマッピングを選択したまま(上画像の状態)、オブジェクトを編集モードにして頂点を全選択(「A」キーを押すと全選択と全解除ができます)。

f:id:narazaka:20190412114149p:plain
この画像のように既存のUVが重なってわけがわからない状態になってる場合、UVマップが既存の「UVマップ」選択になっている可能性があるので要確認!

「U」キーをおして出てくるメニューから「スマートUV投影」を選択します。

f:id:narazaka:20190412114706p:plain
ショートカットだと「U」キー→「スマートUV投影」

パラメーター設定のウインドウが出てくるんですが、元記事の通り「島の余白」(自動でシームが切られて分割されるUVのまとまりを配置する余白?)を0.06にして「OK」

f:id:narazaka:20190412115205p:plain
島の余白0.06

するとUVが平面上に重ならないようにまとまったやつが出来ます。

f:id:narazaka:20190412115634p:plain
全部位のUVが平面にまとまっている

(3) 既存テクスチャをまとめたUVに従ってベイクする

これでUVが自動で一つになったので、既存の分かれたテクスチャもそのUVに合わせて自動で一つにします。

UVに対応するテクスチャを用意するため、UV/画像エディタで「画像」→「新規画像」を選択します。

f:id:narazaka:20190412115838p:plain
Alt-N

VRChat Quest的には1024x1024以下が良いとのことなのでとりあえずそのサイズでOK。

「アルファ」はUVが当たっていない場所がアルファで抜かれる画像になるらしい(後で画像編集するならどこがUV領域か分かって便利?)ですが、テクスチャ少しでも軽くしたいなら切っておく方が良いかな……?となんとなく思ってチェック外しました。つけといてもいいかもしれません。

f:id:narazaka:20190412120405p:plain

結果。UV背景が真っ黒に。

f:id:narazaka:20190412120339p:plain

こうなった状態(スマートUV投影後のUVとブランク画像が選択されている状態)のまま、写真マークのレンダータブで、やはり下の方にあって多分畳まれてる「ベイク」の項目を展開します。

f:id:narazaka:20190412120711p:plain
モデリング時全然使わなかった写真マーク、「レンダー」というらしいです

f:id:narazaka:20190412120942p:plain
「ベイク」は下から2番目でした

ここで「ベイクモード」を「テクスチャ」に切り替えます。(デフォルトの「フルレンダー」だと影とか入っちゃうので)

f:id:narazaka:20190412121019p:plain
ベイクモード→テクスチャ

「ベイク」ボタンを押します。

f:id:narazaka:20190412121117p:plain
でかくて選択UIっぽいけどボタンです

すると自動で既存テクスチャからUVに従って座標変換されて色が置かれ、さっき作った新しいテクスチャ画像にまとまります。

f:id:narazaka:20190412121310p:plain

で、この画像をマテリアルに設定するためにどこかに保存します。

f:id:narazaka:20190412121639p:plain
F3

(4) ベイクしたテクスチャを新しい一つのマテリアルに適用する

マテリアルタブからマテリアルを新規に作ります。

f:id:narazaka:20190412121901p:plain
+ボタンを押して「マテリアルスロット」を新規に作り
f:id:narazaka:20190412122041p:plain
その状態でさらに下の「新規」ボタンを押すとマテリアルが出来るらしい
f:id:narazaka:20190412122345p:plain
白いマテリアルが出来ます

このマテリアルを選択した状態でテクスチャタブに行き(なぜかスクロールが下いっぱいになっている場合があるのでその場合上にスクロール)、ここでも「新規」ボタンでテクスチャを作ります。

f:id:narazaka:20190412122731p:plain

さらに下のほう「画像を開く」からさっき保存したベイク済みテクスチャを開きます。

f:id:narazaka:20190412122851p:plain
画像を開いてさっき保存したベイク済みテクスチャを選択

f:id:narazaka:20190412123031p:plain
なんだかわけわからんプレビューになると思う
f:id:narazaka:20190412123111p:plain
マテリアルタブに戻ってちゃんとテクスチャが適用されていることを確認

これで複数あったテクスチャとマテリアルを1つに統合できました。

不要になった元のマテリアルを削除していきます。

f:id:narazaka:20190412123255p:plain
-ボタンでマテリアルスロットを削除
f:id:narazaka:20190412123417p:plain
削除中なんかヤバい見た目になるけどスルーしよう
f:id:narazaka:20190412123609p:plain
マテリアル一つの状態に

あとUVマップも最初に選択した「UVマップ」のほうを削除します。

f:id:narazaka:20190412123657p:plain
これも「UVマップ」を選択した時点でヤバい見た目になると思うけどスルー
f:id:narazaka:20190412123741p:plain
ベイク後の物だけの状態に

不要なボーンを削除

Dynamic Boneが動かないので不要なボーンは削除します。(ウエイト振り直しなどが発生することも多いので、Mediumに入るレベルならやらない方がラクかも。)

髪とか胸とかね……

f:id:narazaka:20190412131817p:plain
Dynamic Boneは使えないので……
f:id:narazaka:20190412132012p:plain
ツリーの親を削除しても子が削除されるわけではないので全部選択
f:id:narazaka:20190412131917p:plain

これであとはいつもどおりfbxをエクスポート。

ポリ数10000以下・マテリアルとテクスチャが1つだけのモデルが出来ました。

Unityに持っていく

アバターが出来たのでUnityに持っていきましょう。

SDK更新

VRChatがQuest対応する以前からSDKを更新していない場合は先に更新してください。最新のやつを入れれば問題ないはずです。

fbxインポート

繰り返しますがバックアップを取ってください。(自分はgit管理でやっています)

fbxを普通に新規インポートしてRigを設定して、シーンにそのまま置くか、シーンを新しく作ってそこに置きます。

色々同じ設定使うでしょうしPC用とプロジェクト自体分けるほどでもないと思います(分けても問題ないです)。

f:id:narazaka:20190412131233p:plain
カクカク

カクカクになってたので既存アバターと同じスムージングが効くようにfbxインポートの設定弄ってApply。Rigも忘れず設定します。

f:id:narazaka:20190412131414p:plain
ここは各人設定違うと思うのでそれぞれよしなにしてください

なお新規インポートしてRig再設定とかやるのが微妙に面倒だからと超雑にやるなら、fbxとテクスチャをUnityの既存のとこに上書きしても良いです。(よくあるfbxの更新手順) Unityがよしなにしてくれて、元の構造を保ったままfbx内のオブジェクトだけ変更された感じになります。

ただ制約が強い故にDynamic BoneとかFixed Jointとかどのみち外すことになるので、設定を維持すること自体はあんまり意味ない気がします。 結局ほぼfbx素上げみたいな感じになると思うので。

Avatar Descripter等の設定うつし

シーンに置いたアバターオブジェクトにVRC_Avatar Descripterコンポーネントを追加し、元のアバターからコピペで値をはっつけると良いと思います。

f:id:narazaka:20190412132744p:plain
コピー
f:id:narazaka:20190412132916p:plain
貼り付け

オブジェクトに直接目パチを設定している場合も同じようにコピペで出来ると思います。 シェイプキーはそのままなので、自分のやった感じでは普通に動きました。 f:id:narazaka:20190412140546p:plain

ただこれをやるとアバター動作由来のアニメーターと目パチとでアニメーターが2つになってExcellent判定から外れるのでやらない方が良いかもしれません。

シェーダー設定(Quest実証後追記)

さて、鬼門のシェーダーです。

自分は普段まんまるシェーダー1.4βを使っているのですが、先述の通り「VRChat/Mobile以下のシェーダー」しか使えないという制約があるので、その中から選ばなければなりません。

それ以外のシェーダーを指定した場合、

  • 普通のシェーダーならVRChat/Mobile/Bumped Diffuse
  • パーティクル系シェーダーならVRChat/Mobile/Particles/Additive

あたりにフォールバックされる挙動になり、目的のシェーダーでは描画されないようになります。

基本的に透過がサポートされないため注意が必要です。 どうしても透過が必要な場合はパーティクル系シェーダーをなんとか無理矢理使うみたいな対応になりそう……?

どれもキャラクターを存分に表現するのには恐らく不十分な中で、恐らくVRChat/Mobile/ToonLitが無難な候補かと思います。潔く変更していきましょう。

ちなみに抜け道は無いのかというと、実はアニメーションでマテリアルを書き換えると任意のシェーダーにできるという裏技はあるようです。 どうしても特定シェーダーで無ければ表現できないという場合は、そういった手段を執っても良いと思います。(今のところこの記事では説明しません)

f:id:narazaka:20190528111956p:plain
VRChat/Mobile/Bumped Diffuse (Standard的なやつ)

f:id:narazaka:20191117150424p:plain
VRChat/Mobile/ToonLit(Toon系)

アップロード

以上。アバターは完成です。早速アップロードしましょう。

Dynamic BoneもFixed Jointも使えないし、アニメーションコントローラーや口パクはコピペで持ってきたし、もう設定することはない気がします。

f:id:narazaka:20190412152337p:plain
アバター以外を消して、Directional Lightとかライト系も消すと、SetPass calls(=ドローコール数)が3くらいになって軽いことが分かる

Android用ビルド

Quest用リリースにはAndroidビルドが必要です。

Unityをインストールする際にAndroidビルドツールを除外してインストールした場合は別途インストールする必要があります。

「File」→「Build Settings」を開いてAndroidのとこを選択し、「Open Download Page」からインストーラーをダウンロードできるはずです。

インストールする時にインストール先が空欄になる場合はVRChat用のUnity 2017のフォルダを選択します。

どのUnityフォルダをインストール先にするか分からないという場合は、C:\Program Files\Unity\Editor\Unity.exeあたりを右クリックしてプロパティを出して詳細タブを開くとバージョンが書いてありますので、それで判断すると良いです。

f:id:narazaka:20190412141300p:plain
Unity Hubとかで分からない場合にもバージョン確認可能

あとAndroid SDKが必要という話もあるんですが、自分は既に前に入れてたので、インストール必要ならそれっぽい記事を見てください。 Unity公式の案内はこちらです。 docs.unity3d.com

インストール後Unity開き直してAndroidの項目にいくと画面が変わると思います。

Androidの最小APIレベルを変更

で、これはもしかしたらUnity 5.6時代からのアバターだけかも知れませんが、Androidに変えただけだと警告が出てビルドできません。(すんなりビルド出来そうな場合はスルーしてください。)

f:id:narazaka:20190412141623p:plain

「Color Spaceと現在の設定の非互換性をPlayer Settingsにいって直してくれ」と言う話なのでそちらを開くと、「Linerカラースペースは~~Android 4.3以上が必要」と書いてありました。

f:id:narazaka:20190412141933p:plain
警告がでている

他のOpenGL ES3.0とか云々は満たしてそうなので、ちょっと下の方にあるMinimum API Levelを4.3にすると解消しました。

f:id:narazaka:20190412142257p:plain
最小API Levelを変更

Android用ビルド(再)

警告が出なくなったら左の方にあるSwitch Platformをクリックするとプラットフォームの切り替えが始まります。 これは全リソースの再インポートが入るので、ちょっと時間がかかる可能性があります。(特に色々アセット入れてる場合数分レベルはかかる)

これをPC用とAndroid用で毎回切り替えるのが面倒なので、VRChat公式ではプロジェクトをコピーしてやると良いと書いてありますが、そのままでもできるっちゃできます。

自分は雑なのでそのままやりますが、たとえばGitHub管理(最近プライベートリポジトリ無料になりました!)で2カ所にクローンして同期を取る様にすれば楽かも知れません。

ともかくSwitch Platformです。

f:id:narazaka:20190412142514p:plain

アップロード

長いロードが走った後操作可能になると思うので、そのままいつもと同じようにビルド&アップロードしましょう。

公式によれば、同じblueprint IDでもAndroidビルドとPCビルドで別のデータとしてアップロードするようになっていて、出し分けがされるようです。

念のためいつものアバターのとこにアップロードする前に別のblueprint IDで両方アップロードしてみて具合を見るのも良いかも知れませんね。

上記で目パチ設定をしていなければきっとExcellentになっているのではないでしょうか。 気持ちよくアップロードして、Quest持ってる人に確認してもらいましょう(他力本願)。

f:id:narazaka:20190412144703p:plain
Excellent

まとめ

以上超雑にQuest規格に合わせてアップロードする記事でした。

色々最適な手段じゃない可能性がありますが、アバター制作素人が雑にやってもなんとかなりそうな気がしました。

みなさんもこれを機にローポリでかわいいアバターを作ってOculus Quest一般人をかわいさで圧倒して下さい。

自分は「ECO」こと、かわいいアバターがいっぱい!エミル・クロニクル・オンラインメディス子さん・スノウエルフちゃん等の作者であるアルマジロン先生がモデルを作ってたりしたMMORPG(サービス終了済))アバターを参考にざっくりローポリテイストで自作アバターを作ってますが、あのオーパーツ的ローポリかわいさを色んな人が目指すと良いなと思ってます。

スクショを見て研究すると、こんなに少ない分割でこんなにかわいいアバターが作れるんだ!と発見があると思います。オススメ。

関係ないけどついでに宣伝

上記で説明用に使っている拙作アバターAINAはboothで無料配布しています。そのほかにも色々便利なツールなどあるので覗いてみてください。 narazaka.booth.pm

あと、VRChatのソーシャル機能が弱いので、プロフィール登録とフレンド・インスタンス検索、フレンドへの個人メモが出来るサイトを運営してます。

VRChat APIの制約でちょっとログインが微妙ですが、良かったら使ってください。 vrcprofile.com