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 em dispositivos móveis geralmente são compatíveis com 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. Essa compatibilidade é feita 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 compatíveis.

Os formatos de compactação de textura comuns são os seguintes:

  • DDS ou S3TC: às vezes chamado de DXTC ou DXTn Três formas desse formato são compatíveis com o OpenGL.
  • ETC1: compatível com a maioria dos dispositivos. Esse formato não é compatível com transparência, mas os jogos podem usar um segundo arquivo de textura para o componente alfa.
  • ETC2: compatível com todos os dispositivos que aceitam GLES3.
  • PVRTC: popular entre jogos para iOS e compatível com alguns dispositivos Android.
  • 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.

Os seguintes formatos são compatíveis com as seguintes percentuais de dispositivos Android:

Formato de compactação de textura Percentual de dispositivos do Google Play compatíveis 1
ETC1 99%
ETC2 87%
ASTC 77%
ATC 35%
PVRTC 11%
DXT1 0,7%

1 Porcentagens calculadas usando dados coletados de dispositivos ativos do Google Play em setembro de 2020

Um formato padrão

Com tantos formatos disponíveis (com diferentes níveis de compatibilidade com 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 for compatível com os outros formatos especificados, os recursos que usam esse formato padrão serão instalados.

A menos que você direcione para hardware específico do dispositivo, o ETC1 e o ETC2 são boas opções para um formato padrão porque são compatíveis com a maioria dos dispositivos. Caso seu jogo seja destinado ao OpenGL ES 3.0 ou mais recente, você poderá escolher o ETC2 como o formato padrão se escolher um dos formatos ETC2 que têm garantia de compatibilidade com OpenGL ES 3.0.

Criar um pacote de apps

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 à execução do jogo. Esses APKs otimizados incluem um único conjunto de recursos de textura, formatados com a compactação ideal para o 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.

Caso seu jogo use o Unity, você poderá usar um plug-in do Unity para criar um pacote de apps.

Usar o Gradle

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

  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 software como TexturePacker ou a execução de um script que converta recursos brutos em recursos com um formato específico (por exemplo, astc-encoder).

  4. Crie pacotes de recursos (consulte Criar para conteúdo nativo 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 ver 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. Faça o download de bundletool no repositório do GitHub dele.

  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 software como TexturePacker ou a execução de um script que converta recursos brutos em recursos com um formato específico (por exemplo, astc-encoder).

  4. Crie pacotes de recursos (consulte Criar para conteúdo nativo 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 (como level1/assets/textures). Alguns mecanismos de jogos podem detectar o formato de um arquivo, portanto, seu jogo pode ser independente do formato de recursos de textura que estiver 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 da API 21) 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

Faça o download do bundletool no repositório do GitHub, caso ainda não tenha feito.

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

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 o TCF alvo foi aplicado corretamente. Se você descompactar o conteúdo de um APK de nível (por exemplo, asset-slices/level1-astc.apk), poderá verificar se apenas um diretório denominado 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 instalará apenas 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 ser compatível com o OpenGL ES versão 3.0 ou mais recente.
etc1 GL_OES_compressed_ETC1_RGB8_texture
paletted GL_OES_compressed_paletted_texture