Алгоритмы сжатия игровых текстур. Часть 2.
DXT2/DXT3 (BC2)
Эти 2 алгоритма практически полностью идентичны, поэтому с версии DX10 их объединили в один. Основан на DXT1 но позволяет хранить полноценную альфу с градациями серого. Достигается это увеличением блока в 2 раза: до 128 бит. В первой половине блока хранится альфа с глубиной серого в 4 бита (16 оттенков серого), что в свою очередь позволяет хорошо сохранить контрастные границы и резкие изменения цвета, при этом все 16 цветов могут быть одновременно в 1 блоке. Во втором блоке в 64 бита хранится DXT1.
Рисунок 15. На примере в исходнике блока альфа канала использованы все 16 цветов которые поддерживаются алгоритмом, поэтому разница незаметна.
Принцип сжатия альфа-канала довольно простой: у алгоритма все 256 цветов серого разбиты на 16 групп с результирующим усреднённым цветом. Эти цвета жёстко заданы и неизменны. К примеру цвета в диапазоне от 117 до 133 всегда будут давать в dds 125.
Рисунок 16. Наглядный пример сжатия градиента с глубиной 256 в 16 цветов dds.
Главное отличие dxt2 от dxt3 – это их способ представления альфа канала: в dxt2 используется пре-умноженная альфа, а в dxt3 хранит альфа канал отдельно. Такое разделение было вызвано начавшимся распространением фильтрации текстур в играх (не путать с антиалиасингом) – условным размытием пикселей текстур перед обработкой шейдером: одни шейдеры множили текстуру на альфу до фильтрации, а другие после. В зависимости от особенностей самой текстуры это могло давать артефакты в виде обводки по краям прозрачных объектов — цвет зависел от цвета фона текстуры. С таким артефактом можно было бороться разными путями, один из которых – предварительное спечение альфа-канала, при котором текстура распаковывалась уже с прозрачностью.
Сравнение преумноженной альфы и не преумноженной дано на рисунках 17 и 18.
Рисунок 17. Альфа канал множит текстуру до фильтрации, поэтому на выходе чистые тексели.
Рисунок 18. Альфа канал множит текстуру после фильтрации, поэтому на выходе видны артефакты от фона.
Несмотря на это, разницы в хранении и декодировании информации между dxt2 и dxt3 нет, а имя алгоритма просто указывало как интерпретировать данные. По мере развития технологий начиная с DX10 эти 2 алгоритма были объединены в BC2, так как шейдеры стали сами определять, как им интерпретировать и работать с текстурами.
Несмотря на свои преимущества в виде отдельного альфа канала с низким шумом, DXT2/ DXT3 (BC2) не пользуется популярностью по причине малой глубины цвета – всего 16 цветов и проигрывает в гибкости следующему рассматриваемому алгоритму.
DXT4/ DXT5 (BC3)
Единственное отличие от DXT2/ DXT3 (BC2) в способе сжатия альфа-канала: теперь тут не простое ужимание 256 оттенков серого в 16, а довольно занятная система кодирования. В блок альфа-канала записывается 2 оттенка серого с точностью 8 бит (256 цветов), а 16 пикселей кодируются 3битными индексами:
Рисунок 19. Кодирование блока альфа-канала
При декодировании индексированные цвета восстанавливаются линейно смешением двух записанных оттенков, по следующему алгоритму:
Заметим, что алгоритм позволяет держать 2 типа блоков: первый более гибкий, а второй имеет жёстко обозначенные цвета – чёрный и белый. Эти блоки применяются выборочно на усмотрение кодировщика.
Сейчас у плагинов и программ для работы с dds форматом, есть «подвид» bc3n. Технически это самый обычный bc3, однако при сохранении красный канал исходника помещается в альфа канал файла dds. Это позволяет получить более высокое качество нормал мапы: как мы помним у альфа канала 8 бит на пиксель, а у зелёного 5. Таким образом информация распределяется по самым «жирным» каналам (см. рис. 20). Голубой канал не представляет ценности т.к. будет восстановлен программно.
Рисунок 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. Суть алгоритма – получить для шейдера значения аппаратно, уже в определённом диапазоне и не заниматься преобразованиями в шейдере. Какой алгоритм будет предпочтительнее зависит от реализации шейдера.
Рисунок 21. Сравнение исходника и пожатых файлов алгоритмом ВС4.
Кроме того, алгоритм часто используется для хранения специфической информации. На рисунке 22 пример карты signed distance field (дистанция до суши) локации «Север» проекта «Мир Кораблей».
Рис 22. Signed distance field локации «Камчатка».
Используется шейдером воды для отрисовки прибрежных волн. Она сжата алгоритмом BC4 UNorm.
BC5 (ATI2/3Dc)
В середине нулевых начали появляется игры с шейдерами поддерживающими normal map. Алгоритмы DXT1-5 не подходили для хранения нормала, т.к. основе имели dxt1, а он плохо справлялся с плавными градиентами, кроме того, в нём разные цветовые каналы могут негативно влиять друг на друга. Ответом на запрос был BC5. Он представлял из себя 2 блока BC4 для красного и зелёного канала соответственно. Синий канал восстанавливается по формуле и в хранении не нуждается. Если сравнивать алгоритмы целиком, то разница плохо видна — визуально после декодирования синий канал в ВС5 не отображается (см. рис 23).
Рисунок 23. Слева-направо: исходник, ВС5, DXT1(BC1).
Давайте вглянем на красный канал всех трёх изображений что бы почувствовать разницу: качество ВС5 станет очевидным:
Рисунок 24. ВС5 от исходника практически не отличается, а в ВС1 куча артефактов.
У BC5, как и у BC4, есть 2 варианта BC5_UNORM и BC5_SNORM. В большинстве случаев используют ВС5_u – этот алгоритм идёт по умолчанию, однако выбор в первую очередь зависит то шейдера.
Продолжение будет в следующем посте.