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:
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..?
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 network • my 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
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2622 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
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)
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2622 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.
OctreeNode(N), TargetObject(T), OtherObjects(O) Als erstes braucht man den kürzesten Schnittpunkt auf der Linie N-T für O.
Code:
M=T.Pos-N.Pos
t0 = dot(M, O.Pos - N.Pos) / dot(M, M)
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.
Mitglieder in diesem Forum: 0 Mitglieder und 6 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.