Войти
ПрограммированиеСтатьиГрафика

Работа с расширениями OpenGL с использованием NVIDIA OpenGL SDK 5.1. (Часть 6) (4 стр)

Автор:

Сравнение форматов сжатия S3TC

Для того чтобы понять достоинства и недостатки различных форматов S3TC необходимо немного разбираться в их алгоритме. Алгоритм S3TC-компрессии текстур любого формата можно описать следующим образом. Сначала текстура разбивается на блоки 4x4 текселя.  Затем в каждом блоке выбираются два наиболее характерных текселя (обычно наиболее яркий и наиболее тёмный). Эти 2-текселя сохраняются в неизменном виде. Для остальных текселей запоминаются коэффициенты интерполяции, для хранения которых отводится очень маленькое число бит (обычно 2-3 бит).
Чтобы лучше понять алгоритм компрессии, рассмотрим процесс компрессии блока 4x4 пикселей, изображённого на рисунке 2 (взятом из DirectX 8 SDK) с использованием формата GL_COMPRESS_RGB_S3TC_DXT1_EXT.

Изображение
Рисунок 2

Для начала выбираются два наиболее характерных цвета, которые запоминаются в 16-битном формате. В нашем случае этими цветами будут ярко красный и чёрный (цвет 0 и цвет 1). В связи с тем, что человеческий глаз наиболее чувствительный к зелёному цвету, для хранения каналов R, G и B отводятся  5, 6 и 5 бит соответственно. Для хранения коэффициентов интерполяции каждого текселя отводится 2 бита. Но т.к. 2 бита явно не хватит для хранения двух коэффициентов интерполяции, вместо самих коэффициентов интерполяции будут хранится индексы из таблицы 3. Сама таблица обычно хранится в ROM видеокарты.

Индекс (в двоичном виде)  Коэффициент перед
цветом 0 
Коэффициент перед
цветом 1
00  0
01  1
10  2/3  1/3
11  1/3  2/3

Таблица 3. Индексы интерполяции для формата GL_COMPRESS_RGB_S3TC_DXT1_EXT.

Например, если индекс текущего текселя равен 10, то его цвет будет рассчитываться по формуле:

2/3*(цвет 0)+1/3*(цвет 1).

Итак, у нас есть два 16-битных цвета  и шестнадцать 2-битных индексов. Для хранения этой информации достаточно 16*2+2*16=64 бита. В тоже время несжатое 24-х битное изображение требует для хранения 24*16=384 бита. Следовательно, мы получаем сжатие в 384/64=6 раз. Но платой за это является то, что в блоке 4x4 пикселей не может быть больше 4-х разных цветов, т.е. алгоритм производит сжатие с потерей информации.

Формат GL_COMPRESS_RGBA_S3TC_DXT1_EXT отличается от предыдущего формата  поддержкой работы с текстурами, содержащими 1 бит прозрачности (т.е. текстура может быть либо непрозрачной, либо 100% прозрачной).  Такие текстуры очень удобны для создания текстур-трафаретов. Это достигается путём небольшой модификации таблицы индексов (таблица 4).

Индекс (в двоичном виде)  Коэффициент перед
цветом 0 
Коэффициент перед
цветом 1 
Итоговый
альфа-канал (0..1)
00  1
01  1
10  1
11  0

Таблица 4. Индексы интерполяции для формата GL_COMPRESS_RGBA_S3TC_DXT1_EXT.

Как видно, индексу 11 теперь соответствует полностью прозрачная текстура. Но теперь в блоке 4x4 пикселей не может быть больше 3-х разных цветов.

Из всего выше сказанного следует вывод, что формат GL_COMPRESS_RGBA_S3TC_DXT1_EXT НИКОГДА не следует использовать для сжатия полупрозрачных текстур, т.к. он приведёт к сильному искажению альфа канала.

Формат GL_COMPRESS_RGBA_S3TC_DXT3_EXT предназначен для хранения полупрозрачных текстур и отличается. В этом случае, каждый блок 4x4 текселя состоит из двух частей: блок альфа компонентов текселей и 64-х битного блока с RGB-компонентами текселей. Причём, структура RGB-блока фактически является GL_COMPRESS_RGB_S3TC_DXT1-блоком.

В блоке альфа каналов храняться 4 старших бита альфа канала каждого текселя, т.е. этот блок занимает 4*16=64 бита. Из этого можно сделать вывод, что по качеству передачи прозрачности текстуры формата GL_COMPRESS_RGBA_S3TC_DXT3 полностью аналогичны RGBA текстурам формата (4-4-4-4). В итоге весь фрагмент 4x4 текселя занимает в памяти 64+64=128. В тоже время несжатый 32-х битный блок  4x4 текселя требует для хранения 32*16=512 бита. Следовательно, степень сжатия в этом случае равна 512/128=4.

Формат сжатия текстур GL_COMPRESS_RGBA_S3TC_DXT5_EXT отличается от GL_COMPRESS_RGBA_S3TC_DXT3_EXT лишь тем, что блок альфа канала храниться теперь в сжатом виде, причём алгоритм сжатия очень напоминает алгоритм сжатия RGB-блока. Сначала запоминаются альфа каналы двух текселей, которые имеют минимальную и максимальную прозрачность. Для остальных текселей запоминаются 3-х битные индексы коэффициентов интерполяции.

Индекс (в двоичном виде)  Коэффициент перед
альфа каналом 0 
Коэффициент перед
альфа каналом 1
000  0
001  1
010  6/7  1/7
011  5/7  2/7
100  4/7  3/7
101  3/7  4/7
110  2/7  5/7
111  1/7  6/7

Таблица 5. Индексы интерполяции для формата GL_COMPRESS_RGBA_S3TC_DXT5_EXT.

В блоке альфа каналов в этом случае так же  16*2+3*16=64 бита, т.е. степень сжатия полностью аналогична GL_COMPRESS_RGBA_S3TC_DXT3_EXT.

После этого небольшого поверхностного обзора форматов компрессии попробуем ответить на вопрос, какой в каких случаях какой формат оптимальнее всего использовать.

Если мы сжимаем RGB-изображение, то наш выбор однозначно формат GL_COMPRESS_RGB_S3TC_DXT1_EXT. Хотя если текстура  имеет небольшое разрешение или на передачу оттенков накладываются довольно жесткие требования (например, текстура должна использоваться в качестве карты рельефа), то лучшим форматом будет классический GL_RGB.

Если сжатие изображения с одним битом прозрачности (спрайты и т.д.), то здесь возможны 2 варианта. Если изображение довольно монотонное, то можно попробовать использовать GL_COMPRESS_RGBA_S3TC_DXT1_EXT, в противном случае оптимальным выбором будет формат GL_COMPRESS_RGBA_S3TC_DXT3_EXT (GL_COMPRESS_RGBA_S3TC_DXT5_EXT).

При  сжимании полупрозрачного изображения выбор сделать не так уж просто. Если в пределах одного блока 4x4 возможны хаотичные резкие "скачки" прозрачности в широком диапазоне, то лучшим выбором скорее всего будет GL_COMPRESS_RGBA_S3TC_DXT3_EXT, в противном - GL_COMPRESS_RGBA_S3TC_DXT5_EXT.

Если же тип текстуры заранее не известен, то лучше использовать формат GL_COMPRESS_RGBA_S3TC_DXT5_EXT, который в подавляющем большинстве случаев даёт наилучшее качество изображения.

Все эти рассуждения пока носят чисто теоретический характер. На практике ситуация намного сложнее.

Страницы: 1 2 3 4 5 Следующая »

#расширения OpenGL, #NVIDIA, #OpenGL

13 апреля 2003 (Обновление: 6 окт. 2009)