【Untyアセットアドカレ】Set Pass Callを劇的に減らす「Mesh Baker」の使い方と、HoloLensでの動作結果

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


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

昨日はkazumalabさんによる、「【Unity アセット真夏のアドベントカレンダー 2017】世界をローポリにしてやろうか!」でした。

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

はじめに


HoloLensは空間認識を交えた機能が秀逸ですが、描画機能だけに絞ると性能は高くありません。

そのため、VR系の開発をした経験から同じ感覚でアプリを作ると、簡単にFPSが低くなります。

FPSが低くなる原因の一つに、表示させたモデルの描画負荷が高いことが挙げられます。

CGモデルの描画負荷を下げる方法を調べていたところ、@waffle_makerさんと@izmさんに「Mesh Baker」を教えていただきました。
(@waffle_makerさんと@izmさん、ありがとうございます)

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



===

目次

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

2.Mesh Bakerとは?

3.使い方

4. HoloLensで試した結果

4-1. Simple Trains - Cartoon Assets の場合
4-2. Urban City Scene
4-3. Japanese Classroom Set

5. 考察

6. Tips

6.1. Material生成をしようとするとエラーになる
6.2 スクリプトから制御する方法
6.3 有償版と無償版の違い

7.終わりに


===


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

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

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

f:id:Takyu:20170808194803p:plain

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

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


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

docs.unity3d.com

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

qiita.com

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

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

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

Performance recommendations for Unity

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


下記の記事では、著者はポリゴン数を減らした場合、Shaderを変えた場合のCGモデルをHoloLensで表示し、そのときのFPSを比較しています。

umbra3d.com

実験による考察として、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.


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

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


2.Mesh Bakerとは?

f:id:Takyu:20170813063034j:plain

Asset Storeの紹介文に、「Combine meshes and materials to reduce draw calls.」とあるように、メッシュをひとまとめにし、まとめたメッシュ単位でマテリアルを作ることで、描画負荷を減らすアセットです。

モバイルやHoloLensのアプリ開発では、描画負荷が高い=処理落ちすると、コンテンツの評価が下がりやすくなるため、適用範囲が広いアセットと思います。


3. 使い方

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

kan-kikuchi.hatenablog.com


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

(1) Baker作成

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

f:id:Takyu:20170813055931p:plain

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

f:id:Takyu:20170813060641p:plain

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

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

③Add Selected Meshes To Targetを選択

(2) アセット作成

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

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

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

(5) メッシュを結合

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

f:id:Takyu:20170813061615p:plain

この状態ではメッシュ情報が残っていません。

f:id:Takyu:20170813061643p:plain

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

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

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

f:id:Takyu:20170813062113p:plain

f:id:Takyu:20170813062343p:plain

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

f:id:Takyu:20170813062510p:plain

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

f:id:Takyu:20170813062734p:plain

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


ちなみに、上記の方法はこちらの動画から参照しました。4:00頃から説明されています。
www.youtube.com

4. HoloLensで試した結果

過去に買ったことがある3Dモデルアセットをいくつか調べてみました。

Unity Editor上のStatisticsと、HoloLensで動かした場合の動画を載せています。
ただし、いずれも描画範囲によって負荷が変わるので、このようなルールで記録しました。


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

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

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

4-1. Simple Trains - Cartoon Assets


Mesh Bakerを使わない場合

f:id:Takyu:20170811002353p:plain

Mesh Bakerを使った場合

f:id:Takyu:20170811002405p:plain

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

4-2. Urban City Scene

Mesh Bakerを使わない場合

f:id:Takyu:20170813073303j:plain


Mesh Bakerを使った場合

f:id:Takyu:20170813070845j:plain

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


4-3. Japanese Classroom Set


Mesh Bakerを使わない場合

f:id:Takyu:20170813065622j:plain

Mesh Bakerを使った場合

f:id:Takyu:20170813065846j:plain


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) シェーダ毎にマテリアルを作成のところで、以下のようなエラーがでることがあります。

f:id:Takyu:20170813074352p:plain

これは、結合対象のオブジェクトにマテリアルがアタッチされていないためです。

ここではGameObject at position 3 in list of Objects という記載があります。結合対象リストの3つめをみてみます。

f:id:Takyu:20170813074643j:plain

このように、Chain_Fense_CLOSSBARというオブジェクトがピンク色になっており、以下の通りマテリアルが設定されていません。

f:id:Takyu:20170813074826p:plain

このマテリアルを指定すれば、エラーが消えてメッシュ結合処理を進めることができます。

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

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

詳細はマニュアルのP.16以降のAdvancedを参照ください。

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


6.3 有償版と無償版の違い

実は、Mesh Bakerには無償版もあります。

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

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

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

・Prefab化ができない

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

f:id:Takyu:20170813084529p:plain

7.終わりに

このアセットはパフォーマンス改善に有効なので、HoloLensに限らず汎用的に使えると思います。

次回は、baba_sさんによる、「Project ビューのフォルダを彩る「Rainbow Folders」紹介」です。よろしくお願いします。