Wie wird Animation in nicht sofortigem OpenGL behandelt?

8

Ich bin ein Neuling im modernen OpenGL. Ich bin mit der unmittelbaren OpenGL-Methodik vertraut, habe aber noch nie ernsthaft mit VBOs gearbeitet. Meine Frage betrifft die Animation. Im Sofortmodus müssen Sie zum Erzielen einer Animation nur verschiedene Scheitelpunktpositionen (aus Keyframes interpoliert) im Objektraum streamen.

Wie wird dies in nicht sofortigem OpenGL erreicht? Offensichtlich wird das Hochladen neuer VBO-Daten für jeden Frame den Grafikbus sicher belasten. Ich habe keine Literatur über die moderne Art und Weise gefunden, dies zu tun. Als ich darüber nachdachte, kam ich zu mehreren Optionen:

  • Attribute: Animation als 3D-Offset. Für jeden Frame wird für jeden Scheitelpunkt ein anderes (möglicherweise interpoliertes) Versatzattribut übergeben, das bei jedem Keyframe auf denselben Scheitelpunkt angewendet wird.
  • Indizes: Speichern von Keyframes als absolute Eckpunkte und Zugriff auf diese durch Indizierung unter Verwendung eines anderen Satzes von Eckpunkten für jeden Keyframe. Ich finde diesen Ansatz unmöglich, da Sie nicht auf benachbarte Keyframes zugreifen können und daher nicht zwischen ihnen interpolieren können. Auch scheint eine schlechte Idee für prozedurale Animation.
  • Textur: Das mag sehr dehnbar sein, klingt aber nach einer guten Lösung für mich. Auch hier wird die Animation als xyz-Versatz für jeden Scheitelpunkt betrachtet. Jeder Keyframe kann in einer 1D-Textur gespeichert werden, in der die Dimension vertexID zugeordnet ist. Wenn ich mich nicht irre, können Sie in OpenGL 4.0 von jedem Shader aus auf Texturen zugreifen, sodass Sie diese Textur aus dem Vertex-Shader lesen und jede Vertex-Transformation anwenden können. Eine 2D-Textur kann mehrere Frames enthalten. Sie führen weiterhin eine Interpolation durch (und wenn die Interpolation für Texturen außerhalb des Fragment-Shaders funktioniert, bei denen ich mir nicht sicher bin, können Sie kostenlos linear interpolieren!) Dies kann ohne großen Aufwand auf komplexere Animationssysteme wie die Knochenanimation angewendet werden.

Überdenke ich das? Kann jemand etwas Licht ins Dunkel bringen?

kaoD
quelle

Antworten:

5

Ich habe keine Literatur über die moderne Art und Weise gefunden, dies zu tun.

Dies liegt im Allgemeinen daran, dass die "moderne Art" der Charakteranimation darin besteht, das Wiegen von Skelettknochen und nicht das Mischen von Scheitelpunkten zu verwenden.

Wenn Sie jedoch darauf bestehen, eine auf Scheitelpunktmischungen basierende Animation durchzuführen, können Sie dies tun. Am einfachsten ist es, einfach die beiden Keyframes, zwischen denen Sie mischen möchten, als Attribute zu senden. Sie haben Positionsdaten für alle verschiedenen Keyframes. Verwenden Sie einfach glVertexAttribPointer(oder glVertexPointerwenn Sie darauf bestehen), um bestimmte Keyframes auszuwählen. Da für jeden Keyframe die Positionsdaten in derselben Reihenfolge gespeichert werden sollten (für entsprechende Positionen), können sie dieselbe Renderliste zum Rendern verwenden.

Der Shader erhält zwei "Positions" -Attribute, eines für den Keyframe vor der aktuellen Zeit und eines für den Keyframe danach. Sie würden auch eine Uniform übergeben, die angibt, wie viel von einer Mischung zwischen ihnen zu tun ist. Sie berechnen die neue Position als Mischung zwischen den beiden Keyframes und führen dann die üblichen Transformationen von dort aus durch.

Nicol Bolas
quelle
Haben Sie empfohlene Bücher oder Artikel zum Lesen, um zu lernen, wie man Code für das Wiegen von Skelettknochen schreibt?
michael.bartnett
Ich suchte nach dem "Verschieben von Scheitelpunkten" und nicht nach der eigentlichen Animation. Nun, es ist nicht so anders mit der Skelettknochengewichtung, schließlich kommt es darauf an, dass sich die Scheitelpunkte bewegen, ob sie vorberechnet (vertexgemischt) oder im laufenden Betrieb knochengewichtet sind. Sind Attribute der einzige Weg, um noch zu gehen? Ist der texturbasierte Ansatz nicht immer noch machbar und schneller als die Weitergabe vieler Daten für jeden Scheitelpunkt in jedem Frame? (mindestens beide Keyframes pro Knochen und der Mischungsfaktor) Eine Textur kann immer noch die Knochendrehung codieren, und die Textur-Suche ist viel schneller als das Weitergeben von Attributen.
kaoD
Außerdem: "Da in jedem Keyframe [...] Positionsdaten gespeichert sein sollten, können sie dieselbe Indexliste zum Rendern verwenden." Ist das nicht unmöglich? Wie kann ich auf zwei Indizes zugreifen, um zwischen ihnen zu interpolieren? Ist sich der Vertex-Shader nicht des anderen Vertex und noch mehr anderer Indizes bewusst?
kaoD
@kaoD: Unmöglich? Tun Sie das derzeit nicht, um die neue Scheitelpunktposition zu berechnen? Für jede Position in jedem Keyframe-Array mischen Sie sie zusammen und schreiben sie in die OpenGL. Ich sage nur, dass Sie OpenGL diese Keyframe-Arrays zur Verfügung stellen und den Shader das Mischen durchführen lassen. Bei Textur-Lookups befinden sich in der Hierarchie der "schnellen Dinge in Shadern" Textur-Lookups im Allgemeinen ganz unten . Attribute sind mehr oder weniger frei .
Nicol Bolas
@NicolBolas: Gut zu wissen, dass die Textur-Suche langsamer ist als ich dachte. Was ich mit unmöglich meine, ist, dass, wenn ich mich nicht irre, jeder Scheitelpunkt nur sich selbst im Shader "sehen" kann und daher keine anderen Scheitelpunkte indizieren oder auf andere Arrays (Keyframes) zugreifen kann. Was ich aus Ihrer Antwort verstehe muss ich diese beiden Keyframe-Positionen als Attribute für jeden Scheitelpunkt übergeben, zusammen mit einem einheitlichen Mischfaktor, aber dann hätte ich kein Scheitelpunkt-Array, oder? Obwohl ich gerade festgestellt habe, dass Sie den aktuellen Keyframe als Vertex-Array und den nächsten Frame als Attribut-Array verwenden können, haben Sie das gemeint?
kaoD