Сжатие текстур: форматы и компромиссы для разработчиков игр

Сжатие текстур: форматы и компромиссы для разработчиков игр сен, 5 2026

Вы когда-нибудь задумывались, почему ваша игра с красивыми текстурами высокого разрешения тормозит на мобильном телефоне, но летает на мощной видеокарте? Или почему файл сборки весит гигабайты, хотя моделей там не так много? Ответ часто кроется в том, как вы храните пиксели. Сжатие текстур - это не просто способ уменьшить размер файла на диске. Это критически важная техника, которая позволяет графическому процессору (GPU) читать данные напрямую из памяти без предварительной распаковки. Без этого современные игры были бы невозможны.

Но здесь есть подвох. Не существует универсального формата сжатия, который идеально подходит для всего. Выбор между качеством картинки и производительностью - это постоянный баланс. Если выбрать неправильный формат, вы либо потеряете детали, либо заставите игрока ждать загрузки уровней вечность. Давайте разберем, как работают разные алгоритмы и как выбрать правильный инструмент для вашей задачи.

Почему обычное сжатие изображений не работает в играх

Начнем с основ. Когда вы открываете JPG или PNG в браузере, компьютер должен полностью распаковать картинку в оперативную память перед тем, как показать ее вам. Для статичного изображения это нормально. Но в играх ситуация другая. GPU нужно считывать текстуры случайным образом, фрагментами, чтобы отрисовать объект на экране. Если он будет ждать полной распаковки каждой текстуры, частота кадров упадет до нуля.

Именно поэтому используются специальные форматы сжатия, поддерживаемые аппаратно. Они делятся на два больших лагеря:

  • Блочное кодирование (Block Compression): Разбивает изображение на маленькие блоки (обычно 4x4 или 8x8 пикселей) и кодирует их отдельно. GPU может прочитать нужный блок мгновенно.
  • Аппаратные декодеры: Видеокарта имеет встроенные чипы, которые расшифровывают эти блоки «на лету» с минимальными затратами энергии и времени.

Если вы попытаетесь использовать обычный JPEG внутри движка Unity или Unreal Engine без конвертации в поддерживаемый формат, движок сначала распакует его в несжатый RGB-буфер, займет кучу памяти и только потом отправит данные на рендеринг. Вы потеряете все преимущества экономии памяти.

Обзор основных форматов сжатия текстур

Рынок разделен по платформам. То, что отлично работает на ПК, может быть бесполезно на Android, и наоборот. Понимание этих различий сэкономит вам часы оптимизации.

Сравнение популярных форматов сжатия текстур
Формат Платформа Качество Поддержка альфа-канала Особенности
BC1 / DXT1 PC (DirectX) Низкое/Среднее Нет (или бинарный) Стандарт де-факто для непрозрачных текстур на PC. Очень быстрый.
BC3 / DXT5 PC (DirectX) Среднее Да (интерполированный) Стандарт для текстур с прозрачностью на PC. Хороший баланс.
BC7 PC (DirectX 11+) Высокое Да Лучшее качество среди BC-форматов. Требует поддержки DX11.
ASTC Mobile (iOS/Android) Отличное Да Гибкий. Можно менять степень сжатия. Стандарт для современных мобильных GPU.
ETC2 Android (старые устройства) Среднее Да Базовый стандарт для Android. Хуже ASTC, но шире поддержка.
PVRTC iOS (старые устройства) Низкое Да Устаревает. Сейчас Apple рекомендует переходить на ASTC.

PC-гейминг: Мир форматов BC

На персональных компьютерах царят форматы семейства Block Compression (BC). Они исторически развивались вместе с DirectX. Самым распространенным остается BC7. Почему? Потому что он дает почти идеальное качество при разумном размере файла.

BC7 использует сложную схему кодирования, которая анализирует каждый блок 4x4 пикселя и выбирает лучшую из нескольких схем предсказания цветов. Результат? Картинки выглядят практически неотличимо от оригиналов, особенно если исходник был качественным. Однако есть нюанс: BC7 требует поддержки DirectX 11 и выше. Если вы делаете игру для очень старых видеокарт (до 2010 года выпуска), вам придется использовать более простые форматы вроде BC1 или BC3.

Что насчет BC1 и BC3? BC1 не поддерживает нормальный альфа-канал (прозрачность). Он либо делает пиксель полностью прозрачным, либо непрозрачным. Это ужасно выглядит на краях объектов, таких как листья деревьев или волосы персонажей. Поэтому для всего, где нужна мягкая тень или полупрозрачность, используйте BC3. Он хранит альфу отдельно, интерполируя её значения, что дает плавные границы.

Совет из практики: никогда не используйте BC1 для карт нормалей (Normal Maps). Из-за низкой точности кодирования на плоских участках карты нормалей появляются заметные артефакты в виде ступенек или полос. Для карт нормалей лучше подходит BC5, который специально оптимизирован для хранения двух каналов данных (X и Y), игнорируя Z, который можно восстановить математически.

Сравнение текстур на ПК и мобильных устройствах

Мобильная разработка: Битва ASTC против ETC2

Здесь ситуация сложнее. Мобильные GPU (Adreno у Qualcomm, Mali у ARM, PowerVR у Imagination) имеют свои требования. Долгое время стандартом для Android был ETC2, а для iOS - PVRTC. Но времена меняются.

Сегодня королем является ASTC (Adaptive Scalable Texture Compression). Этот формат уникален тем, что позволяет гибко выбирать степень сжатия. Вы можете настроить размер блока от 4x4 до 12x12 пикселей. Чем больше блок, тем сильнее сжатие и меньше размер файла, но ниже качество.

Для большинства мобильных проектов ASTC 6x6 или 8x8 - это золотая середина. Качество сравнимо с BC7 на PC, а размер файла значительно меньше. Поддержка ASTC есть во всех современных iPhone (начиная с A9 чипа) и на большинстве Android-смартфонов последних 5-7 лет.

Когда стоит использовать ETC2? Только если вы обязаны поддерживать старые устройства на Android (например, смартфоны 2014-2016 годов выпуска), которые не понимают ASTC. Учтите, что ETC2 хуже справляется с деталями и шумом, чем ASTC. Если ваша аудитория смешанная, многие студии используют двойной пайплайн: генерируют ASTC для новых устройств и ETC2 для старых, выбирая нужную версию при запуске игры.

Компромиссы: Память, Пропускная способность и Время загрузки

Выбор формата - это всегда три угла треугольника: качество, скорость загрузки и потребление памяти.

  1. Размер на диске: Влияет на размер установщика и время скачивания из магазина приложений. Сжатые текстуры могут быть в 4-8 раз меньше несжатых.
  2. Размер в VRAM: Самый важный параметр для FPS. Если текстура не помещается в видеопамять, система начинает постоянно подгружать её из RAM или даже диска. Это вызывает микрофризы. Аппаратно сжатые текстуры занимают ровно столько места, сколько занимает их сжатый вид.
  3. Время загрузки: Хотя сжатые текстуры быстрее читаются с диска, они требуют работы декодера GPU. На слабых устройствах этот процесс может занять доли секунды, создавая эффект «всплывания» текстур (texture popping).

Есть еще один скрытый враг - пропускная способность памяти. Даже если текстура лежит в VRAM, GPU должен постоянно считывать её данные. Форматы с высоким коэффициентом сжатия (как ASTC 8x8) уменьшают объем передаваемых данных, снижая нагрузку на шину памяти. Это особенно критично для мобильных устройств, где энергопотребление ограничено батареей.

Абстракция баланса качества, памяти и скорости загрузки

Инструменты и автоматизация процесса

Ручная конвертация каждой текстуры - путь к сумасшествию. Современные игровые движки делают большую часть работы за вас, но нужно правильно настроить импорт.

В Unity вы можете задать целевую платформу в настройках импорта. Движок автоматически выберет лучший формат (ASTC для мобильных, BC7 для PC) и уровень качества. Используйте функцию «Texture Import Settings», чтобы вручную понизить разрешение для фоновых объектов или повысить для лиц персонажей.

В Unreal Engine используется система LOD (Level of Detail) и виртуальные текстуры. UE автоматически генерирует mip-maps (уменьшенные копии текстур) и упаковывает их в контейнеры. Обратите внимание на настройки компрессии в Material Editor. Для материалов с высокой детализацией убедитесь, что вы используете sRGB корректно, иначе цвета будут выглядеть бледными после сжатия.

Для продвинутых пользователей существуют внешние утилиты, такие как Crunch (Crunch.js) или KTX2. Они позволяют создавать супер-сжатые форматы, которые занимают минимум места на диске, а затем пережимаются в нативный формат платформы уже при загрузке. Это идеальный вариант для мобильных игр, где каждый мегабайт на счету.

Практические советы по выбору формата

Чтобы не утонуть в таблицах совместимости, следуйте этим простым правилам:

  • Только PC: Используйте BC7 для всего, кроме масок и карт нормалей. Для карт нормалей берите BC5. Если нужна максимальная экономия и старое железо - BC3.
  • Только Mobile (современный): ASTC 6x6 или 8x8. Это лучший выбор по соотношению цена/качество.
  • Кроссплатформенный проект: Генерируйте две версии ассетов. ASTC для мобильных и BC7 для десктопа. Большинство движков умеют хранить несколько вариантов одной текстуры.
  • UI Элементы: Часто лучше оставить несжатыми или использовать форматы с потерями минимального уровня, так как UI требует четких линий и текста. Артефакты сжатия на кнопках раздражают игроков сильнее, чем на фоне леса.

Помните, что сжатие с потерями (lossy compression) неизбежно искажает данные. Всегда проверяйте результат на реальных устройствах. То, что хорошо выглядит на мониторе дизайнера с разрешением 4K, может рассыпаться на пиксели на экране телефона среднего класса.

Что такое Mip-maps и зачем они нужны при сжатии?

Mip-maps - это набор заранее подготовленных уменьшенных копий текстуры. Когда объект находится далеко от камеры, GPU использует маленькую версию текстуры вместо большой. Это предотвращает мерцание (алиасинг) и снижает нагрузку на память. При сжатии текстур важно генерировать mip-maps ДО применения блока сжатия, чтобы каждый уровень детализации был закодирован независимо и корректно.

Почему мои текстуры выглядят размытыми после сжатия?

Это типичный артефакт блочного сжатия, особенно в форматах с низким битрейтом (как BC1 или PVRTC). Алгоритм усредняет цвета внутри блоков 4x4 или 8x8 пикселей. Если на границе блока резкий контраст (например, черная линия на белом фоне), алгоритм смешает цвета, создав серую зону. Решение: увеличить разрешение исходника, использовать более качественный формат (BC7/ASTC) или добавить шум в текстуру, чтобы обмануть алгоритм сглаживания.

Можно ли использовать PNG в игре без сжатия?

Технически да, но это крайне неэффективно. PNG сжимается программно CPU при загрузке, занимая много оперативной памяти (RAM) и вызывая длительные паузы при старте уровня. Кроме того, GPU не умеет читать PNG напрямую. Вам все равно придется конвертировать его в формат типа RGBA32, который занимает в 4-8 раз больше места в видеопамяти, чем аппаратно сжатый аналог. Используйте PNG только для временных файлов или UI элементов небольшого размера.

Какой формат лучше для карт высот (Heightmaps)?

Для карт высот часто используют форматы с одним каналом данных, такие как R8 или RG8, если сжатие не требуется. Если же нужно сжатие, лучше избегать сильных потерь. Форматы вроде BC4 (один канал) или специализированные варианты ASTC с высокой точностью подходят лучше всего. Важно помнить, что ошибки в карте высот приводят к геометрическим артефактам ландшафта, которые видны глазу сразу.

Как влияет HDR на выбор формата сжатия?

HDR (High Dynamic Range) текстуры требуют большей глубины цвета (часто 16 бит на канал вместо 8). Стандартные форматы BC/ASTC рассчитаны на LDR (Low Dynamic Range). Для HDR обычно используют несжатые форматы (RGBA16F) или специализированные схемы сжатия, такие как BPTC (BC6H) на PC. На мобильных устройствах поддержка HDR текстур пока ограничена и часто реализуется через эмуляцию или использование дополнительных масок яркости.