Autor Wątek: Dynamiczne ładowanie świata  (Przeczytany 4695 razy)

Offline Kos

  • Użytkownik
    • kos.gd

# Kwiecień 19, 2008, 18:32:40
A to terenu 3d, powiedzmy heightmapy+obiektów, nie można dzielić na kafle 100x100? :]

Offline Mr. Spam

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

Offline Syriusz

  • Użytkownik

# Kwiecień 19, 2008, 19:57:18
Ja kojarzę kafle raczej z czymś płaskim, w końcu kafle są płaskie jak...  kafle ;). Poczekamy, zobaczymy co kacperz miał na myśli...

Offline Mattrick

  • Użytkownik

# Kwiecień 20, 2008, 00:42:02
Pewnie chodziło mu o kafle w sensie segmenty. ; p

Vipa

  • Gość
# Kwiecień 20, 2008, 01:29:07
A ja odpowiem tak: stosujcie się do wskazówek Krzysztofa K. Z tego co widzę chłopak ma głowę na karku.

Offline kedan

  • Użytkownik

# Kwiecień 20, 2008, 01:40:37
Kiedyś myślałem żeby zrobić tak: na począku wczytać wszystkie (albo te najważniejsze i największe) potrzebne PODSTAWOWE modele (roślinność, postacie, budynki, lub części budynków) z któych dopiero później za pomocą powiedzmy skryptów (czy tablic z cyferkami), będą tworzone większe lokacje. Wtedy doczytywania kafli z dysku byłoby faktycznie odczytem pliku np ASCII z rozłożeniem modeli czy ukształtowaniem terenu (+ ewentualne doczytanie niewielkich, specyficznych danych). Niestety nie sprawdzałem tego w praktyce..

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Kwiecień 20, 2008, 02:57:39
Cytuj
Kiedyś myślałem żeby zrobić tak: na począku wczytać wszystkie (albo te najważniejsze i największe) potrzebne PODSTAWOWE modele (roślinność, postacie, budynki, lub części budynków) z któych dopiero później za pomocą powiedzmy skryptów (czy tablic z cyferkami), będą tworzone większe lokacje.
Problem będzie tylko jeżeli tych podstawowych modeli będzie więcej, niż można pomieścić (zwłaszcza może być problem nie tyle z modelami, co z ich teksturami). Poza tym w ten sposób możesz ekstremalnie wydłużyć czas początkowego ładowania. Najsensowniejszym rozwiązaniem by było cacheowanie takich modeli i doczytywanie tych, które są używane przez kafle, a których jeszcze nie ma w pamięci.

Cytuj
Wtedy doczytywania kafli z dysku byłoby faktycznie odczytem pliku np ASCII z rozłożeniem modeli czy ukształtowaniem terenu (+ ewentualne doczytanie niewielkich, specyficznych danych).
Plik ASCII jest takim sobie pomysłem (chociaż zachowałeś nieco zdrowego rozsądku i nie zaproponowałeś XML'a ;)). Do przechowywania wszelakich danych streamowanych z dysku proponowałbym pliki binarne, najlepiej w dodatku skompresowane jakimś w miarę szybkim niezbyt złożonym algorytmem (np. range encoding z jawnie zapisaną tablicą prawdopodobieństw bajtów, albo range encoding + model-1). Dodatkowo dane można początkowo przetransformować żeby mniej zajmowały, np. zapisując współrzędne obiektów jako liczby 16-bitowe (w końcu kafel ma ograniczoną powierzchnię), czy olewając współrzędne Z (albo Y, w zależności od układu) dla typów obiektów z definicji przypiętych do heightmapy. Dla danych heightmap można zastosować algorytmy kompresji 2D (np. falki - niestety JPG'i i większość gotowych formatów nie przejdzie, bo mają za małą precyzję koloru do reprezentacji heightmap). W efekcie pliki powinny się drastycznie zmniejszyć, co bardzo ładnie wpłynie na szybkość ładowania. :)

Offline Reg

  • Administrator
    • Adam Sawicki - Home Page

# Kwiecień 20, 2008, 13:21:33
Esidar: Czy wobec tego jest możliwość tworzenia tych zasobów typu bufory i tekstury w osobnym wątku? Bo ja słyszałem, że to się kompletnie nie opłaca, bo urządzenie Direct3D utworzone z flagą D3DCREATE_MULTITHREADED po prostu zabezpiecza wszystkie metody D3D jedną wielką sekcją krytyczną, co tylko jeszcze bardziej spowalnia.

SauRooN: Czy histereza będzie lepsza, niż trzymanie określonej liczby ostatnio użytych sektorów i ich wymiana na zasadzie LRU - Last Recently Used?

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Kwiecień 20, 2008, 14:20:51
Cytuj
Czy wobec tego jest możliwość tworzenia tych zasobów typu bufory i tekstury w osobnym wątku? Bo ja słyszałem, że to się kompletnie nie opłaca, bo urządzenie Direct3D utworzone z flagą D3DCREATE_MULTITHREADED po prostu zabezpiecza wszystkie metody D3D jedną wielką sekcją krytyczną, co tylko jeszcze bardziej spowalnia.
Można by spróbować wywoływać wszystko z wątku głównego, a drugiemu wątkowi zostawić ładowanie i dekompresję danych do obszarów zalockowanych przez wątek główny. :)

Offline SauRooN

  • Użytkownik

# Kwiecień 20, 2008, 14:40:07
SauRooN: Czy histereza będzie lepsza, niż trzymanie określonej liczby ostatnio użytych sektorów i ich wymiana na zasadzie LRU - Last Recently Used?

Podałem tylko ogólną zasadę. Dobór optymalnego algorytmu zależy od kilku czynników - wielkości sektorów, układu sektorów (szachownica/heksy/quadtree/pełne 3D itd.), złożoności mapy, pola widzenia itp. Ważne jest, żeby algorytm określający sektory do wyładowania dobrze współgrał z wybranym algorytmem predykcji sektorów do załadowania. Większość algorytmów predykcji doczytywania opiera się w dużej mierze o kierunek przemieszczania się postaci w ostatnim czasie. Dla takiej predykcji LRU praktycznie zawsze zawiedzie, kiedy nagle postać zawróci i będzie szła drogą, którą przyszła, ponieważ po przejściu pewnej drogi okaże się, że będziemy dochodzić do sektora, na którym od dłuższego czasu nie byliśmy, LRU powie nam, że trzeba go wyładować, a za momencik albo w tym samym czasie algorytm predykcji powie nam, że trzeba go załadować. Ta sama sytuacja wystąpi, kiedy będziemy poruszać się po kole. Ogólnie nigdy nie powinno się zakładać stałej ilości wczytanych sektorów w pamięci. Jeśli mamy odpowiedni zapas wolnej pamięci, powinniśmy zaufać algorytmom, które wybraliśmy i nie ograniczać ich pola działania narzucając dodatkowe reguły.

Offline kacperz1

  • Użytkownik

# Kwiecień 20, 2008, 16:30:10
Postaram sie zrobić to tak, czy sie uda to nikt tego nie wie. Podzielę świat na części. Z bazy danych będę odczytywał na której mapie (część świata) znajduje sie gracz. Z pliku tekstowego albo jak wymyślę jakiś algorytm będę wczytywał sąsiednie mapy.Będę ładował te mapy a potem je zwalniał.

Dziękuję za odpowiedzi i na pewno pomoże mi to bardzo w dalszym rozwoju gry, lecz nie ma mowy o wątkach. Znaczy się że ja kiedyś z nimi pracowałem i pracowało mi się okropnie.
W takim razie polecam lekturę tego: http://msdn2.microsoft.com/en-us/library/aa365683(VS.85).aspx
Mniej więcej działa to tak, że prosisz Windowsa, żeby Ci coś załadował, a on Ci grzecznie mówi, kiedy skończy. :)
A nie mogę po prostu wsadzić ładowania i zwalniania map przed funkcja renderującą w pętli komunikatów?

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Kwiecień 20, 2008, 16:47:29
Cytuj
Z bazy danych będę odczytywał na której mapie (część świata) znajduje sie gracz.
Jaką bazę danych masz na myśli? Bo mam nadzieję, że nie MySQL, czy coś w tym stylu. :)

Offline kacperz1

  • Użytkownik

# Kwiecień 20, 2008, 16:51:26
Moja (nasza) gra jest grą typu mmorts. Klient łączy się z serwerem a serwer z bazą mysql która zawiera informacje o graczu.

Offline SauRooN

  • Użytkownik

# Kwiecień 20, 2008, 17:34:00
:O Trzeba było tak mówić od razu... Kolego, w pierwszym poście mówiłeś o World of Warcraft, wszyscy myśleli, że o takim silniku rozmawiamy...

Offline kacperz1

  • Użytkownik

# Kwiecień 20, 2008, 17:37:27
Heh, ale to chodzi o dynamiczne ładowanie terenu co w grze mmorts może być takie same jak w grze mmorpg.

Offline Esidar

  • Użytkownik

# Kwiecień 21, 2008, 02:50:27
Esidar: Czy wobec tego jest możliwość tworzenia tych zasobów typu bufory i tekstury w osobnym wątku? Bo ja słyszałem, że to się kompletnie nie opłaca, bo urządzenie Direct3D utworzone z flagą D3DCREATE_MULTITHREADED po prostu zabezpiecza wszystkie metody D3D jedną wielką sekcją krytyczną, co tylko jeszcze bardziej spowalnia.

Nie wiem czy ktoś zrobił jakiś porządny test wydajności. W tej chwili portuję grę z X360 w której jest kod z żywca z xboxa i tam rendering jest na jednym wątku a wczytywanie zasobów, tworzenie shader'ów, tekstur, buforów itd na drugim. Jest oczywiście włączone D3DCREATE_MULTITHREADED i gra działa bardzo przyzwoicie (40-80fps na 7900GT - Core2 2.4GHz). Nie wiem czy gra by dużo zyskała gdyby wyłączyć tą flagę :) Z resztą zdaje się DX10 działa w tej chwili jako MULTITHREADED już zdefaulta. Koszt sekcji krytycznej która nie ma konfliktu, jest bardzo niski (ok. 100 cykli, jeśli dobrze pamiętam). W porównaniu z kosztem dowolnej funkcji DX9 która ma średnio 5,000 cykli to 100 w jedną czy drugą stronę to żadna różnica :)

Cytuj
Cytuj
Bez wątków i procesora z co najmniej dwoma rdzeniami nie dasz rady
Myślę, że tutaj nie jest aż tak tragicznie

Dlatego zaznaczyłem, że to zależy od tego co się ma :) W firmie mam w tej chwili ATI 1300 w kompie i gra o której wspomniałem wyżej (D3DCREATE_MULTITHREADED + 2 wątki) wczytuje się/uruchamia ze 3x wolniej niż na NVidii 7900GT. Oczywiście główny powód to tworzenie tekstur, buforów, shader'ów itd. Na szczęście mam DualCore ale wole na razie nawet nie myśleć co się zacznie dziać jak zacznę to odpalać na single core :)