効率的なスプライトのバッチ処理


7

XNAからStage3D API(Molehill)への移植を検討しています。したがって、パフォーマンス検査としてスプライトバッチ処理を実装しましたが、パフォーマンスはそれほど優れていませんが、XNAを使用すると、最大500,000のクワッドを簡単に描画できますが、Molehillを実装すると、約1000クワッドを描画できます。 CPU側ではかなり劇的なパフォーマンスの違いが予想されましたが、これはGPUにバインドされているためです。

したがって、現在の実装は次のとおりです。

set render states

let texture be null
let batchSize be arbitrary

for each sprite in queue
    if texture is not sprite texture
    or buffers are full

        upload vertex data to index buffer
        upload index data to vertex buffer

        bind texture
        draw triangles

        flush vertex data
        flush index data


    add sprite vertices to vertex data
    add sprite indices to index data
end

upload remaining vertex data to vertex buffer
upload remaining index data to index buffer
draw remaining triangles

flush data

ボトルネックはバッファのアップロードですが、より良い実装については、ここでの議論を期待しています。

乾杯。

リビジョン:

頭に浮かぶ1つの最適化は、インデックスが予測可能であり、常に同じ形式に従うため、インデックスバッファーを永続化することです。それを今ベンチマークするつもりです。


インデックスバッファーをキャッシュしてもパフォーマンスはそれほど向上しなかったため、ボトルネックがどこにあるかを理解するためにC#/ XNAに移植しましたが、Microsoftの実装よりも少し遅いですが、GPU容量は500倍以上ありますMolehillの実装。

Molehillは単に非常に悪い抽象化レイヤーですか?


インデックスバッファを永続的にすることは良いアイデアであり、少しのパフォーマンス向上に役立つ場合があります。私があなたの疑似コードを見ることから私が考えることができる他の唯一のものは、あなたが常にテクスチャを再バインドすることです。テクスチャが呼び出し間で変更されたかどうかを確認してから、新しいテクスチャをバインドする必要があります。そうしないと、たとえば、テクスチャアルタスを使用してもパフォーマンスが向上しません。
ジョナサンコネル

実際には、テクスチャは1回だけバインドされます。おそらくもう一度読み直してください。
Casper Beyer

そうそう、バインド時にスプライトのテクスチャに「テクスチャ」が割り当てられているということです。
Casper Beyer

for eachループに「Bind Texture」があります。2つのスプライト間でテクスチャが変更されていないときにBind Textureを呼び出さないようにする必要があると言っていました。現時点では、すべてのループでテクスチャを再バインドするようGPUに要求しています。これはコストのかかる操作であり、必要ない場合があります。
ジョナサンコネル

繰り返しますが、それは一度だけバインドされます。条件付きチェックは、ほとんどコストのかかる操作ではありません。
Casper Beyer

回答:


2

キーがテクスチャであるスプライトのマルチマップを作成し、レンダリング時にマップの各キーを通過して、そのテクスチャに関連付けられているスプライトの各グループをレンダリングできます。スプライトがすべて同じテクスチャを共有している場合、2つの三角形とテクスチャ座標ですべてのスプライトを表すことができます。つまり、同じテクスチャを使用するすべてのスプライトを、単一の頂点バッファーとインデックスバッファーを使用して、1回のパスで描画できます。

私はXNAを使用していますが、スプライトバッチを使用するのではなく、独自のレンダリングおよびバッチ処理プロセスをロールバックしました。一度に約3000のスプライトをレンダリングし、現在Nvidia GTX 275で約600 fpsを取得しています。上述。スプライトをスプライトバッチメソッドに渡したとき、XNAは約25 fpsでした。

私の場合、マルチマップではなく、テクスチャと頂点のリストを含むクラス(SpriteData)があります。スプライトがレンダラーに登録されるたびに、レンダラーは一致するテクスチャタイプが見つかるまでSpriteDataのリストを調べ、そのスプライトを頂点リストに追加します。

また、空間分割を行って、表示されているスプライトのみが考慮されるようにしています。

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