1

opengl を使用して Android でゲームを開発していますが、パフォーマンスに少し問題があります。

たとえば、草の「茂み」で部分的に満たされた背景を描きたいとしましょう。茂みは異なる x、y、z、異なるサイズなどを持ち (各茂みは 2D スプライトです)、互いに部分的に隠れる可能性があります (私は遠近法カメラを使用しています)。これらのスプライトが大きい場合 (つまり、テクスチャ サイズ/解像度ではなくクワッド サイズ)、大きなパフォーマンスの問題が発生します。

  • (オーバードローを避けるために) 従来のフロントツーバック ドローを使用すると、(私が思うに) アルファ テストが原因で問題が発生します。茂みに不透明で完全に透明なピクセルしかなく (部分的な透明度はありません)、適切なアルファ テスト比較 (GL_EQUAL 1) を使用すると、多くのピクセルをアルファ テストする必要があるため、パフォーマンスが低下します (正しく理解している場合)。 .

  • アルファ テストを無効にしてバック ツー フロント ディスプレイを使用すると、デプス バッファの書き込みを無効にしてもパフォーマンスが大幅に低下します (ただし、今回はオーバードローの問題が原因です)。仕方)。

アルファ テストを行わずに前後を使用すると、パフォーマンスは良好ですが、もちろん、スプライトのカットアウトは完全になくなりました。これは非常に悪いことです。

すべての茂みは同じテクスチャを持ち、16 ビット カラー、ミップ マッピング、ジオメトリ バッチ処理、カリング フェース、シェーダーなしなどを使用します。テクスチャ圧縮を除いて、パフォーマンスを向上させるために考えられるすべてのこと (他の場合は悪くありません)。 . スプライトをフィルタリングして、スプライトが画面外に「表示」されないようにします。また、テクスチャを完全に不透明にする、テクスチャの解像度を大幅に下げる、ブレンドを無効にするなど、テスト目的でいくつかの「激しい最適化」を試みましたが、アルファ テストの削除を除いてパフォーマンス面で素晴らしいものはありませんでした。

パフォーマンスを助けるためにここに何かを忘れていたのではないかと思っていました。バックツーフロントはオーバードローを作成し、アルファテストのためにフロントツーバックは遅くなります(そして、茂みを「正方形」のイメージにしたくないので、アルファテストを無効にすることはできません)。小さいスプライトを作成すると、(スプライトの数が多くても) パフォーマンスははるかに向上しますが、これは回避策にすぎません。

要約すると、カットアウトが必要なオーバーラップする大きなクワッドを、パフォーマンスを損なうことなく表示するにはどうすればよいでしょうか?

PS:ネクサスでテストしています。

PS2 : いくつかの最適化では、クワッドを作成せずにジオメトリをテクスチャに「適合」させることを提案していますが、それは非常に面倒なプロセスのようで、あまり役に立たないと思います。

4

1 に答える 1

1

前から後ろに描画することは、初期 z のため、通常は利点があります。ハードウェアは、テクスチャのフェッチまたはシェーディングを行う前に、ラスタライズの直後に深度テストを実行できます。前から後ろへの並べ替えでは、ほとんどのフラグメントが深度テストに失敗し、テクスチャ帯域幅、シェーディング スループット、および zbuffer 書き込み帯域幅を大幅に節約できます。

しかし、アルファテストはそれを破ります。フラグメントが深度テストに合格した場合でも、アルファ テストによって強制終了される可能性があるため、テクスチャリング/シェーディングが完了するまで zwrite は発生しません。Early-z を実行できるほとんどのハードウェアは、パイプラインの zwrite と同じポイントで深度テストを実行する必要があるため、アルファ テストでは、テクスチャリングとシェーディングの後に ztest + zwrite を実行することになります。その結果、前から後ろへの並べ替えは、zwrite の帯域幅を節約するだけで、他には何も節約しません。

大幅にオーバーラップする大きなスプライトが本当に必要な場合は、2 つのオプションがあると思います。

(a) スプライトには 2 つまたは 3 つの異なる Z 値のみを使用します。ブレンディング(およびアルファテストが役立つ場合)を使用して、それらを前後に描画します。レイヤー内での重複はありません。各レイヤーを元のアセットで事前にレンダリングするか、実行時に 1 回レンダリングしてから、左右にシフトするだけです。

(b) スプライトに半透明の境界線で囲まれた大きな不透明領域がある場合、最初のパスでアルファ テストなしで不透明領域を描画し、次に別のパスとして境界線を描画できます。これにより、アルファ テストされたフラグメントの数が削減されます。

于 2013-05-15T22:40:36.743 に答える