Cross Technology

Unity、VR、MR、ARを中心とした技術ブログ

【Unityアセット】Set Pass Callを劇的に減らす「Mesh Baker」の使い方とTips

====
2017/8/21 追記
5章の考察に、Set Pass Callsが200程度のモデルをHoloLensで見た場合の結果を追記しました
====

この記事は「Unity アセット真夏のアドベントカレンダー 2017」の13日目の記事です。

昨日はkazumalabさんによる、【Unity アセット真夏のアドベントカレンダー 2017】世界をローポリにしてやろうか!」でした。
(2018/8/20 追記 kazumalabさんのリンクが消えていたのでURLを削除しました)

本日は、モデルの処理負荷を下げるアセットを、HoloLensを交えて紹介します。

0. はじめに

HoloLensは空間認識を交えた機能が秀逸ですが、描画機能だけに絞ると性能は高くありません。そのため、VR系の開発をした経験から同じ感覚でアプリを作ると、簡単にFPSが低くなります。

FPSが低くなる原因の一つに、表示させたモデルの描画負荷が高いことが挙げられます。そこで、CGモデルの描画負荷を下げる方法を調べていたところ、@waffle_makerさんと@izmさんに「Mesh Baker」を教えていただきました。
(@waffle_makerさん、@izmさん、ありがとうございます)

今回はこれの使い方と、いくつかのCGモデルを用いてHoloLensで試した結果を解説します。

1. Unity全般とHoloLensでの描画負荷に関する基本情報

1-1. Unity全般での描画負荷に関する基本情報

こちらでも書きましたが、描画負荷についてはUnity EditorのStatisticsに記載されている値を目安にします。

Unity EditorのStatistics画面の例

Tris(ポリゴン数)、Verts(頂点数)は、Cameraの描画範囲にオブジェクトが増えるほど大きくなります。

たとえば、この動画では、Cubeを1つずつ増やしています。そのときにTrisとVertsという数値が増えていることが確認できます。

下記の公式マニュアルにも記載があるとおり、Set Pass Call(レンダリングパスの回数)は、同一マテリアルがあるかによって変化します。

Unity - マニュアル: ドローコール バッチング

Set Pass Callの考え方や削減方針については、こちらでとても明快な解説をされているので、ご参考ください。

【Unity】簡単明快なdrawcall削減の例

次に、白と赤の二つのマテリアルを使ってみました。

TrisとVertsがCubeの出現によって増えるのは先ほどの動画と同じですが、SetPassCallはCube1種類のときよりも大きな値になります。

ところで、動画の終わりのところでは、わざとカメラを動かしています。カメラの描画範囲にオブジェクトが増えたり減ったりすることで、TrisやVerts、SetPassCallなど、描画負荷を示す数値が変化することも確認できます。

1-2. HoloLensに関する描画負荷の考え方

私が調べた範囲では、「この数値以内のTris、Verts、Set Pass Call値ならよい」と明記したものはありませんでした。

How many polys can the Hololens render? — Windows Mixed Reality Developer Forum

→ポリゴン数についてのトピックが少ないことに言及

Performance recommendations for HoloLens apps - Mixed Reality | Microsoft Docs

→MS公式HP。FPSの値、Shaderの使用基準などは記載あり。

Performance recommendations for Unity - Mixed Reality | Microsoft Docs

→Unityの設定に関する記載あり

下記の記事では、著者はポリゴン数を減らした場合、Shaderを変えた場合のCGモデルをHoloLensで表示し、そのときのFPSを比較しています。実験による考察として、HoloLensの場合、このうちのTris値が80,000以下だと快適な描画になるという記載がありました。

HoloLens is comfortable rendering 80K triangles simultaneously. Around this value it’s important to craft your shaders carefully because heavy calculation in the fragment shader will have a severe impact on performance.

引用元:Getting It Just Right - Benchmarking On HoloLens

ただ、Set Pass Calls値の変化によるパフォーマンスの差については言及がありませんでした。

今回試した結果だと、Set Pass Callsの値も影響することがわかりました。あくまで今回試した3つのモデルでの結果ですが、「5.考察」に傾向を書きましたのでご参考ください。

2.Mesh Bakerとは?

メッシュをひとまとめにし、まとめたメッシュ単位でマテリアルを作ることで、描画負荷を減らすアセットです。モバイルやHoloLensのアプリ開発では、描画負荷が高い=処理落ちすると、コンテンツの評価が下がりやすくなるため、適用範囲が広いアセットと思います。

3. 使い方

使い方を書こうかなと思いましたが、すでに詳しく書かれているサイトがありましたので、こちらを紹介させていただきます。

Mesh Bakerを使ってメッシュをまとめ、Draw Callsを1306から6にしてみた【Unity】【アセット】 - (:3[kanのメモ帳]

主な手順は上記ブログの通りです。Mesh Bakerのバージョンアップのためか、一部見た目が変わっていたので、補足します。

(1) Baker作成

GameObject/ Create Other/ Mesh Baker/ Texture Baker and MultiMeshBaker に変わっていました。

Texture Baker and MultiMeshBaker からMesh Bakerを使う手順の画面

また、Open Tools For Adding Objectsをクリックすると、このようなウインドウが表示されます。

Mesh Bakerのコントロール画面

①Search For Meshes To Addというタブをクリック

②ひとまとめにしたいモデルをHierarchy Viewで選択 (親オブジェクト1つでよい)

③Add Selected Meshes To Targetを選択

(2) アセット作成

「アセット」については調べても出てきませんでしたが、このように結合対象のマテリアルを管理するファイルと考えればよさそうです。

(3) シェーダ毎にマテリアルを作成
(4) マテリアルをまとめる

(3),(4)は同じなので説明を割愛します。

(5) メッシュを結合

このとき、Outputの初期設定は「Bake Into Scene Object」になっています。

Mesh BakerのBake Into Scene Objectの設定画面

この状態ではMesh情報が残っていません。

Mesh Bakerを使ってMesh情報が残っていない例

そのため、結合したモデルをPrefabにして、後でスクリプトからinstantiateしても何も表示されません。これを回避する方法を追記します。

まず、Outputのオプションを「Bake Into Prefab」に指定します。

次に、Project Viewから空のPrefabを生成します。ここでは「urbancityprefab」という名前にしました。

空のPrefabを生成した例

続けて、Hierarchy Viewで空のGameObjectを生成し、先ほどのurbancityprefabにドラッグします。これで、白色だったprefabアイコンが青色になります。

空のPrefabにEmpty Gameobjectを充てる例

青色になったprefabを、先ほどのOutputにあったCombined Mesh Prefabという項目にドラッグします。

Combined Mesh Prefabに割り当てる例

この状態で、「Bake」ボタンを押すと、Project Viewのurbancityprefabの下にメッシュファイルが追加されます。

ちなみに、上記の方法はこちらの動画から参照しました。4:00頃から説明されています。
Tutorial 1 Combining Meshes With The Mesh Baker Component - YouTube

4. HoloLensで試した結果

過去に買ったことがある3Dモデルアセットをいくつか調べてみました。Unity Editor上のStatisticsと、HoloLensで動かした場合の動画を載せています。ただし、いずれも描画範囲によって負荷が変わるので、このようなルールで記録しました。

Unity Editor上で表示する場合:モデルの外観が見える位置にMain Cameraを設置し、その場所でStatisticsが見えるようにしてスクショを保存

HoloLens:モデルの外観を見えるように配置し、モデルの周囲を見る様子を録画

以下、画像と動画を見ていただければわかりますが、Mesh Bakerをかける前と後では、見た目の変化はほとんどわかりません。

4-1. Simple Trains - Cartoon Assets

Mesh Bakerを使わない場合

Mesh Bakerを使わない場合のSimple Trains - Cartoon Assetsの処理負荷


Mesh Bakerを使った場合

Mesh Bakerを使った場合のSimple Trains - Cartoon Assetsの処理負荷

Trisはあまり変わっていませんが、Set Pass Callsが325から14に減っています。HoloLensで見てもカクツキは気にならなくなりました。

4-2. Urban City Scene

=====
2018/2/18 追記
アセットストアから削除されていました
=====

Mesh Bakerを使わない場合

Mesh Bakerを使わない場合のUrban City Sceneの処理負荷


Mesh Bakerを使った場合

Mesh Bakerを使った場合のUrban City Sceneの処理負荷

こちらもTrisはあまり変わっていませんが、Set Pass Callsが1488から27に減っています。HoloLensで見てもカクツキは気にならなくなりました。

4-3. Japanese Classroom Set

=====
2018/2/18 追記
アセットストアから削除されていました
=====

Mesh Bakerを使わない場合

Mesh Bakerを使わない場合のJapanese Classroom Setの処理負荷

Mesh Bakerを使った場合

Mesh Bakerを使った場合のJapanese Classroom Setの処理負荷

Trisはやはり大きく変わらず、Set Pass Callが76から24に減りました。ただ、Mesh Bakerの有無でとくに体感上のカクツキは気になりませんでした。

5.考察

今回の検証では、Tris & VertsかSet Pass Callのどちらかが大きいと、HoloLensの見た目のカクツキに大きく影響することがわかりました。
たとえば、Urban City SceneとClassroomアセットでは、Trisは84,000〜130,000程度ですが、Set Pass Callsは1400と76と、大きな差がありました。1400だったUrban City Sceneはパフォーマンスが悪かったです。

また、Simple Trainsでは、Tris が260,000近く、Set Pass Callsが325でしたが、Mesh BakerによってSet Pass Callが14に下がるとパフォーマンスの影響は気になりませんでした。また、Classroomアセットでは、Trisが130,000、Set Pass Callsが76でしたが、とくにカクツキしませんでした。

3つの例だけなのであくまで傾向の一例ですが、HoloLensにおいては、以下の状況であれば描画のカクツキは気にならないと考えられそうです。

・Trisが260,000近くあってもSet Pass Callsが20以下

・Trisが130,000程度、Set Pass Callsが80以下

===
2017/8/21 追記
別のモデルで、Tris :25万程度、Set Pass Calls: 220前後のモデルをHoloLensで見たところ、カクツキがありました。
===

6. Tips

6.1. Material生成をしようとするとエラーになる

Mesh Bakerでメッシュ結合を進めている時、(3) シェーダ毎にマテリアルを作成のところで、以下のようなエラーがでることがあります。

Mesh BakerでMaterial生成をしようとすると出てくるエラーログ

これは、結合対象のオブジェクトにマテリアルがアタッチされていないためです。ここではGameObject at position 3 in list of Objects という記載があります。結合対象リストの3つめをみてみます。

マテリアルがアタッチされていない例

このように、Chain_Fense_CLOSSBARというオブジェクトがピンク色になっており、マテリアルが設定されていません。マテリアルを指定すれば、エラーが消えてメッシュ結合処理を進めることができます。

6.2 スクリプトから制御する方法

マニュアルによると、スクリプトから制御する方法も紹介されています。この仕組みを使うと、アプリ実行中にシーンの軽量化ができることになります。詳細はマニュアルのP.16以降のAdvancedを参照ください。

ただ、マテリアルのベイクで処理に時間がかかるので、シーン実行中に使うには、使用するテクスチャを調整しておくなど、色々と工夫が必要そうです。

6.3 有償版と無償版の違い

Mesh Bakerには無償版もあります。しかし、無償版にはいくつか制限があります。主な制限事項です。

・使えるシェーダーがDiffuse and Bumped Diffuse のみ

使用が推奨されている、HoloToolkit同梱のShaderは使えません。また、使用するモデルに適用されているShaderがDiffuseとBumped Diffuseだった場合、個別に変換する必要があります。

・Prefab化ができない

無償版ではPrefab化はできません。3.使い方 (5)メッシュの結合でBakeボタンを押すと、このようにエラーがでます。

Mesh Bakerの無償版で出るエラー

7.終わりに

このアセットはパフォーマンス改善に有効なので、HoloLensに限らず汎用的に使えると思います。次回は、baba_sさんによる、「Project ビューのフォルダを彩る「Rainbow Folders」紹介」です。よろしくお願いします。