Файлы DDS. Описание формата DXTn, его возможностей, простые рекомендации по выбору формата компрессии.
DDS файлы — изображения, в которых данные хранятся так же, как в видеопамяти (включая мипмапы). Это позволяет их быстро загружать в игре. В DDS могут храниться объёмные текстуры, куб-мапы и прочие необычные (для графических файлов) вещи.
2D слои в DDS-файле могут храниться в RGBA формате, а могут быть сжаты в форматы DXT1, DXT3, DXT5.
Это сжатие с потерями, как Jpeg. Оно было специально разработано для того, чтобы видеокарта могла «расжимать» гигабайт текстур за секунду, отображая на экране сжатую текстуру сразу из видеопамяти, без промежуточного конвертирования.
DXT1 — для RGB картинок c однобитной альфой, четыре бита на пиксел (сжатие в 8 раз по сравнению с RGBX).
DXT3 и DXT5 — для картинок с альфа-каналом, типично DXT5 лучше. 8 бит на пиксел, сжатие в четыре раза.
Подробней про метод сжатия, на уровне битов:
Изображение делится на блоки 4x4. Для каждого блока хранится два 16-битных цвета. При распаковке из двух цветов x,y генерится четыре последовательных цвета, палитра [x, ⅔x + ⅓y, ⅓x + ⅔y, y]. После 2*16 бит цветов хранится 4*4 двухбитых индексов в эту палитру. Порядок двух цветов (цвет_0 > цвет_1 ?) также содержит один бит информации. Если цвет_0 > цвет_1, то в палитре одно из значений используется как нулевая альфа, и остальные 3 цвета [x, ½x + ½y, y] — палитра из непрозрачных цветов. Всего получается 64 бита на блок 4x4 пиксела.
В DXT3 и DXT5 rgb-канал хранится точно так же как в DXT1. Альфа в DXT3 хранится просто как округлённое с 8 битов до 4 битов на пиксел, без сжатия. В DXT5 для альфы используется метод сжатия, похожий на метод для RGB в DXT1. Два значения альфы на блок 4x4. Если цвет_0 > цвет_1, создаётся 6 промежуточных значений альфы в палитре и ещё отдельно два особых значения 0 и 1 для альфы. Если цвет_0 <= цвет_1, то из двух крайних значений альфы создаётся 8 промежуточных. После двух 8-битных граничных значений альфы идёт 16 3-битных индексов. DXT5 обычно гораздо точней сохраняет альфу и рекомендуется вместо DXT3.
Артефакты после сжатия малозаметны, чаще всего их можно увидеть в блоках, где сходится 3 разных оттенка (3 оттенка в 2-х на один блок не помещаются).
DXT2 раскодируется так же как DXT3, а DXT4 так же как DXT5, только программа должна интерпретировать RGB как уже умноженный на альфу. В них хранится флажок «premultiplied alpha», который может быть интересен универсальной смотрелке картинок, но не игровому движку.
Это сжатие с потерями, паковщик должен выбрать два идеальных цвета для квадрата 4x4, поэтому разные инструменты могут конвертировать с разным соотношением время работы/качество результата (см. иллюстрацию в конце). NVidia хвастается, что её nvcompress лучший, не знаю насколько справедливо. На глаз вроде результат лучше, чем у TEXCONV из D3D SDK.
При сжатии DXT в zip имеет смысл разделить индексы и палитру, хранить приращения. Тогда сожмётся чуть лучше. Увы сам не мерял, только напел. Если вы пробовали — напишите, интересно.
Можно чуть-чуть «подвигать» ползунок качество/сжатие таким образом: перед DXT-сжатием использовать текстуру которая в 2 раза больше, если такая есть. Например, уменьшить то, что нарисовал художник не с 4096x4096 до 128x128x, а до 256x256.
Итого:
Если картинка без альфы или достаточно однобитной альфы, используйте DXT1. С альфой — DXT5. На «мультяшных» картинках с мелкими деталями будут артефакты, на реалистичных текстурах с шумом и градиентом компрессия незаметна.