NHN Cloud Meetup 編集部
アプリの実行速度を向上させる最適化ガイド(2)
2018.05.30
2,435
スマートフォンのハードウェア性能は、ますます高まってきています。
当然の話ですが、大体のゲームは機器の性能によって実行時間が概ね速くなります。
実際に特定の機器で多くの問題が発生したり、実行がスムーズにいかない機種は対応機種から外す場合もありますが、低スペックのスマートフォンであっても普及率が高く、競合会社のゲームが円滑に動作できているとしたら、どうすればよいでしょうか?
機器の性能を最適化でき、ユーザーは低スペックで高品質なゲームを楽しむことができ、開発会社は一人のユーザーでも多く確保できる共生の道を探ることが本章の目的です。
3.何を、どのように最適化するか?
相対的に実行速度が速いアプリに対してインタビューした結果と、国内外の改善研究事例から、4つのカテゴリーで改善案を導き出しました。
- 1. イメージリソースの最適化
アプリ容量とメモリを占有する主な要素は、イメージリソースである。 - 2. Asset bundleリソース処理
アプリ実行速度を速くするためにAssetを使わないということではない。
どのように使えばよいか考えてみよう。 - 3. イベントなど他システム連動処理
広報やユーザーを対象にイベントを提供することがゲーム成功への無視できない要素になっている。
快適なアプリ実行のためのトレードオフも考慮してみよう。 - 4. 音源リソースやその他の最適化
その他、パッケージと大きいレベルから開発方法論まで調べてみます。
3.1実行時間の短縮案 – イメージリソースの最適化
なぜイメージが最優先なのか、下表からTexture2D容量がアプリサイズを最も多く占めていることがわかります。
表のアプリはAndroid OSのゲームで、APKのサイズはすべて100MB未満です。
イメージリソースを処理して、メモリにアップロードされる画像サイズを減らし、アプリ容量を減らす方法でイメージ圧縮の最適化を行います。非可逆圧縮ではイメージリソースのサイズは減りますが、品質低下の恐れがあります。ゲームによってはトレードオフ可能なレベルで進行し、最適化する必要があります。
元画像をそのまま使用する場合は、Unity3Dのテクスチャサイズに応じてメモリを浪費することがあります。面積とメモリの関係を見ると、サイズが半分であれば、容量は1/4に減ります。
RGBA値を適切にして色数などを調整すると、より大きく容量を確保できます。
テクスチャ面積とメモリの関係:(Width x Height)x(R + G + B + A)
2048 x 2048 => 4MB => 4MB x 32bit(RGBA)=> 16MB
1024 x 1024 => 1MB => 1MB x 32bit( RGBA)=> 4MB
Alpha値が必要ない場合:4MB x 24bit => 12MB、1MB x 24bit => 3MB
- 縦横の長さが半分であれば、画像サイズは1/4
- サイズを小さくすると、一度にロードされる容量が少なくなり、メモリの浪費を防いでロード時間を短縮できる
- 圧縮によりダウンロード時間確保
- ディスク容量とI/Oボトルネックの負担軽減
3.1.1イメージリソースの最適化 – 圧縮フォーマット
OS別の主要な圧縮方法を案内します。
iPhoneはPVRTC方式、AndroidはETC1が最も一般的にサポートされている圧縮方式です。
Untiyが提供している「プラットフォーム別オーバーライドのためのテクスチャ圧縮フォーマット」というガイドがあります。
3Dグラフィックスのハードウェアでは、迅速なテクスチャサンプリングのために最適化されたフォーマットでテクスチャを圧縮する必要がある。それぞれ使用が可能なプラットフォームやデバイスには固有の排他的フォーマットがある。
※出典:プラットフォーム別オーバーライドのためのテクスチャ圧縮形式(Texture compression formats for platform-specific overrides)
プラットフォーム(OS、WebGLなど)とデバイス(製品モデル)によって使用する圧縮形式が異なる可能性があるということです。
ここではスマートフォンアプリ(ゲーム)の最適化を論じていますが、プラットフォームはiOSとAndroidに限定し、変数はGPUのみにしたいと思います。
GPU別に対応する圧縮形式がどう違うのか、もう少し調べてみよう。
上表のようにiPhoneはPRVTC、AndroidフォンはETCを主にサポートしますが、すべてがそうではありません。
サービスターゲットとするデバイスのGPUを把握し、それに合わせてリソース圧縮形式を指定することが必要です。アプリでインストール機器のGPUを確認し、分析したGPUに合うAssetをダウンロードするような処理を推奨します。
GPU別の圧縮形式に合うリソースをそれぞれの経路で配布するように分岐すればよいでしょう。
- メーカー別の圧縮方式
メーカー | 代表GPU | 圧縮方式 | 特徴 |
---|---|---|---|
ARM | Mali | ETC | -ETC1: ほぼすべてのAndroid端末が対応、Alphaは非対応 -ETC2: Alpha対応(openGL 3.0から可能) |
Qualcomm | Adreno | ATITC | |
Imagination | PowerVR | PVRTC | -2^nサイズの正方形テクスチャのみ圧縮可能 -該当しない場合は、強制的に2^nサイズでテクスチャ変更 -但し圧縮していないテクスチャは正方形制限なし |
nvidia | Tegra | DXT | -PCで使用されたDXT方式をそのまま使用可能 |
※出典:ドラゴンブログ
- スマートフォン機種別GPUリスト
Smartphone | GPU model |
---|---|
Apple iPhone 7 | PowerVR Series7XT Plus |
Apple iPhone 7 Plus | PowerVR Series7XT Plus |
Samsung Galaxy S8 – EMEA | Qualcomm Adreno 540 |
Samsung Galaxy S8 – USA and China | ARM Mali-G71 MP20 |
Google Pixel | Qualcomm Adreno 530 |
Google Pixel XL | Qualcomm Adreno 530 |
Sony Xperia XZ Premium | Qualcomm Adreno 540 |
LG G6 | Qualcomm Adreno 530 |
HTC U11 | Qualcomm Adreno 540 |
Huawei P10 | ARM Mali-G71 MP8 |
Xiaomi Mi 6 | Qualcomm Adreno 540 |
Oneplus 5 | Qualcomm Adreno 540 |
出典:DeviceAtlas
3.1.2イメージリソースの最適化 – 圧縮対象
圧縮方法のうち、テクスチャアトラスを圧縮する方式と、元画像を圧縮する方式の2つについて調べます。
- ファイル容量を大幅に削減したい場合は、テクスチャアトラスを圧縮して使用します。
元画像にアトラスを作成し、アトラスを非可逆圧縮する方式です。
結果は一目瞭然、低品質です。
もちろん容量を大幅に減らすことができます。
テスト結果によると、TinyPNGでAtlas PNGの可逆圧縮をした場合、元画像に比べ88%容量が削減できました。
- 画像の品質をある程度維持しながら容量を減らしたい場合は、元画像を圧縮する方法をとってみます。
元画像を圧縮し、Low Qualityのイメージでアトラスを生成します。
圧縮対象を変えたところ、圧縮率と品質に大きな違いが生じました。
イメージの色と文字がいくつか異なるのは、作業過程で精巧に比較しないためです。
容量はTinyPNGで原本PNGを可逆圧縮した場合、約28%程度となりました。
3.1.3イメージリソースの最適化 – テクスチャアトラスの最適化
スプライトの画像を組み合わせ可能な最小単位で集めて、テクスチャアトラスを作成して使用します。
テクスチャは、GPUの中で2^nサイズで保存します。以下のように元画像をテクスチャにアップして使用する場合、メモリを浪費することがあります。
テクスチャを効率的に使用するためアトラスを作成して使用します。
用語を整理してみよう。
- スプライト
- ゲームオブジェクトの動作を表現するときに使用する方法。ゲーム内で一度動かすと似たようなものも含めてスプライトと呼ぶ
- アニメーション作業の特性上、背景と分離して動く物体に使われる”マンガ的イメージ”という意味で使われている
- アトラスを構成する論理単位であり、部品のように組み合わせ可能である。あるいは単独で意味を表現できるイメージの単位
- テクスチャ
- Material(マテリアル)に用いられる画像のことで、マテリアルが適用されている表面にマッピングされる(出典:http://api.unrealengine.com/KOR/Engine/Content/Types/Textures/)
- スプライト画像をアップする2^n(POT)サイズのペイント
- テクスチャアトラス
- 複数のスプライトをテクスチャに集めたもの
スプライトをテクスチャにまとめて作る操作は、ここでは言及しません。
テクスチャアトラスの個別イメージを変更する場合にも、アトラスを再作成する必要があります。
可能ならスプライトとテクスチャを1対1で構成することをお勧めします。
テクスチャアトラスを最適化するための方法はいくつかあります。
- アトラス最適化という側面から簡単に説明します。
完成した画像をそれぞれテクスチャに載せず、下のように分離して入れます。
512 x 512のサイズを512 x 256に減らすことができます。
スプライトのスライスなどの手法を活用すれば、対称イメージを作成し、元のサイズを減らすのに役立ちます。
上記の方法で最適化した結果、8Mbytes(2048 x 1024)サイズを4Mbytes(1024 x 1024)に減らすことができました。
もちろんアトラス最適化によるデメリットもあります。
Asset制作の難易度が高くなり、それによって作業期間が増えることがあります。
また分離作業中、スプライトが抽象化されメンテナンス難易度が高くなる可能性もあります。
3.2実行時間の短縮案 – イベント処理
アプリを実行すると、ゲームに応じて4~5個のポップアップを経てゲーム画面に接続することになります。これらのイベントは、ユーザーにプレイの方向を提示し報酬を提供することでリテンションを維持し、ゲームを盛り上げる要素として多く活用されています。しかし意図せずイベントウィンドウによってゲーム接続にストレスを与える場合があります。
ポップアップ要素の中で区分が可能なものはlazy loading処理をして、ゲーム開始時のトラフィックを分散/軽減し、進行時間を短縮することを考慮することも必要です。
イベントによってはスタート画面にすぐ出したり、ユーザーが必要なときに参照できることも考慮してみましょう。
3.3実行時間の短縮案 – Assetリソース処理
リソースをアプリに含めてビルドしゲーム進入時、Assetダウンロードとチェック時間にメリットを見ることができます。リソースの修正が必要な場合、新規ビルドの配布が必要です。Googleプレイにリリースする際、100MBを超える場合は拡張ファイル(OBB)の活用を考慮してもよいでしょう。Assetを分離する方式ではなく、リソースの修正が必要な場合、新規のビルドをリリースしなければなりません。
アプリの容量とAsset活用により最適化が必要です。
そのうちの1つにマルチダウンロード手法を活用する方式がありますが、ここでは詳細は省略します。
マルチダウンロードソリューションでTOAST Cloudのスマートダウンローダーを活用すると簡単に適用できます。
https://toast.com/service/game/smart_downloader
特定のステージに登場する英雄/モンスターなどのリソースは、ステージオープン/進入時や、そのキャラクターを獲得した時にダウンロードすることも多く用いられます。
一方でAsset bundleに分離、アプリに含めてビルド/配布し、その後は修正可否に対するチェックと、小規模Assetだけがパッチされるように処理をする場合もあります。
3.4実行時間の短縮案 – 音源やその他の方法
音源も使用に応じて容量とメモリに上がるサイズが異なります。同じ音源を繰り返し使用するか(効果音)、BGMとして使用するかによって異なるでしょう。サービスに合わせて音源フォーマットとサイズを確保することをお勧めします。
3.4.1音源最適化
- MP3を主に使用
- 96kbs程度ならユーザーが聞くのに大きな違いは感じない(筆者基準)
- 必ずしも必要でないなら、スマートフォンゲームではステレオの代わりにMonoサウンドを使用(1/2サイズ)
- プレイ時間別の容量
3.4.2パッケージの最適化
パッケージの最適化も必要な要素となります。
- 最初からすべてのリソースをSceneやPrefabに参照をかけない。ダウンロードしたりランタイム接続するAssetは計画的に選定して別途管理する
- Sceneとprefabは可能な限りAssetを共有しない。共有するとパッケージにリソースが重複し容量が増加する
- Sceneを分離してバンドルし、必要に応じてダウンロードして使用。(BuildStreamedSceneAssetBundle)/Resourcesや/StreamingAssetsディレクトリに使用していないAssetがあれば削除する
3.5実行時間の短縮案 – リソースの最適化Tip
リソース最適化のヒントとして、前述した最適化の要因をまとめてみよう。
- テクスチャカラー
- 32Bit-> 16Bitに減少(1/2で容量減少)
- テクスチャは通常32bitで使用するが16bitに減らしても、目視で大きな違いはない
- テクスチャサイズ
- 3Dオブジェクトに与えるテクスチャの場合、サイズを減らしても大きな差がない
- 縦横を半分に減らすだけでも1/4に容量減少
- 背景画像
- ゲームによって異なるが、一般的に大容量を占める部分
- 背景にはAlphaが必要なくRGBのみを使用
- 反復する背景ならば一定サイズに切り取ってパターン化
- JPEGなどの圧縮ファイル形式使用
- フォント
- 国別に母国語のみのフォントを使用、またはシステムフォントの使用を推奨
- 韓国語や中国語などを含むフォントを使うと容量増加(normal、Boldを含めて約4MB)
- 不要なファイルを削除する
- C:\Users\NHNEnt\AppData\Local\Unity\Editor\Editor.logから、ビルドで容量を多く使用するファイルが分かる
- プロジェクト最適化スケジュールを反映
- 企画と設計段階から最適化の検討が必要
- 作業ステップ前後にリソース最適化のための確認スケジュールを含める
4.最適化による期待効果
4.1協業マインドの向上
最適化にはアプリ企画段階から考慮が必要だということがわかります。信頼性が高く快適なアプリを作成するにはメンバー全員の関心と努力が前提として必要です。最適化することで様々な肯定的な効果を期待できます。
- 実行時間測定
- 継続的な実行時間モニタによる管理
- サービス中のアプリでは実行時間の増減確認
- 新規アプリでは企画/設計から最適化を考慮して進行
- メンバー間の円滑なコミュニケーション
- 実行時間を改善するための最適化はプロジェクトメンバーすべての役割
- 企画者、サーバー開発者、クライアント開発者、デザイナー、事業担当すべてが関心を持ち意思疎通が必要
- ノウハウではない日常業務
- 最適化は経験豊富な開発者の隠されたスキルではなく、日常的な業務である
4.2 App実行時間の改善効果
当然、サービスの競争力の向上が優先事項ですが、快適な実行時間でゲームプレイ頻度が増えることが期待されます。
短いゲーム進入時間で顧客離れの可能性も低下できることを期待しましょう。
おわりに
上記の内容は、すでに大半のゲーム業界関係者がどのレベルであれ、悩んで研究したものです。
この資料が最適化について考えるきっかけになるとうれしいです。
ゲーム開発はそれぞれの立場があり、重要なものや、品質に対する目線、抵抗感も異なるでしょう。
しかし、サービスの成功が全員の目標だということには異論がないでしょう。最適化されたスマートなアプリは、そうでない場合よりもさらに成功条件に近いことでしょう。
冒頭にも述べたように「ハードコアしないように」作成しました。
企画、ビジネス、デザイン、開発者などの方々がすべて消化することができ、メンバー間で最適化のコミュニケーションツールとして活用されることを願っています。