Сжатие текстур: S3TC (DXTn)
от mrEDitor
S3 Texture Compression (S3TC, иногда также DXTn или DXTC) – группа алгоритмов сжатия текстур с потерями, разработанная Konstantine I. Iourcha и компанией S3 Graphics Ltd Для использования в графическом процессоре Savage 3D.
В отличие от многих других алгоритмов сжатия изображений (таких, как JPEG), алгоритмы сжатия S3TC, равномерно сжимающие данные и требующие только один проход по исходным данным, способны к обработке информации «на лету», а значит, отлично подходят для сжатия текстур в графических процессорах, в том числе поддерживающих аппаратное ускорение. Кроме того, поддержка алгоритмов сжатия S3TC была реализована в Microsoft DirectX 6 и OpenGL 1.3, что в конечном итоге обеспечило им поддержку со стороны многих программных и аппаратных продуктов.
Группа алгоритмов S3TC включает пять алгоритмов сжатия:
DXT1 – сжатие текстур с однобитным альфа-каналом
DXT3 – сжатие текстур с четырёхбитным альфа-каналом, содержащим произвольные значения
DXT2 – аналогично DXT3, но с предумножением цвета на альфа-канал
DXT5 – сжатие текстур с восьмибитным альфа-каналом, содержащим табличные значения
DXT4 – аналогично DXT5, но с предумножением цвета на альфаканал
В настоящее время в подавляющем большинстве случаев используется сжатие DXT1/3/5.
Все алгоритмы основаны на следующем подходе: изображение делится на блоки 4*4 пикселя и каждый блок последовательно преобразуется в 64- или 128-битную последовательность (в зависимости от конкретного алгоритма). Так как сжатие производится с потерями, различные типы изображений в разной степени подвержены появлению артефактов при сжатии.
Недостатки алгоритмов сжатия S3TCОсновной причиной проблем, возникающих при хранении изображений, сжатых согласно S3TC, является ограничение палитры четырьмя цветами, находящимися на одной линии в цветовом пространстве.

Рис. 1. Потеря оттенков при сжатииНа рис. 1 показана показана потеря части оттенков одного цвета при сжатии. Слева показаны 16 оттенков красного, от чистого красного до чистого черного. Справа – только четыре цвета из этих 16 оттенков, оставшиеся после S3TC-сжатия.

Рис. 2. Потеря цветов при сжатииНа рис. 2 показана потеря цветов, не находящихся на одной линии в цветовом пространстве. В этом случае были использованы все крайности палитры RGB (красный, зеленый и синий). Очевидно, в результате интерполированные цвета не совпадают с оригиналами. Обычно в области пикселей 4*4 не такой широкий выбор цветов, но это показывает, что текстуры с сильно разлиающимися цветами при сжатии страдают особенно сильно.
Разбиение изображений на блоки

Рис. 3. Разбиение изображения и порядок обработки блоковПри S3TC-сжатии изображения хранятся в виде блоков размером 4*4 пикселя.
В примере на рис. 3 для изображения размером 16*16 пикселей показан его первый блок и порядок обработки блоков. Всё изображение состоит из четырёх таких блоков, обрабатываемых при компрессии и декомпрессии слева направо и сверху вниз.
DXT1Алгоритм компрессии DXT1 (также известный как Block Compression 1) предназначен для хранения текстур с однобитным альфа-каналом, в которых каждый блок размером 4*4 пикселя представлен R5G6B5-палитрой из четырёх цветов.
Сжатый размер блока 4*4 пикселя – 64 бит.
Структура блока, сжатого в DXT1{Хранение палитры
Каждый блок изображения содержит пиксели не более, чем четырёх различных цветов.
Двумя основными цветами палитры принимаются цвета с максимальным и минимальным RGB-кодом, промежуточные два цвета вычисляются по следующим правилам:
* если
:


* иначе

, полностью прозрачный чёрный.

Рис. 4. Цвета изображенияТак, для примера на рис. 4, C0 = #480400 и C1 = #FFFFA8, то есть
, поэтому
C2 = #
= #A38154 и C3 – прозрачный.
Цвета C0 и C1 этой палитры сохраняются в первые 32 бита в следующем виде:
* Один цвет занимает 16 бит, где для красного и синего каналов отводится по 5 бит, а для зелёного – 6 бит.
* Младшие биты каналов, 3 – для красного и синего, 2 – для зелёного, отбрасываются.
* В первые 3 бита записываются 3 младших бита зелёного канала.
* В следующие 5 бит – синий канал.
* В следующие 5 бит – красный канал.
* В последние 3 бита записываются старшие 3 бита зелёного канала.
Для примера на рис. 4. палитра сохраняется в следущем виде:
C0 = #480400 = 01001000 00000100 00000000
C1 = #FFFFA8 = 11111111 11111111 10101000
Индексы цвета пикселей
Рис. 5. Десятеричные -> двоичные индексыСогласно количеству цветов в палитре индексы принимают значения от 0 до 3 (как показано на рис. 5), то есть индекс цвета каждого пикселя занимает 2 бита,
а обработка пикселей идёт справа налево и сверху вниз.
В следующей таблице представлен блок индексов для примера на рис. 5:
DXT3Алгоритм компрессии DXT3 (также известный как Block Compression 2) предназначен для хранения текстур с четырёхбитным альфа-каналом, в которых каждый блок размером 4*4 пикселя представлен R5G6B5-палитрой из четырёх цветов.
Сжатый размер блока 4*4 пикселя – 128 бит.

Структура блока, сжатого в DXT3Хранение значений альфа-канала
DXT3-сжатие предусматривает четырёх-битный альфа-канал для каждой точки сжимаемой текстуры.
Рис. 6. Альфа-каналы изображенияТак, в примере на рис. 6 представлен блок 4*4 пикселя, состоящий из абсолютно чёрных пикселей (#000000) с различными значениями альфа-канала. Значения альфа-канала при сжатии записываются группами по два расположенных рядом по горизонтали пикселя в один байт: альфа-канал каждого первого первого пикселя – в младшие 4 бита, второго пикселя – в старшие 4 бита. Обработка таких пар пикселей производится слева направо и сверху вниз. Пример блока альфа-канала для рис. 6 представлен на таблице:
Хранение палитры
Палитра цветов в DXT3 практически идентична DXT1, за исключением, того что цвета C2 и C3 всегда вычисляются как
и
.
Индексы цвета пикселей
Индексы цвета пикселей в DXT3 хранятся идентично DXT1.
DXT5
Алгоритм компрессии DXT5 (также известный как Block Compression 3) предназначен для хранения текстур, в которых каждый блок размером 4*4 пикселя представлен цветовой палитрой R5G6B5 из четырёх различных цветов и альфа-палитрой из восьми восьмибитных уровней прозрачности.
Сжатый размер блока 4*4 пикселя – 128 бит.
Структура блока, сжатого в DXT5Хранение таблицы альфа-каналов
Значение альфа-канала каждого пикселя может принимать одно из семи возможных восьмибитных значений A0 – A6, причём A0 и A1 хранятся непосредственно, а A2 – A6 высчитываются по формулам:
* если
:






* иначе:






Рис. 7. Уровни прозрачности и их индексы в десятеричном и двоичном видеТак, в примере на рис. 7. представлен блок 4*4 пикселя, состоящий из абсолютно чёрных пикселей (#000000) с различными значениями альфа-канала и отмечены их индексы в таблице прозрачности. В данном примере A0 = #FF и A1 = #3D, остальные же уровни в таблице вычисляются по приведённым выше формулам:






Альфа-уровни A0 и A1 записываются в виде однобайтных значений:
Индексы прозрачности пикселей
Трёхбитные индексы альфа-уровня, содержащие значение 0-7 записываются в следующем порядке (2 строки по 4 пикселя на 3 байта, нумерация пикселей слева направо и сверху вниз):
* Индекс первого пикселя записывается в младшие 3 бита первого байта
* Индекс второго пикселя записывается в следующие по старшинству 3 бита первого байта
* 2 младших бита индекса третьего пикселя записываются в старшие 2 бита первого байта
* Старший бит индекса третьего пикселя записывается в младший бит второго байта
* Индекс четвёртого пикселя записывается в следующие по старшинству 3 бита второго байта
* Индекс пятого пикселя записывается в следующие по старшинству 3 бита второго байта
* Младший бит индекса шестого пикселя записывается в старший бит второго байта
* 2 старших бита индекса шестого пикселя записываются в 2 младших бита третьего байта
* Индекс седьмого пикселя записывается в следующие по старшинству 3 бита третьего байта
* Индекс восьмого пикселя записывается в старшие 3 бита третьего байта
Пример таблицы индексов альфа-уровней для рис. 7:
Хранение палитры
Палитра цветов в DXT3 практически идентична DXT1, за исключением, того что цвета C2 и C3 всегда вычисляются как
и
.
Индексы цвета пикселей
Индексы цвета пикселей в DXT3 хранятся идентично DXT1.
Пара изображений для сравнения глубины альфа-канала DXTn-сжатия:
Размер оригинальных несжатых изображений 460*460 A8R8G8B8 = 846 400 байт.
Со сжатием DXT1 – 105 800 байт, DXT3/5 – 211 600 байт.
Но S3TC-сжатие может терять не только прозрачность, но и цвета. И если результат сжатия фотографии кота Риса (рис. 8) вполне приемлимый, то сжатие изображений, не имеющих цветового шума и требующих чётких цветовых контуров, даст посредственный результат (рис. 9):

Рис. 8. Кот Рис

Рис. 9. Сжатие текстур с текстом
В отличие от многих других алгоритмов сжатия изображений (таких, как JPEG), алгоритмы сжатия S3TC, равномерно сжимающие данные и требующие только один проход по исходным данным, способны к обработке информации «на лету», а значит, отлично подходят для сжатия текстур в графических процессорах, в том числе поддерживающих аппаратное ускорение. Кроме того, поддержка алгоритмов сжатия S3TC была реализована в Microsoft DirectX 6 и OpenGL 1.3, что в конечном итоге обеспечило им поддержку со стороны многих программных и аппаратных продуктов.
Группа алгоритмов S3TC включает пять алгоритмов сжатия:
DXT1 – сжатие текстур с однобитным альфа-каналом
DXT3 – сжатие текстур с четырёхбитным альфа-каналом, содержащим произвольные значения
DXT2 – аналогично DXT3, но с предумножением цвета на альфа-канал
DXT5 – сжатие текстур с восьмибитным альфа-каналом, содержащим табличные значения
DXT4 – аналогично DXT5, но с предумножением цвета на альфаканал
В настоящее время в подавляющем большинстве случаев используется сжатие DXT1/3/5.
Все алгоритмы основаны на следующем подходе: изображение делится на блоки 4*4 пикселя и каждый блок последовательно преобразуется в 64- или 128-битную последовательность (в зависимости от конкретного алгоритма). Так как сжатие производится с потерями, различные типы изображений в разной степени подвержены появлению артефактов при сжатии.
Недостатки алгоритмов сжатия S3TCОсновной причиной проблем, возникающих при хранении изображений, сжатых согласно S3TC, является ограничение палитры четырьмя цветами, находящимися на одной линии в цветовом пространстве.

Рис. 1. Потеря оттенков при сжатииНа рис. 1 показана показана потеря части оттенков одного цвета при сжатии. Слева показаны 16 оттенков красного, от чистого красного до чистого черного. Справа – только четыре цвета из этих 16 оттенков, оставшиеся после S3TC-сжатия.

Рис. 2. Потеря цветов при сжатииНа рис. 2 показана потеря цветов, не находящихся на одной линии в цветовом пространстве. В этом случае были использованы все крайности палитры RGB (красный, зеленый и синий). Очевидно, в результате интерполированные цвета не совпадают с оригиналами. Обычно в области пикселей 4*4 не такой широкий выбор цветов, но это показывает, что текстуры с сильно разлиающимися цветами при сжатии страдают особенно сильно.
Разбиение изображений на блоки

Рис. 3. Разбиение изображения и порядок обработки блоковПри S3TC-сжатии изображения хранятся в виде блоков размером 4*4 пикселя.
В примере на рис. 3 для изображения размером 16*16 пикселей показан его первый блок и порядок обработки блоков. Всё изображение состоит из четырёх таких блоков, обрабатываемых при компрессии и декомпрессии слева направо и сверху вниз.
DXT1Алгоритм компрессии DXT1 (также известный как Block Compression 1) предназначен для хранения текстур с однобитным альфа-каналом, в которых каждый блок размером 4*4 пикселя представлен R5G6B5-палитрой из четырёх цветов.
Сжатый размер блока 4*4 пикселя – 64 бит.

Структура блока, сжатого в DXT1{Хранение палитры
Каждый блок изображения содержит пиксели не более, чем четырёх различных цветов.
Двумя основными цветами палитры принимаются цвета с максимальным и минимальным RGB-кодом, промежуточные два цвета вычисляются по следующим правилам:
* если
* иначе

Рис. 4. Цвета изображенияТак, для примера на рис. 4, C0 = #480400 и C1 = #FFFFA8, то есть
C2 = #
Цвета C0 и C1 этой палитры сохраняются в первые 32 бита в следующем виде:
* Один цвет занимает 16 бит, где для красного и синего каналов отводится по 5 бит, а для зелёного – 6 бит.
* Младшие биты каналов, 3 – для красного и синего, 2 – для зелёного, отбрасываются.
* В первые 3 бита записываются 3 младших бита зелёного канала.
* В следующие 5 бит – синий канал.
* В следующие 5 бит – красный канал.
* В последние 3 бита записываются старшие 3 бита зелёного канала.
Для примера на рис. 4. палитра сохраняется в следущем виде:
C0 = #480400 = 01001000 00000100 00000000
C1 = #FFFFA8 = 11111111 11111111 10101000


Рис. 5. Десятеричные -> двоичные индексыСогласно количеству цветов в палитре индексы принимают значения от 0 до 3 (как показано на рис. 5), то есть индекс цвета каждого пикселя занимает 2 бита,
а обработка пикселей идёт справа налево и сверху вниз.
В следующей таблице представлен блок индексов для примера на рис. 5:

DXT3Алгоритм компрессии DXT3 (также известный как Block Compression 2) предназначен для хранения текстур с четырёхбитным альфа-каналом, в которых каждый блок размером 4*4 пикселя представлен R5G6B5-палитрой из четырёх цветов.
Сжатый размер блока 4*4 пикселя – 128 бит.

Структура блока, сжатого в DXT3Хранение значений альфа-канала
DXT3-сжатие предусматривает четырёх-битный альфа-канал для каждой точки сжимаемой текстуры.

Рис. 6. Альфа-каналы изображенияТак, в примере на рис. 6 представлен блок 4*4 пикселя, состоящий из абсолютно чёрных пикселей (#000000) с различными значениями альфа-канала. Значения альфа-канала при сжатии записываются группами по два расположенных рядом по горизонтали пикселя в один байт: альфа-канал каждого первого первого пикселя – в младшие 4 бита, второго пикселя – в старшие 4 бита. Обработка таких пар пикселей производится слева направо и сверху вниз. Пример блока альфа-канала для рис. 6 представлен на таблице:

Палитра цветов в DXT3 практически идентична DXT1, за исключением, того что цвета C2 и C3 всегда вычисляются как
Индексы цвета пикселей
Индексы цвета пикселей в DXT3 хранятся идентично DXT1.
DXT5
Алгоритм компрессии DXT5 (также известный как Block Compression 3) предназначен для хранения текстур, в которых каждый блок размером 4*4 пикселя представлен цветовой палитрой R5G6B5 из четырёх различных цветов и альфа-палитрой из восьми восьмибитных уровней прозрачности.
Сжатый размер блока 4*4 пикселя – 128 бит.

Структура блока, сжатого в DXT5Хранение таблицы альфа-каналов
Значение альфа-канала каждого пикселя может принимать одно из семи возможных восьмибитных значений A0 – A6, причём A0 и A1 хранятся непосредственно, а A2 – A6 высчитываются по формулам:
* если
* иначе:

Рис. 7. Уровни прозрачности и их индексы в десятеричном и двоичном видеТак, в примере на рис. 7. представлен блок 4*4 пикселя, состоящий из абсолютно чёрных пикселей (#000000) с различными значениями альфа-канала и отмечены их индексы в таблице прозрачности. В данном примере A0 = #FF и A1 = #3D, остальные же уровни в таблице вычисляются по приведённым выше формулам:
Альфа-уровни A0 и A1 записываются в виде однобайтных значений:

Трёхбитные индексы альфа-уровня, содержащие значение 0-7 записываются в следующем порядке (2 строки по 4 пикселя на 3 байта, нумерация пикселей слева направо и сверху вниз):
* Индекс первого пикселя записывается в младшие 3 бита первого байта
* Индекс второго пикселя записывается в следующие по старшинству 3 бита первого байта
* 2 младших бита индекса третьего пикселя записываются в старшие 2 бита первого байта
* Старший бит индекса третьего пикселя записывается в младший бит второго байта
* Индекс четвёртого пикселя записывается в следующие по старшинству 3 бита второго байта
* Индекс пятого пикселя записывается в следующие по старшинству 3 бита второго байта
* Младший бит индекса шестого пикселя записывается в старший бит второго байта
* 2 старших бита индекса шестого пикселя записываются в 2 младших бита третьего байта
* Индекс седьмого пикселя записывается в следующие по старшинству 3 бита третьего байта
* Индекс восьмого пикселя записывается в старшие 3 бита третьего байта
Пример таблицы индексов альфа-уровней для рис. 7:

Палитра цветов в DXT3 практически идентична DXT1, за исключением, того что цвета C2 и C3 всегда вычисляются как
Индексы цвета пикселей
Индексы цвета пикселей в DXT3 хранятся идентично DXT1.
Пара изображений для сравнения глубины альфа-канала DXTn-сжатия:


Размер оригинальных несжатых изображений 460*460 A8R8G8B8 = 846 400 байт.
Со сжатием DXT1 – 105 800 байт, DXT3/5 – 211 600 байт.
Но S3TC-сжатие может терять не только прозрачность, но и цвета. И если результат сжатия фотографии кота Риса (рис. 8) вполне приемлимый, то сжатие изображений, не имеющих цветового шума и требующих чётких цветовых контуров, даст посредственный результат (рис. 9):

Рис. 8. Кот Рис

Рис. 9. Сжатие текстур с текстом
На правах прав на копирайт