読者です 読者をやめる 読者になる 読者になる

テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】LOD(Level of Detail-距離に応じたハイポリ/ローポリの切替)をキャラクターで使用する方法

f:id:tsubaki_t1:20151227222747g:plain

Level of Detailをキャラクター・・・と言うかアニメーションを持つキャラクターに対して使用する方法についてです。

LOD(Level of Detail

Level of Detailは距離に応じて描画するモデルのポリゴン数を制御する機能です。近距離のモデルはハイポリ、遠距離のモデルはローポリで表現することで、オブジェクトの描画負荷を低減します。

例えば下の画像は左が通常ポリゴン、右がリダレクション*1を行ったモデルです。近くで見ると右は歪んでいますが、遠距離で見ると左のポリゴン密度が高すぎる点が気になります。

f:id:tsubaki_t1:20151227221611j:plain

f:id:tsubaki_t1:20151227221618j:plain

今までの自分の認識ではポリゴン数が問題になる事はそこまで無かったのですが、PBRを綺麗に見せようとすると超ハイポリによる表現が必要な点や、表情を綺麗に変形させたい場合にポリゴン数が多くなりがちな所から、重要度が上がってきてるかなって認識です。

キャラクターとLOD

さてキャラクターに対してLODを実施する訳ですが、もう少し正確に言うならばSkinedMeshRendererをAnimatorで動かすモデルに対してLODを行います。

単純にキャラクターをLODとして表現しようと思った場合、表現それ自体は簡単に設定は可能です。つまり、モデルとAniamtorごとLOD化します。

f:id:tsubaki_t1:20151227223424j:plain

このアプローチは一見上手く動作するのですが、二つの大きな問題があります。一つはAnimatorを幾つも制御しなければならない点、もう一つはRagdollやFinalIKをはじめとしたボーン制御を使用した機能を使用した場合に破たんすることです。
f:id:tsubaki_t1:20151227222542j:plain

例えばAnimatorが複数ある場合、単純にAnimatorを複数同時に「同じ内容になるよう」制御する必要があります。
一応LOD対象外の時はアニメーションを行わないよう設計されていますが、Apply Root Motionで動く場合は動いてしまう事、またLOD0とLOD1が違うモーションを行っている場合、LOD切り替えで内容が切り替わってしまう事が問題として上がります。

f:id:tsubaki_t1:20151227224707j:plain

RagdollやFullbodyIKを行っている場合はもっと微妙です。スケルトンを複数持つのであれば、RagdollやFinalIKを用いるスケルトンと、それに同期するだけのスケルトンを用意する必要があるからです。
つまり今回の回答は、複数のSkinedMeshRendererを単一のスケルトンで表現する事となります。

一つのAnimatorでLOD

やり方は簡単です。SkinedMeshRendererにスケルトンが格納されているので参照関係を構築してやるだけです。

ここでヒントになるのが、ボーンが何処に格納されているのかAnimatorとAvaterのルールです。Animatorは子階層に一致するスケルトンがあれば操作出来る点(直親で無くても良い)と、SkinedMeshRendererのスケルトンはSkinedMeshRendererが格納している事です。
つまり、こうします。

f:id:tsubaki_t1:20151227230256j:plain

LODのではなくオブジェクトのRootにAnimatorを持たせ、単一のスケルトンを操作してもらいます。また、各SkinedMeshRendererは同一のスケルトンを参照させます。

要するにメッシュの差し替え(距離)を行います。

やり方

設定手順はこんな感じです。

まずシーンにモデル「Ethan」を配置します。*2

f:id:tsubaki_t1:20151227230833j:plain

このEthanBody(イーサンの体)とEthanGlasses(イーサンの眼鏡)にSkinedMeshRendererが使用されています。
この二つのオブジェクトを複製します。

複製したオブジェクトEthanBody(1)は、EthanBodyと同じスケルトンへの参照を持っています。これで参照の問題は解決です

f:id:tsubaki_t1:20151227230946j:plain

後はEthanBody(1)やEthanGlass(1)のSkinedMeshRendererのMeshに、LOD用に用意したローポリモデルを設定します。

f:id:tsubaki_t1:20151227232127j:plain

この時、同じボーン順番でないと絵が破たんします。もし絵が破たんした場合は、

【Unity】動的にキャラクターの衣装を差し替える - テラシュールブログにあるような形でスケルトンを確認します。

f:id:tsubaki_t1:20151227232323j:plain

後は親オブジェクトにLODを設定し、EthanBodyとEthanGlassesをLOD1、EthanBody(1)とEthanGlasses(1)をLOD2に設定すればOKです。登録するのはオブジェクトではなくあくまでRendererである点が多分ポイントです。

f:id:tsubaki_t1:20151227232624j:plain

関連

tsubakit1.hateblo.jp

megumisoft.hatenablog.com

tsubakit1.hateblo.jp

「見ろ、人がゴミのようだ」の作り方(RagDoll with Unity)

psychic-vr-lab.com

 
 

*1:ポリゴン数の削減

*2:このモデルはStandardAssetsのCharacterから入手可能です