Compressed textures: KTX2 и Basis Universal

В современном 3D-разработке для веба оптимизация ресурсов играет ключевую роль. Сжатые текстуры позволяют значительно уменьшить размер загружаемых файлов и ускорить рендеринг сцены без заметной потери качества. В A-Frame для этого активно используются форматы KTX2 и Basis Universal.


Основы KTX2 и Basis Universal

KTX2 (Khronos Texture 2) — контейнер для хранения текстур с поддержкой современных алгоритмов сжатия, включая Basis Universal. Основные преимущества:

  • Поддержка GPU-компрессии на лету через WebGL.
  • Возможность автоматического выбора формата сжатия в зависимости от устройства пользователя (ETC2, ASTC, BC7 и др.).
  • Универсальность и стандартизация от Khronos Group.

Basis Universal — алгоритм сжатия текстур, который обеспечивает:

  • Кросс-платформенную совместимость.
  • Снижение объема текстур в несколько раз.
  • Быструю декомпрессию на GPU без значительной нагрузки на CPU.

KTX2-файлы часто содержат текстуры, закодированные через Basis Universal, что делает их идеальными для использования в веб-приложениях на базе A-Frame.


Подключение сжатых текстур в A-Frame

A-Frame позволяет загружать сжатые текстуры через стандартный компонент material. Основной подход:

<a-entity geometry="primitive: box"
          material="src: url(texture.ktx2); encoding: sRGB; repeat: 2 2;">
</a-entity>

Ключевые моменты:

  • src указывает путь к .ktx2 файлу.
  • encoding: sRGB необходим для корректного отображения цветов.
  • repeat управляет повторением текстуры по осям.

Для корректной работы с KTX2 необходимо подключить Basis Universal transcoder, который A-Frame использует через three.js:

<script src="https://cdn.jsdelivr.net/npm/three@0.161.0/examples/jsm/libs/basis/BasisTextureLoader.js"></script>

После этого A-Frame автоматически подберет оптимальный GPU-формат для устройства пользователя.


Настройка трансформации текстур

KTX2 поддерживает mipmap, что позволяет применять текстуры на объектах с различной дистанцией от камеры без потери качества. Пример настройки:

AFRAME.registerComponent('ktx2-material', {
  init: function () {
    const loader = new THREE.KTX2Loader()
      .setTranscoderPath('/basis/')
      .detectSupport(this.el.sceneEl.renderer);

    loader.load('texture.ktx2', (texture) => {
      texture.encoding = THREE.sRGBEncoding;
      this.el.getObject3D('mesh').material.map = texture;
      this.el.getObject3D('mesh').material.needsUpdate = true;
    });
  }
});

Объяснение кода:

  • KTX2Loader() создаёт загрузчик KTX2-файлов.
  • setTranscoderPath('/basis/') указывает путь к транслятору Basis Universal.
  • detectSupport() автоматически выбирает подходящий формат сжатия.
  • Присвоение текстуры объекту через material.map и обновление флага needsUpdate гарантирует корректное отображение.

Совместимость и рекомендации

  • ASTC: оптимально для мобильных устройств iOS и Android.
  • BC7/BC1: предпочтительно для десктопов.
  • ETC2: для широкого спектра мобильных устройств, поддерживающих OpenGL ES 3.0.

Важно учитывать, что не все старые браузеры и устройства поддерживают KTX2. Для них рекомендуется предоставлять fallback-текстуры в формате PNG или JPEG.


Оптимизация загрузки

  1. Lazy Loading текстур: загружать текстуры по мере необходимости, например, при приближении камеры к объекту.
  2. Пакетирование текстур: объединять несколько маленьких текстур в атлас.
  3. Использование mipmap: снижает aliasing и позволяет GPU выбирать уровень детализации.

Пример lazy loading через компонент:

AFRAME.registerComponent('lazy-ktx2', {
  schema: { type: 'string' },
  init: function () {
    const el = this.el;
    const src = this.data;

    el.addEventListener('model-loaded', () => {
      const mesh = el.getObject3D('mesh');
      if (!mesh) return;

      const loader = new THREE.KTX2Loader()
        .setTranscoderPath('/basis/')
        .detectSupport(el.sceneEl.renderer);

      loader.load(src, (texture) => {
        mesh.traverse((child) => {
          if (child.isMesh) {
            child.material.map = texture;
            child.material.needsUpdate = true;
          }
        });
      });
    });
  }
});

Преимущества использования KTX2 и Basis Universal в A-Frame

  • Снижение времени загрузки: файлы значительно меньше PNG/JPEG.
  • Улучшенная производительность GPU: текстуры сразу декомпрессируются на графическом процессоре.
  • Кросс-платформенность: одинаковая сцена работает на мобильных и десктопных устройствах.
  • Гибкость настройки: возможность выбора оптимального формата сжатия для конкретного устройства.

Использование KTX2 и Basis Universal в проектах на A-Frame позволяет создавать интерактивные 3D-сцены высокой детализации с минимальной нагрузкой на сеть и GPU, что критично для веб-приложений и VR/AR-опытов.