Różne wymiary klatek w sprite sheet dla jednostki

Różne wymiary klatek w sprite sheet dla jednostki
Kokoniłaj
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 197
0

Zastanawiam się nad podejściem do sprite sheetów tego rodzaju. W tym przykładzie, którym się posłużę klatki mają następujące wymiary: 50x50, 50x57, 70x50.
Widzę 3 opcje:

  1. Stworzenie kilku sprite sheetów. W zależności od wymiarów.
  2. Jeden spritesheet z wymiarami 70x57.
  3. Taka hybryda: 1 sprite sheet, wiele rozmiarów i ogarnianie tego w kodzie. Przykładowo pierwsze 2 wiersze mają wymiary 50x50, kolejny 50x57 etc.

Jakbyście podeszli do tego tematu?

Sprite sheet autorstwa Master484
OpenGunnerHeroVer2.png

Spine
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7122
1

W Unity masz automatyczne Spite Atlasy.

Robisz listę obrazków i one automatycznie są upakowywane w jedną teksturę.
Referencje do wszystkich obrazków wykorzystujesz w odpowiednich miejscach zgodnie z workflowem Unity.


W sumie to nawet mógłbyś bezpośrednio z takiego pliku powycinać sprite'y w Unity i referencje do nich przypisać w atlasie.
Tylko przydałoby się to jednokolorowe tło zamienić na kanał alpha ;)

screenshot-20251001203517.png

screenshot-20251001203101.png

screenshot-20251001203424.png

screenshot-20251001203358.png


A różnymi rozmiarami klatek się nie przejmuj. Każdej klatce możesz odpowiedni pivot ustawić, jeśli postać będzie wyświetlana z przesunięciem.

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12317
1

U siebie mam na razie obsługę atlasów ze sprajtami znaków (jeden atlas zawiera wszystkie znaki danej strony fontu) oraz ze sprajtami kształtów kursorów (jeden atlas zawiera sprajty wszystkich kształtów i klatek animacji). Niżej wrzucam testowe atlasy, jeden z fontem, drugi z kursorem:

screenshot-20251002135520.png screenshot-20251002135555.png

Tworzę je w swoich edytorach, dodając do projektu zbiory plików (jeden plik to jeden znak lub klatka danego kształtu kursora), przy zapisie projektu edytor tworzy binarkę z gotowym fontem/kursorem, która oprócz atlasu, zawiera również lookup table z obszarami wszystkich sprajtów, dzięki czemu renderowanie tekstu czy kursora ogranicza się do pobrania obszaru z lookup table i bezpośredniego użycia (nie trzeba niczego obliczać).

Dla fontów i kursorów stosuję prosty algorytm układania sprajtów w atlasie (po stronie edytora) — obliczam maksymalną wysokość i szerokość sprajtu i ona określa rozmiar komórki w atlasie. Następnie konwertuję liczbę sprajtów na liczbę komórek w pionie i poziomie, tak aby atlas był jak najbliższy kwadratowemu. Na koniec maluję każdy sprajt w lewym górnym rogu każdej komórki.

Atlasy ston fontów i kursorów są mikroskopijne, więc taki prosty sposób jest w ich przypadku w zupełności wystarczający. Być może skorzystam z niego również do budowania atlasów ze sprajtami dla animacji wszelkich ruchomych obiektów (postaci, przedmiotów itd.).

Natomiast atlasy z kaflami służącymi do budowania terenu najpewniej będę pakował w inny sposób. Wszystko dlatego, że sprajty dla scenerii będą miały drastycznie różne rozmiary, więc aby nie marnować przestrzeni w atlasach (i zwiększać zapotrzebowania na VRAM), te najpewniej będą ciasno pakowane w atlasach (są do tego algorytmy), tak aby ograniczyć puste przestrzenie do minimum. Ale tak samo jak w przypadku fontów i kursorów, do atlasu dołączony będzie lookup table z obszarami każdego sprajtu, żeby można było szybko i wygodnie pobierać obszary sprajtów i je renderować.

obscurity
  • Rejestracja: dni
  • Ostatnio: dni
2
flowCRANE napisał(a):

Tworzę je w swoich edytorach, dodając do projektu zbiory plików (jeden plik to jeden znak lub klatka danego kształtu kursora), przy zapisie projektu edytor tworzy binarkę z gotowym fontem/kursorem, która oprócz atlasu, zawiera również lookup table z obszarami wszystkich sprajtów, dzięki czemu renderowanie tekstu czy kursora ogranicza się do pobrania obszaru z lookup table i bezpośredniego użycia (nie trzeba niczego obliczać).

kolejny który tworzy własne edytory zamiast użyć istniejących narzędzi 🙄

Dla fontów i kursorów stosuję prosty algorytm układania sprajtów w atlasie (po stronie edytora) — obliczam maksymalną wysokość i szerokość sprajtu i ona określa rozmiar komórki w atlasie.
Następnie konwertuję liczbę sprajtów na liczbę komórek w pionie i poziomie, tak aby atlas był jak najbliższy kwadratowemu. Na koniec maluję każdy sprajt w lewym górnym rogu każdej komórki.

fajnie, nazywa się to font asset creator, wystarczy wybrać font i nacisnąć "OK", są też takie narzędzia online

Natomiast atlasy z kaflami służącymi do budowania terenu najpewniej będę pakował w inny sposób. Wszystko dlatego, że sprajty dla scenerii będą miały drastycznie różne rozmiary, więc aby nie marnować przestrzeni w atlasach (i zwiększać zapotrzebowania na VRAM), te najpewniej będą ciasno pakowane w atlasach (są do tego algorytmy), tak aby ograniczyć puste przestrzenie do minimum.

choć staranie się żeby oszczędzić w porywach 1MB VRAMu prawdopodobnie nie ma w dzisiejszych czasach żadnego sensu, to jednak najbardziej sensowna rzecz z tego posta.

Odpowiadając @Kokoniłaj - po prostu sobie tak ustal te atlasy żeby było ci wygodnie, żeby zmaksymalizować kompatybilność z różnymi silnikami graficznymi i starszymi kartami najlepiej tak żeby atlas miał kwadratowe wymiary będące wielokrotnością dwójki i żeby był maksymalnie upchany bez pustych przestrzeni, tak żeby do pamięci nie ładować niepotrzebnie dużej tekstury która jest głównie pusta. Natomiast to wszystko ma tak naprawdę mikroskopijne znaczenie, o ile nie tworzysz gry na jakiś bardzo pradawny sprzęt.

Bardziej niż optymalizację dla GPU myślę że warto wziąć pod uwagę optymalizację pod modowanie gry - puste obszary marnują zasoby ale można opisać i stworzyć ładne granice w grafice co sprzyja modowaniu i tworzeniu customowych skórek nawet przez laików. W teorii można taki sprite sheet upchać gęściej programowo przed samym załadowaniem do VRAM, ale nie wiem czy gdzieś się stosuje takie praktyki bo ciężko doszukać się sensu, skoro gry 2D na nowoczesnym sprzęcie bez vsync chodzą w dziesiątkach tysięcy klatek na sekundę a takie optymalizacje nie dodadzą nawet jednej więcej.

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12317
1
obscurity napisał(a):

kolejny który tworzy własne edytory zamiast użyć istniejących narzędzi 🙄

Oczywiście — preferuję własne narzędzia, niż uzależnianie się od cudzych, w tym z podstępnymi licencjami.

fajnie, nazywa się to font asset creator, wystarczy wybrać font i nacisnąć "OK", są też takie narzędzia online

Fajnie, wystarczy wybrać font — skąd taki font wziąć? Wiadomo, z neta, czyli wracamy do cudzych prac i licencji. A co jeśli będę potrzebował (a będę) fontu zawierającego specjalne znaki, specyficzne dla mojej gry, takie jak np. miniaturki klawiszy czy przycisków gamepada, albo ikonki UI do wyrenderowania w formie tekstu? Zostaje szukanie czegoś gotowego, co się nada, albo stworzenie własnego fontu (np. .ttf) używając przeznaczonych do tego edytorów. I znów kolejne uzależnienia i licencje.

A u mnie? Rysuję takie znaki jakich potrzebuję, wrzucam do edytora, eksportuję — gotowe. Glify znaków mogą zawierać absolutnie cokolwiek, nie ma tutaj żadnych ograniczeń, a tym bardziej uzależniania się od cudzych prac.

choć staranie się żeby oszczędzić w porywach 1MB VRAMu prawdopodobnie nie ma w dzisiejszych czasach żadnego sensu, to jednak najbardziej sensowna rzecz z tego posta.

Przy docelowych tysiącach tekstur używanych do renderowania zawartości map i nie tylko, zysk z sensownego ich pakowania w atlasach może być znacznie większy niż 1MB.

Spine
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7122
0
flowCRANE napisał(a):
obscurity napisał(a):

kolejny który tworzy własne edytory zamiast użyć istniejących narzędzi 🙄

Oczywiście — preferuję własne narzędzia, niż uzależnianie się od cudzych, w tym z podstępnymi licencjami.

Ja bym tego tak nie piętnował. Mnóstwo ludzi żyje z tymi licencjami.
Większości użytkowników one nie dotykają, bo nie zarabiają na swoich pracach aż tyle żeby musieć cokolwiek płacić.
A jeśli zarabiają aż tyle, to mają z czego pokryć zobowiązania licencyjne.

flowCRANE napisał(a):
obscurity napisał(a):

fajnie, nazywa się to font asset creator, wystarczy wybrać font i nacisnąć "OK", są też takie narzędzia online

Fajnie, wystarczy wybrać font — skąd taki font wziąć? Wiadomo, z neta, czyli wracamy do cudzych prac i licencji. A co jeśli będę potrzebował (a będę) fontu zawierającego specjalne znaki, specyficzne dla mojej gry, takie jak np. miniaturki klawiszy czy przycisków gamepada, albo ikonki UI do wyrenderowania w formie tekstu? Zostaje szukanie czegoś gotowego, co się nada, albo stworzenie własnego fontu (np. .ttf) używając przeznaczonych do tego edytorów. I znów kolejne uzależnienia i licencje.

Znalazłem np. taką czcionkę z ikonkami gamepada: https://esquiredevmark.itch.io/generic-gamepad-font
Można ściągnąć i używać za free (GNU General Public License v3.0).

W Unity jest Text Mesh Pro, który ma możliwość łączenia czcionek. Jeśli nie znajdzie danego znaku w jednej czcionce, to szuka tego znaku w czcionkach ustawionych jako Fallback.
Czyli możesz sobie zorganizować czcionki w taki sposób, żeby bez modyfikacji czcionki głównej (tekstu), mieć też zestawy ikonek, czcionkę z chińskimi znakami itd. w obrębie jednego wyświetlanego tekstu.

screenshot-20251002230326.png

Oczywiście możesz to uznać za fikołek, bo wymaga trochę przygotowań, ale...

flowCRANE napisał(a):

Zawsze można mieć własny format fontów i nie musieć robić takich fikołków w ogóle.

...własny format to też fikołek.

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12317
0
Spine napisał(a):

Znalazłem np. taką czcionkę z ikonkami gamepada: https://esquiredevmark.itch.io/generic-gamepad-font
Można ściągnąć i używać za free (GNU General Public License v3.0).

Bardzo fajny ten font. No i bardzo fajnie wyglądają glify, gdy je wyrenderuję w małym rozmiarze, odpowiednim dla gry w stylu retro, w której tekst ma wysokość 8-10 pikseli:

screenshot-20251002235212.png

Śliczne — jakie ostre i czytelne! 😉

Ten z lewej to rozmiar 8 (rozmiar tekstu, nie w pikselach), w środku ma 10, po prawej 24. Jeśli zechcę wyrenderować glof mający 10 pikseli wysokości, to będzie rozmazaną kupą.

O tym właśnie pisałem — i teraz kombinuj co z tym zrobić, albo szukaj innego fontu, bo ten się nie nada.

...własny format to też fikołek.

To konieczność, a nie fikołek. W moim przypadku, używanie normalnych fontów jest problematyczne (patrz wyżej), więc skorzystałem z własnej, prostej implementacji, zamiast próbować na silę wykorzystać cudzą. Dzięki czemu nie tylko zapewniłem sobie możliwość użycia absolutnie dowolnych glifów, ale i uniknąłem kosztownego rastrowania de facto wektorowych fontów i systemu cache'owania renderowanych glifów.

Spine
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7122
0

@flowCRANE: No akurat ta czcionka widocznie jest stworzona dla większych rozdzielczości. Pod retro grę wolałbyś mieć bardziej kanciaste grube retro kształty.
Więc zostaje szukanie innej czcionki, albo zrobienie czcionki samemu.
Zrobienie własnego wektorowego TTF to raczej nie jest bardziej skomplikowany proces niż rysowanie czcionki w jakimś Paint'cie.

Poza tym Text Mesh Pro ma różne opcje rasteryzacji czcionki.

screenshot-20251003004434.png

Aplikacja, w której przeprowadziłeś test, rozmywa ikonki z czcionki.
Co i tak nas nie urządza w przypadku tej konkretnej czcionki ;)

Raster 24
screenshot-20251003004555.png

Raster 32
screenshot-20251003004619.png

Raster 64
screenshot-20251003004709.png

SDFAA_HINTED 24
screenshot-20251003004856.png

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12317
0
Spine napisał(a):

Więc zostaje szukanie innej czcionki, albo zrobienie czcionki samemu.

I właśnie dlatego robię swoje.

Zrobienie własnego wektorowego TTF to raczej nie jest bardziej skomplikowany proces niż rysowanie czcionki w jakimś Paint'cie.

Zobacz sobie jak wyglądają edytory do tworzenia fontów wektorowych, a się przekonasz, że ich tworzenie jednak jest zdecydowanie bardziej skomplikowane, niż ustalanie kolorów poszczególnych pikseli w jakimś Paint.

Poza tym Text Mesh Pro ma różne opcje rasteryzacji czcionki.

Nie ważne jakiej metody użyjesz, glify i tak są kompletnie nieczytelne. Najlepiej prezentuje się Raster 64 z tych wymienionych, ale to i tak niczego nie zmienia, bo glif jest tak ze dwa razy za duży. Dla mniejszych wyjdzie straszna kupa.


Pasuje wrócić do pierwotnej dyskusji — w końcu @Kokoniłaj pytał o atlasy ze sprajtami animacji postaci, nie o fonty.

Kokoniłaj
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 197
0

Dziękuję Wam za porady. Nie planuję używać unity. Zgadzam się z flowCRANE jeżeli chodzi o licencje programów.

Jeżeli znacie jakieś programy do pakowania atlasów to bardzo chętnie je sprawdzę. Nie mam nic przeciwko używaniu jakiś sprawdzonych narzędzi. Sam bardzo lubię program Tiled, w którym tworzę mapy/poziomy.

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12317
2

Jak wspomniałem wcześniej, takie algorytmy są już opracowane i są do nich biblioteki. Nie wiem jakiego języka programowania używasz, ani czy potrzebujesz te atlasy pakować po stronie edytora (wydajność nie ma znaczenia) czy w runtime (wydajność ma znaczenie), ale możesz rzucić okiem na poniższe:

https://github.com/TeamHypersomnia/rectpack2D
A header-only, very efficient 2D rectangle packing library. Used in Assassin's Creed and Skydio drones. 2 scientific references.

https://github.com/nothings/stb/blob/master/stb_rect_pack.h
Useful for e.g. packing rectangular textures into an atlas. Does not do rotation.

https://github.com/soimy/maxrects-packer
A max rectangle 2d bin packer npm-module for packing glyphs or images into multiple sprite-sheet/atlas

Ogólnie najlepsze są algorytmy MaxRects i Skyline, z których do generowania atlasów korzystają choćby Unity, Godot czy libGDX. Z tego co doczytałem, Skyline charakteryzuje się najlepszą wydajnością. W razie czego zerknij też na artykuły o tych algorytmach, np. ten: The Skyline algorithm for packing 2D rectangles.


Nie wiem z którego ostatecznie skorzystam w swoim edytorze assetów, ale to raczej obojętne, bo wydajność nie będzie miała większego znaczenia (w końcu pakowanie atlasów będzie w edytorze, nie w runtime gry). Albo machnę własny algorytm — zobaczymy. 😉

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.