Сравним все три полученные результаты - однопроходный с округлением (идеальный), двухпроходный с округлением и двухпроходный без округления:
Как видим, наиболее отличный от идеала последний. В первых двух случаях границы между цветами максимально плавные, тогда как в последнем такое правило нарушается и уже сам по себе неидеальный 16-битный цвет выдает ещё более грубую картинку. Большинство видеокарт в 16-битном режиме не используют округление при смешивании, однако для повышения качества используют технологию дизеринга (а некоторые даже не используют дизеринг).
В 32-битном цвете ситуация немного другая. Некоторые видеокарты последних поколений используют избыточную логику для округления результата при смешивании цветов и качество графики при этом получается очень высоким. Другие видеокарты используют все 32 бита, где, как и в обычной схеме, в старших 24 битах хранятся реальные цвета, а биты избыточности (дробные части цветов) хранятся в младших 8 битах. Такая схема наиболее предпочтительна, но, к сожалению, просто мизерная часть современных видеоакселераторов поддерживают данную схему. И, наконец, некоторые видеокарты (их, слава богу, меньшинство) используют схему смешивания без округления с дизерингом (как и в 16-битном цвете). Есть ещё несколько схем реализации смешивания цветов, но я лично не встречал видеокарты, реализующие подобные алгоритмы, поэтому рассматривать их не будем.
В итоге, уже при двухпроходном рендеринге мы наблюдаем некоторое отклонение от нормы как в 16-битном, так и 32-битном цвете. Современные программы создают сцену за относительно малое число проходов, и для нас 32-битный цвет кажется идеальным. Но, с усложнением сцен мы сможем увидеть недостатки и в 32-битном цвете. А такое будущее уже не за горами, - уже в DOOM-3 планируется рендеринг с наложением 6-8 текстур на треугольник, и это без учета дополнительных эффектов типа блики, дым, огонь, облака и им подобных. И при реализации трилинейной фильтрации используются два текстурных модуля акселератора, а это значит, что при рендеринге такого "сложного" треугольника придется накладывать уже 12-16 текстур, а ни один современный акселератор в один проход этого не сделает. Сам же Джон Кармак, постоянно работая с главными разработчиками видеочипов, предлагает в будущих проектах использовать 64-битный цвет. Это поможет помимо 8 бит реального цвета на цветовой канал хранить ещё и 8 бит дробной части для каждого цветового канала, тем самым обзавестись идеальным качеством. 64-битный цвет дает огромный запас по избыточности, что делает его высококачественным ещё как минимум на шесть лет. Но, к сожалению, ни один современный непрофессиональный видеочип не поддерживает 64-битного цвета, и в ближайшем будущем такого видеочипа не ожидается.
Как изображение из видеопамяти попадает на экран
Те, кто знает ответ на этот вопрос, могут переходить к чтению следующей части. Остальных же прошу слушать внимательнее, потому что мы все ближе и ближе подходим к сущности работы постфильтра.
Итак, идея в том, что обычный CRT-монитор получает аналоговые сигналы, а в памяти видеоадаптера информация хранится в цифровом виде. Front Buffer должен постоянно и непрерывно показываться на мониторе. А его показом занимается RAMDAC. А точнее, последовательным преобразованием цифрового значения каждой его точки в аналоговый сигнал. Обычный RAMDAC состоит из двух основных блоков. Первый - блок выборки из памяти. Он выбирает из участка памяти, где храниться Front Buffer, последовательно цвета всех пикселей (для упрощения не будем рассматривать 1-, 2-, 4- и 8-битные цветовые режимы). Обычно он же временно сохраняет эти данные в кэше, что ускоряет процесс обращения к памяти. Главная задача этого блока постоянно предоставлять информацию о цветах следующего пикселя в порядке следования луча по экрану монитора - слева направо, сверху вниз. Следующий блок - это DAC (по-русски - ЦАП). Он синхронизируется с монитором, и каждый такт выводит комбинацию аналоговых сигналов, соответствующих цвету точки, полученному от предыдущего блока. Казалось бы, все просто. Но, как мы помним, видеокарта может работать в разных цветовых режимах. Поэтому большинство видеоакселераторов содержат в блоке DAC несколько наборов логики. Чаще всего это DAC8, DAC15, DAC16, DAC24 и DAC32 (DAC8 отвечает за палитезированные режимы и поэтому работает как с 256-цветовым режимом, так и с 16-, 4- и 1-цветовым). Некоторые видеокарты могут не содержать некоторые наборы (например, DAC15 или DAC24).
Вот и всё. Вот так работает RAMDAC, и так часть видеопамяти под названием Front Buffer попадает к нам на экран.
Дизеринг
Теперь перейдем к технологии дизеринга (dithering). Так как она нашла свое основное применение именно в 16-битном цвете, то его и рассмотрим. Каждый текстурный конвейер в видеочипах, работающих с High Color режимом, имеет разрядность 24 бита, т.е. по 8 бит на цветовой канал. Такую же разрядность имеет и модуль смешивания цветов. Эффективная же их разрядность 22-бита (знакомо?). Это значит, что какую бы разрядность не имели эти модули, на их выходе реально используются только 22 бита. То есть 7 бит на красную, 8 бит на зеленую и 7 бит на синюю составляющие. Но, как мы помним, мы сейчас генерируем 16-битную картинку, а это значит, что 6 бит у нас лишние. Их можно просто отбросить. Если сделать это, то есть при пересылке не пересылать два младших бита от каждой цветовой составляющей, то мы получим 16-битную картинку без дизеринга. А выглядит это так:
Бяка, одним словом. Слишком явные границы между соседними цветами. А ведь смешивание происходит с более высокой точностью, и именно эту точность мы "отбрасываем" вместе с шестью "лишними" битами. А ведь их можно учитывать. И делается это очень просто. Рассмотрим пример для красной составляющей (как мы видим, наша картинка именно красного цвета, а на самом деле это кусок неба из Quake3:Arena). После генерации реального цвета точки на части выходов блока смешивания появляется 8 бит определяющие красный цвет. Из них мы точно берем старшие шесть бит. Например, эти шесть бит определяют значение 27. Но нам так же интересны и оставшиеся два бита. Если там ноль, значит мы имеем дело с реальным цветом 27, его и ставим. Если два младших бита равны единице, то реальный цвет 27.25, т.е. на четверть больше. И тогда, если точка ставиться на нечетную координату экрана X и четную координату экрана Y, то на это место ставится цвет на единицу больший по интенсивности, в нашем случае 28. Таким образом, на поле из цвета 27 каждая четвертая точка имеет значение 28, т.е. среднее значение цвета поля получается 27.25, что нам и нужно. Если два младших бита, равны 10b (двум), то реальный цвет точки 27.5. Таким образом, уже каждая вторая точка должна иметь значение на единицу больше. Условие усложняется. Если точка ставится на нечетную координату экрана X и четную координату экрана Y, или на четную координату экрана X и нечетную координату экрана Y, то на это место ставится цвет на единицу больший по интенсивности (у нас 28). Аналогично строится условие, в случае, когда младшие два бита равны 11b (тройке). Если точка ставится на нечетную координату экрана X и четную координату экрана Y, или на нечетную координату экрана X и четную координату экрана Y, или на четную координату экрана X и четную координату экрана Y, то на это место ставится цвет на единицу больший по интенсивности. В этом случае на поле из цвета 28 остается каждая четвертая точка 27. И наша картинка (часть неба Quake3) будет выглядеть уже иначе:
Это та же картинка, но уже с дизерингом. Эта картинка ещё и увеличена, для того чтобы была отчетливее видна сеточка дизеринга. В реальном масштабе сеточка заметна ещё меньше, так как глаз видит уже достаточно однородное поле. Отодвиньтесь дальше и вы сами увидите это.
Алгоритм дизеринга можно представить и графически. Таблица ниже показывает, как изменяются четыре соседних точки в зависимости от двух младших битов. В позициях точек указано приращение к базовому цвету, записанному в старших битах.
Такая схема дизеринга называется Ordered. Именно её и использует Voodoo3. Существуют и другие способы дизеринга (другие маски, алгоритмы), но именно Ordered наиболее эффективен, если в видеочипе встроен постфильтр.
Постфильтр
Посмотрим ещё раз на небо Quake3, а точнее на его часть.
Мы видим, как работал дизеринг, и можем с большой уверенностью сказать, какие цвета на самом деле были на выходе блока смешивания, и со стопроцентной вероятностью сказать какие цвета "увидит" наш глаз (не забываем о том, что глаз смешивает соседние невыделенные цвета). Если мы можем определить, какие цвета должны стоять на месте каждого поля из точек, почему это не может видеокарта? Так заставим же её это сделать. Блок DAC16 модуля RAMDAC читает именно такую картинку. Естественно в его кэш поступает не вся картинка сразу, а только несколько горизонтальных линий. Минимальное количество линий две. Как известно, Voodoo Graphics использует маску постфильтра 1x4. Модели 3dfx, начиная с Voodoo2 и выше, используют маску 2x2. DAC16, используя дополнительную логику, сравнивает соседние четыре пикселя, и увидев знакомую "шахматку" смешивает эти цвета. Естественно смешивается не любые четыре соседних цвета, а только те, которые могли создаться дизерингом. То есть дополнительная логика ищет цвета отличающиеся друг от друга на малое значение. Найдя такие, она проверяет их на соответствие таблице Ordered. Зачем? Ну, представим себе, что логика нашла четыре точки, три из которых имеют одинаковый цвет, а один чуть светлее. Естественно таких комбинаций может быть четыре. Но только одна из них могла быть вызвана постфильтром. Эта более светлая точка должна стоять на координатах с нечетным значением X и четным значением Y. Если условия четности выполняются, то логика считает, что это поле продукт дизеринга и смешивает четыре цвета с повышенной точностью. Таким образом, возможно восстановление двух потерянных бит на выходе блока смешивания и восстановления их с точностью в 22 бита. Дополнительная логика DAC16 и называется постфильтром. Постфильтр производит обработку изображения "на лету" и поэтому не влияет на производительность системы. Для повышения качества постфильтрация производится для каждого цветового канала независимо, а не для всего цвета пикселя. Вероятность смешивания цветов, полученных не дизерингом, крайне мала (на практике меньше одного процента), и даже если смешивание таких цветов произойдет - ничего в этом страшного нет, так как наш глаз так и так был бы обманут и самостоятельно смешал бы соседние цвета. Таким образом, постфильтр - это аппаратно-программный комплекс повышения визуализации графического изображения.
В общих словах схема работы такая. Внутренний рендеринг видеокарты Voodoo3 происходит с 22-битной точностью цвета. При этом в память видеокарты (во Frame Buffer) записывается 16-битная отрендеренная картинка с использованием схемы дизеринга на основе признаков четности координат. После завершения рендеринга RAMDAC читает готовое изображение в кэш и на основе признаков ближних цветов для каждого цветового канала и признаков четности координат восстанавливает 22-битный цвет. На выходе RAMDAC получается набор аналоговых сигналов, которые поступают на монитор. Всего комбинаций аналоговых сигналов - 4194304 (произведенные от 22-битов). Это более чем в два раза меньше, чем способен различить человеческий глаз, но гораздо больше, чем реальный 16-битный цвет (в 64 раза точнее).
Уровень (глубина) постфильтрации
Все просто, не так ли? С учетом признаков четности смешиваются мало отличающиеся цвета с маской 2x2. А что значит мало отличающиеся? Для конечной картинки созданной без наложения нескольких текстур на один участок экрана или с наложением в один проход - все понятно. Разница между отдельными цветовыми каналами в пределах одного поля точек, созданных в результате дизеринга, будет равно единице (см. таблицу схемы Ordered выше). А если наложение происходит за несколько проходов? При использовании буфера шаблонов на каждый цветовой канал текстуры приходится по 4 бита, а это значит, что дискретность (а следовательно и разница между "соседними" цветами) возрастет в два/четыре раза. Разницу (глубину) между цветами, которые постфильтр должен считать соседними, устанавливают драйверами. Это значение называется уровнем или глубиной постфильтра. Глубина постфильтра Voodoo3 равна восьми. Кроме того, на создавшийся регион с некоторой сеткой дизеринга (например, светлые единичные точки) может быть наложено изображение, имеющее другую сетку (например, темные единичные точки). Поэтому при более глубоком уровне фильтрации обычной таблицы Ordered недостаточно и необходимо создать новую с производными сетками, получившихся в результате наложения различных и одинаковых сеток, а так же в результате более грубого представления прозрачных текстур.
Таблица сеток постфильтрации с глубиной восемь очень большая, и для того, чтобы мы просто имели представление о полном наборе сеток, ниже приводится такой для постфильтра с глубиной фильтрации равной трем.
При глубине постфильтра равной трем - вот все комбинации четырех соседних пикселей, которые могут создаться в результате дизеринга однопроходного и мультипроходного наложения. Все остальные комбинации создаются не дизерингом. Аналогично составляется таблица соответствия для постфильтрации с другим уровнем (например, для уровня восемь). Алгоритм поиска и сравнения маски упрощается тем, что из четырех соседних цветов, находящейся в маске слева снизу - самый яркий, а справа снизу - самый темный. Как уже говорилось, сравнение происходит для каждого цветового канала независимо, что положительно сказывается на качестве общей картинки. Естественно, чем выше уровень фильтрации, тем с большей глубиной наложения текстур она происходит. Многие замечали в 16-битном цвете при наложении на одно и то же место нескольких полупрозрачных текстур, появляющуюся сеточку дизеринга. Чем больше произошло наложений, тем заметнее сеточка (увеличивается разность между соседними цветами). Например, дым от ракеты в Quake3. Если Voodoo3 производит постфильтрацию с уровнем восемь, то такой постфильтр уберет сеточку на месте наложения максимум восьми текстур. Однако, чем выше уровень фильтрации, тем выше вероятность смешивания соседних цветов, получившихся не в результате дизеринга. Экспериментально была найдена оптимальная глубина постфильтра. Как ни странно, она равна восьми. При уменьшении уровня фильтрации проявляется сеточка на эффектах. Уже при уровне равным шести дым от ракет в Quake3 был явно решетчатым. При увеличении уровня - появляются артефакты, указывающие на смешивание цветов, которые не должны смешиваться и общая четкость картинки резко ухудшается. Дальнейшее рассмотрение работы постфильтра будем проводить для глубины равной восьми.
Полезность постфильтра
Итак, с теорией разобрались, а как же дела обстоят на практике? Посмотрим на следующие скриншоты.
Верхнее изображение - чистый 16-битный цвет, а нижнее с постфильтрацией.
Посмотрим на наиболее интересные фрагменты изображения (начиная справа и по часовой стрелке), сравнивая изображения без постфильтрации (справа) и прошедшие через постфильтр (слева).
Здесь можно отметить отсутствие решетки на небе и на рамке меню. Это же привело к увеличению размеров пикселей. Но в целом картинка смотрится несколько лучше, так как помимо увеличения размера пикселей, разница между границами цветов уменьшилась, так как фактически количество цветов увеличилось в четыре раза. Картинке стала присуща плавность границ между соседними цветами, несмотря на укрупнение пикселей на этих границах. Границы между соседними объектами не изменились. Рамка меню нисколько не изменила свою форму. Сильно заметная сетка на прозрачной части меню была полностью убрана, что существенно отразилось на увеличении качества.
Обратим внимание на цифру "9". Избавившись от решетки, покрывающей девятку, постфильтр не сумел избавиться от "полосатости" цифры. Визуально качество практически не изменилось, а возможно стало немного выше. Полностью убрать решетку со шлема не удалось. Однако даже обработка, прошедшая на части шлема, сделала изображение более плавным, в частности исчезли выбивающиеся из общей картины единичные пиксели. На заднем фоне ворота телепорта (справа) имеют определенный рисунок, который ничуть не пострадал в результате фильтрации, опять же приобретая определенную плавность цветов. Левая часть заднего фона имеет более сложный рисунок, и с ним постфильтр уже не справился, хотя чисто субъективно отфильтрованная картинка мне нравится больше.
А вот тут картина неоднозначная. Да, решетка убрана, но частично. И эта частичность проявляется в виде отдельных пикселей другого цвета на равномерном фоне. Да и рамка меню несколько пострадала. Границы формы стали немного угловаты. Но, фрагмент увеличен, и на картинке "в натуре" эти погрешности особо не заметны. К ним нужно присматриваться, чтобы их найти. Такие явные артефакты проявляются только на полупрозрачных объектах, полученных многократным наложением, а эти объекты в современных программах создают преимущественно динамические эффекты. Поэтому поймать артефакты очень тяжело. Так, (при снятой паузе) телепорт переливался множеством цветов, и в целом заметить ошибки постфильтрации просто не успеваешь.
От этой картинки достаточно приятные впечатления, однако опять по левой кромке рамки меню несколько "оквадратилась" форма. Опять остались единичные пиксели, но они малозаметны. А ворота, приобретя плавность цветов, унаследовали полосатость, за счет того же укрупнения пикселей. Но, опять же на не увеличенной полной картинке все выглядит достаточно мило.
Рассмотрим ещё несколько фрагментов. На этот раз не увеличенных, чтобы составить впечатление от реальной картинки (всегда
верхний скриншот это без постфильтра, а нижний с постфильтром).
Трудно найти отличия, однако то, что снизу мне нравиться больше.
Задний план, а так же реализация дыма и вспышек плазмы с постфильтрации выглядят более эффектно.
А вот этот портал постфильтру обработать удалось несколько хуже, чем предыдущий, однако визуальное качество картинки всё же повысилось.
Здесь со своей задачей постфильтр справился просто блестяще.
Существует мнение, что постфильтр приводит к некоторому размытию картинки. Для того чтобы проверить этот слух, рассмотрим "замыленную" часть картинки прошедшую постфильтрацию (нижняя), и не прошедшую (верхняя).
Как видим, этот артефакт присутствует, однако, на не отфильтрованном фрагменте разглядеть дополнительные детали все же не удается. То есть постфильтр не причастен к факту размытия картинки. Тем более, что на расположенной чуть дальше нечеткого пола стены в точности сохранены все детали. То, что постфильтр замыливает изображение - оказалось не больше чем очередным мифом.
Спрашивается, зачем всё это нужно? Не лучше ли использовать настоящий 32-битный цвет? На самом деле не всегда лучше. Как известно, главная болезнь современных видеокарт - малая полоса пропускания шины данных. А для 16-битного цвета необходима полоса в два раза уже, чем для 32-битного. Таким образом, там, где видеокарта в 32-битном цвете уже не справляется (а такое ПО уже существует для самых мощных современных ускорителей) её можно перевести в 16-битный цвет. И приятно, если в этом режиме работает постфильтр, так как визуально качество картинки несколько увеличивается.
Однако я не могу не удержаться и не продемонстрировать насколько важен 32-битный цвет в серьезных сценах.
nVIDIA RivaTNT2 16-bit 3dfx Voodoo3 16-bit
nVIDIA RivaTNT2 32-bit
Действительно, за 32-битным цветом будущее. Но, возникает логичный вопрос, почему бы не использовать постфильтр и в 32-битном цвете. Ответ прост. Там он бесполезен. Не забываем, что постфильтр увеличивает количество цветов с 16-бит до 22-бит. Следовательно, в True Color режимах он будет увеличивать количество цветов с 24-бит до 30-бит, и даже если он будет включен, то человеческий глаз просто не увидит разницы.
Та же 3dfx сейчас увлеклась 32-битным цветом и перестала оптимизировать 16-битный цвет, а совершенствоваться ещё есть куда. Так, можно использовать другие маски (не Ordered), увеличить размер маски (хотя бы до 4x4, правда при этом придется существенно усложнить алгоритм фильтрации) и многое другое. Но, как говорилось, за 32-битным цветом будущее, и так как 16-битный цвет у 3dfx уже оптимизирован, им теперь со спокойной душой можно заняться 32-битным цветом. Очень жаль, что другие компании так и не обратили внимания на постфильтр в 16-битном режиме, ведь при минимуме затрат это может привести к существенному увеличению качества 16-битной графики. Ведь процесс перехода к эре True Color игр будет проходит плавно и ещё достаточно долгое время. Для тех кому постфильтр мешает, можно просто отключить его в драйверах. Драйверами теоретически можно и изменять глубину фильтрации, однако 3dfx не включила эту опцию в драйверах (может и к лучшему).
Возникает последний вопрос. Есть ли альтернатива постфильтру? Есть, и она уже существует. Это FSAA (антиалиазинг). При правильной реализации, конечно. FSAA может ещё много на что повлиять. Это избавление от постфильтра, алиазинга, бесплатная анизотропная фильтрация и многое другое. Пока же FSAA не бесплатен, можно довольствоваться постфильтром. Хотя все же будущее за FSAA. Но это уже совсем другая история…
Комментарии? Поправки? Дополнения? pavel@ixbt.com
|