Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Sa Jul 26, 2025 01:18

Foren-Übersicht » Programmierung » Shader
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Slerp Bonesystem
BeitragVerfasst: Sa Dez 23, 2006 00:11 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Eventuell ist das was ich jetzt beschriebe kein reines Bonesystem mehr, da sich die Datenstrukturen in den grundsätzen ändern werden. Prinzipiell beziehtsich die hier alles auf Medium und Highpolymodelle

Ein größes problem bei Bonesystemen ist, dass linear interpoliert wird, dadürch wird nicht nur das Skinnen problematisch, sondern das Mesh wird teilweise stark deformiert. z.B. Wird bei einem angewinkeltem Elbogen die Außenseite nicht rund und die Innenseite stark in richtung gelekt eingebogen. Bei stärkeren Winkeln sehen Körperteile eher aus wie abgeknickte Wasserschläuche.

Es gibt einige sehr theoretische ansätzte wie mit Quaternionen und SLERP (interpolation auf einer Sphere) im Vertexshader, jedoch scheint mir es eher so als wenn da Mathematiker am Werk waren und einige besonderheiten bei der shaderprogramierung vergessen haben.


1. Setup der Rohdaten:
Jeder Vertex wird als 4D Vektor relativ zum Joint (z.B. Kniegelenk) encodiert. Er besteht aus den 3 Richtungskomponenten und als 4. Komponet seine länge (spart das zerlegen im Vertexshader)
Jeder Vertex kann nur einem Gelenk zugeordnet werden. Witerhin kann jeder Joint mit einer eingeschränkten Anzahl von Bones verbunden werden. Das sinvolle Limit liegt meiner Meinung nach bei 3 oder 4 (Mir fällt am Menschlickem Körper kein Gelenk ein in dem mehr als 2 Bones sich unabhängig von einander verdrehen können) zu den schon bekannten Vertexdaten kommt also noch ein 4D Vektor hinzu:
Ein Float für die Jointnummer und 3 Floats für die Gewichtung, die Abhängikeiten zu den Bones werden mit der Jointnummer aufgelöst. Da die Summe aller Gewichtungen immer 1 ist, wäre ein 4 Bonejoint durchaus Relaisierbar.

Eine Uniformindextabelle wird benötigt um zu ermitteln welche Bones zu welchem Joint gehören. Jeh ein float3 oder float4 Vektor.


2. Prerendering:
Die CPU berechnet die vor dem Rendern die Positionen der Joints, sowie die Matrizen für die einzelnen Bones. Da beides Uniformdaten sind wäre eine berechnung dien 1000de male im Vertexshader durchgeführt werden Verschwendung. Besonders das muiltiplizieren von Quarternioinen oder Rotationsmatrizen die alle miteinander Uniformvars sind haben im Vertexshader nichts zu suchen.

3. Rendering im Vertexshader:

Ermitteln des richtigem Joints.
Ermitteln der richtigen Bonerotationsmatrizen
Bonematrizen gewichten
Die relative Richtung aus der Position mit der gewichteten Matrix tranformieren.
Das Ergbniss Normalisieren und mit der Wahren länge (4. Komponete von Position) skalieren.
Die Position des Jointsdazuaddieren
Position mit der gl_ModelviewProjectionMatrix multiplizieren
Normal, Tangent ebenfalls mit der gewichteten Matrix und anschließend mit der gl_NormalMatrix berechnen und gegebenfalls normalisieren
Bitangent mit hilfe eines Crossproduktes wiederherstellen


Vorteile:
Wird viel besser aussehen
Skinnen wird wahrscheinlich einfacher werden. Da es in zwei Schritte unterteilt werden kann Auswahl der Jointzone und anschließendes Gewichten. unkontrollierten Vertexpainting wird es nicht mehr geben.
Es werden gegenüber dem klassischem Boneshader nur halb so viele Atributte benötig (kombiniete Abhängikeit mit gewichtung, stat beides getrennt) Die Daten werden quasi durch eine zusätzliuche indizierung weiter komprimiert.
Der gesteigerte rechenaufwand gegenüber einem normalem Boneshader beschränkt sich auf nur eine Normalisation, eine addition und eine Multiplikation.
Die vorberechneten Jointpositionen können für Sweep-Sphereverdrängungskörper benutzt werden um eine Kleidungsimulation auf der GPU laufen zu lassen


Nachteil:
Es gibt noch kein Programm zum skinnen.
Die relativ zu dem Joint angegebene Vertexposition, dürfte fast jeden vorhandene Editor code untauglich werden lassen.
Insgesammt verwirrendes und unverständliches konzept :P (Ich müsste wohl eerst eine 10 Seiten langen Artikel schreiben damit es verstanden werden kann)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 26, 2006 13:56 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hallo oc2k1,

Zitat:
Die relativ zu dem Joint angegebene Vertexposition, dürfte fast jeden vorhandene Editor code untauglich werden lassen.


Das muss nicht sein. Ich verstehe nichts von Shadern, aber dieses Problem könntest Du ganz einfach beheben, wenn Du deine Joint/Bone-Transformationsmatrix mit einem Zusatz-Feature "Vertex in den Joint-Raum transformieren" versiehst.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 26, 2006 14:49 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Naja das könnte noch gehen (Kostet einen weiteren Satz Uniformvariablen), jedoch wird es auch sehr problematisch die Jointzuordunung vorzunehmen, da diese nicht vorhanden ist. Unter gewissen einschränkungen könnte man das beim export automatisch machen, allerdings lassen die Weightpainting tools von Blender etwas extrem zu wünschen übrig (Nein ich kann mich nicht um alles kümmern) EIn sauberes gewichten ist nur dann möglich wenn man alle beinflussenden Bones auf einmal gemeinsam gewichten kann. Im Prinzip müsster es so ablaufen:
1. Vertices den Joints zurodnen
2. Grobes Painting in der Standart Pose teilweise aus den Bones erzeugen
3. Feiners Painting in der Maximal geänderten Pose durch verschieben der Vertice auf der gewichtung


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 26, 2006 15:50 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Nein, ich meine das anders: Du wirst von jedem Modeller ein Mesh hereinkriegen, das sich im Objektraum befindet. Es hilft daher nichts, ein spezielles Exporter Programm zu schreiben. Was Deine Bone/Joint-Transformationsmatrix leisten muss, ist, die Vertices des Mesh vom Objekt-Raum in den Bone-Raum zu bringen. Das ist ein Feature Deines Shaders, nicht des Blender-Exporters. Dafür brauchst Du auch keine zusätzlichen Variablen. Nur die Funktion, die die Transformationsmatrix herstellen soll, muss ein wenig erweitert werden.
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 26, 2006 16:28 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Das wäre ein falscher ansatz. Man soll niemal operationen im shader ausfüheren, die quasi statisch sind.
Eine Lerp- oder Slerpinterpolation ist auch keine einfache transformationsmatrix mehr.
Für die Iterpolation muss ein Reerenzpunkt (Der Joint) bekannt sein und diese information muss vom Editor geliefert werden (was das eigendliche Problem ist)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 26, 2006 17:48 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Aber Du brauchst doch grundsätzlich für die Vertices eine Transformationsmatrix? Ich arbeite nicht mit Shadern. Ich brauche pro Gelenk eine Transformationsmatrix. Das Mesh befindet sich im Objektraum, die Gelenkpositionen auch. Aber wenn ich die Vertices transformiere, brauche ich eine spezielle Transformationsmatrix, die die Vertices vom Objekt- in den Gelenkraum überführen. Müsste bei Dir das nicht ebenso sein? Ich meine jetzt mal abgesehen von der Slerp-Interpolierung.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 26, 2006 19:05 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Bei der Linearen Bone interpolation ist es auch so im Vertexshader. Prinzuipell kann es da auch die CPU die transformationen voher durchführen (Ist aber viel langsamer). Bei der Lerp interpolation gibt die Matrix nur noch die Richtung an, in die gedreht wird. Da da nur eine reine rotationsmatrix ist könnte man überlegen dort Quarternionen einzusetzten. Dann wäre sogar eine Slerp interpolation im Verteshader möglich (bessere Qualität wenn die Glenke mehr als 120 Grad bewegt werden)

Ob man im Veretexshader erst eine Matrix aus den verschienen Bonematrizen misch oder die transformierten Verices mischt muss man bei der Geschwindigkeit abwiegen. auf keien Fall sollte man aber Matrizen im Vertexshader miteinander Multiplizieren, da eine Matreix * Vektor multipülikation schneler geht als Matrix * Matrix. Also wird im Vertexshader auch erst vom Objekt in den Gelenkspace tranformier und erst dann in den Modelviewprojectionspace.
Denkbar wäre auch die Bonematrizen mit der gl ModelviewProjektionmatrix vor dem Rendern zu Multiplizieren, blos würden sich die Zusamengesetzten Matreizen nicht mehr auf 8 Floats komprimieren lassen, so das man keine 1000 Bonesmodelle verwenden könnte :P


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 26, 2006 20:20 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Ich berechne beim Rendervorgang keine Matrizen. Die jeweilige Matrix wird berechnet, wenn eine Bewegung stattfindet. Die Matrix, die sich für das betreffende Bone ergibt wird im Bone auch gespeichert. Das Rendern könnte dann eigentlich auch mit einem gewöhnlichen PushMatrix/PopMatrix stattfinden, wenn man den Bonebaum hinunterläuft. Das Problem dabei ist, dass es beim Abbiegen so hässlich ist. :(


Ach übrigens: ich durfte gestern das "Making Of" vom Film "Pirates of the Caribbean2" bewundern. Da wurde gezeigt, wie sie diesen Kerl mit den Fangarmen im Gesicht gemacht haben. Hast Du das gesehen? Ich würde sagen, was Du da grade machst, ist State of the Art. Hat verflixt nach Slerp ausgesehen. :D


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 26, 2006 23:19 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Ich hab es nicht gesehen. Allerdings weiß ich, das man in Maya das Mesh nachträglich korrigieren kann. Allerdings ist Maya wie all die anderen Modeler auf Animationen ausgelegt die nicht realzeittauglich sein müssen. Die Nutzung für den gamebereich ist da eher eine Zweckentfremdung.

Dein Bonesystem hat einige schlechte Eigenschafft: Es Jeder Vertex kann exakt nur einem Bone zugeordnet werden und die Matrix muss unter umständen nach jedem Vertex gewechselt werden. Ein Versuch mit einem Vertexshader würde da viele neues ermöglichen.
Laut einem englisch IRC channel müsste es möglich sein einen GLSL Vertexshader ohne Pixelshader zu verwenden. Dann sollte die Graka das komplette Bonesystem übernehmen. Es müssen nur alle Matrizen als Uniform array hochgeladen werden und die Gewichtungen und Abhängigkeiten per Atribute übergeben werden. Schau mal in den offlineartikeln im Wiki nach...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 26, 2006 23:39 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Normalerweise ist das doch so, dass jedem Punkt eine gewisse Anzahl von Matrizen mit jeweils einem bestimmten Gewicht zugeordnet ist. Wie die Matrizen auf der CPU berechnet werden ist davon unabhängig.

pos=0;
for(int i=0;i<n;i++)
{
pos += matrix[indices[i]] * vertex * weights[i];
}

Was willst du jetzt genau daran verbessern oder geht es dir eher um die Berechnung auf der CPU? Aus dem Text wird es nicht auf den ersten Blick deutlich.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 26, 2006 23:55 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Das ist die Lineare interpolation. Der letzte Post bezog sich auf Traudes Bonesystem.

Ich hab ein Bild konstruiert in dem Man den unterschied zwischen Liniear und Lerp sehen kann (attachment). DIe Blaue Varieante ist die alt bekannte, die Grüne ist bei konvexen Wölbungen besser und die Rot wäre denkbar um löcher im Spitzem Winkel zu füllen

http://cpux.de/base/bones_interpolate.png attachments gehen anscheinend gerade nicht oder es ist zu groß


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Dez 27, 2006 19:01 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Ach so ist das gemeint (1 Bild sagt mehr als 1000 Worte).


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Dez 27, 2006 19:44 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hallo,
Ich habe erst Anfang dieses Jahres begonnen, mich für Grafikprogrammierung zu interessieren. Mit Delphi/Pascal programmiere ich schon lange, nur OpenGl ist für mich Neuland gewesen. Da ich passionierter Zeichner bin, hatte ich mir folgendes Ziel gesteckt: ich wollte es schaffen, eine voll bewegliche Puppe (a la Sims) mit voll 3D beweglichen Gliedmassen zu coden, als Zeichenvorlage, schliesslich kann OpenGl toll die Körperschatten darstellen. Ich bin dabei bis zu den Bones gekommen und habe es geschafft, Gelenke (mit Limits) zu machen, die sich glaubhaft bewegen können. Ich habe zwar in der Datenstruktur für die MeshPoints vorgesehen, dass sie zu mehreren Joints zugeordnet werden können, aber habe das noch nicht implementiert (ein Zeitproblem). Dieses Ding ist jedenfalls nicht auf Schnelligkeit optimiert, weils mir mehr darum ging, zu verstehen, wie es gemacht wird. Aber für ein Spiel mit vielen 3D-Figuren ist das nicht geeignet.

oc2k1 ist weit darüber hinaus: er hat das ganze bereits mittels shaderprogrammierung gemacht und hat überlegt sich grade, wie man die herkömmliche, nicht so gute lineare Interpolation verbessern könnte, nämlich mit Slerp, eine Möglichkeit, das "Abknicken" des Mesh an den Gelenken zu verhindern. Und er kam auf auf ein Problem von dem ich irrigerweise ahnnahm, das es ganz einfach wäre und habe höchstwahrscheinlich völlig an der Sache vorbeigeredet. Aber ich konnte meinen Schnabel nicht halten weil ich unheimlich spannend finde, was er macht.

Und ich hatte mit eingebildet, diese Technik bei dem "Krakenmensch" aus dem Film "Pirates Of The Caribbean2" wiederzuerkennen. Solltet Ihr die Gelegenheit haben Euch die Zusatz-CD von dem Film ansehen zu können, dann seht Euch das "Making-Of" von diesem Krakenmensch an, ist wirklich sehenswert.
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Dez 29, 2006 02:41 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Ich bin am überlegen ob ich ein spezieles Programm zum Skinnen schreibe. Blender ist hier für meine Zwecke einfach nicht mehr geeignet. Eventuell wäre Maya eine alternative, bloss da hab ich noch nie wirklich was gemacht (und es fragt sich ob die PLE dafür ausreicht)
Eigendlich sollte sich der Aufwand in grenzen Halten da dass Mesh selbst nicht mehr modifiziert werden müsste und neben einem Boneobjekt fast nur Paintingtools eingebaut werden müssen... (Die Daten müssen einfach nur anders als in Blender organisiert werden damit ein vernümftiges Arbeten möglich ist...)


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ] 
Foren-Übersicht » Programmierung » Shader


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.023s | 17 Queries | GZIP : On ]