パフォーマンス
YAUI は何もしなくても高速です。このページでは、何に時間がかかるか、そしてそれを抑える方法を説明します。uGUI や UI Toolkit との比較はベンチマークを参照してください。
ドローコール
パネルは 1 回のドローコールで描画されます。ただし、次の箇所では分割されます。
- 描画順で要素の間でマテリアルが変わる箇所 (カスタムマテリアル)
- マスクが始まる・終わる箇所 (
YauiMask) - 連続する要素が 8 枚を超えるテクスチャを使う箇所。フォントアトラス、スプライトのテクスチャ、動的アトラスのページ、Raw Image のテクスチャはすべて数に含まれます。
- 背景ブラーを描く箇所 (後述)
- 重い機能を使わない要素を軽いシェーダーで描くために分ける箇所 (後述)
同じマテリアルの要素は、描画順で間に他の要素があっても、それらと重ならなければまとめて描画されます。YAUI は結果が変わらない範囲で描画を並べ替えます (uGUI のバッチングと同様です)。
ドローコールを抑えるには:
- カスタムマテリアルではなく、Uber シェーダー (ボックスのスタイル、テキストの効果、画像の種類) を使ってください。プリミティブを独自の方法で描くパッケージは、シェーダーモジュールで Uber シェーダーの中で描けます。
- 矩形または 1 つの角丸矩形で十分な場合は、
YauiMaskではなくClipChildrenを使ってください。 - 小さなスプライトは動的アトラスに入れ、一緒に表示する大きなスプライトは同じスプライトアトラスに入れてください。
- 1 つのパネルで使うフォントの数を少なくしてください。
CPU
| 処理 | ヒント |
|---|---|
| テキスト生成は最もコストの高い処理です。 | テキストは変わったときだけ設定してください。同じフレームで変わるテキストの数を少なくしてください。 |
| レイアウトは変更を含む境界について実行されます。 | 内容によってサイズが変わらないコンテナに固定の Width と Height を与え、レイアウトの境界にしてください。アニメーションにはレイアウトのプロパティではなく描画変換を使ってください。 |
| 階層の変更はパネルの描画順を作り直します。 | 毎フレーム作成・破棄するのではなく、要素を再利用してください。GameObject の有効化・無効化も階層の変更です。 |
YauiPanel.ForceUpdate() はすべての処理をメインスレッドで一度に完了させます。 | 同じフレームで結果が必要なときだけ呼んでください。 |
色、描画変換、不透明度の変更はほぼ無料で、変更のないフレームのコストはほぼゼロです。非表示のパネル (不透明度 0、または見えるものがないもの) は描画されません。
カメラ
カメラモードでは、URP のカメラ 1 台ごとに、パネルの描画よりはるかに大きい CPU の固定費がかかります。UI の層ごとにカメラを用意するのではなく、すでに描画しているカメラに、injection point を分けてパネルを描いてください。別のカメラの絵の上にパネルを重ねるためだけのカメラは、そのパネルのどれかの YauiPanel.IsDrawn が true の間だけ有効にしてください。
GPU
Uber シェーダーには多機能であることによるコストがありますが、シェーダーのバリアントによって使っている機能の分に抑えられます。YAUI の GPU 時間は uGUI と同程度から約 1.5 倍で、UI Toolkit より短くなります (ベンチマークを参照)。これを抑えるには:
- どの UI でも同じですが、大きな半透明の領域の重なり (オーバードロー) を避けてください。
- 影のぼかしが大きいと、描画される Quad が大きくなります。
- カスタムシェーダーの
YAUI_PIXEL_CLIPはモバイルで GPU 時間がかかります。必要なときだけ有効にしてください。
シェーダーのバリアント
各ドローコールは、要素が使う機能 (テキスト、画像、ボーダー (ラジアルフィルを含む)、影) だけを持つ Uber シェーダーのバリアントで描画されます。どの要素も使わない機能にはコストがかかりません。
影のある要素が 1 つあると、そのドローコール全体が影のコストを払うことになります。割に合う場合、YAUI は影 (またはボーダー) のある要素を別のドローコールで描画し、残りの要素に軽いバリアントを使わせます。増えるドローコールの固定費 (GPU と CPU) と、画素で節約できる GPU 時間を比べて決めます。このバランスは YauiBatching で設定します。
| プロパティ | 既定値 | 説明 |
|---|---|---|
SplitByShaderFeatures | true | 重い機能でドローコールを分けるかどうか。 |
GpuWeight, CpuWeight | 1 | GPU 時間と CPU 時間の重み。既定値は処理の総量を最小にし、フレームレートの上限に達しているときの消費電力と発熱を抑えます。GPU がボトルネックのプロジェクトでは GpuWeight を、CPU がボトルネックのプロジェクトでは CpuWeight を上げてください (品質レベルごとに変えるなど)。 |
SplitMargin | 2 | 分割がそのコストの何倍を節約しなければならないか。 |
これらのコストの見積もりは中程度の性能の Android 端末で測ったものです。パネルが動いている間、YAUI は毎フレーム、ワーカースレッドでドローコールを決め直します。その処理が分割で節約できる量より高くつく場合は、パネルが止まるまで 1 つのドローコールのままにします。
バリアントを初めて使うドローコールでは、GPU がパイプラインの状態を作る間、処理が止まることがあります。必要な状態はプロジェクトによって異なるため、YAUI はウォームアップを行いません。必要であればプロジェクトでウォームアップしてください (GraphicsStateCollection など)。バリアントは Hidden/Yaui/Uber のキーワード YAUI_TEXT、YAUI_IMAGE、YAUI_BORDER、YAUI_SHADOW、YAUI_PIXEL_CLIP です。
背景ブラー
背景ブラーは、要素を描く前にパネルのパスを終え、描画先をコピーし、縮小してぼかします。コストは描画先とぼかしの大きさに応じて増えます。同じマテリアルで隣り合う要素は 1 つのコピーを共有するため、階層でも隣り合わせに置いてください。
スクロールビュー
YauiScrollView は描画変換で内容を動かすため、スクロールでレイアウトが実行されることはありません。項目の仮想化は行いません。すべての項目が描画・レイアウトされます。非常に長いリストでは、上位のレイヤーで少数の項目を再利用してください。