Hero background image
テクニカルアーティストのためのモバイル最適化のヒント Part II

このページから得られるもの モバイルゲーム用にアートアセットを最適化するための役立つヒント集 パート2です。パート1は

他にもモバイル最適化のヒントが満載 この包括的な電子書籍 とUnity Learnのコース モバイルアプリケーションの3Dアート最適化

Unityエディタでのライティング設定
ゲームオブジェクトを整理して、このようなバッチ技法を活用する。
ライティング

コンソールやPCと同じ物理ベースのライティングやマテリアルは、Universal Render Pipeline(URP)を使って、携帯電話やタブレットにも拡張できます。

ドローコールをバッチ化する

フレームごとに、Unityはレンダリングするオブジェクトを決定し、ドローコールを作成します。描画コールは、オブジェクト(例えば三角形)を描画するためにグラフィックスAPIを呼び出すことであり、バッチはまとめて実行される描画コールのグループである。描画するオブジェクトを一括にすることで、各オブジェクトの描画に必要な状態の変化を最小限に抑えることができる。これにより、オブジェクトのレンダリングにかかるCPUコストが削減され、パフォーマンスが向上する。

  • ダイナミックバッチング小さなメッシュの場合、UnityはCPU上で頂点をグループ化して変換し、それらを一度に描画することができます。注:十分なローポリメッシュ(頂点アトリビュート900以下、頂点数300以下)がある場合にのみ使用してください。ダイナミック・バッチャはこれより大きなメッシュをバッチ処理しないので、これを有効にすると、毎フレームでバッチ処理する小さなメッシュを探すのにCPU時間を浪費することになる。
  • 静的バッチング:動かないジオメトリの場合、Unityは同じマテリアルを共有するメッシュの描画コールを減らすことができます。ダイナミックバッチングよりも効率的だが、より多くのメモリを使用する。
  • GPU インスタンシング同じオブジェクトが大量にある場合、このテクニックはグラフィックス・ハードウェアを使用することで、より効率的にそれらをバッチ処理することができる。

SRPバッチ処理:URPアセットのAdvancedでSRP Batcherを有効にします。シーンにもよるが、CPUレンダリング時間を大幅に短縮できる。

ダイナミック・ライトの多用は避ける

モバイル・アプリケーションにダイナミック・ライトを追加しすぎないことが重要だ。カスタムシェーダーエフェクトやダイナミックメッシュ用のライトプローブ、スタティックメッシュ用のベイクドライティングなどの代替案を検討してください。

URPとBuilt-In Render Pipelineのリアルタイムライトの具体的な制限については、この機能比較表を参照してください。

影を無効にする

シャドーキャストは、MeshRendererとライトごとに無効にできます。ドローコールを減らすため、可能な限りシャドウを無効にする。

また、キャラクターの下にあるシンプルなメッシュや四角形にぼかしたテクスチャを適用して、偽の影を作ることもできます。そうでなければ、カスタムシェーダーでブロブシャドウを作ることができる。

Unityライトマップ図
シャドウの投影を無効にして、ドローコールを減らします。
照明をライトマップに焼き込む

グローバルイルミネーション(GI)を使って、静的ジオメトリにドラマチックなライティングを追加できます。Contribute GIでオブジェクトをマークすることで、高品質のライティングをライトマップの形で保存できます。

ベイクされたシャドウとライティングは、実行時にパフォーマンスを低下させることなくレンダリングできる。プログレッシブCPUとGPUライトマッパーは、グローバルイルミネーションの焼き付けを高速化することができます。

Unityでライトマッピングを始めるには、マニュアルと ライトの最適化に関するこの記事に従ってください。

Unityエディタで複数のライトレイヤー
レイヤーによって、ライトの影響を特定のカリングマスクに制限できます。
ライトレイヤーを使う

複数のライトがある複雑なシーンでは、レイヤーを使ってオブジェクトを分離し、各ライトの影響を特定のカリングマスクに限定します。

Unityエディタでのライトプローブ
動く物体にはライトプローブを使う

ライトプローブは、高品質の照明(直接照明と間接照明の両方)を提供しながら、シーン内の空きスペースに関する焼き付け照明情報を保存します。球面ハーモニクスを使用しており、ダイナミックライトに比べて計算が速い。

立方体と交差する反射球体
反射プローブの最小化

リフレクション・プローブはリアルな反射を作ることができるが、バッチ数が非常に多くなる。実行時のパフォーマンスを向上させるために、低解像度のキューブマップ、カリングマスク、テクスチャ圧縮を使用します。

Unityエディタでの透明マテリアル
シーンビューのオーバードロー視覚化モード
透明素材に注意

透明なオブジェクトをレンダリングすると、不透明なオブジェクトをレンダリングするよりも常に多くのGPUリソースを使用します。特に、透明なオブジェクトを複数回重ねてレンダリングする場合は、オーバードローとして知られる処理になります。特にモバイル・プラットフォームでは、可能な限り不透明な素材を使うのが良い習慣だ。RenderDocのグラフィックデバッガを使えば、オーバードローをチェックできます。

シェーダーはシンプルに

できるだけシンプルなシェーダー(アンライトシェーダーなど)を使い、不必要な機能は使わないようにしましょう。パーティクルなどのシステム専用に設計されたUnityのビルド済みシェーダーを使用します。URPには、モバイルプラットフォーム用に最適化された、いくつかの軽量なLitシェーダーとUnlitシェーダーが含まれています。過剰描画を最小限に抑えるには、ゲーム内のパーティクルの数やサイズを小さくします。

性能目標を達成するためには、可能な限り、半分の精度でUnlit Opaqueマテリアルを使用することを考慮し、ノード内での複雑な操作に注意すること。シェーダー・グラフに関するこのセッションのヒントをご覧ください。

リトアニアVS.非点灯シェーダー

シェーダを作成するとき、マテリアルが光にどのように反応するかを決めることができます。ほとんどのシェーダーは、点灯または非点灯に分類される。アンライトシェーダは、最も高速で計算量の少ないシェーディングモデルです。下位機種をターゲットにしている場合は、これを使う。

考慮すべきポイントは以下の通り:

  • ライティングは、ライティングされていないシェーディングモデルには影響しません。つまり、スペキュラリティの計算など、多くの計算が不要になる。その結果、レンダリング料金が安くなるか、レンダリング速度が速くなる。
  • アニメのような様式化されたアートディレクションは、照明のないシェーディングと相性がいい。このスタイルは、モバイルプラットフォーム向けのゲームを開発する際に考慮する価値がある。
Unityエディタでのシェーダーグラフ
シェーダー・グラフの頂点変位
頂点シェーダーでの数学演算

バーテックス・シェーダーはすべての頂点で動作し、ピクセル(またはフラグメント)・シェーダーはすべてのピクセルで動作する。通常、レンダリングされるピクセルの数は、画面上の頂点の数よりも多い。つまり、ピクセルシェーダーはバーテックスシェーダーよりも頻繁に実行される。このため、可能な限り計算をピクセルシェーダからバーテックスシェーダに移すことを推奨します。いつものように、最適化に取り組んだ後は、さらにプロファイリングを行って、特定の状況に最適なソリューションを決定する必要がある。

足し算や掛け算といった基本的な演算は、処理速度が速い。低速の数学演算の数をできるだけ少なくするのがベストだ。GLES 2.0を使用しているような古いデバイスでは、使用される複雑な数学の量を低く抑える必要があります。

SRP Batcher

SRP Batcherをオンにするときは、ProfilerビューのStatisticsウィンドウとRendering SectionのVertices Graphを見ます。FPSの向上もさることながら、処理される三角形と頂点の数が劇的に減少する。私たちのオブジェクトはURPと互換性のあるシェーダーを使用しているため、レンダーパイプラインは、処理されるデータ量を減らすために、関連するすべてのジオメトリデータを自動的にバッチ処理します。

キャラクターのアニメーション

デフォルトでは、Unity はアニメーション化されたモデルを Generic リグでインポートしますが、開発者がキャラクターをアニメーション化するときは Humanoid リグに切り替えることがよくあります。ヒューマノイドリグは、フレームごとにインバースキネマティクスとアニメーションのリターゲティングを計算するため、同等の一般的なリグよりもCPU時間を30~50%多く消費します。

スキンメッシュのレンダリングにはコストがかかる。SkinnedMeshRendererを使用するすべてのオブジェクトに必要であることを確認してください。GameObjectにアニメーションが必要なのは一部の時間だけなら、BakeMesh関数を使ってスキンメッシュを静止ポーズでフリーズさせ、実行時にシンプルなMeshRendererに交換する。

UnityのMecanimシステムは主にヒューマノイドキャラクター向けで、かなり洗練されていますが、単一の値(UI要素のアルファチャンネルなど)をアニメーションさせるために使用されることがよくあります。アニメーターの使いすぎを避ける。特にUI要素との組み合わせでは、トゥイーン関数を作成するか、単純なアニメーションのためにサードパーティ製ライブラリ(DOTweenやLeanTweenなど)を使用することを検討してください。

Unityエディタでのインテリアライティングシーン
フレームデバッガツールで描画コール、バッチ処理、レンダリングサイクルの各ステップをチェックする
追加のヒント

1フレームあたりの時間予算を決める

各フレームには、目標とする秒間フレーム数(fps)に基づいたタイムバジェットが設定されます。理想的には、30fpsで動作するアプリケーションでは、1フレームあたり約33.33ms(1000ms / 30fps)を許容します。同様に、60fpsを目標にすると、1フレームあたり16.66msとなる。

デバイスは、短時間(カットシーンやローディング・シーケンスなど)であればこのバジェットを超えることができますが、長時間の使用はできません。

プリセット

デフォルト設定に頼らないこと。プラットフォーム固有のオーバーライドタブを使用して、テクスチャやメッシュジオメトリなどのアセットを最適化します。設定が正しくない場合、ビルドサイズが大きくなり、ビルド時間が長くなり、メモリ使用率が悪くなる可能性があります。プリセット機能を使用して、特定のプロジェクトを強化するベースライン設定をカスタマイズすることもできます。

カメラの使用を制限する

有意義な仕事をしているかどうかにかかわらず、各カメラには何らかのオーバーヘッドが発生する。レンダリングに必要なCameraコンポーネントのみを使用する。ローエンドのモバイル・プラットフォームでは、各カメラが最大1ミリ秒のCPU時間を使用する可能性がある。

フルスクリーン効果を避ける

フルスクリーン グローのようなポストプロセッシングエフェクトは、パフォーマンスを劇的に低下させます。タイトルのアートディレクションには慎重に使用しましょう。

Renderer.materialの扱いに注意

スクリプトでRenderer.materialにアクセスすると、マテリアルが複製され、新しいコピーへの参照が返されます。これにより、すでにその素材を含む既存のバッチは破棄される。バッチオブジェクトのマテリアルにアクセスしたい場合は、代わりにRenderer.sharedMaterialを使用してください。

このコンテンツにご満足いただけましたか?