JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=0372a76f3c3676d6c40e5579efa042e0Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

[Direct3D] Performance-Verbesserung (?) mit Vorpuffer
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 02.11.2006, 17:18    Titel: [Direct3D] Performance-Verbesserung (?) mit Vorpuffer Antworten mit Zitat

Hi,

ich hab beschlossen, meine Engine mal etwas zu aktualisieren und an neue Möglichkeiten anzupassen. Dabei kam mir eine Idee, was das Rendern von Objekten betrifft. Dazu ein wenig Vorgeschichte...

In letzter Zeit gabs mal einige Diskussionen hier, wie zeitaufwändig die Draw-Calls und die SetRenderStates und was weiß ich alles noch seien. Nun dachte ich, dass ich das Ganze etwas beschleunigen könnte, indem ich jeden Render Call intern in meiner Engine "vorrendere"; also ich schreibe alle Daten, die gerendert würden, in eine Liste, und die Vertexdaten aller Objekte zusammen in einen VB. Sind alle Objekte eingetragen, werden die kurz vor EndScene() über D3D gerendert, d.h. ich setze diesen einen VB und rendere dann aus der Liste heraus nacheinander alle Vertices. Zum Schluss kommt der Present()-Befehl. Ich hab schonmal einige Vor- und Nachteile zusammengefasst, die mir so spontan einfielen:

Vorteile:
Arrow setzen eines einzigen VertesBuffers
Arrow spätere Manipulationen wie nachhaltiges Sortieren, opimieren...
Arrow Zusammenfassung der RenderStates, Texturen etc.
Arrow (vllt kurzzeitige Entlastung des Grafikspeichers...)

Nachteile:
Arrow stärkere Belastung des Arbeitsspeichers wegen Extra-Puffer
Arrow (je nach Implementierung zusätzliche Rechenarbeiten)

Das Ganze könnte nun einerseits mir den erhofften Performance-Vorsprung verschaffen, oder aber nur eine sinnlose Schnapsidee sein, die mehr verschlechtert als verbessert.

Meine Frage: Was haltet ihr von der Idee? Wird sowas in der Praxis verwendet?

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 02.11.2006, 18:33    Titel: Antworten mit Zitat

Das ist gängige Praxis Wink

Die Objekte werden nach States7Texturen/Shader/Alphablending sortiert und in einem Rutsch gerendert, im DX SDK gibt es afaik einen Statemanager Sample dazu, schaus dir einfach mal an.

Aber evtl habe ich deine Technik auch nicht ganz verstanden, mache doch mal ein par Beispiele.
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 02.11.2006, 18:51    Titel: Antworten mit Zitat

hmm, also ich glaub schon, dass du das meinst, was ich meine. Also wars doch net nur so en doofer einfall Very Happy

naja, nur der sicherheit halber mal ein beispiel:

ich habe zwei Objekte, die ich rendern will. Bei Methode1 würden zuerst für das 1. Objekt Textur, Matrix, VB, IB usw. gesetzt; dann per Draw...() übers Device gerendert; und zum schluss weider alles zurückgesetzt. Danach passiert dasselbe für die Daten von Objekt 2.
Bei Methode2, die ich oben beschrieben hab, würden die Daten über jeweilige Funktionen in meiner Engine gesetzt werden; zuerst für Obj1 dann für Obj2. Von außen sieht das ungf. dann so ähnlich aus wie Meth. 1, nur dass die Aufrufe net übers Device sondern bei meiner Engine registriert werden. Die Engine speichert alle Daten zwischen und schreibt alle Vertexdaten in einen VB. Erst am Ende der Szene rendert meine Engine das ganze, indem es den VB setzt und die Objekte auf einen Rutsch dem Device mitteilt, also hier kommen erst die Draw() usw. Methoden des Devices ins Spiel.

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Chriss
Senior JLI'ler



Anmeldedatum: 18.08.2004
Beiträge: 267

Medaillen: Keine

BeitragVerfasst am: 02.11.2006, 19:06    Titel: Antworten mit Zitat

Also so wie Fallen es beschrieben hat musst du es schon machen, sonst bringt es dir nicht viel.

Du musst deine Objekte intern schon nach Textur, Shader usw. sortieren. So wie ich dich verstanden habe willst du nur alles in einen VB schreiben aber dann trotzdem SetTexture usw. ausführen wie es kommt.

Wenn du das so machst, liegt dein einziger Vorteil darin, dass du alle Vertexdaten in einem Rutsch kopierst (etwas wirds schon bringen) aber erst wenn du deine Aufrufe zusätzlich nach Renderstates usw. sortierst hast du einen wirklichen Vorteil.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 02.11.2006, 20:20    Titel: Antworten mit Zitat

über den exakten Gebrauch, bis ins Detail, hab ich noch net nachgedacht, aber die Sache mit dem Sortieren war mir schon klar. Ich hab das wahrscheinlich net etwas zu wenig betont, aber oben bei Vorteilen hatte ich das auf jeden Fall erwähnt.

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Dr. Best
Senior JLI'ler


Alter: 34
Anmeldedatum: 17.06.2004
Beiträge: 269
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 03.11.2006, 15:39    Titel: Antworten mit Zitat

Ich hab diese Technik in meiner Engine schon umgesetzt. Wenn man komplexe Objekte mit Shadereffekten, Animation oder Multitexturing braucht werden die einzeln gerendert. Aber wenn das nicht der Fall ist kann man was verwenden was ich Primitive getauft hab.

Primitive erstellt man über eine Primitiv Managment Klasse, d.h. mit den Klassen, die intern verwendet werden kommt man garnicht in Kontakt. Der Primitiv Manager verwaltet Instanzen von zwei anderen Klassen. Die erste ist nicht schwer zu erraten. Sie nennt sich CPrimitive, davon gibt es eine Instanz für jeden erstellten Primitiv und sie verwaltet Textur, Material, Transformation, untransformierten Vertex Buffer und Index Buffer des Primitivs. Die andere Klasse nennt sich CPrimitiveGroup. Wann immer ein Primitiv erstellt wird, der in keine der vorhandenen Gruppen passt, wird eine neue erstellt. Die Gruppe enthält dann die Indizes aller enthaltenen Primitive, einen vortransformierten Vertex Buffer, der groß genug für alle Primitive ist (um genau zu sein für 1 1/2 mal so viele Primitive, damit nicht immer sofort erweitert werden muss wenn ein neuer Primitiv hinzkommt) und einen entsprechend großen Index Buffer. Immer wenn eine Änderung an einem der Primitive vorgenommen wird muss das über den Primitiv Manager geschehen. Der schaut dann, ob der Primitiv in eine neue Gruppe verschoben werden muss oder ob der Vertex Buffer neu transformiert werden muss.

Der Primitv Manager hat eine Memberfunktion Render, die dann in einer Schleife jede Primitiv Gruppe ihre Primitive render lässt. Da der Vertex Buffer der Gruppen unter Umständen enorm oft bearbeitet werden muss (vorallem bei Billboards) verwende ich übrigens tatsächlich garkeinen Direct 3D Vertex Buffer sondern einen DrawIndexedPrimitiveUP call.

Das hilft dir vielleicht ein Bisschen bei der Umsetzung in deiner Engine.
MfG
Dr. Best
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen AIM-Name MSN Messenger
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 03.11.2006, 22:16    Titel: Antworten mit Zitat

danke schön,

die Idee ist interessant, ich überleg mal inwiefern ich das einbauen kann. Allerdings musst du dann den z-Buffer benutzen (wenn man das net eh schon macht), da du die Render-Reihenfolge (z.B. Back to Front Order) ja u.U. änderst, oder? Aber das wird sich schon net so scharf auswirken...

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Dr. Best
Senior JLI'ler


Alter: 34
Anmeldedatum: 17.06.2004
Beiträge: 269
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 04.11.2006, 02:04    Titel: Antworten mit Zitat

Z-buffering hab ich sowieso immer an. Und um back-front-order kümmer ich mich nicht. Wäre mir zu rechenintensiv. Das einzige was ich mache um Probleme mit dem Alphablending größtenteils zu vermeiden ist, dass ich zuerst alle Objekte rendere, die ein nicht transparentes Material verwenden und danach erst die anderen rendere wobei ich dabei Z-buffer-writes deaktiviere.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen AIM-Name MSN Messenger
Jonathan_Klein
Living Legend


Alter: 36
Anmeldedatum: 17.02.2003
Beiträge: 3431
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 04.11.2006, 11:24    Titel: Antworten mit Zitat

Naja, nur ZBufferwriting zu deaktivieren ist vielleicht schon besser, aber wenn du jetzt z.b. nicht richtig transparente Objekte hast, sonder sowas wie Gitter sieht das schon komisch aus, wenn zwei direkt hintereinander stehen und das hintere über dem vorderen ist.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Dr. Best
Senior JLI'ler


Alter: 34
Anmeldedatum: 17.06.2004
Beiträge: 269
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 04.11.2006, 15:23    Titel: Antworten mit Zitat

@ Jona
Ich weiß. Darüber hab ich mich schon oft genug geärgert Wink . Aber in jedem Frame alles in Back-to-Front-Order zu bringen (bzw. in jedem Frame einmal für jedes aktive Kameraobjekt) ist einfach ein enormer Rechenaufwand. Und selbst das ist noch keine Patentlösung. Denn wenn ich alles in Back-To-Front-Order bringen will muss ich ja zwangsläufig für jedes Objekt irgendeinen Mittelpunkt definieren. Aber was wenn das eine Objekt größer ist als das andere und deshalb trotzdem noch etwas von dem kleineren verdeckt, obwohl es als dahinter eingestuft wurde? Und noch schlimmer, was passiert wenn ein Objekt Teile von sich selbst verdeckt?

Eine Lösung, die zwar mit einem recht hohen Aufwand für den GPU verbunden ist, dafür aber immer funktionieren sollte ist die Alpha Map separat von der Color Map in den zweiten Textur Stage zu packen und im zweiten Textur Stage dann Nearest-Point Sampling zu verwenden. Wenn man dann im Alphakanal nur volle Deckkraft oder volle Transparenz hat, wird sich da durch den Texturfilter auch nichts mehr dran ändern. Aber wenn man partielle Transparenz will nützt einem das natürlich auch nichts.

Aber ich würd sagen, damit sollten wir das Thema auch beiseitelegen. Sonst driftet das hier zu sehr ins Off-Topic ab.
Nur eins noch. Wer DirectX 10 benutzt wird sich über sowas nie wieder Gedanken machen müssen Very Happy .
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen AIM-Name MSN Messenger
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 14.02.2007, 17:27    Titel: Antworten mit Zitat

so, ich muss diesen Thread nochmal aufgraben, sry Rolling Eyes

also, die vorgeschichte: ich hab seit dem erstellen des threads nun an meiner engine rumgewerkelt; ziemlich fleißig (fast schon fanatisch) und bin auch schon ziemlich weit gekommen. Jetzt musste ich aber noch mal an den Grafikpart, den ich eigentlich weitgehend abgeschlossen hatte dran, und da kommt genau wieder das ans Tageslicht was ich hier vor fast 1/3 Jahren gefragt hab: Das Vorpuffern.

Genug Vorgeschichte, zum Thema: Ich hab das ganze ungf. so ähnlich gemacht, wie Dr. Best gemacht, also alle primitiven Objekte registrieren sich in meiner Graphics-Umgebung und werden in maps (ziemlich praktisch, da automatisch sortiert, immer ein key etc.) eingeordnet, um möglichst viele Objekte in einem Draw( Indexed )Primitive()-Call zusammenzufassen. Bei Sprites (bzw. Billboards) hab ich meist 4 vertices mit 6 Indices für ein Quad in D3DPT_TRIANGLELIST genommen. Jetzt wollte ich das mal ohne index buffer machen, d.h. 4 Vertices in D3DPT_TRIANGLESTRIP für ein sprite. Beim Gruppieren der Primitive bin ich dann auf folgendes Problem gestoßen:

Die Objekte werden aneinander gerendert. Grundidee war ja:
CPP:
DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
zu
CPP:
DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 4 );
zusammenzufassen, damals hab ich aber nicht an das Problem mit triangle strips gedacht. Nebenbei liegt die texture dann auch nicht auf jedem sprite einzeln, sondern streckt sich als eine quer über alle anderen.

Lange Rede, kurzer Sinn: Gibt es eine andere Möglichkeit, dieses Problem zu umgehen, außer wieder auf triangle list und IB umzusteigen? Denn wenn ich jetzt doch wieder für jedes Trianglestrip einen eigenen DrawPrimitive-Call machen muss, is das ganze Konzept ja umsonst (zumindest für diese primitive) Confused

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Dr. Best
Senior JLI'ler


Alter: 34
Anmeldedatum: 17.06.2004
Beiträge: 269
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 14.02.2007, 20:36    Titel: Antworten mit Zitat

Wenn man bei der Verwendung von Triangle Strips bestimmte Vertices Mehrfach in den Vertex Buffer schreibt, separiert man die Quads dadurch voneinander. Problem ist nur, dass man dann auch wieder genau 6 Vertices pro Quad braucht, man hat also keinen Gewinn im Vergleich zu einer Triangle List. Daher würde ich dir raten einfach Triangle Lists zu verwenden. Da brauchst du keinen Index Buffer und bist mit sechs Vertices pro Quad optimal dabei.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen AIM-Name MSN Messenger
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 14.02.2007, 21:35    Titel: Antworten mit Zitat

ah, thx, dann weiß ich wie ich das problem lösen kann =) also wieder weg vom grafikproblem in den aktuellen part; soundmixer Very Happy

Danke nochmal,
Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 15.02.2007, 00:21    Titel: Antworten mit Zitat

nochmal sorry (für doppelpost), war etwas vorschnell. Also mit den triangle strips geht das ja so, aber gibts da auch ein Trick für triangle fans und line lists? Wäre schön, obwohl ich glaube, dass sowas (leider) nicht geht Confused

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Dr. Best
Senior JLI'ler


Alter: 34
Anmeldedatum: 17.06.2004
Beiträge: 269
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 16.02.2007, 01:24    Titel: Antworten mit Zitat

Was genau meinst du jetzt? Mit Triangle Fans stößt man immer recht schnell an seine Grenzen. Wenn alle Dreiecke einen gemeinsamen Punkt haben müssen kannst du damit schlecht irgendwelche unverbundenen Quads basteln. Also besser einfach auf Triangle Lists umsteigen. Solang es nur um Vertex Quads geht ist das auf jeden Fall die effizienteste Lösung. Und was willst du jetzt nochmal mit Line Lists machen?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen AIM-Name MSN Messenger
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL Alle Zeiten sind GMT
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum