Warsztat.GD

Programowanie => Programowanie grafiki => OpenGL => Wątek zaczęty przez: .:NOXY:. w Grudzień 30, 2009, 15:57:04

Tytuł: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: .:NOXY:. w Grudzień 30, 2009, 15:57:04
Napotkałem sie podczas tworzenia dosc duzej mapy do gry na ciekawe zjawisko jest mi ono bardzo nie na reke wiec chciał bym sie dowiedziec czy ktos kiedys miał taki probelm i czy mozna go jakos roziwazac

Załozenia :

Optymalizacja sceny poprzez Frustrum Culling oraz usuwanie geometrii widzialnej gdy ta przekroczy widocznosc Level of Detail.

Technika:

Jezeli model nie jest widoczny w frustum badz znajduje sie w odleglosci 700m od kamery zaprzestan rysowania , Aby wszystko miało rece i nogi modele , textory , shadery sa wspoldzielone co to oznacza ze kazdy kolejny obiekt stworzony na scenie jest instancja Raz juz zaladowanego otrzymuje tylko jego geometrie oraz cialo ficzne nowa jest tylko pozycja oraz ew rotacja

Zakładamy rowniez ze dla potrzeby testow Wylaczamy generowanie Level Of Detail tak wiec gdy Obiekt pojawi sie w zakresie widocznosci badz w Frustrum Rozpoczynamy Jego rysowanie.

I tutaj pojawia sie moj probelm o ile min jednka instancja modelu jest widoczna gdzies w obszarze widocznosci to nie powoduje to spadku FPS badz drasycznego zwieszenia sceny
Problem pojawia sie gdy mam model ktory ma tylko 1 instancje przykladowo Auto albo 5 samochodow roznego typu Skoro nie uzywamy LOD powiedzmy ze mamy do naglego wyrenderowania 50k Vertow (10k na model) no i tu pojawia sie dramat

W efekcie takiego zagrania dostaje niesamowity ziwech sceny na 1sek czasami 2 co jest nie do pomyslenia Domyslam sie iz wywolane jest to dziwnym cachowaniem geometrii w karcie czy
ktos jest w stanie mi powiedziec jak ten probelm rozwiazac swego rodzaju robienie pre renderu w buffor zeby go wypelnic nie pomaga wiec za kazdym razem gdy bardziej zlozona geometria ma sie ukazac dostaje zweich z poczatku myslalem ze to wina physX i jego proba ustawienia modelu jednak testy dowiodly ze tak nie jest oczywiscie gdy instancji jest wiecej badz jedna jest juz widocza problemu nie ma co wiecej o ile model jest lowpoly probelm jest nie zauwazalny (nie mal ze ;p)

Prosił bym o jakas porade badz naprowadzenie mnie jak przygotowac karte na taki skok vertexow w jej buffor

Pozdrawiam.

Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: Dab w Grudzień 30, 2009, 18:41:28
Domyslam sie iz wywolane jest to dziwnym cachowaniem geometrii w karcie czy
ktos jest w stanie mi powiedziec jak ten probelm rozwiazac swego rodzaju robienie pre renderu w buffor
Na pewno nie. Podejrzewam że masz niewydajny kod cullingu, który w określonych sytuacjach powoduje taki zwis.
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: .:NOXY:. w Grudzień 30, 2009, 19:38:46
Culling wyglada tak:

if(TFrustrum){
if(!TFrustrum->frustum.SphereInFrustum(Posp.x,Posp.y,Posp.z,15)||(distance>DMM)) continue;
}

dla modelu ofc

a sama funkcja:

                    bool SphereInFrustum(float x, float y, float z, float Radius)
{
int i;

for(i = 0; i < 6; i++)
{

if(frustum[i][0] * x + frustum[i][1] * y + frustum[i][2] * z + frustum[i][3] <= -Radius)
{
return false;
}
}

return true;
}
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: Esidar w Grudzień 30, 2009, 21:34:24
Jeżeli używasz Visual Studio to w momencie zwisu na 1-2sec wciskasz F12 i patrzysz w której funkcji zatrzymał ci się kod. Powtarzasz to kilka razy, jeśli za każdym razem zatrzymuje się w tej samej funkcji to jest ona winowajcą.

Drugi sposób (powolniejszy): wstawiasz liczenie czasu pomiędzy poszczególnymi fragmentami kodu i patrzysz który będzie najdłuższy w momencie 1-2sec zwisu.
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: Krzysiek K. w Grudzień 30, 2009, 22:54:12
Cytuj
Prosił bym o jakas porade badz naprowadzenie mnie jak przygotowac karte na taki skok vertexow w jej buffor
Oczywiście rozumiem, że ładujesz wszystko do VBO w trybie STATIC DRAW podczas ładowania i potem już ich nie ruszasz?

Cytuj
Jeżeli używasz Visual Studio to w momencie zwisu na 1-2sec wciskasz F12 i patrzysz w której funkcji zatrzymał ci się kod. Powtarzasz to kilka razy, jeśli za każdym razem zatrzymuje się w tej samej funkcji to jest ona winowajcą.
Taak... a "winowajcą" okaże się jak zwykle wglSwapBuffers. ;)
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: .:NOXY:. w Grudzień 30, 2009, 23:33:37
@Krzysiek: tak geometria cala jest zaladowana w VBO jako STATIC_DRAW i juz z nia nic nie robie. Czeka grzecznie na wyswietlenie
@Esidar: Tak uzywam Visual'a zaraz sprawdze :>
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: Krzysiek K. w Grudzień 30, 2009, 23:41:05
A ładujesz przez BufferData, czy przez mapowanie+memcpy?
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: Esidar w Grudzień 31, 2009, 11:06:57
Taak... a "winowajcą" okaże się jak zwykle wglSwapBuffers. ;)
wglSwapBuffers przez 2sec ? :)
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: .:NOXY:. w Grudzień 31, 2009, 13:03:48
Laduje dosc lamersko:


                                        pglGenBuffers(1,&tempvbo.VBOVertices);
pglGenBuffers(1,&tempvbo.VBOCoords);
pglGenBuffers(1,&tempvbo.VBONormals);
pglGenBuffers(1,&tempvbo.VBOFaces);

glEnableClientState( GL_NORMAL_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_INDEX_ARRAY );

pglBindBuffer(GL_ARRAY_BUFFER_ARB,tempvbo.VBOVertices);
pglBufferData(GL_ARRAY_BUFFER_ARB,tempvbo.vSize*3*sizeof(GLfloat), vertices, GL_STATIC_DRAW_ARB );

pglBindBuffer(GL_ARRAY_BUFFER_ARB,tempvbo.VBOCoords);
pglBufferData(GL_ARRAY_BUFFER_ARB,tempvbo.vSize*2*sizeof(GLfloat), coords, GL_STATIC_DRAW_ARB);

pglBindBuffer(GL_ARRAY_BUFFER_ARB,tempvbo.VBONormals);
pglBufferData(GL_ARRAY_BUFFER_ARB,tempvbo.vSize*3*sizeof(GLfloat), normals, GL_STATIC_DRAW_ARB);

pglBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,tempvbo.VBOFaces);
pglBufferData(GL_ELEMENT_ARRAY_BUFFER_ARB,tempvbo.fSize*3*sizeof(GLuint), faces, GL_STATIC_DRAW_ARB);

glDisableClientState( GL_INDEX_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_NORMAL_ARRAY );

Buffers.push_back(tempvbo);


wyswietlanie:


glPushMatrix();


if(isinsanced) glMultMatrixf(PhysMatrix);

glEnableClientState( GL_NORMAL_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_INDEX_ARRAY );

pglBindBuffer( GL_ARRAY_BUFFER_ARB, Buffers[dm].VBOVertices );
glVertexPointer( 3, GL_FLOAT, 0, NULL );

glClientActiveTextureARB(GL_TEXTURE0);
pglBindBuffer( GL_ARRAY_BUFFER_ARB, Buffers[dm].VBOCoords );
glTexCoordPointer( 2, GL_FLOAT, 0, NULL );

pglBindBuffer( GL_ARRAY_BUFFER_ARB, Buffers[dm].VBONormals );
glNormalPointer(GL_FLOAT, 0, NULL );

pglBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, Buffers[dm].VBOFaces );
glDrawElements(GL_TRIANGLES, 3*Buffers[dm].fSize, GL_UNSIGNED_INT, NULL );

glDisableClientState( GL_INDEX_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_NORMAL_ARRAY );
glPopMatrix();


Jest to spowodowane Moja checia uzycia bibliotego GLOD ktora pozwala na generowanie dyskretnych LOD'ow a jej laczenie dziala na wlasnie takiej zasadzie (zmiana jedynie w vertex i index )

Co do walki z Visualem F12 sprowadza mnie za kazdym razem do pliku ntdll.dll
Ale wydaje mi sie ze chyba wiem co jest problemem zauwazylem ze gdy tak sobie pouciekam i powracam do frusturm zwiechy sa coraz zadsze i krotsze az w koncu zikaja
Sciaglem GPU-Z i tu sie okazuje... ze moje 384Mb Vram to za malo z Expolorerem po walczeniu gry W ramie jest tylko 30mb zuzycia za to o zgrozo ram karty wypeliony jest w 99% :D i wydaje mi sie ze moj kochany przesuwa dane w ram i swap co powoduje te majestatyczne Lagi...
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: Avaj w Grudzień 31, 2009, 13:16:51
Ajjjjjjjjjjjjjjj!!!!

nie czytałem reszty kodu, ale pozbądź się wszystkich linijek z GL_INDEX_ARRAY. A potem wrzuć to w google i zobacz co to robi :P
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: .:NOXY:. w Grudzień 31, 2009, 13:31:31
Osz lol xD tego to ja nie wiedzialem Thx Java ale problemu toraczej nie rozwiaze poki sobie nie kupie karty z wieksza pamiecia Vram ;D jak oscyluje w zapasie 20MB na Vramie Grafy to scena smiga :/
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: Kuba D. w Grudzień 31, 2009, 13:40:20
Z tego co widzę w tym kodzie to namotałeś trochę: podczas ładowania danych do VBO nie trzeba wywoływać glEnableClientState/glDisableClientState. Co do danych w vbo lepiej jest dać to do jednego bufora ( dane do niego pakujesz jako subData a podczas renderingu nie bindujesz co chwilę innego vbo ( tak jak u Ciebie osobno dla vertexów, dla normalnych, texcoordów itd ) tylko bindujesz jeden główny a w gl*Pointer ustawiasz wskaźnik na odpowiednie dane z subBuforów ( czyli tylko offset zmieniasz ).
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: .:NOXY:. w Grudzień 31, 2009, 13:50:28
Mowie ze nie moge tak zrobic bo bede uzywac osobnej biblioteki do towrznia LOD o ile coordy i normalne moge sobie zbindowac w subData tak vertexy i Indexy beda i tak osobnymi bufforami
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: Kuba D. w Grudzień 31, 2009, 13:53:44
Tak, vertexy i indeksy ZAWSZE będą w osobnych VBO bo vbo vertexów to jest GL_ARRAY_BUFFER_ARB a indeksów - GL_ELEMENT_ARRAY_BUFFER_ARB ( pomijając już to, że są to różne typy danych ( float3 vs uint ).
Tytuł: Odp: Wydajnosc sceny podczas optymalizacji Frustrum Culling a Pamiec Karty...
Wiadomość wysłana przez: Krzysiek K. w Grudzień 31, 2009, 15:42:59
Cytuj
wglSwapBuffers przez 2sec ? :)
A czemu nie? :)