Cómo orientar los formatos de compresión de texturas en Android App Bundle

Las texturas son imágenes que se pueden aplicar a la superficie de un modelo 3D. Los procesadores 2D también usan texturas para dibujar elementos, como objetos o fondos. En esta página, se describen los formatos de compresión de texturas más utilizados para juegos y cómo orientarlos en Android App Bundle. Consulta Acerca de Android App Bundle y Play Asset Delivery antes de comenzar con esta guía.

Fondo

Por lo general, las GPU de dispositivos móviles admiten un conjunto de formatos de compresión de texturas. El formato de compresión de texturas (o TCF) es un formato de archivo optimizado para GPU. La GPU carga y renderiza una textura con más rapidez y menos consumo de memoria que si utiliza un arreglo de valores RGBA en la memoria. Esta compatibilidad se realiza en el nivel del hardware: el fabricante de GPU incorpora componentes en el chip de las tarjetas gráficas que leen, descomprimen y procesan los formatos compatibles.

Los siguientes son formatos comunes de compresión de texturas:

  • DDS o S3TC: a veces llamado DXTC o DXTn. OpenGL es compatible con tres formas de este formato.
  • ETC1: compatible con la mayoría de los dispositivos. Este formato no es compatible con la transparencia, pero los juegos pueden usar un segundo archivo de textura para el componente Alfa.
  • ETC2: compatible con todos los dispositivos que admiten GLES3.
  • PVRTC: se utiliza mucho en los juegos para iOS y también es compatible con algunos dispositivos Android.
  • ASTC: formato reciente diseñado para sustituir a los formatos anteriores. Más flexible que los formatos anteriores debido a la compatibilidad con varios tamaños de bloque. El uso de este formato es una buena manera de optimizar el tamaño de tu juego.

A continuación, se muestra el porcentaje de compatibilidad de los dispositivos Android con los formatos:

Formato de compresión de texturas Porcentaje de dispositivos de Google Play compatibles1
ETC1 99%
ETC2 87%
ASTC 77%
ATC 35%
PVRTC 11%
DXT1 0.7%

1 Porcentajes calculados a partir de los datos recopilados de dispositivos Google Play activos en septiembre de 2020

Un formato predeterminado

Con tantos formatos disponibles (con distintos niveles de compatibilidad con dispositivos), es posible que no sepas qué formatos usar cuando compiles las texturas de tu juego. Como protección, el formato del paquete de aplicación te permite seleccionar un formato de compresión de texturas predeterminado para cada paquete de elementos. Si un dispositivo no admite los demás formatos especificados, se instalan los elementos que usan este formato predeterminado.

A menos que el objetivo sea hardware específico del dispositivo, ETC1 y ETC2 son buenas opciones para un formato predeterminado, ya que son compatibles con la mayoría de los dispositivos. Si tu juego se orienta a OpenGL ES 3.0 o versiones posteriores, puedes elegir ETC2 como el formato predeterminado si seleccionas uno de los formatos ETC2 garantizados como compatibles con OpenGL ES 3.0.

Cómo compilar un paquete de aplicación

Google Play usa Android App Bundle para generar y entregar APK optimizados con la configuración del dispositivo de cada usuario, a fin de que los usuarios puedan descargar únicamente el código y los recursos necesarios para ejecutar el juego. Estos APK optimizados incluyen un solo conjunto de elementos de textura, con el formato de compresión óptimo para el dispositivo.

Si tu juego no está en Unity, usa Gradle para compilar un paquete de aplicación. Los usuarios avanzados pueden usar bundletool.

Si tu juego está en Unity, puedes usar un complemento de Unity para crear un paquete de aplicación.

Cómo usar Gradle

  1. Actualiza la versión del complemento de Gradle para Android en el archivo build.gradle de tu proyecto a 4.1 Canary 10 o versiones posteriores (por ejemplo, com.android.tools.build:gradle:4.1.0-alpha10).

  2. Determina el conjunto de tipos de dispositivos a los que quieres orientar tu juego y los formatos de compresión de texturas compatibles (para obtener más información sobre los formatos, consulta Fondo).

  3. Compila versiones de tus elementos para cada formato de compresión de texturas del paso anterior. Es posible que esto implique generar hojas de sprites con software como TexturePacker o ejecutar una secuencia de comandos que convierta elementos sin procesar para darles un formato específico (por ejemplo, astc-encoder).

  4. Crea paquetes de elementos (consulta Cómo compilar para código nativo o Java), que contengan los elementos del juego utilizados con Play Asset Delivery. Por ejemplo, puedes crear un paquete de elementos por nivel o para diferentes partes del juego.

  5. Dentro de los paquetes de elementos, agrega directorios para cada formato de compresión de texturas que quieras admitir. Agrega sufijos compatibles a los nombres de directorios de texturas que correspondan al formato de compresión de texturas utilizado para los archivos contenidos.

    Crea un directorio sin sufijo en el nombre (por ejemplo, common/src/main/assets/textures/). En este directorio, coloca el formato predeterminado de los elementos de textura. El formato predeterminado debe ser compatible con la mayoría de los dispositivos (por ejemplo, ETC1 o ETC2). Si un dispositivo no admite los otros formatos especificados (por ejemplo, PVRTC y ASTC de la tabla a continuación), Google Play Store instalará este directorio en su lugar.

    Directorio anterior Directorio posterior
    Paquete de elementos common:
    common/build.gradle
    common/src/main/assets/textures/…
    Paquete de elementos common:
    common/build.gradle
    common/src/main/assets/textures/…
    common/src/main/assets/textures#tcf_astc/…
    common/src/main/assets/textures#tcf_pvrtc/…
    Paquete de elementos level1:
    level1/build.gradle
    level1/src/main/assets/textures/…
    Paquete de elementos level1:
    level1/build.gradle
    level1/src/main/assets/textures/…
    level1/src/main/assets/textures#tcf_astc/…
    level1/src/main/assets/textures#tcf_pvrtc/…
    Paquete de elementos level2:
    level2/build.gradle
    level2/src/main/assets/textures/…
    Paquete de elementos level2:
    level2/build.gradle
    level2/src/main/assets/textures/…
    level2/src/main/assets/textures#tcf_astc/…
    level2/src/main/assets/textures#tcf_pvrtc/…
  6. Actualiza el archivo build.gradle de tu app para habilitar la división de los paquetes de elementos por texturas.

    // In the app build.gradle file:
    android {
        ...
        bundle {
            texture {
                enableSplit true
            }
        }
    }
    
  7. En Android Studio, selecciona Build > Generate Signed Bundle / APK o inicia la tarea Gradle desde la línea de comandos para generar el paquete.

Cómo usar el complemento de Unity de Google Play

Obtén el complemento de Unity (o el paquete) para Play Asset Delivery a fin de crear un paquete de aplicación con paquetes de elementos orientados a la textura.

Prepara los elementos

Haz lo siguiente para preparar los elementos de textura y compilar un paquete de aplicación:

  1. Empaqueta la escena y los elementos en varios AssetBundles de Unity.

  2. Determina el conjunto de tipos de dispositivos a los que quieres orientar tu juego y los formatos de compresión de texturas compatibles (para obtener más información sobre los formatos, consulta Fondo).

  3. Modifica la secuencia de comandos de compilación del juego para generar los AssetBundles varias veces, una vez por cada formato de texturas que quieras admitir. Observa el siguiente ejemplo de secuencia de comandos:

    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. Verifica que la salida de cada elemento de textura sea a un directorio con el sufijo correcto en su nombre (por ejemplo, #tcf_astc).

    Verifica el resultado de un directorio sin sufijo en su nombre (por ejemplo, Assets/AssetBundles/). Este directorio contendrá el formato predeterminado de los elementos de textura. El formato predeterminado debe ser compatible con la mayoría de los dispositivos (por ejemplo, ETC2). Si un dispositivo no admite los otros formatos especificados (por ejemplo, ASTC en el código del paso anterior), Google Play Store instalará este directorio en su lugar.

    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. Selecciona Google > Android > Assets Delivery.

  6. Haz clic en Agregar carpeta para agregar la carpeta que contiene los paquetes de elementos predeterminados. Estos paquetes se instalan en dispositivos que no admiten los demás formatos definidos.

    Asegúrate de configurar el modo de entrega para el AssetBundle.

    Formato predeterminado de entrega de AssetBundle de Unity

  7. Haz clic en Agregar carpeta para agregar una carpeta que contenga AssetBundles compilados en otro formato (por ejemplo, ASTC). Repite la acción según sea necesario.

    Asegúrate de configurar el modo de entrega para cada AssetBundle.

    Formato ASTC para la entrega de AssetBundle de Unity

Compilación

Selecciona Google > Compilar Android App Bundle para iniciar la compilación de Unity del juego. También empaquetará los AssetBundles en varios paquetes de elementos, donde cada nombre de AssetBundle se convertirá en un solo paquete de elementos.

(Avanzado) Usa bundletool

Para obtener más información sobre bundletool, consulta Cómo compilar un paquete de aplicación mediante bundletool.

Para crear el paquete de aplicación, haz lo siguiente:

  1. Descarga bundletool desde el repositorio de GitHub.

  2. Determina el conjunto de tipos de dispositivos a los que quieres orientar tu juego y los formatos de compresión de texturas compatibles (para obtener más información sobre los formatos, consulta Fondo).

  3. Compila versiones de tus elementos para cada formato de compresión de texturas del paso anterior. Es posible que esto implique generar hojas de sprites con software como TexturePacker o ejecutar una secuencia de comandos que convierta elementos sin procesar para darles un formato específico (por ejemplo, astc-encoder).

  4. Crea paquetes de elementos (consulta Cómo compilar para código nativo o Java), que contengan los elementos del juego utilizados con Play Asset Delivery. Por ejemplo, puedes crear un paquete de elementos por nivel o para diferentes partes del juego.

  5. En los diversos paquetes de elementos, agrega sufijos compatibles a los nombres de directorio de texturas que correspondan con el formato de compresión de texturas utilizado para los archivos incluidos.

    Crea un directorio sin sufijo en el nombre (por ejemplo, common/src/main/assets/textures/). En este directorio, coloca el formato predeterminado de los elementos de textura. El formato predeterminado debe ser compatible con la mayoría de los dispositivos (por ejemplo, ETC1 o ETC2). Si un dispositivo no admite los otros formatos especificados (por ejemplo, PVRTC y ASTC de la tabla a continuación), Google Play Store instalará este directorio en su lugar.

    Directorio anterior Directorio posterior
    Paquete de elementos common:
    common/build.gradle
    common/src/main/assets/textures/…
    Paquete de elementos common:
    common/build.gradle
    common/src/main/assets/textures/…
    common/src/main/assets/textures#tcf_astc/…
    common/src/main/assets/textures#tcf_pvrtc/…
    Paquete de elementos level1:
    level1/build.gradle
    level1/src/main/assets/textures/…
    Paquete de elementos level1:
    level1/build.gradle
    level1/src/main/assets/textures/…
    level1/src/main/assets/textures#tcf_astc/…
    level1/src/main/assets/textures#tcf_pvrtc/…
    Paquete de elementos level2:
    level2/build.gradle
    level2/src/main/assets/textures/…
    Paquete de elementos level2:
    level2/build.gradle
    level2/src/main/assets/textures/…
    level2/src/main/assets/textures#tcf_astc/…
    level2/src/main/assets/textures#tcf_pvrtc/…
  6. Agrega la dimensión de TCF al archivo de metadatos del paquete de aplicación (BundleConfig.json). Usa TEXTURE_COMPRESSION_FORMAT para el campo value:

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

    Configura suffixStripping.enabled como true para quitar el sufijo (por ejemplo, #tcf_astc) de los nombres de directorio cuando se generan los paquetes de elementos. Esto permite que tu juego lea archivos de un nombre de directorio conocido (como level1/assets/textures). Algunos motores de juegos pueden detectar el formato de un archivo, para que tu juego no dependa del formato de los elementos de textura con los que se instaló.

    suffixStripping.defaultSuffix especifica el sufijo de directorio predeterminado cuando bundletool genera un APK independiente para dispositivos con Android 5.0 (nivel de API 21) y versiones anteriores. En la tabla del ejemplo anterior, la versión predeterminada de los elementos de textura se instala en estos dispositivos. Este es el comportamiento deseado en la mayoría de los casos.

  7. Cómo compilar el paquete de aplicación:

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

Cómo verificar el contenido del paquete de aplicación

Si aún no lo hiciste, descarga bundletool del repositorio de GitHub.

Para verificar el contenido del paquete de aplicación de salida, compila los APK desde allí y, luego, inspecciónalos:

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

El resultado debe ser similar al siguiente ejemplo:

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

Estos nombres indican que se aplica correctamente la orientación de TCF. Si descomprimes el contenido de un APK de nivel (por ejemplo, asset-slices/level1-astc.apk), puedes verificar que solo un directorio llamado textures esté presente.

Cómo probar el paquete de aplicación

Conecta un dispositivo y realiza la instalación de los paquetes de elementos aplicables:

bundletool install-apks --apks=APKS.apks

Este comando solo instalará los paquetes de elementos que cumplan con la especificación del dispositivo. Estas especificaciones incluyen ABI, densidad de pantalla, idioma y el formato de compresión de texturas más aplicable. Esta operación simula la acción de Google Play Store con el juego publicado.

Para verificar que se instalaron los paquetes de elementos correctos, realiza una de las siguientes acciones:

  • Usa el comando bundletool extract-apks para enviar los APK instalados en tu dispositivo a un directorio y, luego, inspecciona este directorio.

    1. Extrae la especificación del dispositivo:

      bundletool get-device-spec --output=MY_DEVICE_SPEC.json
      
    2. Ejecuta bundletool extract-apks con la siguiente especificación de dispositivo:

      bundletool extract-apks --apks=APKS.apks --device-spec=MY_DEVICE_SPEC.json \
          --output-dir out
      
    3. Enumera los archivos en el directorio out y verifica la instalación de los paquetes de elementos correspondientes. Los nombres de los paquetes de elementos llevan el sufijo del nombre de formato de textura (por ejemplo, level1-astc.apk).

  • Agrega instrucciones de registro que generen el formato de textura del juego cuando se cargue una textura.

  • Genera un conjunto de pruebas de texturas (por ejemplo, reemplazar una textura por un solo color brillante para un formato determinado). Ejecuta el juego y verifica que eso esté presente.

Si la app contiene los paquetes de elementos on-demand o fast-follow, usa la solución de prueba local para la generación de elementos.

Sufijos compatibles de nombres de directorios de texturas

Google Play admite los siguientes sufijos en los nombres de directorios de textura:

  • #tcf_astc para compresión de textura escalable y adaptable (ASTC)
  • #tcf_atc para compresión de texturas ATI (ATC)
  • #tcf_dxt1 para compresión de texturas DXT1 S3 (DXT1)
  • #tcf_latc para compresión de texturas alfa de luminancia (LATC)
  • #tcf_paletted para compresión de texturas con paleta genérica
  • #tcf_pvrtc para compresión de texturas PowerVR (PVRTC)
  • #tcf_etc1 para compresión de texturas Ericsson (ETC1)
  • #tcf_etc2 para compresión de texturas Ericsson 2 (ETC2)
  • #tcf_s3tc para compresión de texturas S3 (S3TC)
  • #tcf_3dc para compresión de texturas 3Dc de ATI (3Dc)

Reglas de entrega de Google Play

Google Play inspecciona las strings con extensión OpenGL del dispositivo y la versión de OpenGL compatible con el dispositivo. Google Play usa esta información para determinar el formato de textura correcto que se debe entregar al dispositivo desde Android App Bundle.

Google Play entrega el primer formato según el orden indicado en la siguiente tabla, que es compatible con el dispositivo.

Si ninguno de los formatos de texturas de Android App Bundle es compatible con el dispositivo, Google Play entrega los formatos de texturas empaquetados en el formato predeterminado. (A menos que el objetivo sea hardware específico del dispositivo, ETC1 o ETC2 son buenas opciones para un formato predeterminado). Para obtener información sobre cómo empaquetar elementos en el formato predeterminado, consulta Cómo usar bundletool o Cómo usar el complemento de Unity de Google Play.

Si los elementos no se empaquetaron en un formato predeterminado, Google Play marca la app como no disponible para el dispositivo. En este caso, los usuarios no pueden descargar la app.

Formato (designado en tcf_xxxx) Compatible con dispositivos con string de extensión 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 No aplicable. El dispositivo debe ser compatible con OpenGL ES, versión 3.0 o posterior.
etc1 GL_OES_compressed_ETC1_RGB8_texture
con paleta GL_OES_compressed_paletted_texture