Widziałem wiele przykładów renderowania duszków z arkusza, ale nie zrozumiałem, dlaczego jest to najczęstszy sposób radzenia sobie z duszkami w grach 2d.
Zacząłem od renderowania ikonek 2d w kilku aplikacjach demonstracyjnych, które stworzyłem, zajmując się każdą klatką animacji dla dowolnego typu ikonki jako jej własnej tekstury - a ta kolekcja tekstur jest przechowywana w słowniku. Wydaje się, że to działa dla mnie i całkiem dobrze pasuje do mojego przepływu pracy, ponieważ zwykle robię animacje jako pliki gif / mng, a następnie wyodrębniam klatki do poszczególnych png.
Czy istnieje wyraźna korzyść w zakresie wydajności renderowania z jednego arkusza zamiast z poszczególnych tekstur? Czy przy nowoczesnym sprzęcie, który potrafi rysować miliony wielokątów na ekranie sto razy na sekundę, czy ma to w ogóle znaczenie dla moich gier 2D, które mają do czynienia z kilkadziesiąt prostokątów 50 x 100 pikseli?
Szczegóły implementacji ładowania tekstury do pamięci graficznej i wyświetlania jej w XNA wydają się dość abstrakcyjne. Wiem tylko, że tekstury są wiązane z urządzeniem graficznym podczas ładowania, a następnie podczas pętli gry tekstury renderowane są partiami. Nie jest więc dla mnie jasne, czy mój wybór wpływa na wydajność.
Podejrzewam, że istnieje kilka bardzo dobrych powodów, dla których większość deweloperów gier 2D używa ich, po prostu nie rozumiem dlaczego.
źródło
Odpowiedzi:
Silnym argumentem przemawiającym za użyciem arkuszy sprite jest to, że liczba dostępnych tekstur na karcie graficznej może być ograniczona. Dlatego twoja biblioteka graficzna będzie musiała stale usuwać tekstury i ponownie alokować tekstury na GPU. O wiele bardziej efektywne jest jednorazowe przydzielenie dużej tekstury.
Weź również pod uwagę, że rozmiary tekstur są zwykle potęgą 2. Więc jeśli masz Duszka 50x100px, przydzielisz tekstury o rozmiarze 64x128px lub w gorszym przypadku 128x128px. To tylko marnowanie pamięci graficznej. Lepiej spakuj wszystkie duszki w teksturę 1024x1024px, co pozwoliłoby na duszek 20x10, a stracisz tylko 24 piksele poziomo i pionowo. Czasami nawet duszki o różnych rozmiarach są łączone w jeden ogromny arkusz duszka, aby użyć tekstury tak wydajnie, jak to możliwe.
Dodatek: Bardzo ważnym powodem korzystania z arkuszy sprite jest zmniejszenie liczby połączeń losowych na GPU, co może mieć znaczący wpływ na wydajność. Zostało to stwierdzone w innych odpowiedziach i dodam to w celu uzupełnienia, aby uzyskać większą widoczność.
źródło
Powiedziałbym, że argumentem do użycia byłaby zdolność renderowania wielu rzeczy w jednym losowaniu. Weźmy na przykład renderowanie czcionek, bez arkusza sprite'u musiałbyś wyrenderować każdy znak z osobną zamianą tekstur, a następnie wywołaniem rysowania. Rzuć je do arkusza sprite i możesz renderować całe zdania za pomocą pojedynczego wywołania rysowania (znaki różnicowe w czcionce są wybierane przez podanie różnych promieni UV dla rogów). Jest to znacznie wydajniejszy sposób renderowania, gdy bardzo realny narzut renderowania na wielu platformach powoduje zbyt wiele wywołań API.
Może także pomóc zaoszczędzić miejsce, ale przede wszystkim zależy od tego, co zapakujesz do arkusza sprite.
źródło
Każde losowanie ma pewien narzut. Używając arkuszy sprite, możesz grupować rysunek rzeczy, które nie używają tej samej klatki animacji (lub bardziej ogólnie wszystkiego, co jest na tym samym materiale), co znacznie poprawia wydajność. W zależności od gry może to nie mieć większego znaczenia dla nowoczesnych komputerów, ale na pewno ma to znaczenie, powiedzmy, na iPhonie.
źródło
Oprócz względów wydajnościowych arkusze ikonek mogą być przydatne podczas tworzenia sztuki; każda postać może znajdować się w osobnym arkuszu, a wszystkie ramki można zobaczyć, przewijając. Pomaga mi zachować spójny wygląd wszystkich klatek.
Dodatkowo koduję w AS3, a każdy plik obrazu wymaga osobnej instrukcji osadzania. Wolę mieć jedno osadzenie całego arkusza sprite niż 24 osadzanie dla wszystkich ramek, nawet jeśli używam osobnej klasy zasobów.
źródło
Innym powodem, dla którego warto używać arkuszy sprite w XNA, jest to, że przy opracowywaniu Xbox360 występuje znany problem z długim czasem wdrażania / ładowania w stosunku do liczby plików, które masz w swoim projekcie. Tak więc połączenie wielu małych plików obrazów w jeden plik obrazu pomoże zwalczyć ten problem.
źródło
Nie będę tutaj wspominał o pamięci / GPU, ponieważ takich odpowiedzi jest wystarczająco dużo.
Zamiast tego może oczyścić twoją sztukę podczas pracy nad nią - i później. Zamiast przewijać 10 zdjęć, aby zobaczyć cykl marszu, możesz zobaczyć wszystkie klatki za jednym razem. Jeśli chcesz to rozpowszechnić, masz tylko 1 plik do rozwiązania zamiast 10.
A potem czystsze (z organizacyjnego punktu widzenia) jest posiadanie character.png i wroga.png nad characterwalk01 przez characterwalk10, następnie characterattack01 do characterattack05 i trwa.
źródło
Pamięć graficzna nie ma nadmiernego zarządzania pamięcią, takiego jak systemy plików na dyskach; przeciwny przypadek: jest prosty i szybki .
Jednym z takich prostych i szybkich zmian w pamięci może być posiadanie tylko jednego gigantycznego duszka 4096 x 4096, który jest cięty na wiele mniejszych duszek przez połowę jego szerokości i / lub wysokości. (Istnieje podobna 1-wymiarowa technika zarządzania pamięcią, ale zapomniałem nazwy.) Ostatecznie należy przeprowadzić defragmentację.
Aby pominąć takie zarządzanie pamięcią w czasie wykonywania , programiści wypełniają pojedyncze duże duszki wieloma mniejszymi duchami automatycznie podczas kompilacji lub nawet podczas projektowania grafiki.
źródło
Nie zapomnij również o operacjach we / wy, które mogą zaoszczędzić podczas inicjalizacji. Jeśli ładujesz z napędu CD, każdy plik jest dodatkowym wywołaniem We / Wy i jego wyszukiwanie może zająć trochę czasu (współczesne dyski twarde mają około 15 ms na plik, a płyty CD może 50-100 ms?). Pozwala to zaoszczędzić dużo czasu inicjalizacji, ponieważ należy pobrać tylko jeden plik. Umożliwia także systemowi operacyjnemu buforowanie tych operacji we / wy, na wypadek, gdyby aplikacja robiła coś innego (na przykład czekając na GPU).
źródło
Oprócz większej wydajności, uważam, że jest to po prostu łatwiejsze. Wymaga to trochę dodatkowej pracy, aby upewnić się, że Twoje obrazy zawsze mieszczą się w ich granicach podczas tworzenia sztuki, ale o wiele łatwiej jest zobaczyć wszystkie obrazy, z którymi masz obecnie do czynienia.
Moim zdaniem łatwiej jest też kodować. Po prostu mam szereg obiektów, takich jak:
Następnie dla każdego elementu podaję dwie wartości, arkusz i prostokąt. Arkusz będzie indeksem w tablicy obiektów, a rect będzie indeksem w tablicy rects tego arkusza.
źródło