Autor Wątek: LOD mesha oparty na różnych IB  (Przeczytany 1395 razy)

Offline 0x46415243494...

  • Użytkownik

# Styczeń 25, 2013, 22:18:30
Witam,

Zastanawia mnie pewna kwestia związana z wydajnością renderingu mesha z różnym poziomem LOD z zastosowaniem kilku wersji index bufferów.

Otóż załóżmy, że mam sytuację, mam 1 spory vertex buffer z wszystkimi wierzchołkami.
Do tego powiedzmy, że generuję kilka wersji index bufferów (dla tego VB) - ale każdy dla różnego poziomu LOD mesha, tak że każdy kolejny IB poziom będzie używał znacznie mniej wierzchołków.

Najczęściej będą renderowane najniższe poziomy LOD (IB z najmniejszą ilością prymitywów), a więc pytanie, czy i jak duży będzie spadek wydajności z tego tytułu, że dla małego(najniższych LOD) index buffera, będzie ustawiany ten duży VB, w którym de facto większość wierzchołków nie będzie używanych (90%)?
Czy jednak opłaca się dla każdej wersji IB robić oddzielną wersję VB, w której będą tylko te wierzchołki, z których w pełni korzysta?
Innymi słowy, czy wielkość VB(poziom jego wykorzystania) będzie miał wpływ na szybkość?

Mam nadzieję, że przedstawiłem wszystko zrozumiale, jakby co pisać.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Krzysiek K.

  • Moderator
    • DevKK.net

  • +1
# Styczeń 26, 2013, 00:04:05
Cytuj
Czy jednak opłaca się dla każdej wersji IB robić oddzielną wersję VB, w której będą tylko te wierzchołki, z których w pełni korzysta?
Przede wszystkim zrobienie nowego VB nie będzie bardzo szkodziło. W przypadku tekstur każdy LOD (mipmapa) ma kompletnie własną kopię danych zredukowaną do 1/4 i wszystkie poziomy w sumie zajmują mniej niż 1/3 oryginalnej tekstury (hint: suma szeregu geometrycznego).

Za to używając starego VB nie będziesz mógł zoptymalizować VB i IB jako pary. W efekcie cache będzie zaciągał wiele niepotrzebnych danych (sąsiednie wierzchołki w tej samej linii cache). Czy to będzie miało znaczenie? Ciężko powiedzieć.

Offline FoToN

  • Użytkownik

# Styczeń 26, 2013, 00:47:06
IMHO, bardziej się opłaca trzymać w oddzielnych. Poza tym, co napisał KK, dochodzi jeszcze fakt zużycia pamięci. Trzymając wszystko w oddzielnych IB i VB możesz trzymać kilka LOD'ów w jednym pliku mesha. Następnie po prostu ładujesz z niego to, co jest potrzebne (np. po co nam najbliższy LOD jakiegoś odległego modelu? Możemy trzymać w pamięci tylko kilka najbliższych).

Offline 0x46415243494...

  • Użytkownik

# Styczeń 26, 2013, 12:11:43
Przede wszystkim zrobienie nowego VB nie będzie bardzo szkodziło. W przypadku tekstur każdy LOD (mipmapa) ma kompletnie własną kopię danych zredukowaną do 1/4 i wszystkie poziomy w sumie zajmują mniej niż 1/3 oryginalnej tekstury (hint: suma szeregu geometrycznego).
W sumie racja.

Za to używając starego VB nie będziesz mógł zoptymalizować VB i IB jako pary. W efekcie cache będzie zaciągał wiele niepotrzebnych danych (sąsiednie wierzchołki w tej samej linii cache). Czy to będzie miało znaczenie? Ciężko powiedzieć.
Aha, ale co masz na myśli poprzez optymalizację VB +IB "w parę" - mówisz o jakimś połączeniu/związaniu ich w DX3D(o czym nie wiem)? Bo ja do tej pory po prostu wołałem setIndexBuffer/setVertexBuffers dla każdego mesha i już...


Właściwie pisząc mesha, to konkretnie chodziło mi o grid siatki terenu (aczkolwiek byłem generalnie ciekaw jak to będzie odnosiło się ogólnie), (np. LOD0: 128x128, LOD1: 64x64, itd.), więc będzie to dokładnie tak jak z LOD tekstury - chcę wygenerować te kilka poziomów LOD, każda siatka jest w coordynatach x,y:(-1,1), tyle, że z 2x mniejszymi rozdzielczościami, wysokości będę samplował z heightmapy dostarczonej do VS jako tekstura, tak to się chyba teraz robi ( teren z heightmapy na GPU?) + transfomracja grida w określone miejsce świata. Na morphing połączenia różnych LOD też mam pomysł.

Offline Dab

  • Redaktor
    • blog

  • +1
# Styczeń 26, 2013, 15:31:10
Na to o czym piszesz to akurat szkoda miejsca. Powiedzmy że maksymalny rozmiar grida to 256x256. Zamiast wrzucać do VBO/IBO paski po 256, można zrobić coś takiego:



Gdzie na samym początku buforów jest czerwona część, potem zielona, potem niebieska itd. Dzięki temu jest łatwy dostęp do każdego poziomu LOD bo każdy poprzedni zawiera się na początku następnego.
W buforze nie musi być dużo danych. Wystarczą np. 2 floaty w zakresie [0; 1]. Jeżeli rysujesz max LOD to po prostu ich używasz, jeżeli LOD-1 (żółty) to bierzesz te liczby i mnożysz * 2, analogicznie w kolejnych poziomach. Mało danych do czytania == win.

Offline 0x46415243494...

  • Użytkownik

# Styczeń 26, 2013, 16:09:20
W sumie ciekawa koncepcja, czyli rozumiem, że teraz podczas Draw() proporcjonalnie(kwadratowo) zmniejszam ilość prymitywów + przemnażam to razy LOD w VS

Ok dzięki za pomoc

Offline Krzysiek K.

  • Moderator
    • DevKK.net

# Styczeń 26, 2013, 17:39:01
Cytuj
Aha, ale co masz na myśli poprzez optymalizację VB +IB "w parę" - mówisz o jakimś połączeniu/związaniu ich w DX3D(o czym nie wiem)?
Nie ma powiązań. Chodziło mi o to, że siatkę można optymalizować (są do tego funkcje) tak, żeby:
- wierzchołki które są wykorzystywane wiele razy były blisko siebie na liście indeksów (po VS jest cache na GPU, więc oszczędza przeliczania tego samego wierzchołka wiele razy),
- wierzchołki w VB były potem poukładane w takiej kolejności, w jakiej są w IB - lepiej działa cache przed VS