Ich überlege, von XNA auf die Stage3D-APIs (Molehill) zu portieren. Als Leistungsprüfung habe ich Sprite-Batching implementiert, aber die Leistung ist nicht besonders gut, während ich mit XNA problemlos bis zu 500.000 Quads zeichnen kann, aber mit meiner Molehill-Implementierung kann ich ungefähr 1000 Quads zeichnen und während a Auf der CPU-Seite wurde ein ziemlich dramatischer Leistungsunterschied erwartet, der auf die GPU-Bindung zurückzuführen ist.
Derzeit ist die Implementierung also wie folgt.
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
Der Engpass ist das Hochladen der Puffer, aber für eine bessere Implementierung hoffe ich auf eine Diskussion hier.
Prost.
Revision:
Eine Optimierung, die in den Sinn kommt, besteht darin, den Indexpuffer beizubehalten, da die Indizes vorhersehbar sind und immer dem gleichen Format folgen. Ich werde das jetzt messen.
Das Zwischenspeichern des Indexpuffers hatte keine nennenswerten Leistungssteigerungen. Um zu verstehen, wo der Engpass liegt, habe ich ihn auf C # / XNA portiert, etwas langsamer als die Implementierung von Microsoft, aber immer noch über eine 500-mal höhere GPU-Kapazität als die Molehill-Implementierung.
Ist Molehill einfach eine extrem schlechte Abstraktionsschicht?
quelle
Antworten:
Sie könnten eine Multi-Map von Sprites haben, deren Schlüssel die Textur ist. Gehen Sie dann beim Rendern durch jeden Schlüssel in der Map und rendern Sie jede Gruppe von Sprites, die dieser Textur zugeordnet sind. Wenn alle Sprites dieselbe Textur haben, können Sie jedes Sprite mit zwei Dreiecken und Texturkoordinaten darstellen. Dies bedeutet, dass Sie alle Sprites, die dieselbe Textur verwenden, in einem einzigen Durchgang mit einem einzigen Scheitelpunktpuffer und Indexpuffer zeichnen können.
Obwohl ich XNA verwende, habe ich meinen eigenen Rendering- und Batching-Prozess durchgeführt, anstatt Sprite-Batch zu verwenden, und ich rendere ungefähr 3000 Sprites gleichzeitig und erhalte derzeit ungefähr 600 fps auf einer Nvidia GTX 275 mit dem Prozess I. oben beschrieben. Als ich gerade die Sprites an die Spritebatch-Methode weitergab, gab XNA an, dass es ungefähr 25 fps waren.
In meinem Fall habe ich anstelle einer Multimap eine Klasse (SpriteData), die die Textur und eine Liste von Scheitelpunkten enthält. Immer wenn sich ein Sprite beim Renderer registriert, durchläuft der Renderer eine Liste von SpriteData, bis er einen passenden Texturtyp findet, und fügt dieses Sprite der Scheitelpunktliste hinzu.
Ich mache auch räumliche Partitionierung, um sicherzustellen, dass nur die angezeigten Sprites berücksichtigt werden.
quelle