Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Do Mär 28, 2024 14:49

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Di Sep 20, 2016 20:32 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Hi,

was ist zur Zeit (in OpenGL 4.5) die schnellste methode statische (nicht animierte) objekte zu rendern?
Ich habe z.B. gerade 19 verschiedene Objekte die ich insgesamt 2675 mal zeichne (jedes zwischen 100x - 200x) .Frustum Culling etc um nur das zu rendern was wirklich sichtbar ist benutze ich bereits, allerdings sind ggf. auch einfach tatsaechlich alle 2675 instantzen zu sehen.

In zahlen:
  • 19 Objekte
  • 1.212.256 Triangles
  • 2.675 Instanzen
  • 205.136.690 Total Triangles

Ich habe fuer jedes Objekt einen VAO mit jeweils einem VBO fuer Position, Normal, Color und Index.
Meine renderloop sieht in etwa so aus:

Code:
  1. for each object:
  2.     glBindVertexArray(object.vao)
  3.     for each instance of object:
  4.         instance.matrix.bind()
  5.         glDrawElements(GL_TRIANGLES, object.size, GL_UNSIGNED_INT, NULL)


Damit erreiche ich aktuell ~5fps wenn alle instanzen sichtbar sind.

Ich habe es auch schon mit hardware instancing via glDrawElementsInstanced versucht, allerdings ist das bei der menge an Objekten eher noch langsamer (~4fps) und wird erst schneller wenn man wirklich richtig viele instanzen hat.

Gibt es evtl. irgendeinen tollen modernen trick diese 205mio Triangles schneller zu rendern? Oder ist 5fps einfach das maximum was geht..?

Danke!
Daniela


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Sep 21, 2016 15:15 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
205 MTris sind schon ne ganz schöne Hausnummer. Selbst mit 16 MTris hatte ich schon ernsthafte Probleme auf meiner Hardware, und die habe ich immerhin in relativ großen Batches gerendert.

Ich würde vor allem anderen LOD vorschlagen. Kann mir kaum vorstellen, dass man alle 205 MTris in hohem Detail erkennt ;-).

viele Grüße,
Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Sep 21, 2016 17:19 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Da du es nicht erwähnt hast würde ich erstmal ein Z-Pass einführen, damit es die Last beim Fragmentshader reduziert.
Danach würde ich occlusion culling einbauen, idealerweise auf der CPU-Seite, damit die verdeckten Objekte garnicht in die Pipeline gehen.

Als letzten und aufwändigesten Schritt kann man noch occlusion culling auf der gpu Seite einbauen, dabei prüfst du auf trianglepatches.
Umbra tut Modelle so zerlegen, dass mehrere trianglehaufen entstehen und die einzelnen haufen werden noch geprüft, damit die triangles die zur abgewandten Seite bzw. von was anderem verdeckt sind schon frühzeitig in der Pipeline rausgeworfen werden und nicht mal durch den Vertexshader laufen.
Da man dafür seine Meshdaten anfassen und umstrukturieren muss, ist das recht aufwändig und es gibt keine detailierte Beschreibung, wie die das genau umsetzen.
Kann sogar sein, dass die das auf der CPU machen, da die dort schon ein Occlussion culling für Objekte machen.

edit:
Da es statisch ist, wäre eine spatial system mit einer Sichtbarkeitstabelle noch möglich aber da hab ich praktisch noch nie was mit gemacht(steht noch auf meiner Liste ^^).

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Sep 23, 2016 08:08 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 06, 2005 18:34
Beiträge: 362
Wohnort: Hamburg
Wo genau liegt denn das bottleneck?
CPU oder GPU? Und wenn GPU ist es der Vertex oder Fragment shader?

Für CPU kannst du probieren alle Objekte mit kompatiblem Vertex Layout (gleiche Vertex Attributes) in die gleichen VBOs zu packen und dann glMultiDrawElementsIndirect (eventuell mit instancing) einsetzen. Die DrawElementsIndirectCommand kannst du vorberechnen. Um die Daten (Instances + DrawCommands) möglichst schnell jeden Frame auf die Graka zu kriegen kannst du ShaderStorageBuffers benutzen die du 3 mal so groß machst wie benötigt. Dann kannst du jeden Frame die Daten des Frames in ein Drittel des Buffers schreiben während die Graka eventuell noch die Daten aus den anderen Dritteln verwendet. Diese Drittel cyclest du einfach jeden Frame durch.
Das ist nur eine sehr grobe Übersicht der grundlegenden Technik. Das Stichwort dazu ist AZDO (approaching zero driver overhead). Dazu gibt es mehrere Slides im Internet.
Hier z.B. http://de.slideshare.net/CassEveritt/ap ... r-overhead
Und ein github repo mit Beispielen: https://github.com/nvMcJohn/apitest

Für Vertex Shader bieten sich LODs und Occlusion Culling an.

Für den Fragment Shader kann man z.B. einen extra Z-Pass einführen.

Sonst gibts da glaub ich garnicht so viele Tricks, außer die Shader selber zu optimieren.

[Edit]
Wenn die Scene auch dynamisch beleuchtet sein soll, kann man auch einen Deferred Renderer ausprobieren.

_________________
Der Mensch hat neben dem Trieb der Fortpflanzung und dem zu essen und zu trinken zwei Leidenschaften: Krach zu machen und nicht zuzuhören. (Kurt Tucholsky)
Schwabbeldiwapp, hier kommt die Grütze. (Der Quästor)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Sep 26, 2016 14:02 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich hab mal ein bisschen am Whiteboard gegrübelt und gerechnet.
Du kannst die Boundingsphere von jeden Objekt ermitteln und den Radius mit speichern.
Dann noch die Boundingsphere für jedes Node im Octree errechnen(r=sqrt(width²+height²+depth²)/2).
Mit Kugeln wird der Sichtbarkeitstest wesentlich einfacher aber auch verschwenderischer, da Objekte noch als sichtbar erkannt werden, die eventuell garnicht mehr Sichtbar sind.
Ein langes Objekt, was hinter einer Box steht hat wegen seiner länge ein große Boundingsphere und die guckt seitlich von der Box raus.
In anbetracht der Geschwindigkeit für den Test ist das allerdings völlig akzeptable.

Bild
OctreeNode(N), TargetObject(T), OtherObjects(O)
Als erstes braucht man den kürzesten Schnittpunkt auf der Linie N-T für O.
Code:
  1. M=T.Pos-N.Pos
  2. t0 = dot(M, O.Pos - N.Pos) / dot(M, M)
  3. intersectPnt = N.Pos + t0 * M

Nun braucht man an diesem Punkt den Radius, den das OctreeNode als Volume auf TargetObject wirft.
OtherObjects kann nur TargetObject verdecken, wenn der Radius größer oder gleich der Distanz + Radius an dem Punkt ist.
Code:
  1. intersectRadius = N.Radius + t0*(T.Radius-N.Radius)
  2. d = norm(O.Pos-intersectPnt)
  3. visible = O.Radius - d >= intersectRadius ? true : false


Noch nicht runter gecoded und es gibt noch 1-2 optimierungen sowie prüfungen, ob es nicht zwischen OctreeNode und TargetObject liegt.


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 35 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.052s | 17 Queries | GZIP : On ]