Android App Bundle의 타겟 텍스처 압축 형식

텍스처는 3D 모델의 노출 영역에 적용할 수 있는 이미지입니다. 또한 텍스처는 2D 렌더러에서 스프라이트 또는 배경과 같은 요소를 그릴 때도 사용됩니다. 이 페이지에서는 게임에 사용되는 인기 있는 텍스처 압축 형식과 이를 Android App Bundle에서 타겟팅하는 방법을 설명합니다. 이 가이드를 시작하기 전에 Android App Bundle 정보Play Asset Delivery를 읽어보세요.

배경

휴대기기의 GPU는 일반적으로 텍스처 압축 형식 세트를 지원합니다. 텍스처 압축 형식(또는 TCF)은 GPU에 최적화된 파일 형식입니다. GPU는 메모리의 RGBA 값 배열을 사용하는 경우보다 더 적은 메모리로 더 빠르게 텍스처를 로드하고 렌더링합니다. 이러한 지원은 하드웨어 수준에서 이뤄집니다. GPU 제조업체는 지원되는 형식을 읽고 압축 해제하고 렌더링하는 구성요소를 그래픽 카드 칩에 삽입합니다.

다음은 일반적인 텍스처 압축 형식입니다.

  • DDS 또는 S3TC: 때로 DXTC 또는 DXTn이라고 합니다. OpenGL은 이 형식의 세 가지 유형을 지원합니다.
  • ETC1: 대부분의 기기에서 지원됩니다. 이 형식에서는 투명도를 지원하지 않지만 게임은 알파 구성요소에 보조 텍스처 파일을 사용할 수 있습니다.
  • ETC2: GLES3를 지원하는 모든 기기에서 지원됩니다.
  • PVRTC: iOS 게임에서 널리 사용되며 일부 Android 기기에서도 지원됩니다.
  • ASTC: 이전 형식을 대체하도록 설계된 최신 형식입니다. 다양한 블록 크기를 지원하므로 이전 형식보다 더 유연합니다. 이 형식을 사용하는 것이 게임 크기를 최적화하는 좋은 방법입니다.

각 형식을 지원하는 Android 기기의 비율(%)은 다음과 같습니다.

텍스처 압축 형식 지원되는 Google Play 기기의 비율1
ETC1 99%
ETC2 87%
ASTC 77%
ATC 35%
PVRTC 11%
DXT1 0.7%

1 2020년 9월에 사용되고 있는 Google Play 기기에서 수집한 데이터를 활용하여 계산한 비율

기본 형식

다양한 수준의 기기 지원을 포함하여 사용 가능한 형식이 너무 많아 게임 텍스처를 빌드할 때 어떤 형식을 사용해야 할지 모를 수 있습니다. 보호 수단으로, App Bundle 형식을 사용하면 각 애셋 팩의 기본 텍스처 압축 형식을 선택할 수 있습니다. 기기에서 다른 지정된 형식을 지원하지 않으면 이 기본 형식을 사용하는 애셋이 설치됩니다.

특정 기기 하드웨어를 타겟팅하지 않는 한 ETC1 및 ETC2는 대부분의 기기에서 지원되므로 ETC1 및 ETC2를 기본 형식으로 선택하는 것이 좋습니다. 게임이 OpenGL ES 3.0 이상을 타겟팅한다면 OpenGL ES 3.0에서 확실하게 지원되는 ETC2 형식 중 하나를 선택했을 때 ETC2를 기본 형식으로 선택할 수 있습니다.

App Bundle 빌드

Google Play는 Android App Bundle을 사용하여 각 사용자의 기기 설정에 최적화된 APK를 생성하고 제공하므로 사용자는 게임을 실행하는 데 필요한 코드와 리소스만 다운로드하면 됩니다. 이러한 최적화된 APK에는 기기에 최적화된 압축 형식으로 포맷된 단일 텍스처 애셋 세트가 포함됩니다.

게임이 Unity에 없는 경우 Gradle을 사용하여 App Bundle을 빌드합니다. 고급 사용자는 bundletool을 사용할 수 있습니다.

게임이 Unity에 있는 경우 Unity 플러그인을 사용하여 App Bundle을 빌드할 수 있습니다.

Gradle 사용

  1. 프로젝트의 build.gradle 파일에서 Android Gradle 플러그인 버전을 4.1 Canary 10 이상(예: com.android.tools.build:gradle:4.1.0-alpha10)으로 업데이트합니다.

  2. 게임을 위해 타겟팅하려는 기기 유형 세트 및 지원하는 텍스처 압축 형식을 결정합니다. 형식에 관한 자세한 내용은 배경을 참고하세요.

  3. 이전 단계에서 결정한 각 텍스처 압축 형식의 애셋 버전을 빌드합니다. 여기에는 TexturePacker와 같은 소프트웨어를 사용하여 스프라이트 시트를 생성하거나 원시 애셋을 특정 형식(예: astc-encoder)의 애셋으로 변환하는 스크립트를 실행하는 것이 포함될 수 있습니다.

  4. 게임 애셋을 포함하고 Play Asset Delivery에서 사용되는 애셋 팩(네이티브 또는 자바용 빌드 참고)을 만듭니다. 예를 들어 레벨당 하나의 애셋 팩을 만들거나 다양한 게임 요소용으로 각각의 애셋 팩을 만들 수 있습니다.

  5. 애셋 팩 내에 지원하려는 각 텍스처 압축 형식의 디렉터리를 추가합니다. 포함된 파일에 사용된 텍스처 압축 형식에 해당하는 텍스처 디렉터리 이름에 지원되는 접미사를 추가합니다.

    이름에 접미사가 없는 디렉터리를 만듭니다(예: common/src/main/assets/textures/). 이 디렉터리에 텍스처 애셋의 기본 형식을 배치합니다. 이 기본 형식은 대부분의 기기에서 지원되는 형식이어야 합니다(예: ETC1 또는 ETC2). 기기에서 다른 지정된 형식(예: 아래 표의 PVRTC 및 ASTC)을 지원하지 않으면 Google Play 스토어는 대신 이 디렉터리를 설치합니다.

    다음 이전 디렉터리 다음 이후 디렉터리
    common 애셋 팩:
    common/build.gradle
    common/src/main/assets/textures/...
    common 애셋 팩:
    common/build.gradle
    common/src/main/assets/textures/...
    common/src/main/assets/textures#tcf_astc/...
    common/src/main/assets/textures#tcf_pvrtc/...
    level1 애셋 팩:
    level1/build.gradle
    level1/src/main/assets/textures/...
    level1 애셋 팩:
    level1/build.gradle
    level1/src/main/assets/textures/...
    level1/src/main/assets/textures#tcf_astc/...
    level1/src/main/assets/textures#tcf_pvrtc/...
    level2 애셋 팩:
    level2/build.gradle
    level2/src/main/assets/textures/...
    level2 애셋 팩:
    level2/build.gradle
    level2/src/main/assets/textures/...
    level2/src/main/assets/textures#tcf_astc/...
    level2/src/main/assets/textures#tcf_pvrtc/...
  6. 앱의 build.gradle 파일을 업데이트하여 텍스처별로 애셋 팩 분할을 사용 설정합니다.

    // In the app build.gradle file:
    android {
        ...
        bundle {
            texture {
                enableSplit true
            }
        }
    }
    
  7. Android 스튜디오에서 Build > Generate Signed Bundle / APK를 선택하거나 명령줄에서 Gradle 작업을 실행하여 번들을 생성합니다.

Google Play Unity 플러그인 사용

Play Asset Delivery용 Unity 플러그인(또는 패키지)을 다운로드하여 텍스처 타겟 애셋 팩이 포함된 App Bundle을 만듭니다.

애셋 준비

App Bundle 빌드를 위해 텍스처 애셋을 준비하려면 다음 단계를 따르세요.

  1. 장면 및 애셋을 여러 Unity AssetBundle로 패키징합니다.

  2. 게임을 위해 타겟팅하려는 기기 유형 세트 및 지원하는 텍스처 압축 형식을 결정합니다. 형식에 관한 자세한 내용은 배경을 참고하세요.

  3. 지원하려는 각 텍스처 형식마다 한 번씩 AssetBundle을 여러 번 생성하도록 게임의 빌드 스크립트를 수정합니다. 다음 스크립트 예를 참고하세요.

    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. 각 텍스처 애셋이 이름에 올바른 접미사(예: #tcf_astc)가 있는 디렉터리에 출력되는지 확인합니다.

    이름에 접미사가 없는 디렉터리가 출력되는지 확인합니다(예: Assets/AssetBundles/). 이 디렉터리에는 텍스처 애셋의 기본 형식이 포함되어 있습니다. 이 기본 형식은 대부분의 기기에서 지원되는 형식이어야 합니다(예: ETC2). 기기에서 다른 지정된 형식(예: 이전 단계에서 코드의 ASTC)을 지원하지 않으면 Google Play 스토어는 대신 이 디렉터리를 설치합니다.

    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. Google > Android > Assets Delivery를 선택합니다.

  6. Add Folder를 클릭하여 기본 애셋 번들이 포함된 폴더를 추가합니다. 이러한 번들은 개발자가 정의한 다른 형식을 지원하지 않는 기기에 설치됩니다.

    AssetBundle의 Delivery mode를 설정해야 합니다.

    Unity AssetBundle Delivery 기본 형식

  7. Add Folder를 클릭하여 다른 형식(예: ASTC)용으로 빌드된 AssetBundle이 포함된 폴더를 추가합니다. 필요한 경우 반복합니다.

    각 AssetBundle의 Delivery mode를 설정해야 합니다.

    Unity AssetBundle Delivery ASTC 형식

빌드

Google > Build Android App Bundle을 선택하여 게임의 Unity 빌드를 실행합니다. 또한 AssetBundle을 여러 애셋 팩으로 패키징합니다. 이 패키징에서는 각 AssetBundle 이름이 단일 애셋 팩으로 변환됩니다.

(고급) bundletool 사용

bundletool에 관한 자세한 내용은 bundletool을 사용하여 App Bundle 빌드를 참고하세요.

App Bundle을 만들려면 다음 단계를 따르세요.

  1. GitHub 저장소에서 bundletool을 다운로드합니다.

  2. 게임을 위해 타겟팅하려는 기기 유형 세트 및 지원하는 텍스처 압축 형식을 결정합니다. 형식에 관한 자세한 내용은 배경을 참고하세요.

  3. 이전 단계에서 결정한 각 텍스처 압축 형식의 애셋 버전을 빌드합니다. 여기에는 TexturePacker와 같은 소프트웨어를 사용하여 스프라이트 시트를 생성하거나 원시 애셋을 특정 형식(예: astc-encoder)의 애셋으로 변환하는 스크립트를 실행하는 것이 포함될 수 있습니다.

  4. 게임 애셋을 포함하고 Play Asset Delivery에서 사용되는 애셋 팩(네이티브 또는 자바용 빌드 참고)을 만듭니다. 예를 들어 레벨당 하나의 애셋 팩을 만들거나 다양한 게임 요소용으로 각각의 애셋 팩을 만들 수 있습니다.

  5. 다른 애셋 팩에서, 포함된 파일에 사용된 텍스처 압축 형식에 해당하는 텍스처 디렉터리 이름에 지원되는 접미사를 추가합니다.

    이름에 접미사가 없는 디렉터리를 만듭니다(예: common/src/main/assets/textures/). 이 디렉터리에 텍스처 애셋의 기본 형식을 배치합니다. 이 기본 형식은 대부분의 기기에서 지원되는 형식이어야 합니다(예: ETC1 또는 ETC2). 기기에서 다른 지정된 형식(예: 아래 표의 PVRTC 및 ASTC)을 지원하지 않으면 Google Play 스토어는 대신 이 디렉터리를 설치합니다.

    다음 이전 디렉터리 다음 이후 디렉터리
    common 애셋 팩:
    common/build.gradle
    common/src/main/assets/textures/...
    common 애셋 팩:
    common/build.gradle
    common/src/main/assets/textures/...
    common/src/main/assets/textures#tcf_astc/...
    common/src/main/assets/textures#tcf_pvrtc/...
    level1 애셋 팩:
    level1/build.gradle
    level1/src/main/assets/textures/...
    level1 애셋 팩:
    level1/build.gradle
    level1/src/main/assets/textures/...
    level1/src/main/assets/textures#tcf_astc/...
    level1/src/main/assets/textures#tcf_pvrtc/...
    level2 애셋 팩:
    level2/build.gradle
    level2/src/main/assets/textures/...
    level2 애셋 팩:
    level2/build.gradle
    level2/src/main/assets/textures/...
    level2/src/main/assets/textures#tcf_astc/...
    level2/src/main/assets/textures#tcf_pvrtc/...
  6. App Bundle 메타데이터 파일(BundleConfig.json)에 TCF 측정기준을 추가합니다. 다음과 같이 value 필드에 TEXTURE_COMPRESSION_FORMAT을 사용합니다.

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

    애셋 팩을 생성할 때 디렉터리 이름에서 접미사(예: #tcf_astc)를 삭제하려면 suffixStripping.enabledtrue로 설정합니다. 이렇게 하면 게임이 잘 알려진 디렉터리 이름(예: level1/assets/textures)의 파일을 읽을 수 있습니다. 일부 게임 엔진은 파일 형식을 감지할 수 있으므로 게임은 설치된 텍스처 애셋 형식에 구속받지 않을 수 있습니다.

    suffixStripping.defaultSuffixbundletool이 Android 5.0(API 수준 21) 이하를 실행하는 기기의 독립형 APK를 생성할 때 기본 디렉터리 접미사를 지정합니다. 앞에 나온 예의 표에서 텍스처 애셋의 기본 버전은 이러한 기기에 설치됩니다. 이는 대부분의 경우에 바람직한 동작입니다.

  7. App Bundle 빌드

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

App Bundle의 콘텐츠 확인

아직 다운로드하지 않았다면 GitHub 저장소에서 bundletool을 다운로드합니다.

출력 App Bundle에서 APK를 빌드하고 검사하여 출력 App Bundle의 콘텐츠를 확인합니다.

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

출력은 다음과 유사해야 합니다.

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

이러한 이름은 TCF 타겟팅이 적절하게 적용되었음을 나타냅니다. 레벨 APK(예: asset-slices/level1-astc.apk) 콘텐츠의 압축을 풀면 textures라는 디렉터리가 하나만 있는지 확인할 수 있습니다.

App Bundle 테스트

기기를 연결하고 다음과 같이 해당하는 애셋 팩을 설치합니다.

bundletool install-apks --apks=APKS.apks

이 명령어는 기기 사양을 충족하는 애셋 팩만 설치합니다. 이러한 사양에는 ABI, 화면 밀도, 언어 및 가장 적합한 텍스처 압축 형식이 포함됩니다. 이 작업은 Google Play 스토어에서 게시된 게임에 하는 작업을 시뮬레이션합니다.

올바른 애셋 팩이 설치되었는지 확인하려면 다음 중 한 가지 방법을 따르세요.

  • bundletool extract-apks 명령어를 사용하여 기기용으로 설치된 APK를 디렉터리에 출력한 후 이 디렉터리를 검사합니다.

    1. 다음과 같이 기기 사양을 추출합니다.

      bundletool get-device-spec --output=MY_DEVICE_SPEC.json
      
    2. 이 기기 사양을 사용하여 bundletool extract-apks를 실행합니다.

      bundletool extract-apks --apks=APKS.apks --device-spec=MY_DEVICE_SPEC.json \
          --output-dir out
      
    3. out 디렉터리의 파일을 나열하고 적절한 애셋 팩이 설치되었는지 확인합니다. 애셋 팩 이름에는 텍스처 형식 이름이 접미사로 지정됩니다(예: level1-astc.apk).

  • 게임에서 텍스처를 로드할 때 텍스처 형식을 출력하는 로그 구문을 추가합니다.

  • 텍스처의 테스트 세트를 생성합니다(예를 들어 지정된 형식의 밝은 단일 색상으로 텍스처를 대체함). 게임을 실행하고 이 세트가 있는지 확인합니다.

앱에 on-demand 또는 fast-follow 애셋 팩이 포함되어 있다면 Asset Delivery에 로컬 테스트 솔루션을 사용합니다.

텍스처 디렉터리 이름에 지원되는 접미사

Google Play는 텍스처 디렉터리 이름에 사용되는 다음과 같은 접미사를 인식합니다.

  • #tcf_astc - ASTC(Adaptive Scalable Texture Compression)용
  • #tcf_atc - ATI 텍스처 압축(ATC)용
  • #tcf_dxt1 - S3 DXT1 텍스처 압축(DXT1)용
  • #tcf_latc - LATC(Luminance-Alpha Texture Compression)용
  • #tcf_paletted - 팔레트화된 일반 텍스처 압축용
  • #tcf_pvrtc - PVRTC(PowerVR Texture Compression)용
  • #tcf_etc1 - Ericsson 텍스처 압축(ETC1)용
  • #tcf_etc2 - Ericsson 텍스처 압축 2(ETC2)용
  • #tcf_s3tc - S3 텍스처 압축(S3TC)용
  • #tcf_3dc - ATI 3Dc 텍스처 압축(3Dc)용

Google Play 제공 규칙

Google Play는 기기에서 사용하는 OpenGL 확장 문자열과 기기에서 지원하는 OpenGL 버전을 검사합니다. Google Play는 이 정보를 사용하여 Android App Bundle에서 기기로 제공할 올바른 텍스처 형식을 결정합니다.

Google Play는 다음 표에 나열된 순서대로 기기에서 지원하는 첫 번째 형식을 제공합니다.

App Bundle의 텍스처 형식이 기기에서 지원되지 않는 경우 Google Play는 기본 형식으로 패키징된 텍스처 형식을 제공합니다. (특정 기기 하드웨어를 타겟팅하지 않는 한 ETC1 또는 ETC2를 기본 형식으로 선택하는 것이 좋습니다.) 애셋을 기본 형식으로 패키징하는 방법에 관한 자세한 내용은 bundletool 사용 또는 Google Play Unity 플러그인 사용을 참고하세요.

애셋이 기본 형식으로 패키징되지 않았다면 Google Play는 앱을 기기에서 사용할 수 없는 것으로 표시합니다. 이 경우 사용자는 앱을 다운로드할 수 없습니다.

형식(tcf_xxxx로 지정됨) 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 적용 불가능. 기기가 OpenGL ES 버전 3.0 이상을 지원해야 합니다.
etc1 GL_OES_compressed_ETC1_RGB8_texture
paletted GL_OES_compressed_paletted_texture