Direcionar formatos de compactação de textura em Android App Bundles

Texturas são imagens que podem ser aplicadas à superfície de um modelo 3D. Texturas também são usadas por renderizadores 2D para desenhar elementos como sprites ou planos de fundo. Esta página descreve formatos comuns de compactação de textura usados em jogos e como usá-los nos Android App Bundles. Leia Sobre os Android App Bundles e Play Asset Delivery antes de iniciar este guia.

Contexto

As GPUs geralmente oferecem suporte a um conjunto de formatos de compactação de textura. Um formato de compactação de textura (ou TCF, na sigla em inglês) é um formato de arquivo otimizado para GPUs. A GPU carrega e renderiza uma textura mais rapidamente e usando menos memória do que se estivesse usando uma matriz de valores RGBA na memória. Esse suporte é oferecido no nível do hardware: o fabricante da GPU incorpora componentes ao chip da placa de vídeo que lê, descompacta e renderiza os formatos com suporte.

Os formatos de compactação de textura comuns em hardware de dispositivos móveis modernos são estes:

  • ASTC: formato recente criado para substituir formatos anteriores. Mais flexível que os formatos anteriores, devido à compatibilidade com vários tamanhos de bloco. Usar esse formato é uma boa maneira de otimizar o tamanho do seu jogo.
  • ETC2: todos os dispositivos que oferecem suporte ao OpenGL ES 3.0 e versões mais recentes também têm suporte a esse formato. Isso inclui quase todos os dispositivos móveis Android ativos.

Esses formatos têm suporte das porcentagens aproximadas de dispositivos Android abaixo:

Formato de compactação de textura Percentual de dispositivos do Google Play com suporte
ASTC >80%
ETC2 >95%

As GPUs de computadores desktop com o Google Play Games para PC também oferecem suporte a este formato:

  • DDS ou S3TC: às vezes chamado de BCn, DXTC ou DXTn

Formatos de compactação de textura mais antigos e que não são mais recomendados incluem:

  • ETC1: com suporte na maioria dos dispositivos. Esse formato não oferece suporte à transparência, mas os jogos podem usar um segundo arquivo de textura para o componente alfa.
  • PVRTC: popular entre jogos para iOS e com suporte em alguns dispositivos Android.

O suporte a ETC1 só é um requisito para jogos com suporte a dispositivos legados muito antigos ou alguns dispositivos Android TV que não oferecem suporte ao OpenGL ES 3.0 e versões mais recentes.

Um formato padrão

Com tantos formatos disponíveis (com diferentes níveis de suporte a dispositivos), talvez você não saiba quais formatos usar ao criar texturas do jogo. Por segurança, o formato do pacote de apps permite que você selecione um formato de compactação de textura padrão para cada pacote de recursos. Se um dispositivo não oferecer suporte aos outros formatos especificados, os recursos que usam esse formato padrão serão instalados.

A menos que você esteja segmentando hardwares de dispositivo muito antigos, o ETC2 é uma boa opção como formato padrão. Use os formatos ETC2 que tem garantia de suporte ao OpenGL ES 3.0 (link em inglês). Esses formatos também estão disponíveis na API gráfica Vulkan.

O formato ASTC define vários tamanhos de blocos de compactação, o que permite trocar a qualidade da imagem reduzida de forma seletiva por uma compactação melhor. Dependendo da natureza do material de arte original, para uma determinada textura, é possível escolher um tamanho de bloco menor ou maior para manter uma qualidade visual aceitável.

Se o jogo oferece suporte ao Google Play Games para PC e usa Vulkan, você precisa incluir texturas S3TC. Os formatos S3TC oferecem suporte a todas as GPUs de computador.

Criar um pacote de app

O Google Play usa os Android App Bundles para gerar e disponibilizar APKs otimizados para a configuração do dispositivo de cada usuário, para que eles façam o download apenas do código e dos recursos necessários para execução do jogo. Esses APKs otimizados incluem um único conjunto de recursos de textura, formatados com a compactação ideal do dispositivo.

Caso seu jogo não use o Unity, use o Gradle para criar um pacote de apps. Os usuários avançados podem usar bundletool.

Se o jogo usa Unity, o suporte para pacotes de apps com o Play Asset Delivery está disponível no Unity 2021.3 e em versões mais recentes. Para saber mais, consulte a documentação do Unity (link em inglês). Você pode usar um plug-in do Unity para criar um pacote de apps com versões anteriores do Unity.

Usar o Gradle

  1. Atualize a versão do Plug-in do Android para Gradle no arquivo build.gradle do seu projeto para a versão 4.1 ou mais recente (por exemplo, com.android.tools.build:gradle:4.1.0).

  2. Determine o conjunto de tipos de dispositivos para os quais você quer direcionar o jogo e os formatos de compactação de textura compatíveis. Para mais informações sobre formatos, consulte Segundo plano.

  3. Crie versões dos recursos para cada formato de compactação de textura da etapa anterior. Isso pode envolver a geração de folhas de sprite usando softwares como o TexturePacker ou a execução de um script que converta recursos brutos em recursos com um formato específico, por exemplo, astc-encoder (links em inglês).

  4. Crie pacotes de recursos (consulte Criar para C++ ou Java), que contêm os recursos do seu jogo e são usados pelo Play Asset Delivery. Por exemplo, você pode criar um pacote de recursos por nível ou pacotes de recurso para diferentes partes do jogo.

  5. Dentro dos seus pacotes de recursos, adicione diretórios para cada formato de compactação de textura aos quais você quer oferecer compatibilidade. Adicione sufixos compatíveis aos nomes dos diretórios de textura que correspondem ao formato de compactação de textura usado para os arquivos contidos.

    Crie um diretório sem sufixo no nome (por exemplo, common/src/main/assets/textures/). Nesse diretório, coloque o formato padrão dos recursos de textura. Esse formato padrão precisa ser compatível com a maioria dos dispositivos (por exemplo, ETC1 ou ETC2). Se um dispositivo não for compatível com os outros formatos especificados (por exemplo, PVRTC e ASTC na tabela abaixo), a Google Play Store instalará esse diretório.

    Diretório antes Diretório depois
    Pacote de recursos common:
    common/build.gradle
    common/src/main/assets/textures/...
    Pacote de recursos common:
    common/build.gradle
    common/src/main/assets/textures/...
    common/src/main/assets/textures#tcf_astc/...
    common/src/main/assets/textures#tcf_pvrtc/...
    Pacote de recursos level1:
    level1/build.gradle
    level1/src/main/assets/textures/...
    Pacote de recursos level1:
    level1/build.gradle
    level1/src/main/assets/textures/...
    level1/src/main/assets/textures#tcf_astc/...
    level1/src/main/assets/textures#tcf_pvrtc/...
    Pacote de recursos level2:
    level2/build.gradle
    nível2/src/main/assets/textures/...
    Pacote de recursos level2:
    level2/build.gradle
    nível2/src/main/assets/textures/...
    level2/src/main/assets/textures#tcf_astc/...
    level2/src/main/assets/textures#tcf_pvrtc/...
  6. Atualize o arquivo build.gradle do seu app para ativar a divisão de pacotes de recursos por texturas.

    // In the app build.gradle file:
    android {
        ...
        bundle {
            texture {
                enableSplit true
            }
        }
    }
    
  7. No Android Studio, selecione Build > Generate Signed Bundle / APK ou inicie a tarefa do Gradle na linha de comando para gerar seu pacote.

Usar o plug-in do Unity para o Google Play

Faça o download do plug-in (ou pacote) do Unity para o Play Asset Delivery para criar um pacote de apps com pacotes de recursos destinados a texturas.

Preparar os recursos

Para preparar seus recursos de textura para criar um pacote de apps, faça o seguinte:

  1. Empacote o cenário e os recursos em vários AssetBundles do Unity.

  2. Determine o conjunto de tipos de dispositivos para os quais você quer direcionar o jogo e os formatos de compactação de textura compatíveis. Para mais informações sobre formatos, consulte Segundo plano.

  3. Modifique o script de compilação do jogo para gerar os AssetBundles várias vezes, uma vez para cada formato de textura compatível. Veja o exemplo de script a seguir:

    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. Verifique se cada recurso de textura é enviado em um diretório com o sufixo correto no nome (por exemplo, #tcf_astc).

    Verifique se um diretório sem sufixo no nome é enviado (por exemplo, Assets/AssetBundles/). Esse diretório contém o formato padrão dos recursos de textura. Esse formato padrão precisa ser compatível com a maioria dos dispositivos (por exemplo, ETC2). Se um dispositivo não for compatível com os outros formatos especificados (por exemplo, ASTC no código da etapa anterior), a Google Play Store instalará esse diretório.

    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. Selecione Google > Android > Asset Delivery.

  6. Clique em Add folder para adicionar a pasta que contém seus pacotes de recursos padrão. Esses pacotes são instalados em dispositivos que não são compatíveis com os outros formatos que você definir.

    Defina o Modo de transferência do AssetBundle.

    Formato padrão do Unity AssetBundle Delivery

  7. Clique em Add folder para adicionar uma pasta contendo AssetBundles criados para outro formato (por exemplo, ASTC). Repita conforme necessário.

    Defina o Modo de transferência de cada AssetBundle.

    Formato ASTC do Unity AssetBundle Delivery

Criar

Selecione Google > Build Android App Bundle para iniciar a versão do Unity do seu jogo. Ele também empacota os AssetBundles em vários pacotes de recursos, em que cada nome de AssetBundle é convertido em um único pacote de recursos.

(Avançado) Usar o bundletool

Para ver mais informações sobre bundletool, consulte Criar um pacote de apps usando o bundletool.

Para criar o pacote de apps, faça o seguinte:

  1. Fazer o download de bundletool do repositório do GitHub.

  2. Determine o conjunto de tipos de dispositivos para os quais você quer direcionar o jogo e os formatos de compactação de textura compatíveis. Para ver mais informações sobre formatos, consulte Segundo plano.

  3. Crie versões dos recursos para cada formato de compactação de textura da etapa anterior. Isso pode envolver a geração de folhas de sprite usando softwares como o TexturePacker ou a execução de um script que converta recursos brutos em recursos com um formato específico, por exemplo, astc-encoder (links em inglês).

  4. Crie pacotes de recursos (consulte Criar para C++ ou Java), que contêm os recursos do seu jogo e são usados pelo Play Asset Delivery. Por exemplo, você pode criar um pacote de recursos por nível ou pacotes de recurso para diferentes partes do jogo.

  5. Nos diferentes pacotes de recursos, adicione sufixos compatíveis aos nomes de diretório de textura que correspondem ao formato de compactação de textura usado para os arquivos contidos.

    Crie um diretório sem sufixo no nome (por exemplo, common/src/main/assets/textures/). Nesse diretório, coloque o formato padrão dos recursos de textura. Esse formato padrão precisa ser compatível com a maioria dos dispositivos (por exemplo, ETC1 ou ETC2). Se um dispositivo não for compatível com os outros formatos especificados (por exemplo, PVRTC e ASTC na tabela abaixo), a Google Play Store instalará esse diretório.

    Diretório antes Diretório depois
    Pacote de recursos common:
    common/build.gradle
    common/src/main/assets/textures/...
    Pacote de recursos common:
    common/build.gradle
    common/src/main/assets/textures/...
    common/src/main/assets/textures#tcf_astc/...
    common/src/main/assets/textures#tcf_pvrtc/...
    Pacote de recursos level1:
    level1/build.gradle
    level1/src/main/assets/textures/...
    Pacote de recursos level1:
    level1/build.gradle
    level1/src/main/assets/textures/...
    level1/src/main/assets/textures#tcf_astc/...
    level1/src/main/assets/textures#tcf_pvrtc/...
    Pacote de recursos level2:
    level2/build.gradle
    nível2/src/main/assets/textures/...
    Pacote de recursos level2:
    level2/build.gradle
    nível2/src/main/assets/textures/...
    level2/src/main/assets/textures#tcf_astc/...
    level2/src/main/assets/textures#tcf_pvrtc/...
  6. Adicione a dimensão do TCF ao arquivo de metadados do pacote de apps (BundleConfig.json). Use TEXTURE_COMPRESSION_FORMAT no campo value:

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

    Defina suffixStripping.enabled como true para remover o sufixo (por exemplo, #tcf_astc) dos nomes dos diretórios ao gerar os pacotes de recursos. Isso permite que o jogo leia arquivos de um nome de diretório conhecido (por exemplo, level1/assets/textures). Alguns mecanismos de jogos podem detectar o formato de um arquivo. Seu jogo pode não levar em consideração o formato de recursos de textura com que foi instalado.

    suffixStripping.defaultSuffix especifica o sufixo do diretório padrão quando bundletool gera um APK autônomo para dispositivos com o Android 5.0 (nível 21 da API) e versões anteriores. Na tabela de exemplo anterior, a versão padrão dos recursos de textura é instalada nesses dispositivos. Esse é o comportamento desejado na maioria dos casos.

  7. Criar o pacote de apps:

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

Verificar o conteúdo do pacote de apps

Caso ainda não tenha feito isso, fazer o download do bundletool do repositório do GitHub.

Verifique o conteúdo do pacote de apps de saída criando APKs nele e os inspecionando:

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

A saída será semelhante a esta:

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

Esses nomes indicam que a TCF alvo foi aplicada corretamente. Se você extrair o conteúdo de um APK de nível (por exemplo, asset-slices/level1-astc.apk), poderá verificar se apenas um diretório com o nome textures está presente.

Testar o pacote de apps

Conecte um dispositivo e instale os pacotes de recursos aplicáveis:

bundletool install-apks --apks=APKS.apks

Esse comando instala somente os pacotes de recursos que atendem às especificações do dispositivo. Essas especificações incluem ABI, densidade de tela, idioma e o formato de compactação de textura mais adequado. Essa operação simula o que é feito pela Google Play Store para o jogo publicado.

Para verificar se os pacotes de recursos corretos foram instalados, siga um destes procedimentos:

  • Use o comando bundletool extract-apks para gerar os APKs de saída instalados para seu dispositivo em um diretório e, em seguida, inspecione esse diretório.

    1. Extraia a especificação de seu dispositivo:

      bundletool get-device-spec --output=MY_DEVICE_SPEC.json
      
    2. Execute bundletool extract-apks com esta especificação de dispositivo:

      bundletool extract-apks --apks=APKS.apks --device-spec=MY_DEVICE_SPEC.json \
          --output-dir out
      
    3. Liste os arquivos no diretório out e verifique se os pacotes de recursos adequados estão instalados. Os nomes dos pacotes de recursos são sufixados pelo nome do formato de textura (por exemplo, level1-astc.apk).

  • Adicione log statements ao jogo que mostrem o formato da textura ao carregar uma textura.

  • Gere um conjunto de teste de texturas (por exemplo, substitua uma textura por uma única cor brilhante para determinado formato). Execute o jogo e verifique se ele está presente.

Se o app tiver pacotes de recursos on-demand ou fast-follow, use a solução de teste local para a entrega de recursos.

Sufixos compatíveis para nomes de diretório de textura

O Google Play entende os seguintes sufixos usados em nomes de diretórios de textura:

  • #tcf_astc para compactação de textura escalonável adaptável (ASTC, na sigla em inglês)
  • #tcf_atc para compactação de textura ATI (ATC, na sigla em inglês)
  • #tcf_dxt1 para compactação de textura S3 DXT1 (DXT1)
  • #tcf_latc para compactação de textura luminância-alfa (LATC, na sigla em inglês)
  • #tcf_paletted para compactação genérica de textura colorida
  • #tcf_pvrtc para compactação de textura de PowerVR (PVRTC, na sigla em inglês)
  • #tcf_etc1 para compactação de textura Ericsson (ETC1, na sigla em inglês)
  • #tcf_etc2 para compactação de textura de Ericsson 2 (ETC2, na sigla em inglês)
  • #tcf_s3tc para compactação de textura S3 (S3TC, na sigla em inglês)
  • #tcf_3dc para compactação de textura ATI 3Dc (3Dc)

Regras de exibição do Google Play

O Google Play inspeciona as strings de extensão do OpenGL usadas pelo dispositivo e a versão do OpenGL compatível com o dispositivo. O Google Play usa essas informações para determinar o formato de textura correto a ser entregue ao dispositivo a partir do Android App Bundle.

O Google Play envia o primeiro formato, na ordem listada na tabela a seguir, que for compatível com o dispositivo.

Se nenhum dos formatos de textura do pacote de apps for compatível com o dispositivo, o Google Play enviará os formatos de textura empacotados no formato padrão. A menos que você tenha algum hardware específico de dispositivo como alvo, o ETC1 ou o ETC2 são boas opções para um formato padrão. Para ver informações sobre como empacotar recursos no formato padrão, consulte Usar bundletool ou Usar o plug-in do Unity para Google Play.

Se os recursos não tiverem sido empacotados em um formato padrão, o Google Play marcará o app como não disponível para o dispositivo. Nesse caso, os usuários não poderão fazer o download do app.

Formato (designado em tcf_xxxx) Compatível com dispositivos que têm a string de extensão OpenGL
astc GL_KHR_texture_compression_astc_ldr
pvrtc GL_IMG_texture_compression_pvrtc
s3tc GL_EXT_texture_compression_s3tc
dxt1 GL_EXT_texture_compression_dxt1
latc GL_EXT_texture_compression_latc
atc GL_AMD_compressed_ATC_texture
3dc GL_AMD_compressed_3DC_texture
etc2 Não aplicável. O dispositivo precisa oferecer suporte ao OpenGL ES versão 3.0 ou mais recente.
etc1 GL_OES_compressed_ETC1_RGB8_texture
paletted GL_OES_compressed_paletted_texture