Rendering/SkinnedMeshRenderer

Last-modified: 2025-01-11 (土) 13:29:59


SkinnedMeshRenderer(スキンド メッシュ レンダラー)

ボーンやブレンドシェイプの有るMeshを描画する為のコンポーネント


項目

Enabled:
このコンポーネントを有効にするかどうか。

Mesh:
描画するMesh。

Materials(list):
Add押すと増える。
Meshに適用するMaterialのリスト。

MaterialPropertyBlocks(list):
Add押すと増える。
Material Property Blocksのリスト。
同じマテリアルでも、別のテクスチャを表示できる。

ShadowCastMode:
影の設定。
初期設定はOn。
0Off影を落とさない。
1On影を落とす。
2ShadowOnly影のみを落とす。元の姿は描画されない。
3DubleSided両面の影を落とす。
影が必要ない場合は、影をOffにしましょう。
半透明マテリアルの場合は、描画負荷が高くなるので影をOffにする事をお勧めします。
また、頂点数の多い3Dモデルを使用する場合は影をOFFにし、代わりにローポリモデルを用意して、こちらを影のみにすることで影の描画負荷を減らすことができます。

MotionVectorMode:
モーションブラー(ぶれ)の設定。
初期設定はObject。
0Cameraカメラ(視点)側は動くけど、オブジェクト側は動かない場合。
1Objectカメラ(視点)側もオブジェクト側も動く場合。
2NoMotionどちらも動かない場合。

SortingOrder:
表示する順番。
同じ設定の半透明マテリアル等を使用するメッシュが複数個重なる場合、どちらが手前に表示されるか設定できます。
また、マテリアルのRenderQueue設定等の影響で、半透明UI越しだと透けてしまう場合は、-32001にする事で回避できます。(ただし、今度はFog等と干渉するかも。)

BoundsComputeMethod:
メッシュの大きさ(境界)を計算する方法。
初期設定はStatic。
0Static静的初期のMesh形状で一度だけ計算する。
1Explicit明示的手動で大きさを設定する。
2Proxy代理別のSkinnedMeshRendererの計算結果を使用する。
3FastDisjointRootApproximateボーン塊で近似ボーンを一房毎に塊にして、その大きさを計算する。(重い)
4MediumPerBoneApproximateボーン毎で近似各ボーン毎に計算する。(重い)
5SlowRealtimeAccurate超正確スキンドメッシュ自体から計算する。(激重)
接近時に一部のMeshが非表示になるときは、ExplicitとProxyを活用しましょう。(安直にFastDisjointRootApproximate等を使用するのは控えましょう。)
詳しくはページ最下の「その他」に記載します。

ProxyBoundsSource:
BoundsComputeMethodがProxyの時に使用する。
別のSkinnedMeshRendererを指定する。
Proxyモードを正しく機能させるには、それぞれの位置・方向・縮尺等の設定が同じである必要があります。

ExplicitLocalBounds:
BoundsComputeMethodがExplicitの時に使用する。
バウンディングボックスの大きさを設定する。

Bones(list):
(自動)
ボーンのリスト。

BlendShapeWeights(list):
(自動)
ブレンドシェイプのリストと設定。
ブレンドシェイプは0か1の状態と比べると、0.1や0.5等の中間状態の方が描画負荷が高くなります。
DynamicBlendShapeDriverから制御する事も可能です。

SplitBlenshapeAlongAxis(int blendshapeindex,Axis3D axis,float center,float transition,string negativeSuffix,string positiveSuffix)
(スペルミス?「SplitBlendshape」)
FluxのAsunc Function Proxyノードで、ブレンドシェイプを2分割する。
例えば、アバターの表情ブレンドシェイプで両眉が動く場合、左右別々のブレンドシェイプに分割できる。

ちょっとFlux解説。
Arg0分割するブレンドシェイプの番号BlendShapeWeights(list)の一番上が0番
Arg1分割する軸XYZ(右左、上下、前後)
Arg2軸の位置0が中心
Arg3分割する比重0だとくっきり、数値が大きいと曖昧になる
Arg4分割後の名前マイナス側に追加される
Arg5プラス側に追加される
ブレンドシェイプ名先頭の三本線ボタンをクリックすると、コンテキストメニューからも操作できます。
ただし、floatは「0」、stringは「L」と「R」で処理されます。

BakeBlendshape(int blendshapeindex)
FluxのAsync Function Proxyノードで、ブレンドシェイプをベイクする。

RemoveBlendshape(int blendshapeindex)
FluxのAsync Function Proxyノードで、ブレンドシェイプを削除する。

SplitSubmeshes()
FluxのMethod Proxyノード又はButtonActionTriggerコンポーネントを使用して、サブメッシュに分割する。
マテリアルが複数ある場合は、サブメッシュが分割されて子スロットに展開されます。
サブメッシュない場合でも、1個に分割されます。
処理が実行される度に、MeshのアセットIDが変更されます。

MergeByMaterial()
〃、同じMaterialを結合する。
同じIDのマテリアルを参照するサブメッシュ同士が結合します。
マテリアルはなるべく少ない方が良いので、同じ質感のマテリアルであれば、結合して減らしちゃいましょう。
処理が実行される度に、MeshのアセットIDが変更されます。

マテリアルでメッシュを分ける
押すと、サブメッシュに分割する。
同上

同じマテリアル同士で結合
押すと、同じMaterialを結合する。
同上

ブレンドシェイプの影響を受けないメッシュのパーツを分離
ブレンドシェイプでアニメーションしないメッシュ部分を、サブメッシュに分割する。

空のブレンドシェイプを除去
空(N/A)ブレンドシェイプを削除する。

空のボーンの除去
メッシュと無関係(ウェイト付けされていない)ボーンを削除する。

使用していないブレンドシェイプを除去
駆動されていないブレンドシェイプをベイク(除去)する。
アバターの表情ブレンドシェイプ等は超負荷が高いので、使用しないブレンドシェイプは極力除去した方が良いです。(とても軽くなるハズ)

ボーンのバウンディングボックスの可視化
ボーンの境界ボックスを表示する。
可視化ボタンは押す度に増えちゃう。

マージされたボーンのスフィアバウンディングの可視化
ボーン(全て含む)の境界スフィアを表示する。
同上

可視化したボーンのバウンディングボックスを非表示
ボーンの境界ボックス又はスフィアを非表示にする。

現在のポーズから明示的にバウンディングを計算する
BoundsComputeMethodをExplicit変更して、ExplicitLocalBoundsを自動的に設定する。

現在のポーズから明示的なバウンディングを拡張する
同上。違うポーズにしてから押すと、追加で拡張した値を設定できる。
上のボタンよりも先に押すと、すごくでっかくなっちゃうので注意。

スタティックメッシュにベイクする
静的メッシュにベイクする。

ブレンドシェイプを名前でソート(昇順)
BlendShapeWeights(list)を並べ替える。

ブレンドシェイプを名前でソート(文字数順→昇順)
同上

ブレンドシェイプを結合する
ブレンドシェイプを一纏めに結合する。
アニメーション作るときに便利。

<例>
アニメーションキーが二つある場合は、Blender等でシェイプキーを三つ作る必要があります。
1番目にベースと同じ頂点位置のキーが必要です。
(しかし、輸入するとエラーが出たり1番目のキーが消えたりします。そのため、1番目のキーは目立たない頂点を少しだけ動かしておきましょう。)

結合されたブレンドシェイプを0→1にした時の動き。

0ベースベースの状態。
0より大きい11番目のキーが1の状態になる。
0.251→2(クロスフェード)1番目のキーが0.5に減り、2番目のキーは0.5に増える。
0.521番目のキーが0に、2番目のキーが1になる。
0.752→3(クロスフェード)2番目のキーが0.5に減り、3番目のキーが0.5に増える。
132番目のキーが0に、3番目のキーが1になる。


使用例

  • ボーンやブレンドシェイプはResonite内で作る事ができません。Blender等で作ってから輸入します。
    • 輸入時に警告文が出る場合があります。(アバターの場合は元データの修正が必要ですが、アイテム等の場合は無視して構いません。)
  • 普通のMeshは、MeshRendererを使った方が良い。(SkinnedMeshRendererは処理負荷が高い。)
  • このコンポーネントに限らないですが、作業前や作業中のバックアップ保存をお忘れなく。


その他

  • スキンドメッシュ最適化メモ
    • 1Meshあたり、6万頂点以下にする事。(より少ない方が良い。)
      • もし頂点数が多い場合は、「ブレンドシェイプの影響を受けないメッシュのパーツを分離」ボタンを押して、分離する。
      • 複数個(頂点数とても少ない)の場合は、ベイクツールでスキンドメッシュベイクして、まとめると良いかも。
        いずれの場合にせよマテリアルの数や形状等によって個別に判断する必要があります。作業の実行前と実行後で効果を比較検証しましょう。
    • 「使用していないブレンドシェイプを除去」ボタンを押す。
    • 「空のボーンの除去」ボタンを押す。
    • Materialアセットは徹底的に使いまわす。とにかくMaterialの数は少ない方が良い。
    • BoundsComputeMethod(境界計算)は、Static又はExplicitを使用し、Proxyも活用する。
    • MaterialPropertyBlocksを使えば、同じMaterialに別々のテクスチャを使える。
    • 頂点数の多い3Dモデルや半透明マテリアルを使用する場合は、影をOffにする。
    • LODGroupを活用する。


  • バグ?仕様? 写真撮るとアバターのMeshがズレるとき
    動きながら写真に写ると、服がズレて体が見えちゃったり、髪の毛がズレて禿げちゃったりする事が稀にあります。
    (検証する際は、標準の写真機を使用しましょう。MOD等は全て消しましょう。MOD使用者は口をつぐみましょう。
    原因は不明ですが、検証結果からなんとなく状況を把握しました。
    以下に対処法を二つ記しますが、根本的な解決法は不明です。また、アバターによっては、効果が異なる場合もあります。
    • ベイクツールでスキンドメッシュベイクして、一纏めにする。
      SkinnedMeshRendererが一つなら、そもそもズレない。
    • 「空のボーンの除去」ボタンを押す。
      ボーンの数を減らすと、ズレなくなった事例を多数確認した。(逆に、消した結果ズレた事もある。謎は深まるばかりです。)


  • 接近時に一部のMeshが非表示になるとき
    アバター等のSkinnedMeshが、特定の角度や距離で消えてしまう事があります。
    これは、視錐台カリング機能によるものです。
    原因は、バウンディングボックス(境界計算)が適切に設定されていない為です。
    初期の形状から大きく変形する場合や離れる場合に、起こりやすいです。
  • 対策は以下の通りです。(ついでに最適化も行い、ライトに照らされた時の見た目改善や処理負荷軽減等も同時に行います。)
  1. まず、アバターの一番大きなSkinnedMeshRenderer(体)の設定を弄ります。
    1. 「現在のポーズから明示的にバウンディングを計算する」ボタンを押す。
      (注意:「現在のポーズから明示的なバウンディングを拡張する」ボタンを先に押さないでください。)
    2. ExplicitLocalBounds項目の値を手動で調整します。(ギズモを出しながら作業すると捗ります。)
      xyzxyzの6個の数値(左下後右上前)で、大きさを設定します。
      少し大きめで設定します。特に下側は余裕があると良い。(大き過ぎはダメです。適度な大きさにしましょう。)
  2. つぎに、他のSkinnedMeshRendererの設定を弄ります。
    1. BoundsComputeMethod項目を、Proxyモードに設定します。
    2. ProxyBoundsSource項目に、先ほど設定したSkinnedMesh(体)を指定します。
      (裏技:スロットを掴んで入れると、自動的にSkinnedMeshが指定されます。)
  • 別の解決策として、BoundsComputeMethodをFastDisjointRootApproximateモード等に設定する方法があります。
    しかし、この方法は処理負荷が高く、ライトに照らされた時の見た目も改善されないので、お勧めはしません。