Kierowanie na formaty kompresji tekstur w pakietach Android App Bundle

Tekstury to obrazy, które można nakładać na powierzchnię modelu 3D. Mechanizmy renderowania 2D używają też tekstury do rysowania elementów takich jak sprite czy tła. Na tej stronie opisujemy popularne formaty kompresji tekstur używane w grach oraz sposoby kierowania na nie w pakietach Android App Bundle. Zanim zaczniesz korzystać z tego przewodnika, przeczytaj artykuły Informacje o pakietach Android App Bundle i Play Asset Delivery.

Tło

Procesory graficzne zwykle obsługują zestaw formatów kompresji tekstur. Format kompresji tekstur (TCF) to format pliku zoptymalizowany pod kątem procesorów graficznych. GPU wczytuje i renderuje teksturę szybciej i z mniejszą ilością pamięci niż w przypadku użycia tablicy wartości RGBA w pamięci. Ta obsługa odbywa się na poziomie sprzętu: producent GPU umieszcza komponenty w układzie karty graficznej, który odczytuje, dekompresuje i renderuje obsługiwane formaty.

Oto popularne formaty kompresji tekstur na nowoczesnym sprzęcie mobilnym:

  • ASTC: najnowszy format zaprojektowany, aby zastąpić wcześniejsze formaty. Większa elastyczność niż wcześniejsze formaty dzięki obsłudze różnych rozmiarów bloków. Użycie tego formatu to dobry sposób zoptymalizowania rozmiaru gry.
  • ETC2: obsługiwane przez wszystkie urządzenia obsługujące OpenGL ES 3.0 i nowsze. Dotyczy to niemal wszystkich aktywnych urządzeń mobilnych z Androidem.

Te formaty są obsługiwane przez następujące przybliżone wartości procentowe urządzeń z Androidem:

Format kompresji tekstur Odsetek urządzeń Google Play, które obsługują funkcję
ASTC >80%
ETC2 >95%

Procesory graficzne na komputery obsługujące Gry Google Play na PC też obsługują ten format:

  • DDS lub S3TC: czasami nazywany BCn, DXTC lub DXTn.

Starsze, niezalecane formaty kompresji tekstur to:

  • ETC1: obsługiwane na większości urządzeń. Ten format nie obsługuje przezroczystości, ale gry mogą używać drugiego pliku tekstury dla komponentu alfa.
  • PVRTC: popularne w grach na iOS, a także obsługiwane na niektórych urządzeniach z Androidem.

Obsługa ETC1 jest wymagana tylko w przypadku gier obsługujących starsze urządzenia lub wybranych urządzeń z Androidem TV, które nie obsługują OpenGL ES 3.0 i nowszych.

Format domyślny

Przy tak dużej liczbie dostępnych formatów (z różnymi poziomami obsługi urządzeń) możesz nie wiedzieć, których formatów użyć do tworzenia tekstur gry. Na wszelki wypadek format pakietu aplikacji pozwala wybrać domyślny format kompresji tekstur dla każdego pakietu zasobów. Jeśli urządzenie nie obsługuje innych określonych formatów, instalowane są zasoby w tym formacie.

Jeśli nie kierujesz reklam na bardzo stary sprzęt, ETC2 będzie dobrym wyborem dla formatu domyślnego. Używaj formatów ETC2, które będą obsługiwane przez OpenGL ES 3.0. Formaty te są również dostępne w interfejsie Vulkan Graphic API.

Format ASTC określa różne rozmiary bloków kompresji, co umożliwia selektywne handel nimi o zmniejszonej jakości obrazu w celu uzyskania większej kompresji. W zależności od charakteru źródłowego materiału graficznego dla danej tekstury możesz wybrać mniejszy lub większy rozmiar bloków, aby zachować akceptowalną jakość wizualną.

Jeśli Twoja gra obsługuje Gry Google Play na PC i korzysta z interfejsu Vulkan, dodaj tekstury S3TC. Formaty S3TC są obsługiwane przez wszystkie procesory graficzne

Tworzenie pakietu aplikacji

Google Play używa pakietów Android App Bundle do generowania i udostępniania zoptymalizowanych plików APK dopasowanych do konfiguracji urządzenia każdego użytkownika. Dzięki temu użytkownicy pobierają tylko kod i zasoby niezbędne do uruchomienia gry. Te zoptymalizowane pliki APK zawierają pojedynczy zestaw zasobów tekstur sformatowanych z użyciem optymalnego formatu kompresji dla danego urządzenia.

Jeśli Twoja gra nie jest w Unity, użyj Gradle, by utworzyć pakiet aplikacji. Doświadczeni użytkownicy mogą użyć bundletool.

Jeśli Twoja gra jest na platformie Unity, obsługa pakietów aplikacji z funkcją Play Asset Delivery jest dostępna w Unity w wersji 2021.3 i nowszych. Więcej informacji znajdziesz w dokumentacji Unity. Aby utworzyć pakiet aplikacji na starszą wersję Unity, możesz użyć wtyczki Unity.

Używanie Gradle

  1. Zaktualizuj wersję wtyczki Androida do obsługi Gradle w pliku build.gradle projektu do wersji 4.1 lub nowszej (np. com.android.tools.build:gradle:4.1.0).

  2. Określ zestaw typów urządzeń, na które chcesz kierować swoją grę, i obsługiwane przez nie formaty kompresji tekstur (więcej informacji o formatach znajdziesz w sekcji Informacje ogólne).

  3. Utwórz wersje zasobów dla każdego formatu kompresji tekstur z poprzedniego kroku. Może to być np. wygenerowanie arkuszy sprite za pomocą oprogramowania TexturePacker lub uruchomienie skryptu, który konwertuje nieprzetworzone zasoby na te w określonym formacie (np. astc-encoder).

  4. Utwórz pakiety zasobów (patrz Tworzenie plików w języku C++ lub Java), które zawierają zasoby gry i są używane przez Play Asset Delivery. Możesz na przykład utworzyć po 1 pakiecie zasobów na każdy poziom lub różne pakiety dla poszczególnych części gry.

  5. W pakietach zasobów dodaj katalogi dla każdego formatu kompresji tekstur, który chcesz obsługiwać. Dodaj obsługiwane sufiksy do nazw katalogów tekstur odpowiadające formatowi kompresji tekstur używanym w zawartych plikach.

    Utwórz katalog bez przyrostka w nazwie (np. common/src/main/assets/textures/). W tym katalogu umieść domyślny format zasobów tekstur. Ten format domyślny powinien być obsługiwany przez większość urządzeń (np. ETC1 lub ETC2). Jeśli urządzenie nie obsługuje innych określonych formatów (np. PVRTC i ASTC w tabeli poniżej), Sklep Google Play zainstaluje ten katalog.

    Katalog przed Katalog po
    Pakiet zasobów common:
    common/build.gradle
    common/src/main/assets/textures/...
    Pakiet zasobów common:
    common/build.gradle
    common/src/main/assets/textures/...
    common/src/main/assets/textures#tcf_astc/...
    common/src/main/assets/textures#tcf_pvrtc/...
    Pakiet zasobów level1:
    poziom1/build.gradle
    level1/src/main/assets/textures/...
    Pakiet zasobów level1:
    poziom1/build.gradle
    level1/src/main/assets/textures/...
    level1/src/main/assets/textures#tcf_astc/...
    level1/src/main/assets/textures#tcf_pvrtc/...
    Pakiet zasobów level2:
    poziom2/build.gradle
    level2/src/main/assets/textures/...
    Pakiet zasobów level2:
    poziom2/build.gradle
    level2/src/main/assets/textures/...
    level2/src/main/assets/textures#tcf_astc/...
    level2/src/main/assets/textures#tcf_pvrtc/...
  6. Zaktualizuj plik build.gradle aplikacji, aby umożliwić podział pakietów zasobów według tekstur.

    // In the app build.gradle file:
    android {
        ...
        bundle {
            texture {
                enableSplit true
            }
        }
    }
    
  7. W Android Studio wybierz Build > Generate Signed Bundle / APK (Utwórz > Wygeneruj podpisany pakiet / plik APK) lub uruchom zadanie Gradle z poziomu wiersza poleceń, aby wygenerować pakiet.

Użyj wtyczki Google Play Unity

Pobierz wtyczkę (lub pakiet) Unity do Play Asset Delivery, aby utworzyć pakiet aplikacji z pakietami zasobów kierowanych na tekstury.

Przygotowanie zasobów

Aby przygotować zasoby tekstur do utworzenia pakietu aplikacji, wykonaj te czynności:

  1. Zadbaj o oprawę sceny i zasobów w wiele obiektów AssetBundles na platformie Unity.

  2. Określ zestaw typów urządzeń, na które chcesz kierować swoją grę, i obsługiwane przez nie formaty kompresji tekstur (więcej informacji o formatach znajdziesz w sekcji Informacje ogólne).

  3. Zmodyfikuj skrypt kompilacji gry, aby wielokrotnie generować zasoby AssetBundles, po jednym razie dla każdego obsługiwanego formatu tekstur. Zobacz ten przykładowy skrypt:

    using Google.Android.AppBundle.Editor;
    using UnityEditor;
    
    public class MyBundleBuilder
    {
       [MenuItem("Assets/Build AssetBundles TCF variants")]
       public static void BuildAssetBundles()
       {
           // Describe the AssetBundles to be built:
           var assetBundlesToBuild = new []
           {
               new AssetBundleBuild
               {
                   assetBundleName = "level1-textures",
                   assetNames = new[] {"level1/character-textures", "level1/background-textures"}
               },
               new AssetBundleBuild
               {
                   assetBundleName = "level2-textures",
                   assetNames = new[] {"level2/character-textures", "level2/background-textures"}
               }
           };
    
           // Describe where to output the asset bundles and in which formats:
           var outputPath = "Assets/AssetBundles";
           var defaultTextureFormat = MobileTextureSubtarget.ETC2;
           var additionalTextureFormats = new[] { MobileTextureSubtarget.ASTC, MobileTextureSubtarget.PVRTC }
           var allowClearDirectory = true;
    
           // Generate asset bundles:
           AssetBundleBuilder.BuildAssetBundles(
               outputPath,
               assetBundlesToBuild,
               BuildAssetBundleOptions.UncompressedAssetBundle,
               defaultTextureFormat,
               additionalTextureFormats,
               allowClearDirectory);
    
           // While in this example we're using the UI to configure the
           // AssetBundles, you can use the value returned by BuildAssetBundles
           // to configure the asset packs, if you want to build the bundle
           // entirely using the scripting API.
       }
    }
    
  4. Sprawdź, czy każdy zasób tekstury znajduje się w katalogu z prawidłowym sufiksem w nazwie (np. #tcf_astc).

    Sprawdź, czy katalog bez sufiksu w nazwie jest generowany (np. Assets/AssetBundles/). Ten katalog zawiera domyślny format zasobów tekstur. Ten format domyślny powinien być obsługiwany przez większość urządzeń (np. ETC2). Jeśli urządzenie nie obsługuje innych określonych formatów (np. ASTC w kodzie z poprzedniego kroku), Sklep Google Play zainstaluje ten katalog.

    Assets/AssetBundles.meta
    Assets/AssetBundles/AssetBundles
    Assets/AssetBundles/AssetBundles.manifest
    Assets/AssetBundles/AssetBundles.manifest.meta
    Assets/AssetBundles/AssetBundles.meta
    Assets/AssetBundles/samplescene
    Assets/AssetBundles/samplescene.manifest
    Assets/AssetBundles/samplescene.manifest.meta
    Assets/AssetBundles/samplescene.meta
    Assets/AssetBundles/texturesbundle
    Assets/AssetBundles/texturesbundle.manifest
    Assets/AssetBundles/texturesbundle.manifest.meta
    Assets/AssetBundles/texturesbundle.meta
    Assets/AssetBundles#tcf_astc.meta
    Assets/AssetBundles#tcf_astc/AssetBundles
    Assets/AssetBundles#tcf_astc/AssetBundles.manifest
    Assets/AssetBundles#tcf_astc/AssetBundles.manifest.meta
    Assets/AssetBundles#tcf_astc/AssetBundles.meta
    Assets/AssetBundles#tcf_astc/samplescene
    Assets/AssetBundles#tcf_astc/samplescene.manifest
    Assets/AssetBundles#tcf_astc/samplescene.manifest.meta
    Assets/AssetBundles#tcf_astc/samplescene.meta
    Assets/AssetBundles#tcf_astc/texturesbundle
    Assets/AssetBundles#tcf_astc/texturesbundle.manifest
    Assets/AssetBundles#tcf_astc/texturesbundle.manifest.meta
    Assets/AssetBundles#tcf_astc/texturesbundle.meta
    
  5. Wybierz Google > Android > Assets Delivery.

  6. Kliknij Dodaj folder, aby dodać folder zawierający domyślne pakiety zasobów. Pakiety są instalowane na urządzeniach, które nie obsługują innych zdefiniowanych przez Ciebie formatów.

    Pamiętaj, by ustawić Tryb wyświetlania dla AssetBundle.

    Domyślny format Unity AssetBundle Delivery

  7. Kliknij Dodaj folder, aby dodać folder zawierający pakiet AssetBundles utworzony na potrzeby innego formatu (np. ASTC). Powtórz w razie potrzeby.

    Pamiętaj, aby dla każdego pakietu AssetBundle ustawić tryb wyświetlania.

    Format ASTC Unity AssetBundle Delivery

Budowanie

Wybierz Google > Utwórz pakiet Android App Bundle, aby uruchomić kompilację Unity swojej gry. Pakuje on też obiekty AssetBundles w wiele pakietów zasobów, w których każda nazwa AssetBundle jest konwertowana na jeden.

(Zaawansowane) Użyj narzędzia pakietu

Więcej informacji o usłudze bundletool znajdziesz w artykule Tworzenie pakietu aplikacji za pomocą narzędziabundle.

Aby utworzyć pakiet aplikacji:

  1. Pobierz usługę bundletool ze swojego repozytorium na GitHubie.

  2. Określ zestaw typów urządzeń, na które chcesz kierować swoją grę, i obsługiwane przez nie formaty kompresji tekstur (więcej informacji o formatach znajdziesz w sekcji Informacje ogólne).

  3. Utwórz wersje zasobów dla każdego formatu kompresji tekstur z poprzedniego kroku. Może to być np. wygenerowanie arkuszy sprite za pomocą oprogramowania TexturePacker lub uruchomienie skryptu, który konwertuje nieprzetworzone zasoby na te w określonym formacie (np. astc-encoder).

  4. Utwórz pakiety zasobów (patrz Tworzenie plików w języku C++ lub Java), które zawierają zasoby gry i są używane przez Play Asset Delivery. Możesz na przykład utworzyć po 1 pakiecie zasobów na każdy poziom lub różne pakiety dla poszczególnych części gry.

  5. W różnych pakietach zasobów dodaj obsługiwane sufiksy do nazw katalogów tekstur odpowiadające formatowi kompresji tekstur używanym w przypadku znajdujących się w nim plików.

    Utwórz katalog bez przyrostka w nazwie (np. common/src/main/assets/textures/). W tym katalogu umieść domyślny format zasobów tekstur. Ten format domyślny powinien być obsługiwany przez większość urządzeń (np. ETC1 lub ETC2). Jeśli urządzenie nie obsługuje innych określonych formatów (np. PVRTC i ASTC w tabeli poniżej), Sklep Google Play zainstaluje ten katalog.

    Katalog przed Katalog po
    Pakiet zasobów common:
    common/build.gradle
    common/src/main/assets/textures/...
    Pakiet zasobów common:
    common/build.gradle
    common/src/main/assets/textures/...
    common/src/main/assets/textures#tcf_astc/...
    common/src/main/assets/textures#tcf_pvrtc/...
    Pakiet zasobów level1:
    poziom1/build.gradle
    level1/src/main/assets/textures/...
    Pakiet zasobów level1:
    poziom1/build.gradle
    level1/src/main/assets/textures/...
    level1/src/main/assets/textures#tcf_astc/...
    level1/src/main/assets/textures#tcf_pvrtc/...
    Pakiet zasobów level2:
    poziom2/build.gradle
    level2/src/main/assets/textures/...
    Pakiet zasobów level2:
    poziom2/build.gradle
    level2/src/main/assets/textures/...
    level2/src/main/assets/textures#tcf_astc/...
    level2/src/main/assets/textures#tcf_pvrtc/...
  6. Dodaj wymiar zasad TCF do pliku metadanych pakietu aplikacji (BundleConfig.json). Użyj w polu value parametru TEXTURE_COMPRESSION_FORMAT:

    {
      ...
      "optimizations": {
        "splitsConfig": {
          "splitDimension": [
          ...
          {
             "value": "TEXTURE_COMPRESSION_FORMAT",
             "negate": false,
             "suffixStripping": {
               "enabled": true,
               "defaultSuffix": ""
              }
          }],
        }
      }
    }
    

    Ustaw suffixStripping.enabled na true, aby podczas generowania pakietów zasobów usunąć sufiks (np. #tcf_astc) z nazw katalogów. Umożliwia to grze odczytywanie plików ze znanej nazwy katalogu (np. level1/assets/textures). Niektóre silniki gier wykrywają format pliku, więc gra może rozróżniać format zasobów tekstur, z którymi została zainstalowana.

    suffixStripping.defaultSuffix określa domyślny sufiks katalogu, gdy bundletool generuje samodzielny plik APK na urządzenia z Androidem 5.0 (poziom interfejsu API 21) lub starszym. W tabeli przykładowej na tych urządzeniach jest instalowana domyślna wersja zasobów tekstur. To zamierzone działanie w większości przypadków.

  7. Utwórz pakiet aplikacji:

    bundletool build-bundle --config=BUILD_CONFIG.json \
      --modules=level1.zip,level2.zip,common.zip,base.zip --output=MY_BUNDLE.aab
    

Sprawdzanie zawartości pakietu aplikacji

Pobierz plik bundletool z repozytorium GitHub, jeśli jeszcze go nie masz.

Sprawdź zawartość wyjściowego pakietu aplikacji, tworząc z niego pliki APK i sprawdzając je:

bundletool build-apks --output=APKS.apks --bundle=MY_BUNDLE.aab
zipinfo APKS.apks

Dane wyjściowe powinny wyglądać mniej więcej tak:

toc.pb
splits/base-master.apk
splits/base-armeabi_v7a.apk
splits/…
asset-slices/level1-astc.apk
asset-slices/level1-other_tcf.apk
asset-slices/level1-pvrtc.apk

Te nazwy wskazują, że kierowanie zgodnie z zasadami TCF jest stosowane prawidłowo. Po wyodrębnieniu zawartości pliku APK na poziomie (np. asset-slices/level1-astc.apk) możesz sprawdzić, czy istnieje tylko jeden katalog o nazwie textures.

Testowanie pakietu aplikacji

Podłącz urządzenie i zainstaluj odpowiednie pakiety zasobów:

bundletool install-apks --apks=APKS.apks

To polecenie instaluje tylko te pakiety zasobów, które są zgodne ze specyfikacją urządzenia. Obejmują one interfejs ABI, gęstość ekranu, język i najbardziej odpowiedni format kompresji tekstur. Ta operacja symuluje czynności wykonywane w Sklepie Google Play w odniesieniu do opublikowanej gry.

Aby sprawdzić, czy zainstalowano prawidłowe pakiety zasobów, wykonaj jedną z tych czynności:

  • Użyj polecenia bundletool extract-apks, aby umieścić w katalogu pakiety apks zainstalowane na urządzeniu, a następnie sprawdzić ten katalog.

    1. Wyodrębnij specyfikację swojego urządzenia:

      bundletool get-device-spec --output=MY_DEVICE_SPEC.json
      
    2. Uruchom plik bundletool extract-apks z tą specyfikacją urządzenia:

      bundletool extract-apks --apks=APKS.apks --device-spec=MY_DEVICE_SPEC.json \
          --output-dir out
      
    3. Wymień pliki w katalogu out i sprawdź, czy są zainstalowane odpowiednie pakiety zasobów. Nazwy pakietów zasobów są dodawane do nazwy formatu tekstury (np. level1-astc.apk).

  • Dodaj w grze instrukcje logu, które podczas wczytywania tekstury zwracają format tekstury.

  • Wygeneruj testowy zestaw tekstur (na przykład zastąp teksturę jednym jasnym kolorem dla danego formatu). Uruchom grę i sprawdź, czy jest widoczna.

Jeśli Twoja aplikacja zawiera pakiety zasobów on-demand lub fast-follow, użyj lokalnego rozwiązania testowego do przesyłania zasobów.

Obsługiwane sufiksy dla nazw katalogów tekstur

Google Play rozumie te przyrostki używane w nazwach katalogów tekstur:

  • #tcf_astc na potrzeby adaptacyjnej skalowalnej kompresji tekstur (ASTC)
  • #tcf_atc – kompresja tekstur ATI (ATC)
  • #tcf_dxt1 – kompresja tekstury S3 DXT1 (DXT1)
  • #tcf_latc dla kompresji tekstur Luminance-alfa (LATC)
  • #tcf_paletted – ogólna kompresja tekstur z użyciem palety
  • #tcf_pvrtc – kompresja tekstur PowerVR (PVRTC)
  • #tcf_etc1 dla kompresji tekstur Ericsson (ETC1)
  • #tcf_etc2 dla kompresji tekstur Ericsson 2 (ETC2)
  • #tcf_s3tc – kompresja tekstur S3 (S3TC)
  • #tcf_3dc – kompresja tekstur ATI 3Dc (3Dc)

Reguły wyświetlania reklam Google Play

Google Play sprawdza ciągi rozszerzeń OpenGL używane przez urządzenie oraz obsługiwaną przez nie wersję OpenGL. Google Play wykorzystuje te informacje, aby określić prawidłowy format tekstury, który ma zostać przesłany na urządzenie, z poziomu pakietu Android App Bundle.

Google Play wyświetla pierwszy format obsługiwany przez urządzenie (w kolejności podanej w tabeli poniżej).

Jeśli urządzenie nie obsługuje żadnego z formatów tekstur z pakietu aplikacji, Google Play dostarcza te formaty w formacie domyślnym. (O ile nie kierujesz reklam na konkretne urządzenie, dobrym wyborem jest format domyślny, ETC1 lub ETC2). Informacje o pakowaniu zasobów w formacie domyślnym znajdziesz w artykułach Używanie narzędzia pakietu i wtyczki Google Play Unity.

Jeśli zasoby nie zostały spakowane w formacie domyślnym, Google Play oznaczy aplikację jako niedostępną dla danego urządzenia. W takim przypadku użytkownicy nie mogą pobrać aplikacji.

Format (oznaczony w: tcf_xxxx) Obsługiwany na urządzeniach z ciągiem rozszerzenia OpenGL
astc GL_KHR_texture_compression_astc_ldr
PVR GL_IMG_texture_compression_pvrtc
s3tc GL_EXT_texture_compression_s3tc
DXT1 GL_EXT_texture_compression_dxt1
latc GL_EXT_texture_compression_latc
ATAC GL_AMD_compressed_ATC_texture
3dc GL_AMD_compressed_3DC_texture
itd. 2 Nie dotyczy. Urządzenie musi obsługiwać platformę OpenGL ES w wersji 3.0 lub nowszej.
itd. 1 GL_OES_compressed_ETC1_RGB8_texture
paleta GL_OES_compressed_paletted_texture