Git Product home page Git Product logo

vrmspringbone-optimize's Introduction

VRMSpringBone-Optimize

大量のVRMモデルを動かすことを想定して、dwango/UniVRMに含まれるVRMSpringBoneC# JobSystem ベースで最適化してみたもの。

  • ※ パフォーマンスの計測結果諸々についてはmasterブランチに有るReadmeを参照
  • ※ 実用性を想定して以下の理由からECS対応は一旦オミット
    • パフォーマンスや動的なモデルの追加/削除に伴う負荷を見た感じだと、JobSystemでも十分に稼げているので無理して使う必要が無かった為
    • 変更点への対応追従(ECS自体がまだPreviewなので)

各種バージョン

  • Unity
    • 2018.4.13f1
  • UniVRM
    • UniVRM-0.53.0_6b07
    • UniVRM.asmdef-0.53.0_6b07

依存パッケージ

各モジュールはPackageManagerから取得できる幾つかのパッケージに依存しているので、利用する際には事前に入れておくこと。

  • VRMSpringBoneOptimize-Jobs
    • com.unity.burst: 1.1.2
    • com.unity.collections: 0.0.9-preview.12

各モジュールについて

VRMSpringBoneOptimize-Jobs

C# JobSystemベースで実装してみたもの。
ソースについては"VRMSpringBoneOptimize/Jobs"以下を参照。

機能としてはJobのScheduleに関する管理方法の違いで以下の2点を実装している。

  • CentralizedBuffer
    • 全モデルのJobに関するデータを1箇所で集中管理し、一括でJobのScheduleを行うタイプの物。
    • メリット
      • 一括で行うので数が多いほど効率よく処理できるので早い。
    • デメリット
      • データを集中管理している都合上、動的なモデルの登録/解除を行った際にJobに渡すデータの作り直しが発生するので負荷が高くなる。
  • DistributedBuffer
    • Jobに関するデータをモデル毎に独立して持たせた上で、モデル毎にJobのScheduleを行うタイプの物。
    • メリット
      • データが分散管理されているので動的にモデルを登録/解除しても負荷が高くない。
    • デメリット
      • データ及びScheduleの数がモデル毎に行われるために効率が悪い。

導入方法

こちらを有効にするには「ENABLE_JOB_SPRING_BONE」と言うシンボルを定義する必要がある。
→ Assembly Definition側で設定している

使い方についてはCentralizedBufferDistributedBuffer共に設定について大きな違いは無いので、前者を取り上げる形で説明していく。

事前にモデルに設定する場合

1. モデルに対する設定

  • VRMモデルのルートオブジェクト(VRMMetaなどがアタッチされている物)に対しCentralizedBufferをアタッチ。
    • ※この設定は必須ではない。後述の3の手順にあるSchedulerの登録時にGameObjectを渡すことで動的にアタッチ/登録させることも可能。
  • VRMモデルに設定されているVRMSpringBoneVRMSpringBoneColliderGroupを"VRMSpringBoneOptimize/Jobs/Scripts"以下にある同名のScriptに置き換える。
    • こちらはCentralizeDistributed共通の設定。
    • 置き換え用の拡張を実装してある。メニューにある「VRMSpringBoneOptimize/Replace SpringBone Components - Jobs」を実行することで、Scene中にあるVRMモデルに対し一括で上記2点をJobSystem向けのものに置き換える事が可能。

2. スケジューラーの生成

  • 任意のGameObjectに対しCentralizedJobSchedulerをアタッチ
    • ※画像の例だと管理クラス用にSchedulerと言うGameObjectを用意してそちらにアタッチしている。

job_model_settings2

3. Jobの登録/解除について

  • CentralizedJobSchedulerに以下の関数を実装しているので、こちらに対し登録/解除対象のCentralizedBufferを渡すこと。
    • 登録 : CentralizedJobScheduler.AddBuffer(CentralizedJobScheduler)
    • 解除 : CentralizedJobScheduler.RemoveBuffer(CentralizedJobScheduler)
      • ※オーバーロードでGameObjectも渡せるようにしてある。その場合には渡したObjectにCentralizedBufferがアタッチされていなかったら動的にアタッチしてから登録する仕様となる。
  • CentralizedJobSchedulerの初期化タイミングで良ければこちらのInspectorから設定できるIsAutoGetBufferを有効にすることで、MonoBehaviour.Startのタイミングでシーン中に存在するCentralizedJobSchedulerを自動で集めて登録することが可能。

ランタイムロードの場合

1. モデルに対する設定

VRMモデルに設定されているVRMSpringBoneVRMSpringBoneColliderGroupを"VRMSpringBoneOptimize/Jobs/Scripts"以下にある同名のScriptに置き換える必要があるが、やり方は2つある。

ReplaceComponents.ReplaceJobs(GameObject obj)の利用

上記のstatic methodを用意しているので、こちらにGameObjectを渡すことで一括で置き換えることが可能。

但し、問題点としてこちらのやり方で差し替える場合には微妙にノードの位置などがずれてしまう事が有るので注意。

具体的に話すとVRMをロード後に数フレーム経過してからJob版のComponentへ差し替えを行うと、差し替える前のVRM.VRMSpringBoneのUpdateなどが先に呼ばれてしまってBoneの位置が動いてしまう可能性がある。

その状態で差し替えると初期位置がずれたままとなるので、結果として正常な挙動と比べると微妙に違ってくる可能性が出てきてしまうので確実に潰すならUpdateが呼ばれる前に差し替えるか以下の②の手順を行う必要がある。

②. VRM.VRMSpringUtilityの改造

※記載の通り、UniVRMに手を加えることになるのでバージョン管理や変更に伴う副作用などは自己責任。

ロードしたVRMのSpringBoneの設定は上記のクラスで解析/Componentのアタッチや設定などが行われる模様。
力技にはなってしまうが..シリアライズ可能なフィールドは全て互換性を保つようにしているので、こちらでアタッチされているComponentをJobSystem版のものに変更する事で自動的に差し替えることが可能。
(シンボル定義時とそうでない時でアタッチするComponentを切り替えられるように変更するのも有りかもしれない。)

2. スケジューラーの生成

3. Jobの登録/解除について

※「事前にモデルに設定する場合」に記載している内容と同じ。


License

vrmspringbone-optimize's People

Contributors

mao-test-h avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.