Ansatz zum Terrain-Rendering - noch Probleme beim Textur-Blending



  • rapso schrieb:

    man sollte bedenken, dass man mit d3d maximal ca 1000 bis 2000 renderaufrufe pro frame machen darf, damit es noch flüssig läuft (quelle: nvidia ). falls man nen größeren teil der 1024blöcke sieht(mit nur einem pass), wird es schon enger... sicherlich möchte man da noch mehr als das terrain rendern.

    Stimmt, das könnte eng werden. Bei mir war das damals kein Problem, da waren meistens um die 30 Blöcke sichtbar (Sichtweite war glaube ich 600m bei 1x1m pro Zelle). Aber man kann die einzelnen Blöcke sicher auch größer machen. Wenige, größere Blöcke werden wohl schneller bearbeitet als viele kleine, man hat ja um einiges weniger CPU-Overhead, sowohl bei den Draw-Calls wie auch beim Culling. Sowas kann man aber eh nur empirisch ausprobieren.

    Mein Spiel (OpenGL) ist eigentlich auch mit Vegetation und animierten Charakteren meistens auf 60 FPS gelaufen, wenn man mitten in hohem Gras gestanden ist ists auf 30 runtergegangen (mit VSync, ansonsten auf 40-50). Ich habe auch vor dem ersten sichtbaren Terrain-Rendering-Pass noch einen reinen Depth-Pass gemacht in dem ich den Depth-Buffer befüllt habe damit ich mit early-Z möglichst wenige Fragmente mit den verschiedenen Geländetypen rendern muss. Das hat allerdings kaum Performance gebracht, vielleicht 10%.

    Was für Ideen hast denn du für LOD? Ich habe einmal static LOD probiert, abgesehen von T-Vertices (die kann man ganz gut verstecken) bekommt man ziemlich häßliches Popping wenn ein Block auf eine nächsthöhere Detailstufe umspringt. Dynamic LOD (ROAM etc) bringt auf heutigen Grafikkarten wohl so gut wie gar nichts, viel zu viel CPU-Overhead. Eventuell könnte man Geomipmapping oder so etwas versuchen? Oder man rendert die Szene in mehreren "Slices" entlang der Tiefen-Achse (mit unterschiedlichen LOD-Stufen) und kombiniert die Slices dann in einem Pixel Shader. Damit bekommt man zumindest das Popping weg, obs schön ist ist natürlich immer noch eine andere Frage.



  • Kustl schrieb:

    Was für Ideen hast denn du für LOD? Ich habe einmal static LOD probiert, abgesehen von T-Vertices (die kann man ganz gut verstecken) bekommt man ziemlich häßliches Popping wenn ein Block auf eine nächsthöhere Detailstufe umspringt. Dynamic LOD (ROAM etc) bringt auf heutigen Grafikkarten wohl so gut wie gar nichts, viel zu viel CPU-Overhead. Eventuell könnte man Geomipmapping oder so etwas versuchen? Oder man rendert die Szene in mehreren "Slices" entlang der Tiefen-Achse (mit unterschiedlichen LOD-Stufen) und kombiniert die Slices dann in einem Pixel Shader. Damit bekommt man zumindest das Popping weg, obs schön ist ist natürlich immer noch eine andere Frage.

    Es gibt auch neuere "dynamic" LOD algorithmen, die nicht soviel cpu speed verbraten.. Und LOD-algorithmen brauchste immer dann, wenn die terrains größer werden. Nehmen wir z.B. ein 4096x4096 Terrain, dass du mit Bruteforce rendern willst. Die Kamera befindet sich genau in der Mitte mit 45° sichtwinkel. Dann musste mit einem Bruteforcealgorithmus schon mindestens 4096*4096/8 = 2097152 Vertices pro frame nur für das Terrain rendern..

    Gegen poping helfen dann geomorphing algorithmen, die die neu hinzukommenden Vertices einfach "langsam" an die richtige position schieben..



  • life schrieb:

    Es gibt auch neuere "dynamic" LOD algorithmen, die nicht soviel cpu speed verbraten.. Und LOD-algorithmen brauchste immer dann, wenn die terrains größer werden. Nehmen wir z.B. ein 4096x4096 Terrain, dass du mit Bruteforce rendern willst. Die Kamera befindet sich genau in der Mitte mit 45° sichtwinkel. Dann musste mit einem Bruteforcealgorithmus schon mindestens 4096*4096/8 = 2097152 Vertices pro frame nur für das Terrain rendern..

    Gegen poping helfen dann geomorphing algorithmen, die die neu hinzukommenden Vertices einfach "langsam" an die richtige position schieben..

    Hab deine Homepage gesehen, offenbar hast du dich wirklich schon genauer damit beschäftigt 🙂
    Ich habe mir einmal dieser SOAR-Paper aus 2002 und das Video dazu angesehen, sieht wirklich nicht schlecht aus. Ich nehme an dein Algorithmus läuft hauptsächlich auf der GPU? Vertex oder Index Buffers dynamisch zu ändern kann ja nicht wirklich effizient sein.

    Daher war auch meine Idee zwar statische LOD-Stufen zu verwenden, diese aber in unterschiedliche nach Tiefe sortierte Slices in Offscreen Rendertargets zu rendern und die dann im Framebuffer mit einem Shader mit sanften Übergängen zwischen den einzelnen LOD-Stufen zusammenzusetzen (je nach Tiefenwert des aktuellen Pixels müsste das relativ leicht machbar sein).

    Noch etwas aus meiner persönlichen Erfahrung: Am wichtigsten für die visuelle Qualität eines Terrains sind die Texturen. Ohne gute Texturen oder mit sichtbaren Texturwiederholungen sieht ein Terrain einfach mies aus. Ich habe damals echt lang gesucht bis ich brauchbare Texturen gefunden habe, die sind auch alle entsprechend groß (1024x1024) und wiederholen sich glaube ich alle 16m. In Kombination mit einer zur Textur passenden Detail Map hat das dann ok ausgesehen (ohne Detail Map natürlich zu verwaschen).



  • Kustl schrieb:

    Hab deine Homepage gesehen, offenbar hast du dich wirklich schon genauer damit beschäftigt 🙂
    Ich habe mir einmal dieser SOAR-Paper aus 2002 und das Video dazu angesehen, sieht wirklich nicht schlecht aus. Ich nehme an dein Algorithmus läuft hauptsächlich auf der GPU? Vertex oder Index Buffers dynamisch zu ändern kann ja nicht wirklich effizient sein.

    Eigentlich änder ich wirklich den Vertex und IB dynamisch.. Will aber nicht behaupten, dass das nicht effizienter geht 😉
    Und die Tesslierung läuft bei SOAR auch komplett auf CPU ab, wobei hier die meiste Kriterien schon vorberechnet werden (statisches terrain) und somit die Runtimetesslierung relativ günstig ist..

    Hatte aber auch schon andere Algorithmen getestet, wo auch vieles auf die GPU verlagert wurde (z.B. auch das Geomorphing) und die VB und IB nur minimal geändert wurden pro frame (wenn überhaupt).. Allerdings wurd das ganze sehr schnell sehr kompliziert und den Geschwindigkeithit brachte es auch nicht, da die GPU ja auch noch andere Aufgaben wie z.B. Belichtung ausführen soll und der LOD Algorithmus selber auch ziemlich einfach war..
    Wenn man aber natürlich das ganze in ein Spiel oder so eingebettet hat, wo die CPU eh schon total ausgelastet ist, wird das ganze natürlich interesanter..

    Noch etwas aus meiner persönlichen Erfahrung: Am wichtigsten für die visuelle Qualität eines Terrains sind die Texturen. Ohne gute Texturen oder mit sichtbaren Texturwiederholungen sieht ein Terrain einfach mies aus. Ich habe damals echt lang gesucht bis ich brauchbare Texturen gefunden habe, die sind auch alle entsprechend groß (1024x1024) und wiederholen sich glaube ich alle 16m. In Kombination mit einer zur Textur passenden Detail Map hat das dann ok ausgesehen (ohne Detail Map natürlich zu verwaschen).

    Wenn du so tolle Texturen gefunden hast, könnteste die mir auch gleich mal schicken. 😃


  • Mod

    mit der cpu buffer zu locken ist zwar manchmal unumgänglich, aber das kann sehr viel performance kosten. auf durchschnitts-gpus schafft man heutzutage locker zwei millionen polys pro frame flüssig durchtransformieren zu lassen, falls man buffer lockt, kann das auf 2millionen polys pro sekunde herabgehen. bei solchen benchmarks sollte man dann aber genau wissen wo das bottleneck ist, denn wenn man zuviel overdraw hat, einen zu langen pixelshader oder texturetrasching, dann braucht man das natürlich nicht zu benchen.



  • 2 millionen Vertices extra pro frame zu zeichen kann unter umständen auch sehr viel performance kosten 😉



  • life schrieb:

    Und die Tesslierung läuft bei SOAR auch komplett auf CPU ab, wobei hier die meiste Kriterien schon vorberechnet werden (statisches terrain) und somit die Runtimetesslierung relativ günstig ist..

    Ich denke Geometry Shader werden da in Zukunft sehr viel bringen. Die sind ja schließlich genau dafür da 🙂


  • Mod

    life schrieb:

    2 millionen Vertices extra pro frame zu zeichen kann unter umständen auch sehr viel performance kosten 😉

    klar, aber mit ein wenig culling und meshlods kommt man wohl besser weg als buffer per cpu zu manipulieren.



  • rapso schrieb:

    klar, aber mit ein wenig culling und meshlods kommt man wohl besser weg als buffer per cpu zu manipulieren.

    hm.. sagen wirs so: im allgemeinen nicht! Mag natürlich für einige spezialfälle gelten..


  • Mod

    life schrieb:

    rapso schrieb:

    klar, aber mit ein wenig culling und meshlods kommt man wohl besser weg als buffer per cpu zu manipulieren.

    hm.. sagen wirs so: im allgemeinen nicht! Mag natürlich für einige spezialfälle gelten..

    ist im allgemeinen so, kannst du auch in allen papern nachlesen die optimales arbeiten mit gpus bearbeiten. jeder lock ist sehr evil!



  • ja.. und goto ist auch evil 😉

    Musst nicht alles glauben was die leute schreiben.. Der große Performancetest mit meinen dynamic Indexbuffer mit 3 (oder doch lieber 0?) indices, der jedes mal gelocked/unlocked wird gegen dein 2millionen vertices pro frame ohne lock zeichnen, würde dann glaubich doch zu meinen gunsten gehn 😉

    Wie willste überhaupt ohne locken auskommen, wenn die meshdaten alleine sagen wir mal ~1gb groß sind?


  • Mod

    life schrieb:

    ja.. und goto ist auch evil 😉

    natürlich, ist absolut unnötig und ein überbleibsel aus lowlevel zeiten. hab ich in den letzten 10jahren mit 100%iger sicherheit nicht einmal in c/c++ benutzen müssen.

    life schrieb:

    Musst nicht alles glauben was die leute schreiben..

    da ich das selber schreibe aufgrund meiner erfahrung, darf ich mir glauben, genauso wie du es darfst.

    life schrieb:

    Der große Performancetest mit meinen dynamic Indexbuffer mit 3 (oder doch lieber 0?) indices, der jedes mal gelocked/unlocked wird gegen dein 2millionen vertices pro frame ohne lock zeichnen, würde dann glaubich doch zu meinen gunsten gehn 😉

    ich schlage dir 1000 ibuffer mit je 1000tris vor, du darfst sie dann gerne auf 1-tri stellen und jedesmal locken. dann zeichnest du deine 1k und ich die 1M. du wirst sehen, die stumpfe methode gewinnt.

    [edit]wobei wir für nen echten test dein terrain gegen die bruteforce methode antretten lassen müßte, dann wäre es kein blosser schwanzvergleich, sondern wäre lehrreich für die user hier[/edit]



  • mag sein.. Ich behaupte aber, dass das es ein Spezialfall ist (mal abgesehn, dass ich es eher als stumpf ansehn würde 1000 buffer mit je 1 triangle durchzulocken)..
    Da du aber behauptest es gilt im Allgemeinen, musste schon beweisen, dass es für *jeden* Fall gilt bzw. unabhängig von Fall. Du wirst also schnell merken, dass deine Aussage so nicht haltbar ist 😉

    rapso schrieb:

    natürlich, ist absolut unnötig und ein überbleibsel aus lowlevel zeiten. hab ich in den letzten 10jahren mit 100%iger sicherheit nicht einmal in c/c++ benutzen müssen.

    ob du es glaubst oder nicht: Es gibt immernoch Leute die teilweise auf lowlevel Ebene arbeiten (müssen)..

    [edit]wobei wir für nen echten test dein terrain gegen die bruteforce methode antretten lassen müßte, dann wäre es kein blosser schwanzvergleich, sondern wäre lehrreich für die user hier

    wenn du Lust dazu hast, können wir das tatsächlich machen.. Kannst ja nen Bruteforce algorithmus schreiben, dann schreib ich dir ne abgespeckte version von meiner terrainengine (ohne texturierung (erstmal), belichtung etc)..
    Dann kann man das ganze an unterschiedlich großen Terrains und unterschiedlichen Fehlertoleranzen (LOD) durchtesten und überprüfen, ab welcher terraingröße mein Algorithmus die Nase vorn hat (oder ob Bruteforce im Allgeimeinen besser ist :p)


  • Mod

    life schrieb:

    mag sein.. Ich behaupte aber, dass das es ein Spezialfall ist (mal abgesehn, dass ich es eher als stumpf ansehn würde 1000 buffer mit je 1 triangle durchzulocken)..

    ich würde es schon als stumpf und verschwendung ansehen überhaupt nur ein tri in nem buffer zu haben, unter 200tris (bzw bis 64kb) werden buffer gebatched (ja, für diese locks sind treiber ausgelegt und wenn man es richtig macht, ist es dann schneller, wenn weitere eklärungen nötig sind, pingt)

    life schrieb:

    Da du aber behauptest es gilt im Allgemeinen,

    nein, ich erleutere, dass für den fall, dass das bottleneck der polycount ist, dass dann bufferlocks pro frame sehr evil sind und genau darum dreht sich ja die loddinggeschichte hier.

    Du wirst also schnell merken, dass deine Aussage so nicht haltbar ist 😉

    du wirst lesen können, dass ich mich in einem der vorherigen posts gegen solche exploitversuche meiner tatsachenaussage abgesichert habe;)



  • rapso schrieb:

    life schrieb:

    hm.. sagen wirs so: im allgemeinen nicht! Mag natürlich für einige spezialfälle gelten..

    ist im allgemeinen so[...]!

    btw. lass dann lieber den ultimaten bruteforce vs lod test machen, als diese sinnlosigkeiten fortzusetzen (so leicht kannste dich jetzt nicht mehr rauswinden :p)..



  • Wenn man sich so die ganze Systematik der rendering pipeline ansieht, muss eigentlich sofort völlig klar werden, wie evil ein Lock ist. Selbst bei meiner neuen Grafikkarte in 10 Jahren mit 1024 Vertextransformationen gleichzeitig ist der Lock immer noch genauso schlimm, weil die dann u.U. alle lahmliegen.

    Optimieren bei der rendering pipeline funktioniert aber so, dass man nachschaut, was überbeansprucht wird (Pixelfüllrate, Vertextransformationen, Shader, CPU, Bus zur Grafikkarte) und dann dort für Entlastung sorgt, was an anderer Stelle wieder was kostet. Beispielsweise kostet Backface Culling bei den Vertextransformationen zusätzlich für die Tests, entlastet dann aber den Rasterizer und die Beleuchtungsberechnung. Man versucht also, alle Komponenten gleichmäßig auszulasten.
    Was bringt es jetzt aber, durch einen Lock alles komplett lahmzulegen (ab den Vertextransformationen)? Das kann doch nur böse sein, weil ein großer Teil der Pipeline jetzt überhaupt nicht mehr ausgelastet wird und auf die lahme Kommunikation zwischen CPU und GPU warten muss. Auch mir scheint der Ansatz, manche Buffer je nach Sichtbarkeit einfach gar nicht zu rendern, vielversprechender zu sein.

    Davon abgesehen kann auch der Bus zur Grafikkarte zur Engstelle werden. Es ist besser, man interagiert möglichst wenig zwischen CPU und GPU. Wenn rapso das aus Erfahrung sagen kann und mir das aus meinem theoretischen Wissen schon völlig einleuchtet, ist der Fall für mich klar.



  • Btw. danke für eure Informationen bzgl. des Terrain-Renderings. Ich schau mir am Wochenende das mit den Blendmaps noch an und dann entscheide ich, was ich wie mache. 🙂



  • Es hindert dich niemand die kompletten Vertexdaten in die GPU zu schieben, wenn du meinst das bringt den performancehit.. Ob du dabei LOD oder nicht benutzt hat damit eigentlich wenig zutun...
    Wenn man meine Posts aufmerksam liest, habe ich auch gleich am anfang einräumt, dass das locken der buffer bei jedem frame sicherlich nicht die beste Lösung ist..

    Fakt ist aufjedenfall, dass jedes Spiel, das eine größere Landschaft beinhaltet und das ich kenne irgendeinen LOD Algorithmus benutzt und nicht das ganze mit Bruteforce zeichnet. Ob sie dabei jedesmal die buffer locken kann ich natürlich nicht beurteilen 😉

    Ich biete aber natürlich weiterhin an hier einen kleinen performancetest mein (unoptimiertes) LOD vs Bruteforce zu starten.


  • Mod

    life schrieb:

    ...

    wenn du aufmerksam gelesen hast, hast du sicher gemerkt, dass es hier nicht darum geht ob LOD verwendet werden soll oder nicht, sondern lediglich darum, dass locken von buffern und neufüttern mit daten evil/unperformant ist.

    Du hattest behauptet

    wo auch vieles auf die GPU verlagert wurde (z.B. auch das Geomorphing) ...Geschwindigkeithit brachte es auch nicht

    wohingegen hier behauptet wird, wenn der polycount das problem ist, sind statische buffer auf der graka viel performanter als LOD mit der cpu (und bufferlocks):

    ein wenig culling und meshlods kommt man wohl besser weg als buffer per cpu zu manipulieren.

    btw. hätten wir beim performancetest aufgrund von lodding das problem die gleiche qualität zu erreichen um objektiv die framerate testen zu können.



  • rapso schrieb:

    wenn du aufmerksam gelesen hast, hast du sicher gemerkt, dass es hier nicht darum geht ob LOD verwendet werden soll oder nicht, sondern lediglich darum, dass locken von buffern und neufüttern mit daten evil/unperformant ist.

    natürlich sollte man nach möglichkeit locks vermeiden soweit möglich (hab nie etwas anderes behauptet).. Es gibt allerdings Fälle, bei denen man ohne locks nicht sinnvoll auskommt. Nichts anderes behaupte ich..

    Du hattest behauptet

    wo auch vieles auf die GPU verlagert wurde (z.B. auch das Geomorphing) ...Geschwindigkeithit brachte es auch nicht

    Das ist keine Behauptung, sondern eine Tatsache. Wenn du willst, kannste dir den Sourcecode selber runterladen (zu finden auf meiner HP) und es gerne einmal auf deinem PC durchtesten.
    Vielleicht hätte ich besser schreiben solln, dass des den Geschwindigkeitshit bei mir zumindest nicht brachte.. Mag sein, dass du mich da missverstanden hast..

    btw. hätten wir beim performancetest aufgrund von lodding das problem die gleiche qualität zu erreichen um objektiv die framerate testen zu können.

    Natürlich. Deswegen schrieb ich auch, dass man es mit unterschiedlichen Fehlertoleranzen für die LODs testen müsste (aufmerksam lesen etc.)..


Anmelden zum Antworten