schnelle mehrfache Animationen



  • bin mir nicht 100% ob vertex-shader die beste Lösung ist - hab damit keine Erfahrung - aber bin sicher hier gibt es jemanden der das weiß 😉



  • Das Problem wird auch nicht das malen sein, denn da ist sicher noch etwaws mehr drin. Das Problem wird der übliche Transport über den AGp Bus sein ...
    Du transformierst nicht zufällig in Software und lädts dann das Modell auf die Grafikkarte ?

    Du könntest nämlich das Modell auf die Grafikkarte laden und dann vor dem Zeichnen für jedes Körperteil Matrizen festlegen die alles richtig bewegen ..
    Sorry, grad keine Zeit!



  • Du könntest nämlich das Modell auf die Grafikkarte laden und dann vor dem Zeichnen für jedes Körperteil Matrizen festlegen die alles richtig bewegen ..
    Sorry, grad keine Zeit!

    also über Vetexshader???


  • Mod

    ich vermute bei so extrem kleinen polygonmengen <1mio dass jedes vertex einzeln zur graka geschoben eird mit zig aufrufenß 🙂

    rapso->greets();


  • Mod

    Vertexwahn schrieb:

    Du könntest nämlich das Modell auf die Grafikkarte laden und dann vor dem Zeichnen für jedes Körperteil Matrizen festlegen die alles richtig bewegen ..
    Sorry, grad keine Zeit!

    also über Vetexshader???

    er hat nichts von vs gesagt. er meint wohl die schon in der fixfunc existierende möglichkeit.



  • ich transformiere die models in meiner software, also ausgeführt auf der CPU. ich erstelle finale Matrizen für jeden bone . ich multipliziere die vertieces mit der finalen Matrix, die in der animations-funktion erstellt wird und schiebe die vertieces mit glVertex3f in die graka.
    eine kleine zusatzinfo vieleicht: das model ist vollständig texturiert mit 2 texturen.
    wie würde ich denn vorher das model in die graka schieben können? oder mit vertex-shadern (hab mich mal reingelesen, n leckeres thema 😉 ) ?
    während der animation ändern sich ja alle finale matrizen für die animation, dann wäre das das einzige, was über den agp laufen muss.
    hatte aber nicht toms-hardware einen bericht gehabt, dass eigentlich heut zu tage nicht einmal der agp-8mal in spielen ausgenutzt wird?
    (http://www.tomshardware.de/graphic/20040425/pci-express-02.html)
    und bei 100 modellen fällt folgender aufwand an: ca 25000 Vertieces und 55000 dreiecken -> 165000 Aufrufe der Funktion glVertex3f.
    ich werd gleich mal testen, in wie weit die texturen den speed beeinflussen.
    ich hab auch schon mal häufiger was von Vertexbuffern gehört und gelesen, hab mich aber noch nicht mit befasst, könnten die evtl weiterhelfen ??
    heimschmiede



  • ich hab mir das model mal ohne texturen und materials anzeigen lassen und es ist nur minimal schneller (von 12FPS auf 13FPS)
    ich habe mir nochmal gedanken über den agp-bus gemacht. wenn agb-8x einen datentransfer von abgerundet 2100 MByte/s schafft, dann kann man ja die benötigte zeit errechnen, wie lange es dauert die daten zu senden.
    165.000 Aufrufe der funktion glVertex3f -> übertragung von 3 floats (jeweils 4byte lang). also erzeuge ich einen traffic von 1.980.000 Bytes (165000*3*4). das sind ca 1,888 MBytes.
    benötigte zeit der übertragung: 1,888 MBytes / 2100MBytes/s = ~ 0,9 ms
    dann muss man noch bedenken, dass protokoll-traffic dabei erzeugt wird. aber summa sumarum dürfte das nicht mehr als 2-3 Millisekunden dauern bei allen AGP-8x-Karten.

    also helfen in dem problem den draw-prozess zu beschleuningen nur die vertex-shader weiter? wie beschleuningt ihr eure spiele oder grafikanwendungen ??

    heimschmiede



  • Das böse OGL hat wieder mal zugeschlagen. So viele glVertex3f sind nun mal lahm, lahm, lahm.

    Bye, TGGC (Das Jahr des Helden)



  • Hi,

    Auf der Seite www.nvidia.com findest du unter der Sparte Developer einige Präsentationen in denen unter anderem erklärt wird, wie du vertex-shader für bone-animationen bzw. key-frame interpolationen nutzen kannst (Wirklich viele Präsentationen!!!!).

    Falls die FrameRate doch mal an der animation hängt bietet sich auch folgende Lösung an: Benutze deine Animations-Klasse nur um etwa alle 0.05 sec einen Keyframe zu berechnen und dann die GrKa(Vertexshader) um zwischen den letzten Keyframes zu interpolieren. Damit hängst du zwar minimal in der Zeit hinterher, hast aber einige Vorteile wie z.B.:
    -Solltest du gezwungen sein ein einzelnes Modell mehrfach in einem Frame zu rendern (um z.B. coole Lichteffekte o.ä. zu erreichen) muß die GaKa einen weniger aufwändigen Shader beackern -> mehr fps.
    -Natürlich wird die CPU weniger durch animationen belastet usw.
    -Die Effektivität der Vertexbuffer (falls du welche einbaust) wird erhöht falls du die Bone-Animation auf der CPU ausführst (da du sie nicht jeden Frame neu beschreiben mußt) - Führst du alles auf der GraKa aus zieht dieses Argument natürlich nicht
    .
    .
    .
    Natürlich ist es außerdem wichtig wirklich nur die Objekte zu animieren und zu zeichnen die sichtbar sind...



  • also, ich werde mal schaun, wie weit ich es gebrauchen werde. ich denke mir mal, dass die kombination aus vertexbuffer + vertexshader + animationsberechnung auf der CPU die sinnvollste variante wäre. ich errechne also auf der CPU die finalen Matrizen und schiebe sie dann auf die graka, wo dann der vertexshader die matrizen empfängt, sich die vertices aus dem vertexbuffer holt und richtig rendert. ist es denn möglich speicherplatz auf dem graka-ram zu reservieren (für die finalen Matrizen) ?
    und eine weitere Frage zu den vertex-shadern: ist es für das Programmieren egal, welche version der shader installiert ist? und von welchem Hersteller die graka ist? (ATI, nVidia) ?? oder muss ich mehrere versionen schreiben, sodass es auf ATI- und nVidia-Karten läuft ?
    heimschmiede



  • Shader sind ein sehr sehr interessantes aber auch hoch komplexes Thema.
    Ich würde es für dein Vorhaben nicht benutzen. Es ist mit Kanonen auf Spatzen geschossen. Und Animationen gab es auch schon bevor es VertexShader gab !
    Lern erstmal noch ein bisschen den richtigen Umgang mit OpenGL, da kann man noch eine ganze Menge herausholen !
    Hier mein Vorschlag den ich neulich nicht zuende schreiben konnte, da ich nun weiss das du über Software Transformierst.
    Jede T&L Karte kann auf Hardware transformieren. Also alle Karten die so momentan im Umlauf sind halt.
    Deshalb ein Vorschlag.
    1. Lies dir was an wie du ganze Arrays an Vertices auf einmal an die Grafikkarte schicken kannst. Transformiere immernoch in Software und schicke dann alle Daten GESAMMELT im Array an die Gk (pro Modell).
    Dies sollte dir einen ersten Eindruck geben wieviel die ganzen FunktionCalls zu glVertex3f gekostet haben als du jedes Vertex einzeln hochgeladen hast. (Diese Funktionen sind eigentlich nur für kleine Demos zum testen etc... nicht als praktikable Lösung gedacht)

    Danach verwirf das alles und unterteile dein Modell in alle Beweglichen Teile und lege einen VertexBuffer auf der Grafikkarte für jedes dieser Teile an.
    Also hast du dann Arm, Torso, Fuss, Hand, Kopf, etc... auf der Grafikkarte liegen.

    Dann gehst du durch die Liste deiner "virtuellen" Modells und errechnest die Animationsmatrix für das entsprechende Körperteil(so wie bisher in Software auch)
    Nur das du jetzt nicht in Software deine Vertices mit der Matrix multiplizierst sondern die TransformationsMatrix direkt an OpenGL auf die Grafikkarte schickst. Dann Renderst du den Körperteil.
    Dies machst du einfach für alle Körperteile aller Models.
    Dadurch wird die Matrixmultiplikation jedes einzelnen Vertex auf der Grafikkarte ausgeführt was natürlich viel viel schneller ist. Ausserdem musst du (siehe AGP) nicht jedesmal deine VertexDaten auf die Grafikkarte schicken(diese liegen dort untransformiert im Speicher) sondern nur die Transformationsbeschreibungen (Matrizen) für die einzelnen Körperteile. Und dies spart ordentlich Overhead über den AGP.
    Diese Variante lässt sich noch um einiges Optimieren indem du TeilTransformationen (Position des Modells, Arm bewegt auch Hand etc...) behälts und die letzte Transformationsmatrix auf der GK nur mit der neuen Mutliplizierst.

    3. Diese Variante ist dann nur wenn du alles vorher gut gemacht hast und es dir immernoch zu langsam seien sollte(was ich nicht recht glaube 😃 )
    Du kannst versuchen die BewegungsMatrizen auf dem Shader zu berechnen, so das du diese Berechnung auch von der Software auf die Hardware verlagerst. Ich weiss nicht genau wie dies funktioniert. Ich nehme an die setzt einige Werte für deine Vertices im Buffer auf feste Vectoren(wie der Arm gedreht werden kann, etc...) und schreibst dir dann einen Shader der durch Shaderparameter weiss an welcher Stelle der Animation das Modell gerade sein soll und daraus die Matrizen berechnet.
    Dadurch hast du dann nur noch ein paar Shadervariablen pro Model und Frame(bzw. Animationsabschnitt(muss nicht jedes Frame sein(->gilt auch für die anderen Varianten)) die über den AGP gehen müssen. Ausserdem sind dann sämtliche Berechnungen auf der Harfware, wofür sie schliesslich da ist.

    K, hoffe ich hab nicht zu viel scheisse geredet, hab mich verdammt lange nicht mit Grafik beschäftigt.



  • das hört sich doch schon sehr gut an. aber wie wird das dann wiederum in ogl realisiert?
    1. wie sende ich ein ganzes Paket von Vertices rüber? ich kenn nur glVertex3fv und der verlangt nur einen Vertex in nem array.
    2. wie lasse ich in ogl die Transformationsmtrix auf der graka errechnen ohne den in 3 angesprochenen VertexShader zu benutzen?
    3. alles im shader arbeiten lassen, das wird noch ein heiden spaß 🤡

    und nochmal die weitere Frage zu den vertex-shadern (damit sie nicht untergeht): ist es für das Programmieren egal, welche version der shader installiert ist? (änderungen der versionen sind logisch, sind sie aber auch abwärtskompatibel?) und von welchem Hersteller die graka ist? (ATI, nVidia) ?? oder muss ich mehrere versionen schreiben, sodass es auf ATI- und nVidia-Karten läuft ?

    heimschmiede



  • Ob ati oder nvidia ist egal, solange die karte die entsprechende shader version unterstütz. Die Karten unterstützen auch immer ältere Shader. (Die Shader werden kompiliert und dann vom Prozessor der Karte ausgeführt. Da diese Prozessoren normalerweise immer umfangreichere Operationen unterstützen ist die Abwärtskompatibilität so weit ich das sehe eigentlich fast garantiert).Die Transformations - matrizen kannst du dir nicht auf der GraKa berechnen lassen (wäre zumindest nicht sinnvoll, da du die Berechnung dann für jeden vertex wieder ausführen müßtest). Die Transformationen der vertices bei gegebenen Matrizen auf der GraKa auszuführen ist hingegen sehr sinnvoll, da deren Prozessor für solche Rechnungen optimiert ist.

    Zu Punkt 2 von Chaos Angle
    Diese Unterteilung ist nur dann sinnvoll, wenn du kein skinning benutzt, d.h. wenn deine vertices nicht von mehreren bones beeinflußt werden. Falls du dich trotzdem dafür entscheidest wäre es etwas schneller, wenn du dein gesamtes modell in einem vertex-buffer schreibst und dir nur die offsets der jeweiligen Teile merkst. -> Dadurch mußt du den Buffer seltener wechseln.

    Auf der folgenden Seite findest du einige Methoden, wie du deine Dreiecke schneller auf die Karte bekommst.

    http://nehe.gamedev.net/



  • zu finale matrizen-multiplikation der vertices auf der graka. ich meine das genau so, wie das gesagt hast mac_bu. nur die matrix-vektor-multiplikation auf der graka. aber wie mache ich diese finale multiplikation auf der graka? das dürfte doch nur mit nem vertex-shader funzen, oder? und wie bekomme ich dann die finale matrix auf die graka? (Quelltext)

    die nehes kenne ich größten teils, aber der nutzt ja auch hauptsächlich die Funktion glVertex3fv. ansonsten verwendet er vertex-buffer. bei welchem tut siehst du, wo er nen vertex-array am stück rüber zieht??

    heimschmiede



  • Entschuldige, ich meinte die VertexBuffer. Zu VertexList gibt es zwar auch etwas (Begin(List), dann die draw aufrufe, dann end) und anschließend diese Liste zeichnen. Das ist aber eigentlich nur für statische Objekte sinnvoll. Ich komme von DX, daher habe ich hier keine besonders tiefgehenden Kenntnisse.
    Unter DX gibt es den Aufruf SetVertexShaderConstant(...) mit dem sich eine begrenzte Anzahl an Konstanten (üblicherweise Vektoren) setzen läßt (?196 Vektoren?). Hiermit würdest du der Karte die Matrizen übermitteln. Anschließend kannst du auf diese Konstanten von deinem Shader aus zugreifen. Mit OGL dürfte es wohl ähnlich ablaufen. Anstelle von Matrizen könntest du in diese Konstanten auch Quaternione legen (+TranslationsVektoren). Dadurch könntest du auf mehr Bones zugreifen (Dürfte aber mehr Rechenaufwand sein). Solltest du Pro Modell mehr Bones haben, als sich in den ?196? Vektoren übermitteln lässt musst du dein Modell 'zerschneiden' d.h. in 2 Objekte unterteilen, die möglichst wenige gemeinsame Bones haben.
    Sieh dir mal die Teile auf der NVidia homepage an, da bekommst du denke ich ein ganz gutes Gefühl, wie das ganze funktioniert.

    Da fällt mir noch was ein:
    Schau dir mal die Funktionen
    glInterleavedArrays, glDrawArrays, glDrawElements, glArrayElement an.

    VertexBuffer wären aber wahrscheinlich trotzdem schneller (zumindest bei DX - ich weiß nicht in wie weit die ähnlich sind).

    Viel Spaß damit!



  • Also Nehe hat eigentlich alles was du für diese einfache Aufgabe brauchst.
    Ansonsten würde ich dir gerne das OpenGL ReadBook zu Herzen legen. Ist zwar schon etwas älter aber ein sehr gutes Buch um zu sehen was man alles wie machen machen.

    Hab grad mal etwas oberflächlich dort gesucht:
    glVertexPointer und glDrawElements oder ähnliche Sachen sollten dir bei Aufgabe 1. helfen.

    Die Matrizen auf der Grafikkarte rechnen lassen das tust du Teilweise schon.

    Wie bewegst und rotierst du deine Objekte denn. Ich glaube doch kaum in Software !!

    Du Benutzt die Methoden glRotate/Translate
    Also entweder benutzt du anschliessend diese um deine Körperteile zu bewegen, oder du übergibst gleich die Matrix mit den Befehlen glLoadIdentity oder glLoadMatrix/MultMatrix

    Damit schickst du die Matrizen zur Transformation an die GK, danach zeichnest du dein Objekt und die GK Multipliziert deine Vertices mit der Matrix (und noch einigen anderen Matrizen (Projektion, World, etc...)

    Wie gesagt, lass erstmal noch die Finger von Shadern. Sie sind sehr interessant, aber vorher brauchst du noch ein paar Grundkenntnisse was die generelle Kommunikation mit der GK angeht.



  • Ist schon richtig. Wenn du auf shader zurückgreifen würdest müßtest du in denen auch die beleuchtung deiner Objekte selbst berechnen. Lohnen könnte es sich trotzdem!

    Das mit den Matrizen war wohl ein Missverständis meinerseits.



  • das was ich bisher von den shadern gesehen habe, sieht sehr übel aus, deshalb wollt ich erst einmal auf andere methoden zurückgreifen.
    momentan berechne ich alle meine punkte in software. dh: an hand der keyframes und den absoluten und relativen matrizen werden die finalen matrizen erstellt, die dann die ganze tranformation enthalten. diese werden dann bei mir im code in software transformiert und dann erst in die graka verschifft. in der graka kommt dann noch das anderes gedönse, der vorher mit glRotate und glTranslate erstellt wird. das ist ja im prinzip auch nur ne matrix.
    ich denke, dass ich mal mit glDrawArrays rumexperimentiere um zu sehen, wie viel es mir wirklich bringt.
    dann danke ich mal allen für die guten antworten! ich werd wahrscheinlich mal wieder kommen, wenn ich irgendwo wieder probleme haben werde.
    aber wer noch weitere ideen ´hat, kann ja ruhig weiter posten 😉

    heimschmiede



  • Wie gesagt, DrawArrays wird sich auf jeden Fall lohnen. Aber noch viel mehr (oder genauso, egal, beides wird SEHR SEHR VIEL bringen) lohnt sich die Matrix Multiplikation auf der GK.
    Die Grafikkarte muss sowieso jedes Vertex mit der Matrix multiplizieren. Es ist also kein Mehraufwand.

    Teste einfach mal all deine Modelle OHNE Animation !
    Diese Geschwindigkeit sollte ungefähr die gleiche sein wie wenn du die Matrizen mit glLoadMatrix erst auf der GK mutltiplizierst.

    Viel Spass beim ausprobieren !



  • moinmoin,
    ich werde dieses thema wieder auffrischen müssen. es hat so lang gedauert, weil noch ein paar klausuren dazwischen lagen ....

    ich hab mir ja auch viel von den vertex-arrays versprochen, deshalb hab ich alles uaf vertex-arrays umgebaut und nachher wieder viele zeiten gemessen. leider sind die vertex-arrays kein bischen schneller als die massenweisen alten glVertex3f(v)-funktionen. auf die 100 models ist keine veränderung zu spüren. zusätzlich muss auch noch gesagt werden, dass man wegen der transformationen noch zusätzlichen speicherplatz reservieren muss. leider hat es sich nicht gelohnt. jetzt bin ich aber am überlegen, wie ich da noch was rausholen kann.
    ansatz: alle matrizen-multiplikationen auf der GK durchführen lassen. da im milkshape-model-format jeder vertex einem bone zugeordnet ist, ist es sinnvoll das gesamte format nach den bones zu sortieren, sonst könnte es passieren, dass bei jedem vertex ne neue matrix rübergeschoben werden muss, was eher kontraproduktiv wäre. also wären ale bones zusammen mit bone-eigener matrix, wo sich auch dann seperate vertex-buffer lohnen könnten. nachteil: es ist nicht vorher bekannt, ob alle dreiecke eines bones die selbe textur besitzen. es könnte also vorkommen, dass innerhalb des rendern eines bones mehrfach die textur geändert werden muss. -> ist aber ein eher kleinerer nachteil, weil man beim modellieren dieses problem beseitigen könnte.
    das milkshape-model ist nach meshes aufgebaut und sortiert. ein mesh besitzt maximal ein material und somit auch maximal eine textur.

    ist dieser ansatz vielversprechend? könnt ihr mir weitere nachteile oder auch weitere vorteile nennen?? denn dies ist mit ner menge arbeit verbunden, deshalb wollt ich lieber einmal nochmal nachfragen.

    heimschmiede


Anmelden zum Antworten