.[ ČeskéHry.cz ].
Skeletální animace+VBO+GLSL
Jdi na stránku 1, 2, 3  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> 3D API / 3D Enginy
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
HonzikJ



Založen: 04. 02. 2010
Příspěvky: 21

PříspěvekZaslal: 25. březen 2011, 11:10:32    Předmět: Skeletální animace+VBO+GLSL Odpovědět s citátem

Zdravím,

řeším teď skeletální animace. Načítám model z MS3D. Zatím tak, že pro každý joint mám vlastní matici (zhruba takto):

struct joint
{
..
CMatrix4f matrix;
}

a potom přes CPU všechno propočítám a provedu interpolace a animace.

Nyní bych to chtěl předělat přes VBO a transformaci bych pak prováděl ve Vertex Shaderu. Spíš bych řekl, že myšlenkovitě vím co udělat, ale nemám až příliš zkušenosti s shadery (akorát nějaký to texturování, bump,...).

Jak to zatím řeším:
1. Vytvořím si VBO, zatím do něj cpu jen vertexy
2. vykresluji VBO(ten shader zatím co tam mám pouze vybarví na červeno:-), abych ověřil funkčnost):

X3D_ShaderManager::GetIntance()->GetShader("pokusShader")->Bind();

glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, this->m_uiVBOvertices);
glVertexPointer(3, GL_FLOAT, 0, (char*)NULL);
glDrawArrays(GL_TRIANGLES, 0, this->m_usNumVerts);
glDisableClientState(GL_VERTEX_ARRAY);

X3D_ShaderManager::GetIntance()->GetShader("pokusShader")->UnBind();

Tak a teď nevím co dál. Myslím si, že bych měl předat všechny matice jointů do vertex shaderu:
VERTEX SHADER:
uniform mat4 boneMatrix[MAX_BONE];

Ale nevím jak(zatím ty matice mám rozdělené po jedné), tak jestli je nějak složit a pak předat jako celek do pole boneMatrix, nebo v nějakém for cyklu předat je po jedné do pole v shaderu. Ale technicky nevím jak by se to po jedné předávalo a zase skládat všechny matice do jednoho pole mi příjde taky divné.

Pomocí CPU pak provádím transformaci takto:

Joint * pJoint = &m_pJoints[pVert->m_cBone];
vecVertex = pVert->m_vVert;
vecVertex = pJoint->m_matFinal * vecVertex;

Čili získávám index jointu, ke kterému je přiřazen vertex. Pokud bych vykresloval po trojúhelníkách tak bych to do shaderu nacpat uměl, ale když to pak vykresluji přes VBO(jak ukazuji výše), tak nevím jak ten index předat.

Moc děkuji za všechny rady, už si s tím lámu hlavu pár dní, takže budu vděčný za pomoc. Díky, Honzík
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Poky



Založen: 29. 06. 2009
Příspěvky: 184
Bydliště: Písek / Plzeň

PříspěvekZaslal: 25. březen 2011, 13:42:01    Předmět: Odpovědět s citátem

Já osobně bych matice převedl na quaternion (místo matice 4x4 dostaneš pouze 7 hodnot(3 pro pozici a 4 pro natočení)) a ten teprve posílal do shaderu Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
]semo[



Založen: 29. 07. 2007
Příspěvky: 1526
Bydliště: Telč

PříspěvekZaslal: 25. březen 2011, 14:14:00    Předmět: Re: Skeletální animace+VBO+GLSL Odpovědět s citátem

HonzikJ napsal:
Čili získávám index jointu, ke kterému je přiřazen vertex. Pokud bych vykresloval po trojúhelníkách tak bych to do shaderu nacpat uměl, ale když to pak vykresluji přes VBO(jak ukazuji výše), tak nevím jak ten index předat.


Jakkoliv, buť glVertexAttribPointer, ale nejjednodužší bude, když do shaderu pošleš 4 složkový vertex - [X, Y, Z, index], místo obyč. [X, Y, Z]. Tzn. do VBO nacpeš tyhle "větší" vertexy a v shaderu přistupuješ k indexu jako (gl_Vertex.w), používáš-li gl_Vertex.
_________________
Kdo jede na tygru, nesmí sesednout.
---
http://www.inventurakrajiny.cz/sipka/
Aquadelic GT, Mafia II, simulátory
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
HonzikJ



Založen: 04. 02. 2010
Příspěvky: 21

PříspěvekZaslal: 25. březen 2011, 14:17:41    Předmět: Odpovědět s citátem

citace:

Já osobně bych matice převedl na quaternion (místo matice 4x4 dostaneš pouze 7 hodnot(3 pro pozici a 4 pro natočení)) a ten teprve posílal do shaderu


Ano, tak jsem to zkoušel taky nicméně stále mám ten stejný technický problém jak to do shaderu posílat.
Vlastně jsem to měl tak, že jsem měl pro každý joint quaternion (čili jako ta matice) a do shaderu jsem chtěl posílat quaternion + pozici, de bych udělal matici a pronásobil to. Ale problém mám v tom, že nevím jak to tam naposílat, tzn, jak tam poslat(třeba těch 50 kvaternionů + 50 pozic), a potom při vykreslování přes VBO index jointu, ke kterému patří daný vertex.


Naposledy upravil HonzikJ dne 25. březen 2011, 14:24:27, celkově upraveno 1 krát
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
HonzikJ



Založen: 04. 02. 2010
Příspěvky: 21

PříspěvekZaslal: 25. březen 2011, 14:22:20    Předmět: Re: Skeletální animace+VBO+GLSL Odpovědět s citátem

]semo[ napsal:
HonzikJ napsal:
Čili získávám index jointu, ke kterému je přiřazen vertex. Pokud bych vykresloval po trojúhelníkách tak bych to do shaderu nacpat uměl, ale když to pak vykresluji přes VBO(jak ukazuji výše), tak nevím jak ten index předat.


Jakkoliv, buť glVertexAttribPointer, ale nejjednodužší bude, když do shaderu pošleš 4 složkový vertex - [X, Y, Z, index], místo obyč. [X, Y, Z]. Tzn. do VBO nacpeš tyhle "větší" vertexy a v shaderu přistupuješ k indexu jako (gl_Vertex.w), používáš-li gl_Vertex.


Takže já tam pošlu třeba quaternion 4 složky, pozici 3 složky X,Y,Z a k tomu přihodím ještě W jako index? To mě nenapadlo, to hned zkusím. A nevíte ještě jak tam předat ty pole kvaternionů (nebo matic) nějak hromadně? Já vím, že tam jde jako přes funkce vvkládat pole, ale problém je, že mám ty matice, popřípadě kvaterniony rozdělené vždy ke každému jointu, jak píši výše.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Vilem Otte



Založen: 18. 09. 2007
Příspěvky: 462
Bydliště: Znojmo - Sedlesovice, Kravi Hora

PříspěvekZaslal: 25. březen 2011, 14:28:43    Předmět: Odpovědět s citátem

Mno, já naopak quaternion + vektor (není to jen quaternion) moc pro skeletální animace nedoporučuju (určitě ne do začátků), udělají v tom celkem zmatek a celý model docela zkomplikují (pak si člověk sice může dovolit dual quaternion skinning, ale je to už docela těžké na implementace a matice už jsou rychlejší).
_________________
Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail Zobrazit autorovi WWW stránky
nou



Založen: 28. 07. 2007
Příspěvky: 1047

PříspěvekZaslal: 25. březen 2011, 14:41:51    Předmět: Odpovědět s citátem

len daj pozor a v shadery pred tranformaciou prepis ten W index na 1.0.

a ked budes mat uniform mat4 bones[MAX_BONES] tak potom ich nahras proste cez glUiformMatrix4fv("bones", MAX_BONES, false, bones);
_________________
Najjednoduchšie chyby sa najtažšie hľadajú.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
]semo[



Založen: 29. 07. 2007
Příspěvky: 1526
Bydliště: Telč

PříspěvekZaslal: 25. březen 2011, 14:43:41    Předmět: Odpovědět s citátem

Vilem Otte: souhlas. Pokud by ale Honzik chtěl přesto do shaderu posílat méně dat pro rotaci, může použít trik, který tu někdo na fóru před časem popisoval:

Když nebude mít scale, tak bázové vektory v transformační matici jsou jednotkové. Proto může poslat jen dvě složky vektoru a třetí dopočítat (ví, že délka je 1). Navíc ty tři vektory jsou na sebe kolmé, takže může poslat jen dva a třetí dopočítat cross-produktem. Takhle může mít pro rotaci jen 4 čísla, ale neni to quaternion.

Honzik: zjisti pozice prvků pole v shaderu pomocí glGetUniformLocation(program, "pole[0]");
glGetUniformLocation(program, "pole[1]");
...
viz http://www.opengl.org/wiki/GLSL_Uniform

EDIT: co píše nou, se zdá být lepší
_________________
Kdo jede na tygru, nesmí sesednout.
---
http://www.inventurakrajiny.cz/sipka/
Aquadelic GT, Mafia II, simulátory
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
HonzikJ



Založen: 04. 02. 2010
Příspěvky: 21

PříspěvekZaslal: 25. březen 2011, 14:58:55    Předmět: Odpovědět s citátem

nou napsal:
len daj pozor a v shadery pred tranformaciou prepis ten W index na 1.0.

a ked budes mat uniform mat4 bones[MAX_BONES] tak potom ich nahras proste cez glUiformMatrix4fv("bones", MAX_BONES, false, bones);


No já to mám takto:

VERTEX SHADER:
uniform mat4 bone[MAXBONE];
.
.
takže teď když mám v GL render, tak přidám toto:
glUiformMatrix4fv("bone", MAXBONE, false, bones) no a to bones je vlastně pole matic, ale všech ne? To znamená, že já ty matice naskládám do jednoho pole?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
nou



Založen: 28. 07. 2007
Příspěvky: 1047

PříspěvekZaslal: 25. březen 2011, 15:32:52    Předmět: Odpovědět s citátem

presne proste budes mat v C kode float bones[MAXBONE*16]; len si treba dat pozor na maximalny pocet uniform premennych.
_________________
Najjednoduchšie chyby sa najtažšie hľadajú.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
HonzikJ



Založen: 04. 02. 2010
Příspěvky: 21

PříspěvekZaslal: 25. březen 2011, 15:41:02    Předmět: Odpovědět s citátem

OK tak zatím všem děkuji, zkusím se na to vrhnout a uvidím jak to půjde, popřípadě se opět ozvu. Myslím ale, že jsem získal všechny informace, které jsem potřeboval Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
HonzikJ



Založen: 04. 02. 2010
Příspěvky: 21

PříspěvekZaslal: 26. březen 2011, 13:56:07    Předmět: Odpovědět s citátem

Tak kupodivu mi to nefunguje Very Happy.

Postupuji, tak jak jste mi poradili, čili do vertexu jako atribut w předávám index joint matice:


CVector4* v_Temp = new CVector4[this->m_usNumTriangles*3];

int index = 0;
for(int i=0; i<this->m_usNumMeshes; i++)
{
for(int j=0; j<this->m_pMeshes[i].m_usNumTris; j++)
{
ModelTriangle *pTri = &m_pTriangles[m_pMeshes[i].m_uspIndices[j]];
for(int v=0; v<3; v++)
{
ModelVertex * pVert = &m_pVertices[pTri->m_usVertIndices[v]];

v_Temp[index].x = pVert->m_vVert.x;
v_Temp[index].y = pVert->m_vVert.y;
v_Temp[index].z = pVert->m_vVert.z;
v_Temp[index].w = pVert->m_cBone;

index++;
}
}
}

glGenBuffersARB(1, &this->m_uiVBOvertices);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->m_uiVBOvertices);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, this->m_usNumTriangles * 3 * 4 * sizeof(float), v_Temp, GL_STATIC_DRAW_ARB);

delete [] v_Temp;
v_Temp = NULL;

a dále ze všech matic utvořím jedno pole, které předávám do shaderu:

int loc = glGetUniformLocation(X3D_ShaderManager::GetIntance()->GetShader("pokusShader")->GetIDprogram(), "bone");
glUniformMatrix4fv(loc, 92, false, this->m_Matrix);

v Shaderu to pak akorát pronásobím:

const int MAXBONE = 92;
uniform mat4 bone[MAXBONE];

void main(void)
{
mat4 curMatrix = bone[gl_Vertex.w];
gl_Vertex.w = 1.0;
gl_Position = gl_ModelViewProjectionMatrix * curMatrix * gl_Vertex;
}

Zatím jsou nastaveny jen jednotkové matice, čili mělo by to vykreslit pouze model, animace ještě nedělám. Na CPU to takto funguje, ale jak to pošlu přes shader dějí se na obrazovce velmi zajímavé věci.

Nevidíte tam nějakou chybu, prosím?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
nou



Založen: 28. 07. 2007
Příspěvky: 1047

PříspěvekZaslal: 26. březen 2011, 14:43:15    Předmět: Odpovědět s citátem

ked odstranis tu curMatrix z nasobenia tak sa to nejak prejavy?

zisiel by sa screenshot co to roby. su modely rozbite ako keby len zmet trojuholnikov?
_________________
Najjednoduchšie chyby sa najtažšie hľadajú.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
HonzikJ



Založen: 04. 02. 2010
Příspěvky: 21

PříspěvekZaslal: 26. březen 2011, 14:56:14    Předmět: Odpovědět s citátem

Ano když odstrraním curMatrix projeví se to tak, že je to takový malý shluk trojúhelníku v malé oblasti.
Zatímco když tam nechám tu matici, tak je to o dost větší shluk trojúhelníku, který se při pohybu výrazně problikává a zdá se, že také transformuje.

ALE když renderuju přes cpu a odstraním násobení matic před vykreslením, tak se defacto jedná o tu samou věc, jakokdyž při vykreslování odstraním tu curMatrix, a ve výsledku se jedná zřejmě spíš o rozbití modelu, čili výsledek je jiný než když odstraním curMatrix ze shaderu.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
HonzikJ



Založen: 04. 02. 2010
Příspěvky: 21

PříspěvekZaslal: 26. březen 2011, 16:27:11    Předmět: Odpovědět s citátem

Objevil jsem dvě chybičky, zřejmě.

1. přepsal jsem v renderu
glVertexPointer(3, GL_FLOAT, 0, (char*)NULL);
na
glVertexPointer(4, GL_FLOAT, 0, (char*)NULL);

páč posílám vlastně ještě do w jako index.

2. když jsem vyráběl to pole z matic, tak jsem je podsouval transponované, takže jsem změnil indexy.

No a výsledek? Very Happy Opět zajímavý; renderuje mi to hlavu a kousíček (možná ramena) což teďka absolutně nechápu.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> 3D API / 3D Enginy Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2, 3  Další
Strana 1 z 3

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna