Wie werden große Mengen an Objecten verwaltet und gerendert?
-
Wie ist es möglich derartig viele objekte zu zeichen wie es beispielsweise bei der CryEngine oder der Frostbite engine der Fall ist?
Man kann da killometerweit gucken, und sieht immernoch jeden einzelnen Baum.Nur durch LOD und Frustum Culling kann es doch eigentlich nicht möglich sein tausende Objekte zu verwalten und auch noch zu zeichen oder am besten noch zu animieren?
Es wäre nett, wenn mir irgentjemand mal grob erklären könnte in welche Richtungen die Techniken von denen gehen, sodass es ihnen möglich ist derartige Landschaften zu zeichen.
http://www.pcgames.de/screenshots/667x375/2012/04/cryengine_3_7.jpg
-
Nur durch LOD und Frustum Culling kann es doch eigentlich nicht möglich sein tausende Objekte zu verwalten und auch noch zu zeichen oder am besten noch zu animieren
Warum nicht?
-
weil wir alle keine NASA rechner haben? wie sollst du bitte 60 mal pro sekunde tausende bäume, gräser und andere objekte animieren, zeichen, und noch die passende LOD stufe, usw. herausfinden? und das ist ja nur das zeichen, die physik ist zwar bei solchen engines in einem seperaten thread, aber immerhin, die verbraucht auch noch rechenzeit.
Willst du mir echt erzählen, das sowas nur mit LOD tesselation und geschicktem Frustum Culling funktioniert?
-
Also wenn Grass weit weg ist, dann wird es nicht gerendert. Alles was weit weg ist, wird in den Details reduziert. Ja, das ist LOD. Desweitern wird Gras als Shader realisiert. Dann besteht nicht jede sichtbare Geometrie wirklich aus Polygonen, im einfachsten Fall sei hier bump mapping genannt.
Ansonsten: Ja, von aktuallen Grafikkarten erwarte ich, dass sie Spiele verdammt gut darstellen und bei ein paar tausend Objekten nicht schlapp macht. Limitierender Faktor ist wahrscheinlich die Verbindung CPU und Grafikkarte, deswegen habe die ja auch so viel Speicher, damit die Kommunikation stark reduziert werden kann.
-
knivil schrieb:
Warum nicht?
weil alleine die drawcalls, mit einfachstem material und selbst bei einem poly pro objekt, nicht schnell genug waeren.
knivil schrieb:
Also wenn Grass weit weg ist, dann wird es nicht gerendert.
da es spielrelevant ist, wird es in crysis 1 noch in 1km entfernung gerendert (z.b. wegen multiplayer).
knivil schrieb:
Alles was weit weg ist, wird in den Details reduziert. Ja, das ist LOD.
nein, das reicht nicht, dann haettest du immer noch 100k drawcalls.
Desweitern wird Gras als Shader realisiert. Dann besteht nicht jede sichtbare Geometrie wirklich aus Polygonen, im einfachsten Fall sei hier bump mapping genannt.
das gras hat immer bumpmapping, unabhaengig von der entfernung, jedoch reduziert bumpmapping nicht den aufwand (hebt ihn eher).
knivil schrieb:
Ansonsten: Ja, von aktuallen Grafikkarten erwarte ich, dass sie Spiele verdammt gut darstellen und bei ein paar tausend Objekten nicht schlapp macht. Limitierender Faktor ist wahrscheinlich die Verbindung CPU und Grafikkarte, deswegen habe die ja auch so viel Speicher, damit die Kommunikation stark reduziert werden kann.
das problem ist der overhead zwischen applikation und treiber, jeder drawcall der gemacht wird ist sehr teuer, frueher hattest du ein limit von vielleicht 1000, zu crysis zeiten normalerweise 2000 bis 3000. das ist kein hardware oder kommunikationsproblem, den auf konsolen, wo es diese schnittstelle nicht gibt, hast du auf einer ps2 mehr drawcalls machen koennen als auf einem high end PC heutzutage, geschweige denn was eine konsole heute leisten kann.
auch opengl auf winXP hat zwei mal soviele drawcalls abschicken koennen, wie es directX damals konnte.@gamer8o4
um das zu umgehen nutzt man exzessiv instancing und impostor rendering
- beim "instancing" zeichnest du z.b. mit einem drawcall eine baum geometrie an 10 unterschiedliche stellen. das zeichnen an sich ist von der graphikkarte her gesehen vielleicht ca 10% langsammer, aber da du nicht GPU sondern drawcall limitiert bist, ist es quasi umsonst.
- beim impostor rendering zeichnest du eine geometrie in eine textur einmal (oft sogar nur einmal alle n-frames), und dann anstatt der geometrie, ein sprite/particle mit dieser textur. so kannst du in der entfernung 100 oder 1000 baeume mit nur einem drawcall zeichnen..
-
@rapso
Wie sehr oder wenig hat sich das eigentlich mit DX10 bzw. DX11 verbessert?
BTW: sorry falls du mir die Frage schon mehrfach beantwortet haben solltest, ich bin bei sowas manchmal recht vergesslich
-
das kommt drauf an wie man DX10/11 anwendet. DX9 engines auf DX10 wurden durchweg langsammer, weil man zumeist alles auf DX9 optimiert hatte und dann quasi einen emulationslayer dazwischen haengt.
z.b. ist die idee states zu haben die zur startzeit erstellt werden und der treiber sie validieren kann sehr gut, jedoch kann in einem spiel ein game script irgendwo einen effekt triggern, der dann states modifiziert (z.b. infrarot-rendering) und je nachdem wo man dann gerade ist, muss man von existirenden models die states modifizieren wie es die engine beim start up nicht wissen konnte (und alle permutationen zu machen waere zum einen kontraproduktiv, und zum anderen gibt es recht kleine limits von z.b. 4096 rasterizer state objects).entsprechend zeigen die benchmarks durchweg dass DX10 spiele langsammer waren.
wenn neuere treiber rauskommen, haben die treiberentwickler sich fuer 99% der states schon ihre hashes mit optimierten setups gebastelt und dann siehst du wieder 10% speed up.ein schonmal guter ansatz ist der von DICE, bei dem sie alle drawcalls per compute shader cullen. wenn man das ein wenig weiter treibt, koennte man eine art redux machen, sodass man ein array mit "offset|count" der vertices von zu gesehenden drawcalls erstellt und dann mit einem compute shader durchtransformiert, in den darauffolgenden passes koennten die vertexshader die dreieck zum rasterizer durchschieben und man indiziert im pixelshader die passenden resourcen. zZ hat man noch ein paar limits wie z.b. 128sampler stages, aber seit Kepler werden diese per pointer indiziert, das heisst, man koennte mit ein paar wenigen compute shader aufrufen das ganze rendering der GPU ueberlassen, die dann nicht drawcall limitiert waere und es waere relativ egal ob 2 oder 1000 polys pro mesh.
wenn man soweit waere, koennte man das shading ueber light-indexed-rendering machen wobei man auf dreiecks-basis die dreiecke sortiert, das wuerde recht gut (bei den kleinen dreiecken die man heutzutage hat) die richtige reihenfolge fuer transparente objekte ergeben und man koennte mit 4x MSAA und beliebigen lichtquellen anzahlen arbeiten. was ein ziemlicher vorteil gegenueber heutigen deferred ansaetzen waere die doch sehr leiden sobald man AA haben will.
-
Okay, ich hab jetzt ja einigen Ansätze, bei denen ich weiter nachlesen kann, danke schon mal