測定基準ビュー
測定基準(Metrics)ビューでは、スケルトンの実行時のパフォーマンスを確認することができます。
各項目は表示中のすべてのスケルトンの合計値を表示しています。
アニメーション関係の項目は、アニメ化モードでのみ表示されます。
スケルトン
ボーン(Bones)
各スケルトン内のボーンの総数です。
ボーンのワールドトランスフォームの計算にはCPUを使用します。比較的軽量ですが、それぞれが多くのボーンを持つスケルトンがたくさん画面上にある場合には増加します。例えば、各スケルトンに30個のボーンがあり、これらのスケルトンのうち50個が一度に画面上にある場合、ボーン1500個のワールドトランスフォームを計算する必要があります。
ランタイムでは、ローカルのボーンのトランスフォームを(しばしばアニメーションを適用して)操作してスケルトンがポーズされると、各ボーンのワールドトランスフォームが計算されます(典型的なコード)。 通常、これはスケルトンのupdateWorldTransformが呼び出されたときに行われます。
デスクトップでは、何千ものボーンがあっても一般的には問題になりません。モバイルでは、数千個以上のボーンが問題になることがあります。例えば、いくつかのテストでは、Nexus 4で約2000個のボーンを処理すると、フレームレートが毎秒60フレーム以下に落ちてしまうことが分かっています。
コンストレイント(Constraints)
コンストレイントの計算にはCPUを使用します。この計算は比較的軽量ですが、画面上にコンストレイントを使用しているスケルトンがたくさんある場合には増加します。
IKコンストレイントはボーン1本だけであれば非常に簡単ですが(典型的なコード)ボーン2本を使ったIKはより多くの処理を必要とします(典型的なコード)、ただしいくつかのコードパスはめったに取られません。
トランスフォーム・コンストレイントは、コンストレイントされたボーンごとに適用されますが、それほど多くの処理を必要としません(典型的なコード)。
パス・コンストレイントは、パスの頂点数や制約されるボーン数に応じて、かなりの数の処理が必要になります(典型的なコード)。
スロット(Slots)
各スケルトン内のスロットの総数です。
スロットの数がパフォーマンスに与える影響はごくわずかです。各スロットには0個または1個のアタッチメントが表示されるため、この指標は任意の時点で表示可能なアタッチメントの最大数を示しています。
アタッチメント
合計(Total)
各スケルトン内のアタッチメントの合計数です。
アタッチメントの総数は、レンダリングパフォーマンスには影響せず、ロード時間にもごくわずかな影響しかありません。
表示中(Visible)
各スケルトンが表示しているアタッチメントの数です。
「アタッチメントが表示されている」というだけでは、レンダリングのパフォーマンスに影響しない場合があります。例えば、境界ボックスアタッチメントは何もレンダリングされません。
頂点(Vertices)
表示されているすべてのアタッチメントの頂点数です。
頂点数は、GPUに送られるジオメトリの量を示します。
頂点トランスフォーム(Vertex transforms)
表示されているすべてのアタッチメントに対してトランスフォームされる頂点の数です。
頂点のトランスフォームにはCPUを使用します。この計算は比較的軽量ですが、画面上に多くのスケルトンがあると加算されます。頂点の数と、各頂点に対してどれだけのボーンがウェイトを持っているかによって、頂点トランスフォームの数が決まります。
ボーンと同様に、アタッチメントの頂点もローカル座標からワールド座標に変換する必要があります(典型的なコード:領域アタッチメント、メッシュアタッチメント)。
三角形(Triangles)
表示されているすべての領域またはメッシュアタッチメントの三角形の数です。
三角形の数は、GPUに送られる頂点インデックスの数を示します。
面積(Area)
スケルトンをフルサイズで描画したときに描画されるピクセル数です。これには、透明なピクセルや、オーバードローにより複数回描画されたピクセルが含まれます。
描画されるピクセル数は、スケルトンのレンダリングに使用されるGPUフィルレートの大きさを示します。
クリッピングポリゴン(Clipping polygons)
凸型クリッピングポリゴンの数です。クリッピングアタッチメントの頂点が凹型の場合、2つ以上の凸型ポリゴンに分解されます。
パフォーマンス的に最適なのは、各クリッピングアタッチメントが凸型で、結果として1つのクリッピングポリゴンになっている場合です。複数のクリッピングポリゴンがあると、クリッピングされる三角形の数が増えてしまいます。詳しくは、クリッピングのパフォーマンスをご覧ください。
クリップされた三角形(Clipped triangles)
表示されているクリッピングアタッチメントによってクリップされたアタッチメントの三角形の数です。
パフォーマンスのためには、できるだけ少ない三角形をクリップするのが最適です。詳しくはクリッピングのパフォーマンスをご覧ください。
選択
1つ以上のアタッチメントが選択されている場合、いくつかの指標では2つの数値が表示されます。フォワードスラッシュの前の数字が、選択中のアタッチメントの数値です。フォワードスラッシュの後の数値は、すべてのアタッチメントの情報です。
アニメーション
タイムライン(Timelines)
現在アクティブなアニメーションのタイムラインの合計数です。
タイムラインの適用にはCPUを使用します。1つのタイムラインを適用するのは比較的軽量ですが、多くのスケルトンで各フレームごとにアニメーションが適用されている場合、その数は増加します。また、1つのスケルトンに複数のアニメーションが毎フレーム適用されることもあります。例えば、走りと射撃を同時に行う場合や、クロスフェードのためにアニメーションをミックスする場合などです。
ランタイムでのアニメーションは、いくつかの「タイムライン」から構成されます。各タイムラインには、キーの値のリストがあります。アニメーションが適用されると、そのアニメーションの各タイムラインが適用されます。タイムラインはそのリストを見て、現在のアニメーション時間のキー値を見つけ、その値でスケルトンを操作します (典型的なコード)。フレーム0でキーが1つしかないタイムラインでも、アニメーションがスケルトンに適用されるたびに適用されます。
パフォーマンス
パフォーマンスの興味深い点は、大きな問題になるか、まったく問題にならないかのどちらかになることです。ひどい性能のハードウェアで動作するひどいアプリケーションであっても、パフォーマンスが許容範囲内であれば、最適化の必要はありません。ルールとしては、パフォーマンスを向上させてもユーザーが気づかないのであれば、パフォーマンスの向上に費やす時間はまったくの無駄です。その時間は常に、ユーザーにとって目に見えるものに費やした方が良いのです。実際、必要以上に最適化すると、アニメーションの質が低下してしまったり、ソフトウェアが複雑になってメンテナンスが大変になったりするので、不必要に最適化しないことが重要です。
これは、開発中にパフォーマンスを無視してはいけないということではなく、パフォーマンスの問題を回避するためには、事前に最小限のパフォーマンスを考慮する必要があるということです。特に多くの可変要素が関係している場合には、行き過ぎて時間を無駄にすることがよくあります:
- アプリケーションがどのハードウェア上で動作しているか
- アプリケーションとゲームのツールキットがスケルトンのレンダリング以外に行うすべてのこと
- ゲームツールキットとSpineランタイムがどのようにレンダリングを行うか
- どれだけの数のスケルトンがレンダリングされるか
- 各スケルトンはどのように構成されているのか
- どのくらいのピクセル数が描画されるのか
- その他様々な点
Spineのアニメーションをデザインする際、アニメーターがこれらすべてを考慮して、パフォーマンスの高いアセットだけを提供することは不可能です。その代わり、パフォーマンスを無駄にしないよう、変形に必要な数のメッシュ頂点のみを使用するなど、合理的な努力をする必要があります。パフォーマンスに問題が発生してから、スケルトンを単純化するための追加の努力をすべきです。
パフォーマンスは非常に多くの可変要素に依存しているため、測定基準ビューのどの数値が高すぎるかを一般化することはできません。パフォーマンスを限界まで押し上げたい場合は、実際のスケルトンとアプリケーションの残りの部分をさまざまなハードウェアでテストして、特定の環境での限界を把握する必要があります。CPUやGPUを限界まで使用していないのであれば、パフォーマンスを気にしてアニメーションのクオリティを犠牲にする必要はありません。
パフォーマンスの問題が発生した場合は、まず最初に、パフォーマンスに最も大きな影響を与えるボトルネックを特定することが重要です。Spineのスケルトンをレンダリングする際の最も一般的なボトルネックは、CPU使用率、フィルレート、およびドローコールです。
CPU使用率
CPU使用率が高すぎるということは、アプリケーションが大量のCPUを使用し、レンダリングが許容できるフレームレートを下回ることを意味します(通常、60または30フレーム/秒以下)。CPU使用率の最も重要な指標は、ボーン、タイムライン、頂点トランスフォーム、コンストレイント、クリッピングです。これらはいずれも過剰に使用されると問題になります。
ウェイトを使用すると、頂点の数と各頂点にウェイトを持つボーンの数に応じて、頂点トランスフォームの数を大幅に増やしてしまいます。削減を使用すれば、頂点トランスフォームの数を減らすことができます。
タイムラインの数は、アニメーションを適用するために必要な処理を増加させてしまいます。アニメーションのクリーンアップで、タイムラインの数を減らすことができます。
クリッピングは非常に演算コストが高いため、他の画像のオーバードローによって隠せる場合などは、可能な限り使用を避けるべきです。クリッピングを使用する場合は、凸型にして、できるだけ少ない頂点を使用し、できるだけ少ない三角形をクリップするようにしてください。
また、スケルトンの複雑さを減らす以外にも選択肢があるかもしれません。スケルトンがたくさんある場合は、ラウンドロビン方式でフレームごとにサブセットだけを更新することもできます。また、少数のスケルトンだけをアニメーション化し、そのポーズを使って多数のスケルトンをレンダリングするという方法もあります。
フィルレート
GPUフィルレートが枯渇しているということは、許容できるフレームレートでGPUが描画できる以上のピクセルを描画しようとしていることを意味します。ピクセルが描画されるたびに、フィルレートがカウントされます。これは、ピクセルが完全に透明な場合や、アタッチメントが重なっている場合など、同じピクセルが複数回描画される場合(これを「オーバードロー」と呼びます)にも当てはまります。
フィルレートが制限された場合の解決策は常に同じで、より少ないピクセルを描画するようにすることです。メッシュを使えば、透明なピクセルの描画を削減することができますが、その場合、CPUでトランスフォームする頂点の数が増えることになります。完全に透明なピクセルはフィルレートを消費するので、アルファをゼロにするのではなく、アタッチメントを非表示にする必要があります。例えば、2つ以上の画像を重ねる代わりに、1つの大きな画像を使用することで、オーバードローを最小限に抑えることができます。
ドローコール
GPUに描画を依頼すると、新しい描画タスクを受け付ける前に実行中のタスクを終了する必要があるため、演算コストのかかる操作になってしまいます。描画を要求される回数が多すぎると、GPUは許容できるフレームレートですべての描画を完了することができなくなります。
ほとんどのゲームツールキットは、GPUが描画を要求される数がより少なくなるように、できるだけ多くのジオメトリをバッチ処理します。通常、GPUが別のテクスチャから描画する必要があるときにはバッチをフラッシュする(流す)必要があるので、テクスチャアトラスを使用してテクスチャスイッチを減らします。スロットにブレンドを使用した場合も、バッチのフラッシュの原因となります。