Kacheln rendern

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Kacheln rendern

Beitrag von dronus »

Hi,

ich rendere Polygone in eine Textur, wobei die Fläche dabei in Kacheln unterteilt ist, z.b. 16x16. In jeder Kachel werden gleichviele Polygone, aber an anderen Positionen gerendert. Die Polygone werden gestreamt, also ändern sich in jedem Frame. Im Moment muss ich aber jede Kachel einzeln rendern, z.b. per glDrawArrays, weil ich mittels glViewport die Kachel festlegen muss. Gibts da eine Alternative?

danke dank

Paul
joggel

Re: Kacheln rendern

Beitrag von joggel »

Und wenn Du auf der gesamten Fläche alles Renderst, und zum Schluss die Textur in Kacheln unterteilst?
Wäre das eine alternative?
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Kacheln rendern

Beitrag von Schrompf »

Shader. Mit einem VertexShader könntest Du für jedes Polygon getrennt festlegen, in welche Kachel es gehen soll, und gleichzeitig alle Polygone in einem Rutsch rendern. Das würde allerdings auch bedeuten, dass Du dann VBOs einsetzen müsstest, denn sonst bremst das ganze glVertex()-Gedöns den Vorgang und Du sparst gar nichts.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Kacheln rendern

Beitrag von Krishty »

Clippt der Viewport die Geometrie denn auch, oder bleibt die von sich aus immer innerhalb der Kachelgrenzen? In ersterem Fall wird es nämlich ein wenig kompliziert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Re: Kacheln rendern

Beitrag von dronus »

Krishty hat geschrieben:Clippt der Viewport die Geometrie denn auch
Genau so ist es. Sonst würd ich die Polygone mittels Vertex-Shader in die passende Kachel transformieren und alle mit einem Aufruf rendern.

Man könnte die Dreiecke in einem Geometry-Shader clippen... aber die Rechenorgie klingt nicht gut und Geometry-Shader gibts nicht immer.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Kacheln rendern

Beitrag von Chromanoid »

mit dem pixelshader müsstest du doch den bereich der "berendert" werden soll ziemlich leicht eingrenzen können. einfach nen array mit den kacheln a'la [left, top, right, bottom] bereitstellen - bei einer gleichmäßigen unterteilung erübrigts sich das - (triangles könnten einen index auf den array haben oder so) und dann je nachdem volle transparenz zurückgeben (musst halt die position zum pixelshader übergeben)...
anonym
Beiträge: 79
Registriert: 15.07.2009, 07:35
Kontaktdaten:

Re: Kacheln rendern

Beitrag von anonym »

Wäre es nicht möglich, neben der tatsächlichen Position auf dem Rendertarget in POSITION auch die nicht in die Kachel transformierte Position des Vertex in TEXCOORDn durch den Rasterizer zu jagen und anschließend im Pixelshader discard oder die Volle-Transparenz-Blendlösung anzuwenden, wenn die Kachel-Koordinaten des Pixel aus TEXCOORDn nicht in [-1.0; 1.0] liegen?
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Kacheln rendern

Beitrag von Chromanoid »

jo. discard kannte ich gar nicht ist natrülich viel besser als transparenz ^^ - puh bin ich aus dem zeug draußen :)
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Kacheln rendern

Beitrag von Krishty »

Discard war zu D3D9-Zeiten immer ein ähnlicher Performance-Killer wie manuelle Z-Writes. Solange man nicht knapp bei Bandbreite ist, dürfte die Transparenz besser wegkommen … aber vllt hat sich da ja auch in den letzten Jahren was getan, ich weiß es nicht.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Re: Kacheln rendern

Beitrag von dronus »

Witzig: Ich hab mal Performance-Tests gemacht, was passiert, wenn ich alle Polygone in dieselbe Kachel rendere. Ich vermutete, dass es viel schneller würde, weil ja viel weniger Zielfläche (Speicher) beschrieben werden muss. Es wird jedoch viel langsamer.

Meine Erklärung: Die GPU kann nicht parallel arbeiten, da ja alle Polygone übereinander gezeichnet werden und daher sequentiell gemalt werden müssen.

Wenn das so ist, ist aber die jetzige Lösung mit den vielen Render-Calls kaum zu schlagen. Denn nur mit dem richtigen Viewport-Clipping kann die GPU die Zeichenvorgänge parallel ausführen, da das sicherstellt dass die jeweils bemalten Flächen sich nie überlappen. Wenn erst im Pixelshader ein nicht-zugehöriges Pixel feststeht, dann musste die GPU mit dem Zeichnen dieses Polygones ja bereits warten dass aller Speicher in der potentiell bedeckten Fläche exklusiv beschreibbar ist. Die Zeichenbereiche vieler Kacheln überlappen sich dann nämlich.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Kacheln rendern

Beitrag von Krishty »

Der Performance-Einbruch beim Rendern in dieselbe Kachel ist ein interessantes Ergebnis ... wahrscheinlich liegst du damit, dass die hohe Konkurrenz blockiert, richtig -- aber wenn das geschieht, dann im Output-Merger beim Blenden und Schreiben der Farbwerte; nicht bei deren Berechnung.

Dass die GPU die Zeichenvorgänge parallel ausführen kann, weil sich die Viewports nicht überlappen, ist aber Unsinn -- sie führt sie schon allein deshalb nicht parallel aus, weil es getrennte Draw-Calls sind.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Re: Kacheln rendern

Beitrag von dronus »

Krishty hat geschrieben:Dass die GPU die Zeichenvorgänge parallel ausführen kann, weil sich die Viewports nicht überlappen, ist aber Unsinn -- sie führt sie schon allein deshalb nicht parallel aus, weil es getrennte Draw-Calls sind.
Hm, ist das irgendwo so definiert? Auch innerhalb eines Calls müssen ja überlappende Dreiecke in der gegebenen Reihenfolge gezeichnet werden. Wenn die Karte innerhalb eines Calls mehrere Dreiecke parallel zeichnet, dann machts doch Sinn dass auch bei mehreren Calls zu tun oder nicht? Die Calls werden bei OpenGL ja sowieso irgendwie gequeuet, jedenfalls ist es immer wundersam an welcher Stelle man plötzlich auf die GPU warten muss..
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Kacheln rendern

Beitrag von Krishty »

dronus hat geschrieben:Auch innerhalb eines Calls müssen ja die Dreiecke in der gegebenen Reihenfolge gezeichnet werden. Wenn die Karte innerhalb eines Calls mehrere Dreiecke parallel zeichnet […]
Die Sätze schließen sich gegenseitig aus – die Parallelität ist eine Optimierung, von der deine Anwendung garnichts wissen darf. Die Hardware muss sich nach außen hin verhalten, als arbeitete sequentiell Dreieck für Dreieck ab – denn sonst würde bei sich überschneidenden, transparenten Dreiecken mal ein Pixel des einen Dreiecks im Back-Buffer landen und mal einer des anderen – je nachdem, welcher Pixel zuerst fertig ist. Definiert ist das afaik für D3D, für OpenGL wäre es aber unsinnig, da anders vorzugehen.

Dass Grafikhardware extrem parallelisiert ist, rührt von dem Glücksfall her, dass sich nahegelegene (nicht räumlich, sondern im Sinne der Render-Reihenfolge!) Dreiecke in einem Draw-Call fast nie überschneiden. Vereinfacht gesagt: Man rasterisiert, gibt 300 Threads je einen Pixel und lässt machen. Bei normaler Geometrie wird sich dann keine zwei Pixel jemals überschneiden, man kann das Gesetz der sequentiellen Abarbeitung vergessen und darum ist das auch hocheffizient.

Überschneiden sich aber die Dreiecke, muss die Reihenfolge wieder eingehalten werden. Konkret muss der Output-Merger (ist jetzt nur Halbwissen), bevor er das Blending durchführt, warten, bis die neuen Farbwerte des Pixels in chronologischer Reihenfolge vorliegen und dabei ggf das Depth-Buffering erneut vornehmen (die Pixel der verschiedenen Dreicke werden schließlich unterschiedliche Tiefenwerte haben und wir wollen sie möglicherweise nicht alle schreiben). Das sorgt dafür, dass Threads brach liegen, riesen Leistung zur Synchronisation aufgewendet werden muss und die Performance einbricht.
dronus hat geschrieben:[…] dann machts doch Sinn dass auch bei mehreren Calls zu tun oder nicht? Die Calls werden bei OpenGL ja sowieso irgendwie gequeuet, jedenfalls ist es immer wundersam an welcher Stelle man plötzlich auf die GPU warten muss..
Draw-Calls bedeuten für den Treiber normalerweise eine abgeschlossene Arbeitseinheit – man unterbricht das Zeichnen nur, wenn es nötig ist, um Texturen / Render-Targets o.ä. wechseln. Es ergibt für den Treiber keinen Sinn, zwei Draw-Calls als ununterbrochene Fütterungsaktion durchzuziehen, weil das Ende eines Draw-Calls normalerweise immer bedeutet, dass jetzt erstmal Pause gemacht werden muss um ein neues Setup einzustellen. Bei solchen Sachen wie den Viewports kann ich mir darüber hinaus vorstellen, dass Viewports global gesetzt werden und es deshalb katastrophal wäre, einfach weiterzurendern (Dreiecke, die noch mit dem alten Viewport rasterisiert werden sollten, aber deren Vertices gerade erst aus dem Vertex-Shader kommen während schon die des nächsten Draw-Calls durchlaufen, fliegen schon raus, weil der Rasterizer nur gegen einen einzigen globalen Viewport (nämlich den neuen) für alle Primitives testet).

Übrigens arbeitet der Rasterizer wie ein Geo-Shader, der die Dreiecke an den Viewport-Kanten abschneidet (darum sind die Viewport-Begrenzungen auch als Gleitkommakoordinaten gegeben, nicht als ganzzahlige Pixel) – mit Multisampling lässt sich sogar sichtbar machen, wie die Dreiecke im Pixel-Shader ankommen, nachdem der Rasterizer sie neu unterteilt hat. (Darum ist interessanterweise die Anzahl der Dreiecke, die auf dem Bildschirm landen, manchmal > derer, die man zum Rendern schickt.) Wenn du dir diese Funktionalität zu nutze machen könntest, wäre das die optimale Lösung. Leider wäre die nächstmögliche Annäherung ein Geo-Shader, der die Dreiecke gemäß irgendwelcher Konstanten zurechtstutzt ich habe keine Informationen darüber, wie so eine Implementierung aussähe, geschweige denn wie aufwändig und performant sie wäre. Falls die Kacheln gleich groß sind und du nicht mehr als acht davon hast, kannst du ja mal multiple Render-Targets ausprobieren … bei Cube-Maps macht man das ja genauso.

Wer mehr weiß, mag gern korrigieren :)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Re: Kacheln rendern

Beitrag von dronus »

Tja, mir scheint dass ich hier mit Experimenten und Halbwissen an einer nicht sehr ergiebigen Optimierung werkel hehe.. werd ich mal andere Stellen zuerst angehen.
Antworten