Variablen in HLSL



  • Ja, wie schon gesagt geht das aufgrund der Art und Weise wie die Grafikkarte arbeitet nicht. Möglichkeiten wären z.B. richtiges Instancing und dabei die Höhe nicht per Texture Lookup sondern aus der per Instance Data lesen. In D3D10+ könnte man auch was mit der Stream Output Stage anstellen falls es unbedingt über eine Displacement Map laufen muss oder z.B. den Geometry Shader verwenden.



  • @dot
    Ja das habe ich natürlich auch versucht, erstaunlicherweise ist es dann aber noch langsamer 😞
    Ich habe generell ein Problem mit den Pflanzen, diese bremsen das System derart übel aus, ich weiss auch nicht, was ich falsch mache.

    Ohne Fauna habe ich ca. 400 fps, mit Fauna gerade noch 80 fps. (Ich zeichne gerade mal 9216 Planzen). Witzig ist allerdings auch, dass wenn ich die Planzen zwar zeichne, jedoch in eine Richtung schaue, wo man sie nicht sieht, dann habe ich immer hin ca. 250 fps. Ich muss das ganze zweimal Rendern, einmal mit Alphatesting und eingeschaltetem Z-Buffer (fürs z-sorting), und dann das Ganze noch einmal mit eingeschaltetem Alphablending für die transparenten Ränder. Erstaunlicherweise macht es allerdings überhaupt keinen Unterschied, ob ich die Pflanzen nun einmal oder zweimal rendere. Auch wenn ich den zweiten Pass mit eingeschaltetem Alphablending komplett weglasse, bemerke ich keinen Unterschied in der Framerate.

    Ich bin bereits seit Tagen damit beschäftigt, den Flaschenhals auszuspüren, finde ihn jedoch nicht 😞



  • @dot
    Was meinst du mit "richtiges Instancing"?



  • Mit richtigem Instancing meine ich sowas wie das hier: http://msdn.microsoft.com/en-us/library/bb173349(VS.85).aspx

    Allerdings halte ich den Texture Lookup im Vertexshader eher nicht für das Problem, deinen Symptomen nach bist vermutlich nicht vertexbound sondern pixelbound (Alphatesting kann da ziemlich reinhaun). Wie verhält sichs mit der Performance wenn du das ganze mal nur einmal renderst und das ohne Alphatesting sondern nur mit Alphablending?



  • @dot

    Mit richtigem Instancing meine ich sowas wie das hier

    Genauso mache ich es doch??

    Du must mir schnell helfen: VertexBound? Fillrate?

    Dein Verdacht bestätigt sich:

    Beide Renderpasses: ca. 80 fps
    Nur Alphatesting: ca. 85 fps
    Nur Alphablendin: ca. 120 fps

    Ohne Alphatesting wird es aber nicht mehr korrekt gerendert (weil die Planzen dann nicht mehr nach z sortiert sind.)



  • Ishildur schrieb:

    Genauso mache ich es doch??

    Stimmt, sry hab ich übersehen. Wäre es dann aber nicht einfach möglich die Höhe jedes Grasbüschels in der Instance Data zu übergeben statt aus der Textur zu samplen? Oder hast du eine animierte Displacementmap oder dergleichen weswegen du unbedingt einen Lookup machen musst?

    Wenn der Flaschenhals beim Vertexprocessing liegt sagt man die Anwendung ist Vertexbound, analog dazu spricht man von Pixelbound wenn der Flaschenhals beim Pixelprocessing liegt. Die Fillrate ist einfach die Anzahl von Pixeln/Fragments die die Graka pro Sekunde schreiben kann. Normalerweise ist man heutzutage viel eher Pixel- als Vertexbound (aufwändige Pixelshader etc). Auch wenn deine Vegetation nicht sehr viele sichtbare Pixel am Bildschirm ausmacht hast du vermutlich einen extrem großen Overdraw, d.h. die Anzahl der Pixel die in den Backbuffer wandern und wieder überschrieben werden ist sehr hoch. Deine 9216*18 = 165888 Vertices machen im Vergleich dazu nicht soviel aus, vor allem da dank Indices und Vertexcache wohl effektiv sowieso weniger als 18 Vertices pro Instance durch den Shader müssen (ich gehe davon aus dass deine Pflanzen aus Quads bestehen).
    Ich könnte mir vorstellen dass die Performance merkbar besser ist wenn du die Szene von einem Blickwinkel betrachtest wo die zuerst gemalten Quads weiter hinten liegende verdecken als wenn du sie aus einem Blickpunkt betrachtest wo die Reihenfolge annähernd "richtig" ist. (Early Z-Culling sorgt in ersterem Fall nämlich dafür dass die "verdeckten" Pixel sofort eliminiert werden)

    Was du versuchen kannst wäre erstmal z.B. die Pflanzen so zu sortieren dass sie Front-To-Back gerendert werden und du ohne Alphatesting auskommst. Desweiteren könntest du z.B. (was heute durchaus üblich ist) einen Z-Prepass rendern. D.h. deine ganze Szene (ohne Gras) erstmal nur in den Z-Buffer rendern (also keine Pixel Shader und D3DRS_COLORWRITEENABLE auf 0, einige Grakas haben einen eigenen Z-Only Mode und rendern dir das bis zu doppelt so schnell als normal). Das sorgt dafür dass das Early-Z-Culling beim darauffolgenden Rendern der Vegetation alles eliminiert was im endgültigen Frame sowieso von anderen Dingen verdeckt würde (Hilft natürlich nur was wenn du nach der Vegetation noch irgendwas rendern würdest was selbige verdecken würde). Wieviel und ob das alles im Endeffekt was bringt hängt letztendlich aber von deiner Szene ab...



  • Ishildur schrieb:

    Ohne Fauna habe ich ca. 400 fps, mit Fauna gerade noch 80 fps. (Ich zeichne gerade mal 9216 Planzen).

    Wie kommst du darauf, das dein Rechner bei 9216 anderen Objekten, die gezeichnet werden, schneller waere? f'`8k

    Gruß, TGGC (der kostenlose DMC Download)



  • @TGGC
    Weil die Planzen jeweils nur aus 3 Planes bestehen und allesamt in einem einzigen Batch mit Geometry Instancing gerendert werden was IMHO so ungefähr dem Zeichnen von EINEM komplexen Objekt entsprechen würde.

    @dot
    Ich kann doch Semitransparente Objekte nicht Front-To-Back rendern?



  • Ishildur schrieb:

    Ich kann doch Semitransparente Objekte nicht Front-To-Back rendern?

    Sry, ich meinte natürlich Back-To-Front...



  • Ishildur schrieb:

    @TGGC
    Weil die Planzen jeweils nur aus 3 Planes bestehen und allesamt in einem einzigen Batch mit Geometry Instancing gerendert werden was IMHO so ungefähr dem Zeichnen von EINEM komplexen Objekt entsprechen würde.

    Dann ist deine Meinung wohl falsch. Hast ja selbst festgestellt, das es langsamer rendert. f'`8k

    Gruß, TGGC (der kostenlose DMC Download)



  • TGGC schrieb:

    Wie kommst du darauf, das dein Rechner bei 9216 anderen Objekten, die gezeichnet werden, schneller waere? f'`8k

    Die Probleme die hier auftreten sind relativ spezifisch für die Vegetation. Falls du darauf hinauswillst dass weniger Pflanzen schneller wären hast du natürlich recht da eine geringere Pflanzendichte auch für weniger Overdraw sorgen würde.
    Allerdings kann man ein oder mehrere "normale" Modelle (also z.B. geschlossene Körper) mit einer äquivalenten Anzahl an Dreiecken mit Sicherheit sehr viel schneller rendern (55296 Dreiecke sind auf aktuellen Karten kein wirklich großes Problem). Sein Problem hängt also nicht so sehr mit der generellen Anzahl der Objekte zusammen sondern vor allem mit der Art derselben.

    Wenn man davon ausgeht dass er ein Feld mit 96x96 = 9216 Pflanzen hat und seine Kamera in typischer Ego-Perspektive relativ flach draufschaut kann man ganz grob über den Daumen sagen dass, wenns blöd läuft, viele Pixel im Bereich von 96 mal überschrieben werden was sehr Bandbreitenintensiv is und hier der Flaschenhals sein dürfte. Bei "normalen" Objekten hast du bei weitem nicht so hohe Werte und damit auch nicht dieses Problem. Ich wette die Performance wäre drastisch besser wenn er die Kamera senkrecht von oben draufrichten würde 😉



  • @dot
    Ganz deine Meinung! 😉

    Hier übrigens ein paar aktuelle Screenshots von unserer Bachelorarbeit mit den Pflanzen 🙂

    http://s1.directupload.net/file/d/2187/2sqo9rmn_jpg.htm
    http://s3.directupload.net/file/d/2187/arf3dt3q_jpg.htm



  • Hm, also handelt es sich um diese Bäume!? Die Screenshots sind recht dunkel aber ich würde mal meinen dass hier kaum alle 9216 Pflanzen ständig sichtbar sind!? Da könnte man sicher was rausholen wenn man möglichst nur die sichbaren rendert. Zumindest einfaches View Frustrum Culling könnte schon was bringen.

    Nichts desto trotz: Schaut cool aus 🙂



  • Und wenn du 10000 Kisten in der Groesse machst und die einfach so zeichnest, dann hast du auch Perspektiven in denen genauso viele Pixel gezeichnet/ ueberschreiben werden. Ergo wird die Framerate dann genauso sein. Was hat das also mit Pflanzen zu tun? Die Frage hoert sich halt momentan so an, sobald ich auf meinem C64 10000 Multiplikationen durchfuehre, bricht die Framrate ein - irgendwie multipliziere ich wohl die falschen Zahlen. f'`8k

    Gruß, TGGC (der kostenlose DMC Download)



  • TGGC schrieb:

    Und wenn du 10000 Kisten in der Groesse machst und die einfach so zeichnest, dann hast du auch Perspektiven in denen genauso viele Pixel gezeichnet/ ueberschreiben werden.

    Da die Kisten aber nicht durchsichtig sind kann man die Front-to-Back und/oder mit Z-Prepass rendern und hat das Problem entschärft da man dann nurmehr Z-Buffer reads aber keine BackBuffer writes mehr hat...



  • dot schrieb:

    [...]und hat das Problem entschärft...

    Eben hast du noch behauptet, es gaebe Probleme nur mit Vegetation. Die Vegetation macht Optimierungen schwieriger, ist aber nicht der Grund des Problems.

    Zeug zeichnen macht das Zeichnen langsamer. "Ich zeichne Zeug und das zeichnen wird langsamer, da ist was falsch?" - ach nein wirklich... f'`8k

    Gruß, TGGC (der kostenlose DMC Download)



  • @dot

    Die Screenshots sind recht dunkel

    Es ist ja auch unter Wasser 😉

    Diese Screenshots sind nun mit ausgeschaltetem Alphablending entstanden (also nur Alphatesting), dadurch könnte man IMHO auch Front-To-Back rendern.

    ich würde mal meinen dass hier kaum alle 9216 Pflanzen ständig sichtbar sind!?

    Das ist leider völlig korrekt, ich würde mit einem viertel der Pflanzen auskommen, wenn ich nur diejenigen Zeichnen würde, die auch tatsächlich sichtbar sind. Das Problem ist, dass es überhaupt nichts gebracht hatte, weil der Flaschenhals im Moment noch das Zeichnen an sich ist (Wie du sagtest, schaue ich senkrecht von oben darauf, habe ich ca. 350 fps). Und der CPU Overhead um zu berechnen, welche Planzen sich im View befinden ist ziemlich gross (lohnt sich IMHO meistens nur dann, wenn man wenige Objekte mit viel Geometry hat).

    Hat man sehr viele Objekte mit sehr wenig Geometry (wie in diesem Fall) ist es IMHO besser, das Culling von der Graka durchführen zu lassen.

    Was ich allerdings versuchen könnte währe wie gesagt eine räumliche sortierung von Front-To-Back um zu sehen, um den Overdraw auf ein Minimum zu beschränken.



  • @TGGC
    Ich empfehle dir diesen Artikel: developer.nvidia.com/docs/IO/8343/Performance-Optimisation.pdf

    Danach wirst du sehen, dass "Zeug zeichnen" nicht gleich "Zeug zeichnen" ist und dass sich die resultierende Performance aus ganz unterschiedlichen Aspekten zusammensetzt (es gibt durchaus auch Situationen wo man mehr zeichnen kann, ohne den geringsten Performanceverlust, wenn man die momentan am meisten ausgelastete Stelle nicht noch zusätzlich beansprucht), also ist deine Pauschalaussage : "Zeug zeichnen macht das Zeichnen langsamer." IMHO einfach falsch!

    Ausserdem ich unterhalte mich gerade so gut mit Dot, ich glaube mit ihm werde ich eine Lösung finden 😉



  • Ishildur schrieb:

    Diese Screenshots sind nun mit ausgeschaltetem Alphablending entstanden (also nur Alphatesting), dadurch könnte man IMHO auch Front-To-Back rendern.

    Wenn die Artefakte tolerierbar sind wäre das natürlich eine Option. Man müsste mal ausprobieren wieviel sich dadurch gewinnen lässt.

    Ishildur schrieb:

    Das Problem ist, dass es überhaupt nichts gebracht hatte, weil der Flaschenhals im Moment noch das Zeichnen an sich ist (Wie du sagtest, schaue ich senkrecht von oben darauf, habe ich ca. 350 fps). Und der CPU Overhead um zu berechnen, welche Planzen sich im View befinden ist ziemlich gross (lohnt sich IMHO meistens nur dann, wenn man wenige Objekte mit viel Geometry hat).

    Das ist im allgemeinen schon richtig, vor allem da diese Optimierung in erster Linie für das Vertexprocessing was bringen würde das hier nicht direkt das Limit ist. Wenn du allerdings deine Pflanzen sowieso schon sortierst kannst du durchaus mal versuchen ob Frustrum Culling (oder zumindest ein einfacher Abstand zur Kamera Test, durch den Nebel fällt da ja in der Ferne schon vieles weg) was bringt, sofern deine CPU genug Zeit hat. Die Instanzdaten streamest du dann ja so oder so zur GPU und Culling würde dann die Datenmenge die über den Bus muss zusätzlich geringer halten...



  • TGGC schrieb:

    Eben hast du noch behauptet, es gaebe Probleme nur mit Vegetation. Die Vegetation macht Optimierungen schwieriger, ist aber nicht der Grund des Problems.

    Ich sagte das Problem liegt vor allen in der Natur der Objekte und nicht rein in deren Anzahl. Natürlich kannst du genauso einen Haufen sich überdeckender Kisten zeichnen und hast das selbe Problem das durch die Transparenz nur noch verschärft wird. Mein Argument richtete sich aber eigentlich gegen deine ursprüngliche Aussage dass es rein an der Anzahl der Objekte liegt, was hier ganz klar nicht der Fall ist. Wenn du deine 10000 Würfel anders verteilt hast siehts schon ganz anders aus, weiters sind von einem Würfel immer nur max. 3 von 6 Flächen sichtbar wodurch du schon eine viel größere Menge an Dreiecken brauchst um in mit der Vegetation vergleichbare Bereiche zu kommen.

    Wie gesagt, es wäre mit Sicherheit kein Problem auf seinem Rechner 9216 andere "Objekte" mit gleicher Anzahl an Dreiecken viel schneller zu rendern, was meine urspüngliche Aussage war...


Anmelden zum Antworten