Компрессированные текстуры: KTX2 и Basis

Основы компрессированных текстур

Компрессированные текстуры используются для уменьшения объёма графических ресурсов и ускорения загрузки сцен. В отличие от обычных изображений формата PNG или JPEG, которые хранят пиксели в виде RGBA или RGB, компрессированные текстуры содержат данные в специализированных форматах, оптимизированных для видеокарты. Это снижает использование видеопамяти и повышает производительность рендеринга.

В современном веб-графическом контексте на основе WebGL2 и Three.js стандартом де-факто являются текстуры в формате KTX2 с кодированием Basis Universal.


Формат KTX2

Файл KTX2 (Khronos Texture 2) является контейнером, который может хранить текстуры в различных GPU-оптимизированных форматах, включая:

  • ASTC (Adaptive Scalable Texture Compression)
  • BC (Block Compression, например BC1–BC7)
  • ETC1/ETC2
  • PVRTC

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

Ключевые особенности KTX2:

  • Универсальность: один файл может содержать версии текстуры для разных форматов GPU.
  • Поддержка MIP-карт: встроенные MIP-уровни позволяют ускорять рендеринг на разных расстояниях.
  • Быстрая декомпрессия: аппаратная поддержка большинства современных GPU.

Кодирование Basis Universal

Basis Universal — промежуточный формат для сжатия текстур. Он позволяет создавать текстуры, которые затем могут быть быстро перекодированы в формат, поддерживаемый конкретным GPU. В процессе подготовки текстуры в KTX2:

  1. Изображение конвертируется в Basis Universal (.basis).
  2. Браузер или движок на лету декодирует его в GPU-формат (например, BC7 или ASTC).

Преимущества Basis:

  • Поддержка RGBA и RGB текстур с альфа-каналом.
  • Компактный размер файлов и высокая скорость загрузки.
  • Кроссплатформенная совместимость без необходимости создания нескольких версий текстур вручную.

Использование KTX2 в Three.js

Three.js предоставляет KTX2Loader для загрузки и декодирования текстур KTX2. Основная последовательность действий:

  1. Импорт библиотеки загрузчика:
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
import { MeshStandardMaterial, TextureLoader } from 'three';
  1. Настройка загрузчика и указание пути к декодеру Basis:
const ktx2Loader = new KTX2Loader()
    .setTranscoderPath('/basis/') // путь к wasm/decoder файлам
    .detectSupport(renderer);
  1. Загрузка текстуры:
ktx2Loader.load('textures/wood.ktx2', function(texture) {
    const material = new MeshStandardMaterial({ map: texture });
    mesh.material = material;
});

Особенности работы KTX2Loader:

  • detectSupport(renderer) автоматически выбирает GPU-оптимальный формат.
  • Декодирование происходит на клиенте, но аппаратная поддержка позволяет выполнять его максимально быстро.
  • Возможность использования текстур с альфа-каналом, с MIP-картами и анизотропной фильтрацией.

Подготовка текстур для веба

Для эффективного использования KTX2 текстуры следует подготовить заранее:

  1. Создать базовую текстуру в формате PNG или HDR.
  2. Конвертировать её в Basis с помощью BasisU CLI или GUI инструментов.
  3. Генерировать MIP-уровни для уменьшения артефактов при масштабировании.
  4. Сохранять файлы с расширением .ktx2 и использовать их напрямую в Three.js.

Пример команды для конвертации:

basisu wood.png -ktx2 -mipmap -q 255
  • -ktx2 — выходной формат KTX2.
  • -mipmap — генерация MIP-карт.
  • -q 255 — максимальное качество сжатия.

Оптимизация и производительность

Использование KTX2 и Basis Universal значительно снижает потребление видеопамяти и ускоряет загрузку сцены. Рекомендации по оптимизации:

  • Подбирать правильный уровень сжатия: высокая компрессия уменьшает размер, но может приводить к артефактам.
  • Использовать MIP-карты для дальних объектов.
  • Проверять поддержку форматов GPU на целевых устройствах (особенно мобильных).
  • Комбинировать с texture atlases для уменьшения числа draw calls.

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


Совместимость с PBR-материалами

Текстуры в формате KTX2 прекрасно интегрируются с MeshStandardMaterial и другими PBR-материалами Three.js. Можно использовать:

  • map — базовая цветовая текстура.
  • roughnessMap — карта шероховатости.
  • metalnessMap — карта металлическости.
  • normalMap — нормали для освещения.

Каждая из этих текстур может быть закодирована в KTX2 и сжата через Basis, что позволяет одновременно экономить память и поддерживать высокое качество рендеринга.