ウーパの手習い

私的開発メモ用途なのでご容赦ください。2020年現在はSwiftとUnityでARのお勉強中。

低負荷のVRChat用アバターを模索中

f:id:uuupacom:20180814134548p:plain

VRChat用の自作アバターを製作しています。人が大勢集まるワールドを考慮してのお作法として、できるだけ低負荷のアバターが良いようです。
そのため一般的には、漫画調のトゥーンシェーディングを採用して、テクスチャ枚数や解像度、低負荷シェーダーを使うのが主流ですが、私が作ろうとしているのは上の画像のように、フィギュア人形調の質感があるアバターを作ろうとしています。

そもそも私はVRChat用自作アバターを作るのが初めてですので、基本的にはWeb上の先駆者様の知見をもとに検討します。

とくにぬこみや様の一連のツイートは対応策含めて順序立てて記載されていて参考になりました。

私の場合

低負荷かつフィギュア人形風の表現ということで、要件としては

  1. 質感表現の都合、1マテリアルにつき、アルベド・ノーマル・メタリックの最低3枚のテクスチャが必要
  2. DynamicBoneはできるだけ導入しない
  3. UnityのシェーダーはStandardシェーダーを基本としつつ
  4. ポリゴンの裏面を表示させたい箇所もあるので、シェーダーを少し改修する

これらをふまえて、以下のような方針で考えています。

テクスチャ解像度を下げる

この記事のトップ画像がテクスチャ解像度の検証画像です。SubstanceDesigner上での比較なので、Unityではもう少し全ての質感は下がるかもしれませんが一旦無視します。帽子の模様部分では差が顕著な一方、肌部分は512pxでも大丈夫かもしれません。
これはUVマップの各部位のUV領域のとり方が大きく影響するのが原因なので、模様があるパーツのUVは大き目にしたりと、BlenderでのUV展開作業時に配慮することで、512pxでも大丈夫かもしれません。

f:id:uuupacom:20180814150536p:plain

自作アバターのUV展開。顔の領域は大きくとっていたので512pxでも十分でした。柄物部分などをちゃんと決めてからUV配置を再検討しようと思います

オブジェクトのメッシュ数を少なくする(1メッシュにする)

Blender上で全てのパーツを1オブジェクトにする(Ctrl+J)ことで、Unity上でオブジェクトのメッシュ数を1にできます。これによりDrawCall(Batches, SetPassCalls)数を減らせると考えています。
※極端な理想です。実際には以下に書く理由で悩むことになります

マテリアル数も少なくする(1にする)

私の場合、マテリアルが1つ増えるごとに、テクスチャが3枚増えるので、できれば1マテリアル、それにStandardシェーダー改造版を使おうと考えています。
ただ、今悩んでいるのが、凹み目(追い目)表現と、両面ポリゴン表示との兼ね合いです。

まず「追い目」については

という実装をしていますが、特に白目が大きく凹んでいるのでStandardシェーダーだと白目の影が表示されてしまいます。

f:id:uuupacom:20180814152940p:plain

  • 追い目表現を諦めて通常の凸形状の目にする
  • 目の部分だけ別メッシュにして別シェーダー(=別マテリアル)をあてる
  • 白目のみEmissionマップで発光させることで白くする(うまくいくかな?)
  • 追記アルベドテクスチャ画像の真っ白(R255,G255,B255)の部分には影を落とさない、その他の色については通常通り、というシェーダーを書く。凹み目以外の白い場所はRGB:254とかにすればちゃんと影が落ちる仕様。

あたりの3案ぐらいが思いつくのですが、どれが良いか悩んでおります。※4案目のシェーダーを時間とって作りたい。

両面ポリゴン表示というのは、ジャケットの裏などが対象となりますが、板ポリゴンの裏側も見えてしまう箇所は、Unityは通常はポリゴンの裏面は透過表示なので透けてしまいます。これはUnityのシェーダーでCull Off記述を追記して両面ポリゴン表示にすれば解決します。
この時、1シェーダーだと、裏面表示の必要のない箇所も含めて、全てが両面表示になります。

  • 全部が両面ポリゴン表示になろうが、1マテリアル1シェーダー!
  • 両面表示が必要なオブジェクトだけ別メッシュにし、別マテリアル別シェーダーを割り当てる

のどちらが軽いのかが悩ましいところです。

その他、少し疑問なのが、例えば私はマテリアル数を1個にしようとしていますが、Unity上で、メッシュ(オブジェクト)が複数個あるけど、マテリアルは全て同じものを使う場合、これがどういう負荷になるかが気になります。帽子だけ個別にCastShadow=Offにしたかったりするんですよねぇ。

f:id:uuupacom:20180814153149p:plain

例:帽子のひさしの影が邪魔。ポリゴンの裏表の影響もあって不思議な影の落ち方してるのも不満

これらの懸念があって、1メッシュで済ませられるか心配ですが、そこまでストイックにならずとも、先述の参考記事にはマテリアル数の推奨は5以下程度とのことで、少し気楽にやっても大丈夫そうです。

DynamicBone

髪・スカート・ネクタイに導入したいのですが、追加ボーンはそこそこ負荷がかかるとWeb上でも言われているので、可能な限りBlenderのウェイトペイントで頑張ろうと思います。

ポリゴン数

VRChatの仕様にて、2万ポリゴン以下に制限されてますが、ポリゴン数自体と負荷については、ここまで挙げた事例ほどクリティカルではないようです。ちなみに私のアバターは15378三角ポリゴンです。
余談ですが、Blender上での三角面表示数とUnityにエクスポートした時のTris数が一致してなくて焦ることがありますが、

  • Blender上で適用前の細分化モディファイアがある
  • Unity上でDirectionalLightを非表示にする

あたりが原因で焦ることが多いです。

今のところ以上です

まだ途中の模索段階ですが、こういう検証作業って、アバターデザインのような感性重視ではなくて、ある程度理詰めで考えられることなので、それはそれで楽しい作業ですね。

追記:AOテクスチャマップも必要かも。都合1マテリアルにつき4テクスチャにするかも。