DGL https://delphigl.com/forum/ |
|
Verständnisfrage zur Matrix basierenden Boneanimation https://delphigl.com/forum/viewtopic.php?f=20&t=9337 |
Seite 1 von 1 |
Autor: | Mandelmann [ Do Jul 15, 2010 14:13 ] |
Betreff des Beitrags: | Verständnisfrage zur Matrix basierenden Boneanimation |
Hallo, im Tutorial Boneanimation per Vertexshader erschien mir der gezeigte Code des Vertexshader für die Matrix-Animation zunächst sinnvoll, aber beim Ausprobieren bin ich auf ein Problem gestoßen, welches ich nicht lösen kann. Nehmen wir an, ich möchte einen Charakter animieren. Für den linken Arm habe ich also einen einen Bone erstellt und alle Vertices des Arms mit dessen ID verknüpft. Die Gewichtung ist 1 und nimmt im Bereich der Schulter zum Körper hin auf null ab. Da sich der Arm nicht um den Nullpunkt drehen soll, habe ich die Matrix des Joints auf die Position in die Mitte der Schulter gelegt (matrix-translations-werte 12,13,14) und ziehe diese Koordinate nach der Multiplikation der Vertices mit der Matrix wieder ab, so dass die Translation wieder Rückgängig gemacht wird, da ich nur eine Drehung um den Drehpunkt "Schulter" haben möchte. Das funktioniert so weit. Allerdings werden alle Vertices mit Gewichtung kleiner 1 um einen falschen Drehpunkt gedreht, da dieser in der Zeile Zitat: mat += Pose[int(Bones[i])] * fract(Bones[i]); ebenfalls nur anteilig verwendet wird, d.h. der Drehpunkt ist bei einer Gewichtung 0.5 in der Mitte zwischen Schulter und Nullpunkt, also irgendwo in der Bauchgegend meines virtuellen Charakters und dies sieht nicht sehr natürlich aus... Was mache ich falsch? |
Autor: | Coolcat [ Do Jul 15, 2010 15:14 ] |
Betreff des Beitrags: | Re: Verständnisfrage zur Matrix basierenden Boneanimation |
Spontane Idee: Würde ein doppelter Bone funktionieren? Also quasi den Bone an der Position des Drehpunktes doppelt auslegen. Einmal mit Rotation und einmal ohne. Dazwischen sollte sich dann interpolieren lassen. (Ich habe von Boneanimation keine Ahnung...) |
Autor: | Traude [ Fr Jul 16, 2010 00:20 ] |
Betreff des Beitrags: | Re: Verständnisfrage zur Matrix basierenden Boneanimation |
Hmmm, leider hast Du keinen Sourcecode gepostet. Also schaun wir mal (es ist allerdings ein Uhr morgens - möglicherweise verhack ich's) Man nehme den Vertex und multipliziere ihn einmal mit Matrix1 und einmal mit Matrix2: das ergibt VertexNew1 und VertexNew2. Der endgültige Vertex ergibt sich dann so: VertexFinal = (VertexNew1 * Weight1) + (VertexNew2 * Weight2) wobei Weight1 und Weight2 jeweils Werte zwischen 0 und 1 sein müssen und außerdem gilt Weight1 + Weight2 = 1 Sollte eigentlich so funktionieren. |
Autor: | Coolcat [ Fr Jul 16, 2010 07:45 ] |
Betreff des Beitrags: | Re: Verständnisfrage zur Matrix basierenden Boneanimation |
@Traude: Zitat: Hmmm, leider hast Du keinen Sourcecode gepostet. Der steht im verlinkten Tutorial. Und da affine Matrizen eine lineare Operation sind, kann man auch einfach die Matrizen interpolieren, wie das im Tutorial auch schon gemacht wird. |
Autor: | Traude [ Fr Jul 16, 2010 10:33 ] |
Betreff des Beitrags: | Re: Verständnisfrage zur Matrix basierenden Boneanimation |
Coolcat hat geschrieben: Und da affine Matrizen eine lineare Operation sind, kann man auch einfach die Matrizen interpolieren Nein, man kann nicht. Das ist keine mathematisch korrekte Methode. Der Threadstarter hatte ja z.B. auch Schwierigkeiten damit. Google mal nach "interpolate matrices", da wirst Du von einschlägigen Informationen fast erschlagen.Zur angesprochenen Wiki-Quelle: wenn das dort wirklich so drinsteht, macht es das auch nicht richtiger. Manchmal stehen im Wiki eben auch Dinge drin, die nicht richtig sind, das geht auch der Wikipedia so. Ich zitiere auch eine Quelle, allerdings in Englisch, und ich kann auch keinen direkten Link angeben, sondern Du musst danach googeln, denn es ist ziemlich tief verschüttet im Citeseer(ein direkt herunterladbares PDF): "Skinned Mesh Character Animation with Direct3D" . Nicht mehr das Neueste, aber eine sehr gute Info, insbesondere von jemandem, der sich jeden Tag damit beschäftigt und der das Ganze nicht nur als Hobby betreibt. Siehe insbesondere der blaue Kasten auf Seite 9. |
Autor: | Coolcat [ Fr Jul 16, 2010 12:00 ] |
Betreff des Beitrags: | Re: Verständnisfrage zur Matrix basierenden Boneanimation |
Zitat: Nein, man kann nicht. Das ist keine mathematisch korrekte Methode. Öh, doch? Bei einer affinen Matrix (also keine Projektion bzw. perspektivische Division) ist das durchaus möglich. M und N sind die Matrizen v ist der ursprüngliche Vertex, v' der transformierte und interpolierte a,b sind die Gewichte Du hast da folgendes: Code: v' = Mv * a + Nv * b <=> v' = a * Mv + b * Nv //erlaubt denn a,b sind Skalare <=> v' = (aM)v + (bN)v // nur anders geklammert <=> v' = (aM + bN)v // Matrix-Multiplikation erfüllt Distributivgesetz Eine perspektivische Division macht das Distributivgesetz natürlich kaputt, aber die wird hier auch nicht benutzt. Das Problem des Fragenstellers ist das er die falsche Matrix (falscher Drehpunkt) zum interpolieren verwendet. Auch ist die Matrix-Interpolation vielleicht nicht immer die Operation die man eigentlich haben will. Also z.B. ist die Interpolation zwischen Einheitsmatrix und einer Rotationsmatrix keine Rotation um den halben Winkel. Im Tutorial werden ja nicht grundlos die Quaternions erwähnt. |
Autor: | Traude [ Fr Jul 16, 2010 12:48 ] |
Betreff des Beitrags: | Re: Verständnisfrage zur Matrix basierenden Boneanimation |
Zitat: v' = Mv * a + Nv * b Das bestreit ich energisch. So hab ich das nicht geschrieben. Ich hatte zwei "Zwischen"-Vertices, die ich getrennt mit je einer Matrix multipliziert habe. Der Ergebnisvertex ist dann eine Interpolation der beiden "Zwischen"-Vertices. Genau das ist ja der springende Punkt.<=> v' = a * Mv + b * Nv //erlaubt denn a,b sind Skalare Zitat: <=> v' = (aM)v + (bN)v // nur anders geklammert Hier machst Du etwas mathematisch Unzulässiges. Die Matrix vorher mit einem Skalar zu verändern, hat einen erheblichen Einfluss auf die zugehörige Rotationsachse, die in der Matrix drinsteckt. Anders ausgedrückt: Du zerstörst damit Deine affine Rotationsmatrix.Wenn man das macht, wächst das transformierte Bone zu einem ungeheuren Ding an. Denselben Effekt kann man z.B. auch mit Quaternionen erzeugen, wenn es nämlich kein Einheitsquaternion ist. Sieht sehr lustig aus, aber glaub mir: so eine Transformation willst Du nicht wirklich haben. Die Multiplikation der Matrix mit dem Vektor darf nicht auseinandergenommen werden. Ich bin kein Mathematiker, aber das ist so etwas Ähnliches als ob Du schreiben würdest: a*x² = (a*x)². Hier kann man nicht ganz einfach anders klammern. |
Autor: | Sellmann [ Fr Jul 16, 2010 13:29 ] |
Betreff des Beitrags: | Re: Verständnisfrage zur Matrix basierenden Boneanimation |
Ich stimme da Traude durchaus zu, denn wenn man zwei Matrizen jeweils um einen Faktor skaliert, und dann beide zusammen rechnet um die beiden Faktoren wieder zu '1' zusammen zu Summieren, so muss nicht automatisch gegeben sein, dass alle Spalten ebenfalls eine Länge von 1 haben nach der Addition. Das ist der springende Punkt. die Richtung der Spalten wird höchstwahrscheinlich stimmen, aber die Länge ist nicht mehr normiert, dadurch entsteht der Effekt, dass zusätzlich zur Rotation der Vertices eine Skalierung stattfindet, die die Vertices zum Ursprung wandern lässt. |
Autor: | Coolcat [ Fr Jul 16, 2010 13:58 ] |
Betreff des Beitrags: | Re: Verständnisfrage zur Matrix basierenden Boneanimation |
@Traude & Sellmann: Ich denke wir klären gerade mal über private Nachrichten wer den nun recht hat. Ich bin mir eigentlich verdammt sicher das ich Recht habe....aber ihr beide offensichtlich auch. Wir müssen Mandelmann ja jetzt nicht noch mehr verwirren. |
Autor: | mrtrain [ Fr Jul 16, 2010 14:26 ] |
Betreff des Beitrags: | Re: Verständnisfrage zur Matrix basierenden Boneanimation |
Back to Topic: Ich glaube ein doppelter Bone würde nicht zum gewünschten Ergebnis führen. Denn das Duplikat müsste dann ja die Gewichtung 1.0 - fract(Bones[0]) haben. Die würde auch für seine (nicht vorhandene) Rotation gelten. Die Gewichtung sollte ja eigentlich ein zweiter Bone mit Rotation bekommen - im Endeffekt würde ein doppelter Bone glaube ich nur zu unerwünschter Skalierung führen. So wie ich den Vertexshader-Code verstehe, ist er wohl nicht ganz korrekt. Ich bin allerdings auch kein Pro in sowas, eigentlich müsste der Autor dieses Wiki-Artikels dir weiterhelfen können (laut History Andreas). Da der Artikel gerade offline bearbeitet wird (von wem eigentlich?), ist die Wahrscheinlichkeit gar nicht gering, dass er Fehler enthält. Bei mir läuft die Bone-Animation noch auf der CPU. Da löse ich das so, dass ich für die Rotation grundsätzlich nur 3x3 Matrizen verwende. Vor der Multiplikation mit dieser ziehe ich vom Vertex den Drehpunkt "manuell" ab und addiere ihn danach wieder - und siehe da, es funktioniert. ![]() Ich weiß, ich bin ein schlechter Erklärer, also einfach nachfragen, wenn hier jemand was nicht versteht. ![]() mrtrain |
Autor: | Mandelmann [ Fr Jul 16, 2010 14:49 ] |
Betreff des Beitrags: | Re: Verständnisfrage zur Matrix basierenden Boneanimation |
Der Tipp von Traude funktioniert: Erst die Vertices berechnen und dann gewichten. Für den Fall, dass der Drehpunkt nicht der Ursprung ist, mache ich es so wie mrtrain geschrieben hat: Den Drehpunkt abziehen, drehen und dann wieder addieren. Im neuen Shader sieht es jetzt folgendermaßen aus: Code: vec4 rotationPoint0 = vec4(matBone0[3]); vec4 rotationPoint1 = vec4(matBone1[3]); vec4 vecBone0 = matBone0 * (gl_Vertex - rotationPoint0); vec4 vecBone1 = matBone1 * (gl_Vertex - rotationPoint1); vec4 transformedVec = (vecBone0 + rotationPoint0) * weight0) + (vecBone1 + rotationPoint1) * weight1); Was ich aber noch nicht verstehe: Ich hätte erwartet, dass durch die Multiplikation mit den Bone-Matrixen die Vertices wieder zum Drehpunkt hin verschoben werden, da die Translation in den Matrixen enthalten ist? Da dies aber nicht der Fall ist, addiere ich den Drehpunkt bei der Gewichtung einfach nochmal. |
Autor: | Coolcat [ Fr Jul 16, 2010 16:09 ] |
Betreff des Beitrags: | Re: Verständnisfrage zur Matrix basierenden Boneanimation |
Zitat: Ich hätte erwartet, dass durch die Multiplikation mit den Bone-Matrixen die Vertices wieder zum Drehpunkt hin verschoben werden, da die Translation in den Matrixen enthalten ist? Sowohl gl_Vertex als auch rotationPoint0 sind vierdimensional, bei beiden steht eine Eins in der letzten Komponente. Diese beiden Einsen ziehst du von einander ab, das gibt eine Null. Wegen dieser Null wird die Translation nicht angewendet. Also so müsste es gehen: Code: vec4 vecBone0 = matBone0 * (gl_Vertex - vec4(rotationPoint0.xyz, 0.0));
|
Autor: | Mandelmann [ Sa Jul 17, 2010 15:46 ] |
Betreff des Beitrags: | Re: Verständnisfrage zur Matrix basierenden Boneanimation |
Richtig, danke sehr. Jetzt werde ich noch dasselbe prozedere für die Normalen-Vektoren einfügen und dann sollte mein Bone-Animation-Vertexshader fertig sein. Danke an alle für die aufschlussreichen Kommentare! |
Seite 1 von 1 | Alle Zeiten sind UTC + 1 Stunde |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |