idee von einem dynamischen vertex/indexbuffer
-
Die shader ERSETZEN das _T_. Wenn man keine shader benutzt, wird das TnL aufgerufen, wenn man shader benutzt, ist man dafür verantwortlich.
Du willst 10 x das gleiche Objekt mit einem DrawPrimitive() Aufruf rendern?
erstmal benutze ich DrawIndexedPrimitive(),dann kann ich alle 10 objekte direkt hintereinander in den index/vertexbuffer der graka schreiben,die indizes kümmern sich um den rest.
ergo hab ich im endeffekt nur einen aufruf,natürlich unter der vorraussetzung, dass alle objekte die gleichen render/textur states etc haben,und das kommt einen wirklich billig, da ein dafür richtig eingestellter buffer noch bei sehr hohen vertexzahlen eine konstante geschwindigkeit aufweist zb bei einem schon etwas älteren system blieb der entsprechende vertexbuffer noch bei 32000 vertices bei konstant 10ms(das war unter testbedingungen), heutzutage sollten es noch viel mehr sein; die daten beziehen sich auf das Buch"3D Spiele programmierung" von David Scherfgen.
Nun kann man ja etwas berechnen, wieweit man normalerweise einen vertex/index buffer füllt,wahrscheinlich nicht mehr als 1000-2000 Einträge pro renderdurchgang,dafür aber vielmehr durchgänge, und das kostet...Die ganze sache ist zwar auch nicht sehr resourcenschonend, und ich weis nicht, wieviel es kostet die einzelnen vertices mit ihren matritzen über die cpu zu jagen, anstatt über die gpu,aber da das culling um einiges leichter sein dürfte,da ich die buffer theoretisch nur "aushängen" muss,kann das system doch wieder ne ganze menge rausholen.
genaueres kann ich natürlich im vorfeld nicht sagen,da mir die theoretischen grundlagen fehlen, um die komplexität eines algorithmus zu berechnen...
ps: für das resourcenproblem kann man aber auch ne lösung finden:
gleiche modelle brauchen genau die gleichen indizes, und für die vertizes würden die eines "grundmodells" reichen, die man einfach nur bei anforderung ausliest, mithilfe einer matrix richtig ausrichtet und an den vertexbuffer schickt-aber das kostet schonwieder^^
-
Hi,
so ein System lohnt sich nur dann (und da auch nur eventuell) wenn das zu Rendernde Objekt (z.B. die Schraube) sehr wenige Vertices hat. Sobald das über 100 Tris hinausgeht dürfte es schneller sein, das ganze über dynamisch Indexbuffer mit mehreren Draw***Primitive() Aufrufen zu rendern. Dafür ist die Grafikkarte ja da. Culling macht man ja auch i.d.R. nur auf der Ebene von Bounding Objekten die mit den zu rendernden Triangles vom geometrischen Standpunkt her wenig zu tun haben
Ciao,
Stefan
-
klar haben dreiecke nur begrenzt mit den bounding boxes zu tun, andererseits müssen die dreiecke aber auch verworfen werden,wenn sie nicht sichtbar sind, und da ist das false setzen eines bool wertes im entsprechenden buffer um einiges einfacher.
jetzt nochmal zum rendern:
rufst du für jeden teilbuffer DrawIndexedPrimitive auf, sind das ja n*10ms die nur fürs laden des vertexbuffers nach den oben genannten daten draufgehen,obwohl rein rechnerisch heutzutage wahrscheinlich weniger zeit benötigt wird, aber dazu auch die anzahl der angezeigten objekte und teilbuffer sich drastisch erhöht hat.
Aufjedenfall muss diese zeit auch erstmal wieder reingeholt werden.aber wenn ihr sagt, dass die punktrechnerei soviel zeit verschlingt, dann muss ich mir vielleicht ein anderes system überlegen.und im zweifesfall kann man auch irgendwann später mal beide systeme gegeneinander austesten...
-
Hi,
andererseits müssen die dreiecke aber auch verworfen werden,wenn sie nicht sichtbar sind
Nein. Je nach Cullingebene die Du auf der CPU durchnudelst kann die Grafikkarte schneller rasterisieren und Pixel verwerfen als Du einzelne Dreiecke auf der CPU cullen kannst. Heutzutage lohnen sich eher Top-Level Scene-Management Ansätze wo man nur Gruppen von Objekten (nicht Triangles) auf Sichtbarkeit prüft.
sind das ja n*10ms die nur fürs laden des vertexbuffers
Das kann man pauschal nicht sagen. Es hängt vom Memory ab in dem die Buffer lagern, wie voll der VRAM in just diesem Moment ist usw.
Die Grundidee viel Geometrie in einem Call rendern zu können ist sicherlich schon richtig. Aber dieses System hat auch Grenzen. Beispielsweise gibt es für jede Grafikkarte eine bestimmte Menge an Triangles die optimal für einen Call ist. Und das variiert von ATI zu NVIDIA und natürlich auch von Karte zu Karte. Tausende von Triangle in einem Call zu rendern ist nicht zwangsläufig schneller als Hunderte von Polygonen in Dutzenden von Calls zu rendern.
Ciao,
Stefan
-
Hi,
andererseits müssen die dreiecke aber auch verworfen werden,wenn sie nicht sichtbar sind
Nein. Je nach Cullingebene die Du auf der CPU durchnudelst kann die Grafikkarte schneller rasterisieren und Pixel verwerfen als Du einzelne Dreiecke auf der CPU cullen kannst. Heutzutage lohnen sich eher Top-Level Scene-Management Ansätze wo man nur Gruppen von Objekten (nicht Triangles) auf Sichtbarkeit prüft.
ich hab mich missverständlich ausgedrückt, ich meinte einfach, dass man den ganzen teilbuffer auf false setzt wenn er nichmehr sichtbar ist, ich wollte das nich so lowlvl machen.
sind das ja n*10ms die nur fürs laden des vertexbuffers
Das kann man pauschal nicht sagen. Es hängt vom Memory ab in dem die Buffer lagern, wie voll der VRAM in just diesem Moment ist usw.
das hab ich ja auch direkt im nächsten satz gesagt, dass es wahrscheinlich nichmehr soviel zeit brauchen wird
Die Grundidee viel Geometrie in einem Call rendern zu können ist sicherlich schon richtig. Aber dieses System hat auch Grenzen. Beispielsweise gibt es für jede Grafikkarte eine bestimmte Menge an Triangles die optimal für einen Call ist. Und das variiert von ATI zu NVIDIA und natürlich auch von Karte zu Karte. Tausende von Triangle in einem Call zu rendern ist nicht zwangsläufig schneller als Hunderte von Polygonen in Dutzenden von Calls zu rendern.
Dann werd ich meine idee wohl erstmal noch ruhen lassen müssen..bis ich mehr erfahrung hab
leider steht aber schond ie grundstruktur der Buffer, glücklicherweise hab ich immer auf die interfaces geachtet, muss nur ein paar implementationen neu machen, dann kann ich wenigstens effektiv verhindern, dass zuviel zwischen 2 zeichenvorgängen geändert werden muss, is ja auch was^^und wehe jetzt kommt jemand mit dem argument, dass die zeit die man zum sortieren benötigt, die zeitersparnis auffrisst, dann schrei ich
-
Mir scheint die Gelegenheit hier ganz gut, um mal eine Frage anzubringen:
Die Geometrie meines Levels liegt komplett in einem einzigen Vertex und einem einzigen Indexbuffer. Das alles wird "virtuell" in einem Baum aufgeteilt,
und in den Blättern dieses Baumes wird dann nur noch gespeichert, wo sich die zum Blatt gehörenden Indexe im großen Indexbuffer befinden. Das ganze ist innerhalb des Blattes
natürlich noch nach Material sortiert.
Beim Cullen erhalte ich dann für jedes Material eine Liste von solchen Subsets, die zu rendern sind. Ich rufe dann für jedes davon einmal DrawIndexedPrimitive() auf.Kann man das geschickter machen? Wenn ich immer erst alle Indexe mit dem gleichen Material in einen Indexbuffer kopieren und den zur Grafikkarte
hochladen muss ist das ja auch nicht schneller als viele Draw Aufrufe !?
-
0x00000001 schrieb:
Die Geometrie meines Levels liegt komplett in einem einzigen Vertex
Geil! Was für 'ne Matrix nutzt Du dafür!?!?
-
wurde nicht mal bewiesen, dass eine echte komprimierung(verlustfrei, und immer gleich gut) einer datei um nur ein bit unmöglich ist?
-
LOL, ich dachte mir, ich könnte den Gedankenstrich mal weglassen, Internetforen sind ja normalerweise kein Platz der guten Orthografie. Aber hier wird zum Glück noch d'rauf geachtet
Korrektur:
Die Geometrie meines Levels liegt komplett in einem einzigen Vertex**-** und einem einzigen Indexbuffer.
-
die komplette geometrie von grund auf in einen buffer zu packen ist nicht immer so die allerbeste wahl, das ganze gebilde wird immer größer, und wenn du dann mal was löschen musst, haste da plötzlich ein loch im speicher...und das aufzufüllen wird schwierig