Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AvatarMakerを支える技術 / cluster_avatarmaker_enginee...

AvatarMakerを支える技術 / cluster_avatarmaker_engineering

Cluster, Inc.

March 04, 2022
Tweet

More Decks by Cluster, Inc.

Other Decks in Technology

Transcript

  1. Cluster, Inc. All Rights Reserved. AvatarMakerの要件 1. cluster内でアバターを作成できること (VR/Desktop/Mobile) 2.

    服装・髪型・色を切り替えられること 3. 顔の造形・パーツを変更できること 4. 社内外のクリエイターの方が素体の部品をアップロードできること 社内に閉じない 制作ワークフロー どこでも動く 大体いじれる
  2. Cluster, Inc. All Rights Reserved. AvatarMaker追加後の設計 • [new] 社内外のクリエイターの方がglTFをサーバーにアップロード •

    [new] clusterアプリで利用時にglTFをダウンロードして組み立てて表示 • [new] clusterアプリがVRMをサーバーにアップロード
  3. Cluster, Inc. All Rights Reserved. Clusterの技術構成 • クライアント ◦ Unity

    2019.4.22f ◦ MVPパターンで大体設計されている ◦ ライブラリ ▪ Zenject ▪ UniRx/UniTask ▪ etc… • サーバー ◦ Go ◦ VRM/glTFを最適化する機構をもりもり搭載している ▪ メタバースプラットフォーム clusterのserverについて(2021応用編) ▪ OSSのglTFライブラリにPull Requestを出した件について クラスター Advent Calendar 2021 参照
  4. Cluster, Inc. All Rights Reserved. 全体実装 • 最初からclusterには組み込まず、独立して開発 ◦ ライブラリと試験実装アプリとして分離

    • 途中からライブラリのみcluster本体に組み込みこんだ ◦ インターフェイスの微調整などしつつ… 社内外で使うためには、 ある程度外に出せるよう に境界を引く必要があっ た…
  5. Cluster, Inc. All Rights Reserved. 全体実装 メリット • 疎結合な設計を強制できる &

    asmdefを切りやすい • 単体アプリとして動作確認のイテレーションを高速にできる デメリット • どこまで最適化するかの塩梅が難しいがち ◦ 組み込んでわかるリソースの上限・プラットフォームごとの差異など 結構あった
  6. Cluster, Inc. All Rights Reserved. glTF 2.0 おなじみ Khronos Group開発の3Dモデルを扱うファイル形式。

    (中身は基本 json + binary blob) 「glTF is the "JPEG of 3D"」 https://www.khronos.org/gltf/ かのVRM形式はglTFの上に構築されてい る
  7. Cluster, Inc. All Rights Reserved. glTF 2.0 メリット • AssetBundleのように各プラットフォームに向けて何度もビルドする必要なし

    • 標準的な規格なので、他言語のライブラリからでも読める相互運用性の高さ ◦ プラットフォームごとのデータの最適化はバックエンド側で担保できる デメリット • glTFの拡張領域を自由にライブラリから使うのが難しい マルチプラット フォームで使うに は最高
  8. Cluster, Inc. All Rights Reserved. glTF 2.0 > デメリット •

    glTFの拡張領域を自由にライブラリから使うのが難しい 解決策 UnityでglTFを扱うライブラリを丸ごと作って解決 yutopp / VGltf using (var importer = new Importer(gltfContainer, timeSlicer)) { importer.Context.Importers.Materials.AddHook(new Hooks.Part.AvatarPartVRM0MtoonImporterHook()); importer.Context.Importers.Nodes.AddHook(new VGltf.Unity.Ext.AvatarImporter()); return await importer.ImportSceneNodes(ct); } glTFのimport/export VRMのexport で利用
  9. Cluster, Inc. All Rights Reserved. アバターの合成実装 ボツ案:複数のglTFパーツは単体でもHumanoidなので、合成せずに Animatorを同じ位置に重ねて表示する。 メリット •

    パーツの合成処理をVRM出力時に1度だけ行えばよい デメリット • パーツ切替時にAnimationのタイミングをすべて合わせるのが非常に面倒 だった… • 必須のComponentをすべてのパーツにつけ、同期するのも大変だった
  10. Cluster, Inc. All Rights Reserved. アバターの合成実装 ボツ案:複数のglTFパーツは単体でもHumanoidなので、合成せずに Animatorを同じ位置に重ねて表示する。 メリット •

    パーツの合成処理をVRM出力時に1度だけ行えばよい デメリット • パーツ切替時にAnimationのタイミングをすべて合わせるのが非常に面倒 だった… • 必須のComponentをすべてのパーツにつけ、同期するのも大変だった Skeletonの付け替えの実行時のコス トはそこまで高くなかった (フレー ム落ちも目立たないくらい)
  11. Cluster, Inc. All Rights Reserved. アバターの合成実装 現行:glTFパーツを切り替えるたびに実行時に1つのHumanoidに合成しなお す。 メリット •

    いくらglTFパーツが増えても、操作するアバターとしては1つの Humanoidモデル扱いできる デメリット • なし
  12. Cluster, Inc. All Rights Reserved. Bone合成 今回のAvatarMakerのglTFパーツは、Humanoidのボーンに関しては仕様を統 一しているので、切替時にHumanDescriptionの変更はしていない。 (基本はSkinnedMeshRendererのSkeletonの付け替えのみ) !Tips

    • Humanoid関連のボーンを組み直す場合は、以下の値を編集したAvatarを animatorにセットする必要がある。 ◦ HumanDescription.human ◦ HumanDescription.skeleton • Avatar.isHumanがfalseを返さないように気をつける。
  13. Cluster, Inc. All Rights Reserved. Texture合成シェーダ ボツ案 : CustomRenderTexture 「カスタムレンダーテクスチャはレンダーテクスチャの拡張機能で、これを使

    うと簡単にシェーダー付きのテクスチャを作成できます。」 https://docs.unity3d.com/ja/2019.4/Manual/class-CustomRenderTexture.html 合成 Shader Material Custom Render Texture 色々なテ クスチャ 色々なプ ロパティ
  14. Cluster, Inc. All Rights Reserved. Texture合成シェーダ ボツ案 : CustomRenderTexture メリット

    • 今どき デメリット • Android端末で異常な結果を返し続ける (真っ黒なtexture)
  15. Cluster, Inc. All Rights Reserved. Texture合成シェーダ Custom Render Texture appears

    black on mobile - Unity Answers 「fairly inane workaround…」
  16. Cluster, Inc. All Rights Reserved. Texture合成シェーダ 現行 : 1x1のメッシュに通常のShaderで描画したものを平行投影で撮影した RenderTextureを使う

    合成 Shader Material Render Texture 色々なテ クスチャ 色々なプ ロパティ 撮影ス クリプト ExecuteCommandBu fferで描画する
  17. Cluster, Inc. All Rights Reserved. Texture合成シェーダ 現行 : 1x1のメッシュに通常のShaderで描画したものを平行投影で撮影した RenderTextureを使う

    メリット • どの環境でも安定して動く、とてつもない安心感 デメリット • 枯れた技術感
  18. Cluster, Inc. All Rights Reserved. IL2CPP • checkedの範囲が変わる ◦ checkedでsignedもunsignedに変換されてしまった

    https://github.com/yutopp/VJson/commit/3d2f4dbefbacf050dcad71e6f8286fa834da1261 + if ( i < 0 ) + { + throw new OverflowException(); + } o = checked((byte)i);
  19. Cluster, Inc. All Rights Reserved. IL2CPP • Type/TypeInfoのGetCustomAttributesで返ってくるインスタンスが キャッシュされてる ◦

    実装依存っぽさ… https://github.com/yutopp/VJson/commit/120020a1c90dd1f0275d0f9353eef4e089943b0a TypeHelper.GetCustomAttribute<JsonSchemaAttribute>(ty)? .MemberwiseClone();
  20. Cluster, Inc. All Rights Reserved. IL2CPP • code strippingによって静かに実行時エラーが発生 ◦

    “[Preserve]” 属性をつけて解決… https://github.com/yutopp/VJson/blob/4db11d1a89fcaa61c8d4f26cf7d2c1f9c2794f18/Packages/net.yutopp.vjs on/Runtime/Attribute.cs#L20 public class PreserveAttribute : System.Attribute { }
  21. Cluster, Inc. All Rights Reserved. IL2CPP • code strippingによって静かに実行時エラーが発生 ◦

    “[Preserve]” 属性をつけて解決… https://github.com/yutopp/VJson/blob/4db11d1a89fcaa61c8d4f26cf7d2c1f9c2794f18/Packages/net.yutopp.vjs on/Runtime/Attribute.cs#L20 • 自前定義…? • Unityに “UnityEngine.Scripting.PreserveAttribute” ない? ◦ PureC#のコード部分なので、UnityEngineへの参照を持ちたくない…
  22. Cluster, Inc. All Rights Reserved. IL2CPP • code strippingによって静かに実行時エラーが発生 ◦

    “[Preserve]” 属性をつけて解決… https://github.com/yutopp/VJson/blob/4db11d1a89fcaa61c8d4f26cf7d2c1f9c2794f18/Packages/net.yutopp.vjs on/Runtime/Attribute.cs#L20 • 自前定義…? • Unityに “UnityEngine.Scripting.PreserveAttribute” ない? ◦ PureC#のコード部分なので、UnityEngineへの参照を持ちたくない 「For 3rd party libraries that do not want to take on a dependency on UnityEngine.dll, it is also possible to define their own PreserveAttribute. The code stripper will respect that too, and it will consider any attribute with the exact name "PreserveAttribute" as a reason not to strip the thing it is applied on, regardless of the namespace or assembly of the attribute.」 https://docs.unity3d.com/2019.4/Documentation/ScriptReference/Scripting.PreserveAttribute.html
  23. Cluster, Inc. All Rights Reserved. IL2CPP • code strippingによって静かに実行時エラーが発生 ◦

    “[Preserve]” 属性をつけて解決… https://github.com/yutopp/VJson/blob/4db11d1a89fcaa61c8d4f26cf7d2c1f9c2794f18/Packages/net.yutopp.vjs on/Runtime/Attribute.cs#L20 • 自前定義…? • Unityに “UnityEngine.Scripting.PreserveAttribute” ない? ◦ PureC#のコード部分なので、UnityEngineへの参照を持ちたくない 「For 3rd party libraries that do not want to take on a dependency on UnityEngine.dll, it is also possible to define their own PreserveAttribute. The code stripper will respect that too, and it will consider any attribute with the exact name "PreserveAttribute" as a reason not to strip the thing it is applied on, regardless of the namespace or assembly of the attribute.」 https://docs.unity3d.com/2019.4/Documentation/ScriptReference/Scripting.PreserveAttribute.html “PreserveAttribute” という名前であ れば、どこに定義していても最適化を抑 制できるattributeとして扱われる (あ りがたいけれどなんだそれは…)
  24. Cluster, Inc. All Rights Reserved. IL2CPP • 開発終盤は (Windows, MacOS,

    iOS, Android, Linux) x IL2CPPビルドで 動作確認するような用心深さに… ◦ CIで回したい
  25. Cluster, Inc. All Rights Reserved. まとめ • 設計を維持するのは最終的に速い • 頑張って共通の規格を使っておくといろいろ相乗りできて便利

    • 開発イテレーションを早く回して罠をたくさん踏み抜くのが大事 ◦ インターフェースの切り方 ◦ Texture、IL2CPPのトラブルシュートなど