[GLSL] Bone Weights Attribute

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
Jonathan
Establishment
Beiträge: 2390
Registriert: 04.08.2004, 20:06
Kontaktdaten:

[GLSL] Bone Weights Attribute

Beitrag von Jonathan »

Ich möchte einen VertexShader für Skelettanimationen schreiben. Dafür brauch ich ja irgendwie die Bone Wieghts als per-Vertex Attribut. Das sieht bei mir auf C++ Seite derzeit so aus:

Code: Alles auswählen

	unsigned int Id[BONE_COUNT];///< IDs for a bone in the skeleton
	float Value[BONE_COUNT];///< the Weight for this bone
(BONE_COUNT ist eine Konstante mit dem Wert 4).

Im VertexShader soll das ganze irgendwie so aussehen:

Code: Alles auswählen

attribute unsigned int WeightIdsAtt[4];
attribute float WeightValuesAtt[4];
Den Vertexbuffer befülle ich dann also mit meinen Daten und kopiere ihn hoch, soweit sollte alles stimmen. Wenn ich jetzt aber die Attribute binden möchte:

Code: Alles auswählen

	GLint WeightIdLocation	= glGetAttribLocation(ShaderProgram, "WeightIdsAtt");
	GLint WeightValueLocation=glGetAttribLocation(ShaderProgram, "WeightValuesAtt");

	glEnableVertexAttribArray(WeightIdLocation);
	glVertexAttribPointer(WeightIdLocation, 4, GL_FLOAT, GL_TRUE, m_VertexSize, (void*)m_WeightsOffset);
	glEnableVertexAttribArray(WeightValueLocation);
	glVertexAttribPointer(WeightValueLocation, 4, GL_FLOAT, GL_TRUE, m_VertexSize,
		(void*)(m_WeightsOffset+sizeof(unsigned int)*4));
knallt es bei glEnableVertexAttribArray, weil WeightIdLocation ein invalid value ist. Die Namen sollten ja passen, der zweite spontane Gedanke war, dass ich die Weights im Shader nicht benutze und er sie wegoptimiert. Das sollte aber beides nicht der Fall sein.

Ich hab ein bisschen gelesen, aber finde keine genauen Infos: Gibt es Probleme mit Arrays als Attributvariablen? Oder mit unsigned int als Typ? Wenn ja, wie soll ich das umgehen, ich brauch ja irgendwie einen Arrayindex, um auf die Richtige BoneMatrix zuzugreifen (die dann später noch kommt). Also gibt es diesbezüglich prinzipielle Einschränkungen?
Und: Kann man das optimieren von Shadern irgendwie deaktivieren? Könnte zum Testen ab und zu nützlich sein.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
kristof
Beiträge: 92
Registriert: 19.01.2009, 13:05

Re: [GLSL] Bone Weights Attribute

Beitrag von kristof »

Bist du denn sicher, dass Arrays von Attributes überhaupt erlaubt sind in glsl? Mir wäre das neu. Du könntest mal gucken ob WeightIdLocation überhaupt einen sinnvollen Wert annimmt.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2390
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: [GLSL] Bone Weights Attribute

Beitrag von Jonathan »

Nein, ich bin mir nicht sicher ob das geht.

Und nein, die Location ist -1. Wenn ich keine Array nehmen kann, wie greif ich dann auf die richtige Matrix zu? Ich meine, dann müsste ich ja schreiben:

Code: Alles auswählen

if(BoneId1==1)
 //use matrix 1
elseif( 2..)
...
Und das ganze 4 mal, für 4 BoneWeights. So viele Abfragen hört sich furchtbar viel an für einen Shader und es schreibt sich auch wesentlich blöder.

Naja, ich such mal, ob ich eine GLSL Vertex Skinning Demo finde.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
kristof
Beiträge: 92
Registriert: 19.01.2009, 13:05

Re: [GLSL] Bone Weights Attribute

Beitrag von kristof »

Ich hab selber auch noch nie skinning implementiert, aber die Anzahl der auf einen Vertex Einfluss nehmenden Bones sollte ja sehr begrenzt sein. Man könnte die Attributes ja auch fest einbauen.

Code: Alles auswählen

attribute float WeightValuesAtt0;
attribute float WeightValuesAtt1;
...
attribute mat4 BoneMatrix0;
attribute mat4 BoneMatrix1;
...
Der Algorithmus wäre dann halt recht unflexibel was Änderungen bezüglich der Anzahl der Bones pro Vertex angeht. Ausserdem weiss ich auch nicht wie einem die Skinning Daten üblicherweise so vorliegen. Das könnte also Mehraufwand beim laden bedeuten.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2390
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: [GLSL] Bone Weights Attribute

Beitrag von Jonathan »

Naja, die Sache ist ja, mein Modell hat meinetwegen 25 Bones, jeder Vertex soll aber nur durch 4 beeinflusst werden. Jetzt render ich eben alles in einem Rutsch (bzw. will), setze die 25 Bone-Matrizen als Uniform und übergebe jedem Vertex als Attribut 4 Bone Wieghts und 4 Bone IDs. Die BoneIds geben an, welche Matrix ich benutzen muss. Und wenn ich da nicht mit Arrays und Indexen arbeiten kann, wie soll ich dann für 25 Bones immer die richtige Uniformvariable benutzen? Und was ist, wenn ich 30 hab?
Also, die Arrays müssen ja nicht dynamsich oder so sein, ich generiere die Shader eh im Code, von daher bin ich da ein wenig flexibel. Aber ich will halt echt keine riesigen Abfrageblöcke einbauen.

[edit]Ich habe hier einen Beispielcode gefunden: http://www.gamedev.net/topic/390581-gls ... e-problem/
Da werden einfach vec4's statt Arrays benutzt. Aber von Beispielcode abzuschreiben ist ja auch nicht immer optimal, vielelicht meldet sich ja hier noch ein GLSL Experte, der mir ein bisschen was über die Hintergründe erzählen kann. Ich meld mich, wenn ich die vec4 Variante getestet habe.[/edit]
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [GLSL] Bone Weights Attribute

Beitrag von Artificial Mind »

Die Bone Matrizen sind doch eh als uniforms drin, also z. B.

Code: Alles auswählen

mat4 boneMatrices[MaxBones];

Wenn du dann pro Vertex deine

Code: Alles auswählen

attribute int boneId1;
attribute int boneId2;
attribute int boneId3;
attribute int boneId4;

attribute float boneWeight1;
attribute float boneWeight2;
attribute float boneWeight3;
attribute float boneWeight4;
hast,
dann musst du doch nur noch folgendes machen:

Code: Alles auswählen

mat4 boneMatrix = 
  boneMatrices[boneId1] * boneWeight1 +
  boneMatrices[boneId2] * boneWeight2 +
  boneMatrices[boneId3] * boneWeight3 +
  boneMatrices[boneId4] * boneWeight4;
(bzw. bessere Interpolation)
oder sehe ich da grade was falsch?
kristof
Beiträge: 92
Registriert: 19.01.2009, 13:05

Re: [GLSL] Bone Weights Attribute

Beitrag von kristof »

Achso, dann kannst du ja die Bone Matrizen als uniform übergeben, da sie global für alle Vertices die gleichen sind. Mit uniforms funktionieren Arrays meines Wissens nach nämlich. Pro Verhex, also in Form eines Attributes, musst du dann nur die jeweiligen IDs und Gewichte der relevanten Bones übergeben. Das kannst du dann über Vektoren oder wie in meinem letzten Beispiel machen.
Edit: Da war ich wohl zu langsam ;)
Benutzeravatar
Jonathan
Establishment
Beiträge: 2390
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: [GLSL] Bone Weights Attribute

Beitrag von Jonathan »

@Artificial Mind: Danke, das macht so natürlich Sinn. Irgendwie hatte ich bei meinem erste Pseudocodeentwurf die Attribute auch alle als Arrays, weil ich dann über alle 4 Weights eine Schliefe machen könnte. Aber bei 4 Stück die gerade aufrollen ist ja kein Thema, würde der Compiler dann wohl sowieso machen. Und dann bin ich wohl irgendwie durcheinander gekommen, und hab nicht gemerkt, dass "Arrays gehen nicht bei Attributen" und "Ich brauche Arrays für die Matrizen" kein Widerspruch ist, bzw. es als "Ich brauche Arrays, die gehen aber nicht" zusammengefasst.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Antworten