XNA 2Dゲームの最適化


56

ビューポート外のオブジェクトのレンダリングをスキップするロジックを実装するのは理にかなっていますか?

回答:


79

カリングはパフォーマンスの最適化です。そのため、単に目的のためにそれを行うだけでは意味がありません。理由が必要です。


GPU(XNA Frameworkではありません)は、目を見張るほど速い速度で三角形とピクセルを選別します。送信するすべての三角形を変換する必要があります(頂点シェーダーを介して)。次に、画面外に落ちたものを間引きします。次に、残りの三角形を塗りつぶし、画面外のピクセルをカリングします。次に、残りのピクセルが(ピクセルシェーダーを介して)バックバッファーに描画されます。

( "then"と言うと、実際にはこれらすべてを超並列パイプラインで実行します。)

そのため、個々の三角形を間引く必要があることは非常にまれで珍しいことです。頂点の制限に達するには、不条理なほど多数の三角形を描画する必要があります。フィルレート、テクスチャフェッチ、またはピクセルシェーディングの制限を達成するには、通常、深度の複雑さを高くする必要があります(この場合、ビューポート/錐台カリングは役に立ちません)。


そのため、通常、ジオメトリを画面外に表示するコストはほとんど、またはまったくありません。

コストは、特に「オブジェクト」(通常は3Dオブジェクト)を描画するコンテキストでは、そもそもそれらのオブジェクトをGPUに送信することにかかっています。送信するオブジェクトが多すぎると、バッチ制限に達します(フレームごとに数千*バッチを取得します)。

バッチの詳細な説明については、この回答とリンクされたスライドデッキを読むことをお勧めします。

このため、錐台カリングを実装すると、GPUに送信するバッチの数を減らすことができます。バッチが制限されている場合-これにより制限を超えてしまいます。


さて-あなたの質問は2D XNAについてです-おそらくあなたは使用していSpriteBatchます。これは少し異なります。

「Sprite Batch」と呼ばれることは間違いありません。やっているのは、描いたスプライトを取得し、それらを一緒にバッチ処理することでできるだけ少ないバッチでそれらのスプライトをGPUに送信するために最善を尽くすことです。

ただし、次の場合、SpriteBatchは新しいバッチの開始を強制されます。

  • 単一のバッチに収まるよりも多くのスプライトを描画します(XNA 4では2048個のスプライト)
  • テクスチャを変更する(これが、テクスチャによる並べ替えオプションがある理由です)

したがって、最初に実行する場合は、カリングが適切な最適化です。膨大な数のスプライトを送信して、バッチが多すぎる場合(おそらく帯域幅も使い果たしているかもしれませんが、最初にバッチ制限に達すると確信しています)。これは通常、本当に巨大な世界がある場合にのみ発生します。そのため、この場合、非常に単純化された、しかし不正確なカリングで大体逃げることができます。

今-あなたはバッチの制限を超えてあなたを取るために十分なテクスチャスワップで描画され、場合及びそれらの多くは、オフスクリーン実際にある、それらをカリングバッチ制限の下であなたを得るでしょう。その後、はい-カリングは機能する最適化です。

ただし、この場合に追求するより良い最適化は、テクスチャアトラス(別名:スプライトシート)を使用することです。これにより、画面上にあるかオフになっているかに関係なく、テクスチャスワップの数、つまりバッチの数を減らすことができます。(これが、スプライトのソース長方形を指定できる主な理由です。)


(いつものように、これはパフォーマンスの最適化に関するアドバイスです。そのため、最適化の追加に努力を費やす前に、ゲームのパフォーマンスと、限界を測定して理解する必要があります。)


5
+1それは、それだけのためにカリングを行わないことについて言及するためですが、パフォーマンスの問題のためにカリングが必要な場合です。
ウィルマルクレール

12
スプライトシートにはプログラマ/デザイナーの利便性以外に存在する理由があることをついに教えてくれたために+1
Bill

3
+1がすばらしい説明です。私はあなたの答えから多くを学びました。
ジェシーエモンド

1
「バッチ、バッチ、バッチ」pdfへのリンクが壊れています。ここに更新されたものがあります:ce.u-sys.org/Veranstaltungen/…–
Marton

13

MSDNのフォーラムの投稿によると、XNAフレームワークは錐台カリングを行いません。

XNAフレームワークでは、錐台カリングは行われません。実際に何が起こるかわからないためです。すべての変換はGPUで実行され、カスタムシェーダーにすることができます。

http://xboxforums.create.msdn.com/forums/p/22763/121897.aspx

この投稿では、シーンに多くのオブジェクトがある場合は、自分でロールする価値があるかもしれないと述べています。


6
特に、スクロールマップがある場合(2Dであると言ったので、これは関連があるかもしれません)。不要な大きなセクションを描画するのは無駄です。それほど難しくはなく、何らかの改善が見られるかもしれません。
マイケルコールマン

1

XNAで数年前から手続き型ボクセルテレインエンジンを開発しています。ほとんどのフレームで、エンジンは文字通り何十万ものクワッドを変換しています。プロファイリングで、錐台とオクルージョンカリングがパフォーマンスを向上させることがわかりました。

XNA HiDefプロファイル(Reachではない)には、オクルージョンカリングの実行に使用されるOcclusionQueryクラスがあります。オクルージョンカリングは、他のクワッドによってビューから隠されているクワッドをビューポートから削除します。

他に考慮すべきことは、生成とテッセレーションの両方を個別にテーディングすることです。

はい、そうです、変換中の各フレームで非常に多くのクワッドに近づくとき、GPUシェーダーへのトラフィックを減らすことにより、フレームレートを維持するためにカリングとスレッディング技術を適用する方法を慎重に考える必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.