[ eva01 @ 29.03.2005. 20:34 ] @
Često mi zatreba da transformišem neke vertekse, recimo za bound sphere ili box-ove. Ovo radim preko cpu-a tako što jednostavno množim vertekse sa matricama. E sada interesuje me da li je to najbolji način da se to odradi ? Za sfere i kocke mi je potreban mali broj transformacija ali ako bih želeo da uradim preciznu detekciju sudara onda bih morao da transformišem scenu dva puta, jednom na cpu jednom na gpu. Dakle ono na šta ciljam je da nekako utrapim taj posao grafičkoj kartici. Takođe me interesuje na koji način mogu da pogledam transformisane koordinate verteksa koje sam poslao na rendering ? Koliko to opterećuje komunikaciju cpu - gpu ?
[ Reljam @ 29.03.2005. 21:35 ] @
U Direct3Du to radis tako sto prosledis parametar D3DCREATE_HARDWARE_VERTEXPROCESSING funkciji CreateDevice. To oznacava da zelis da se transformacija radi na GPUu. Nakon toga, koristis IDirect3DDevice9::SetTransform da namestis matrice koje ti trebaju (D3DTS_VIEW, D3DTS_PROJECTION, D3DTS_WORLDMATRIX).

U vertex buffer stavi netransformisane (model space) vertekse, i namesti da ti tip bude D3DDECLUSAGE_POSITION (D3DFVF_XYZ ako koristis stare FVF kodove) da bi Direct3D znao da koristis netransformisane vertkese.

Inace, kada savladas ovo, gledaj da se prebacis na vertex shadere, to je ionako buducnost D3Da.

GPU transformisane koordinate ne mozes da pogledas u debageru.

Kolizija i fizika se obicno rade tako sto koristis HW vertex processing za rendering, a na CPUu transformises mnogo manji mesh (ili cak bounding boxove/spherove) koji sluzi za koliziju.
[ yooyo @ 29.03.2005. 22:12 ] @
A da probas da transformises vertexe koriscenjem pixel shadera? Ubaci vertexe u rgba32f texturu i napisi pixel shader za procesiranja i renderuj screen aligned quad u texture target (koji je takodje rgba32f). Posle pokusaj da procitas rezultat iz texture.

D3D9 ima metodu IDirect3DDevice9::ProcessVertices koja radi sa nekim ogranicenjima (tj. vertexi se procesiraju na CPU) tako da i to mozes da probas.

yooyo
[ eva01 @ 29.03.2005. 22:46 ] @
Ok. Znao sam kako da transformišem vertekse kada želim da renderujem fejsove. Ono što me je interesovalo jeste dali mogu da pročitam transformisane vertekse. Ako sam dobro shvatio celu priču to je nemoguće izvesti. Tj. preostaje mi samo da transformišem uprošćen model na cpu-u.
[ eva01 @ 29.03.2005. 22:54 ] @
Citat:

A da probas da transformises vertexe koriscenjem pixel shadera? Ubaci vertexe u rgba32f texturu i napisi pixel shader za procesiranja i renderuj screen aligned quad u texture target (koji je takodje rgba32f). Posle pokusaj da procitas rezultat iz texture.


Jos se nisam bacio na programiranje shader-a, ali ipak da te pitam: da li ću ovako imati veliko usporenje jer ću morati da čitam rezultat iz teksture ? Kada se priča o optimizaciji često se govori da ne treba menjati/čitati podatke iz memorije kartice jer ovo opterećuje komunikaciju gpu-cpu.
[ Reljam @ 29.03.2005. 23:05 ] @
Da, procesiranje na GPU da bi posle uradio read-back nece biti brze od procesiranja na CPUu. Moraces da predjes na jednostavnije modele na procesoru.
[ yooyo @ 29.03.2005. 23:46 ] @
Citat:
eva 01: Jos se nisam bacio na programiranje shader-a, ali ipak da te pitam: da li ću ovako imati veliko usporenje jer ću morati da čitam rezultat iz teksture ? Kada se priča o optimizaciji često se govori da ne treba menjati/čitati podatke iz memorije kartice jer ovo opterećuje komunikaciju gpu-cpu.


Zavisi od hw-a i od API-a. Konkretno, na NV karticama i OpenGL-om mozes koristiti pixel buffer objects i asinhroni readback. Ovo ti omogucava da zapocens readback i zatim nastavis da radis nesto drugo pa da se posle vratis da proveris rezultat. Na ovaj nacin i CPU i GPU su maximalno zaposleni. Na zalost, ovo je NV-only resenje.

Neka me Relja ispravi ako gresim, mislim da D3D API ne podrzava asinhrone operacije.

Generalno, sadasnja generacija hw-a (ukljucujuci i NV40) ne podrzava procesiranje vertexa (koriscenjem shadera) za korisnika, vec iskljucivo za (rasterizer). Bilo bi divno da ProcessVertices radi u hw-u... Workaround je tehnika koju sam ti opisao. Zgodna je ako ti rezultat treba da ostane u GPU memoriji za cloth simulaciju ili character skinning.

Ako ti vec trebaju vertexi za collision detection, razmisi o muti-thread resenju. Jedan thread ima zadatak da puni GPU (ako ovo dovoljno dobro radis saobracaj na AGP/PCIX-u ce biti mali), a drugi thread neka radi fizikalije. Ovo bi posebno doslo do izrazaja na hyper-threading masinama.

yooyo
[ Reljam @ 30.03.2005. 00:44 ] @
Da, razlika je u pristupu: D3D za razliku od OpenGLa nema odvojene ekstenzije za odredjene kartice, tako da ne mozes da radis tu vrstu HW-specific optimizacija. Sa druge strane dobijes unificirani API, tako da treba izabrati pravi alat za svaki problem..

Sto se tice obrade podataka u drugom threadu, to je skoro neizbezna stvar za sve igre koje su sada u razvoju: ako pogledas sta pricaju CPU proizvodjaci, buducnost je u multi-core procesorima. Ukoliko ti je cela igra u jednom threadu, izgubices veliki deo performansi.
[ yooyo @ 30.03.2005. 01:32 ] @
Citat:
Reljam: Sto se tice obrade podataka u drugom threadu, to je skoro neizbezna stvar za sve igre koje su sada u razvoju: ako pogledas sta pricaju CPU proizvodjaci, buducnost je u multi-core procesorima. Ukoliko ti je cela igra u jednom threadu, izgubices veliki deo performansi.


Da se nadovezem... Ako igra ima limitirani FPS (kao Doom3 - 60fps) onda ostaje dosta procesorskog vremena za druge stvari. Bas sam probao Doom3 u windowed modu sa startovanim task managerom i gledao zauzece CPU-a za vreme igre.
Ako "zabijes" nos u zid zauzece CPU-a je ~15, a kod komplikovanih scena ide do 45-50% (imam HT masinu). Znaci na HT masinama ostaje ti uglavnom ceo drugi "virtuelni CPU".

yooyo