Алгоритмы сжатия игровых текстур. Часть 2.

DXT2/DXT3 (BC2)

Эти 2 алгоритма практически полностью идентичны, поэтому с версии DX10 их объединили в один. Основан на DXT1 но позволяет хранить полноценную альфу с градациями серого. Достигается это увеличением блока в 2 раза: до 128 бит. В первой половине блока хранится альфа с глубиной серого в 4 бита (16 оттенков серого), что в свою очередь позволяет хорошо сохранить контрастные границы и резкие изменения цвета, при этом все 16 цветов могут быть одновременно в 1 блоке. Во втором блоке в 64 бита хранится DXT1.

15[1].jpg

Рисунок 15. На примере в исходнике блока альфа канала использованы все 16 цветов которые поддерживаются алгоритмом, поэтому разница незаметна.

Принцип сжатия альфа-канала довольно простой: у алгоритма все 256 цветов серого разбиты на 16 групп с результирующим усреднённым цветом. Эти цвета жёстко заданы и неизменны. К примеру цвета в диапазоне от 117 до 133 всегда будут давать в dds 125.

16[1].jpg

Рисунок 16. Наглядный пример сжатия градиента с глубиной 256 в 16 цветов dds.

Главное отличие dxt2 от dxt3 – это их способ представления альфа канала: в dxt2 используется пре-умноженная альфа, а в dxt3 хранит альфа канал отдельно. Такое разделение было вызвано начавшимся распространением фильтрации текстур в играх (не путать с антиалиасингом) – условным размытием пикселей текстур перед обработкой шейдером: одни шейдеры множили текстуру на альфу до фильтрации, а другие после. В зависимости от особенностей самой текстуры это могло давать артефакты в виде обводки по краям прозрачных объектов — цвет зависел от цвета фона текстуры. С таким артефактом можно было бороться разными путями, один из которых – предварительное спечение альфа-канала, при котором текстура распаковывалась уже с прозрачностью.
Сравнение преумноженной альфы и не преумноженной дано на рисунках 17 и 18.

17[1].jpg

Рисунок 17. Альфа канал множит текстуру до фильтрации, поэтому на выходе чистые тексели.

18[1].jpg

Рисунок 18. Альфа канал множит текстуру после фильтрации, поэтому на выходе видны артефакты от фона.

Несмотря на это, разницы в хранении и декодировании информации между dxt2 и dxt3 нет, а имя алгоритма просто указывало как интерпретировать данные. По мере развития технологий начиная с DX10 эти 2 алгоритма были объединены в BC2, так как шейдеры стали сами определять, как им интерпретировать и работать с текстурами.
Несмотря на свои преимущества в виде отдельного альфа канала с низким шумом, DXT2/ DXT3 (BC2) не пользуется популярностью по причине малой глубины цвета – всего 16 цветов и проигрывает в гибкости следующему рассматриваемому алгоритму.

DXT4/ DXT5 (BC3)

Единственное отличие от DXT2/ DXT3 (BC2) в способе сжатия альфа-канала: теперь тут не простое ужимание 256 оттенков серого в 16, а довольно занятная система кодирования. В блок альфа-канала записывается 2 оттенка серого с точностью 8 бит (256 цветов), а 16 пикселей кодируются 3битными индексами:

19[1].jpg

Рисунок 19. Кодирование блока альфа-канала

При декодировании индексированные цвета восстанавливаются линейно смешением двух записанных оттенков, по следующему алгоритму:

20[1].jpg

Заметим, что алгоритм позволяет держать 2 типа блоков: первый более гибкий, а второй имеет жёстко обозначенные цвета – чёрный и белый. Эти блоки применяются выборочно на усмотрение кодировщика.
Сейчас у плагинов и программ для работы с dds форматом, есть «подвид» bc3n. Технически это самый обычный bc3, однако при сохранении красный канал исходника помещается в альфа канал файла dds. Это позволяет получить более высокое качество нормал мапы: как мы помним у альфа канала 8 бит на пиксель, а у зелёного 5. Таким образом информация распределяется по самым «жирным» каналам (см. рис. 20). Голубой канал не представляет ценности т.к. будет восстановлен программно.

21[1].jpg

Рисунок 20. Схема перераспределения каналов исходника текстуры корпуса танка по каналам пожатой текстуры в Мире танков.

До DirectX 10 DXT4 использовался для хранения преумноженной альфы, а DXT5 для не преумноженной. Так же как с предыдущей парой алгоритмов, DXT4 и DXT5 были объединены в BC3.

BC4 (ATI1/3Dc+)
Представляет из себя блок альфа-канала алгоритма bc3, т.е. является алгоритмом для хранения ч/б текстуры: спекуляр, глосс, металл и так далее. Однако в отличие от bc3, который кодирует цвет пикселей в альфа-канале целыми числами (integer), BC4 использует числа с плавающей запятой в диапазоне от 0 до 1 и этот вариант называется BC4_UNORM(BC4u) либо от -1 до 1 и этот вариант называется BC4_SNORM(BC4s). Если в конверторе не указан тип BC4, то имеется ввиду unorm. Суть алгоритма – получить для шейдера значения аппаратно, уже в определённом диапазоне и не заниматься преобразованиями в шейдере. Какой алгоритм будет предпочтительнее зависит от реализации шейдера.

22.png

Рисунок 21. Сравнение исходника и пожатых файлов алгоритмом ВС4.

Кроме того, алгоритм часто используется для хранения специфической информации. На рисунке 22 пример карты signed distance field (дистанция до суши) локации «Север» проекта «Мир Кораблей».

23[1].jpg

Рис 22. Signed distance field локации «Камчатка».

Используется шейдером воды для отрисовки прибрежных волн. Она сжата алгоритмом BC4 UNorm.

BC5 (ATI2/3Dc)

В середине нулевых начали появляется игры с шейдерами поддерживающими normal map. Алгоритмы DXT1-5 не подходили для хранения нормала, т.к. основе имели dxt1, а он плохо справлялся с плавными градиентами, кроме того, в нём разные цветовые каналы могут негативно влиять друг на друга. Ответом на запрос был BC5. Он представлял из себя 2 блока BC4 для красного и зелёного канала соответственно. Синий канал восстанавливается по формуле и в хранении не нуждается. Если сравнивать алгоритмы целиком, то разница плохо видна — визуально после декодирования синий канал в ВС5 не отображается (см. рис 23).

24.png

Рисунок 23. Слева-направо: исходник, ВС5, DXT1(BC1).

Давайте вглянем на красный канал всех трёх изображений что бы почувствовать разницу: качество ВС5 станет очевидным:

25.png

Рисунок 24. ВС5 от исходника практически не отличается, а в ВС1 куча артефактов.


У BC5, как и у BC4, есть 2 варианта BC5_UNORM и BC5_SNORM. В большинстве случаев используют ВС5_u – этот алгоритм идёт по умолчанию, однако выбор в первую очередь зависит то шейдера.

Продолжение будет в следующем посте.


783 0 850 6
4
2025-05-14
Иеее, дождались
2025-05-14
сурс не правильно написали
2025-05-14
Спасибо за статью!
2025-05-16
И снова ждём продолжения!
RENDER.RU