Обработка

Антиалиасинг и анизотропная фильтрация

Геймеры на сегодняшний день являются наиболее активными потребителями всех новых технологий и нововведений в 3D. По большому счёту, мощный 3D-акселератор на сегодняшний день нужен исключительно для игры в последние компьютерные игры с мощными 3D-движками, оперирующие сложными шейдерами различных версий. Сейчас никого уже не удивишь игрой с пиксельными шейдерами.

В сфере 3D уже давно идёт конкурентная битва между двумя столпами производителей графических процессоров: ATI и NVIDIA. Суровая Канада уже давно ведет борьбу против солнечной Калифорнии, и пока конца этому противостоянию не видно, что нам, простым потребителям, конечно, только на руку. Теперь разработать классный движок мало — чтобы иметь успех, нужно заручиться поддержкой либо калифорнийской дивы NVIDIA, либо канадской ATI, благо, теперь и у первой, и у второй есть свои партнёрские программы для разработчиков игр. У NVIDIA такая программа называется «The way it's meant to be played», а у ATI – «Get it in the game». Всё достаточно красноречиво и понятно: NVIDIA говорит, что «играть нужно так», а совсем не эдак, а ATI уверяет, что всё, что мы только ни пожелаем, мы обязательно получим в самой игре.

Если до бесконечности увеличивать количество полигонов в кадре, тем самым получая визуально более красивую для восприятия картинку, то в итоге мы придём к тому, что акселератор не сможет обрабатывать сцену с приемлемым уровнем частоты кадров, но в картинке всё равно будет чего-то не хватать. Лесенки из пикселей всё равно останутся, да и качество текстур не улучшится. Остаются менее явные способы по улучшению качества трёхмерной картинки на мониторе — это анизотропная фильтрация и антиалиасинг. Непосредственно к самому 3D-движку эти техники улучшения изображения не имеют никакого отношения, и сделать сам движок более красивым они, естественно, не могут, однако они могут работать с текстурами и изображением таким образом, что на выходе, то есть на мониторе, мы можем видеть визуально более красивую и мягкую картинку.

Именно на поприще анизотропной фильтрации и антиалиасинга проходит колоссальнейшее количество оптимизаций драйверов как со стороны NVIDIA, так и со стороны ATI.

Антиалиасинг и анизотропная фильтрация

Антиалиасинг

В первую очередь, в слове «антиалиасинг» необходимо выделить часть его — «анти». Предельно ясно, что это часть слова подразумевает то, что само явление «антиалиасинга» направлено на борьбу с чем-то. Как несложно догадаться, в нашем случае — с «алиасингом». Поэтому для нас на данный момент важно чётко разобраться в том, что же представляет из себя пресловутый «алиасинг».

Для начала нужно чётко понимать, что изображение, которое мы с вами можем ежедневно наблюдать на экранах наших с вами мониторов, состоит из так называемых мелких частичек, которые принято называть пикселями. Хорошей аналогией в этом смысле может послужить пример с бумагой в клеточку. Изображение на мониторе — это та же бумага в клеточку, только они в данном случае очень и очень мелкие. Если говорят, что разрешение экрана составляет 1024х768 при 32-битном цвете, то это означает, что по горизонтали на мониторе умещается 1024 точек, а по вертикали — 768. При этом каждая точка может быть закрашена одним цветом из доступных в 32-битной палитре. На данный момент 32-битный цвет — это предел того, чего мы можем добиться на экране компьютера. Лучшие умы человечества (тот же Кармак) уже поговаривают о необходимости перехода на 64-битный цвет и указывают на явные минусы 32-битной палитры. В своё время при переходе с 16-битного на 32-битный цвет данная необходимость была достаточно чётко обоснована и виделись реальные причины, по которым стоило бы перейти на 32 бит. Переход же на 64-битный цвет на сегодняшний день — это скорее излишество. Так же как и в случае с 16 и 32 битами, в своё время придётся достаточно долго ждать, когда акселераторы всех уровней смогут с приемлемой скоростью обрабатывать 64-битный цвет.

Подавляющее большинство статей, в которых затрагиваются тем или иным образом принципы построения изображений в 3D и где ведётся разговор об антиалиасинге, изобилуют простым, но вместе с тем наиболее действенным примером, на котором можно достаточно хорошо понять, что же такое антиалиасинг. Посмотрите на увеличенную надпись «Апгрейд», сделанную в Word’e, а затем просто увеличенную в фотошопе. Не очень хорошо выглядит, не правда ли? По бокам букв видна так называемая гребёнка или, как её ещё называют, «лесенка». В сущности, эта самая «гребёнка» или «лесенка» и есть алиасинг. Можно представить и другой пример в виде геометрического объекта, например, пирамиды. По её краям также хорошо видна всё та же «гребёнка». А теперь посмотрите на другое изображение той же пирамиды, но с увеличенным вдвое разрешением. Выглядит уже значительно лучше, и «гребёнка» практически незаметна. Как уже было сказано выше, данный эффект, сглаживающий «гребёнку», был достигнут за счёт того, что мы увеличили разрешение в 2 раза. Что это означает? Предположим, у нас была отрендерена пирамида с разрешением 200х200 пикселей (выше мы уже подробно прояснили вопрос о том, что такое пиксели и зачем они нужны). Мы увеличили количество точек по вертикали и по горизонтали ровно в 2 раза, то есть получили изображение с разрешением 400 точек по вертикали и 400 точек по горизонтали. Это также означает, что количество точек на нашем объекте, который находился на сцене, увеличилось вдвое. Что это дало применительно к нашему эффекту алиасинга? Очевидно, что он стал минимален, то есть сгладился — ведь количество точек по краям объекта также возросло вдвое. Именно слово «сгладился» является здесь ключевым. Ведь антиалиасинг по-иному называют сглаживанием, что отражает самую суть технологии, которая сглаживает ту самую «лесенку» по краям трёхмерных объектов.

На самом деле, после увеличения разрешения «лесенка» с края пирамиды никуда не делась — она остаётся там по-прежнему. Однако за счёт того, что мы увеличили разрешение (что означает увеличение точек, которые расходуются на отображение пирамиды), эффект «лесенки» сгладился благодаря особенностям человеческого зрения, которое уже менее чётко видит пиксели на крае объекта. Абсолютно понятно, что если увеличивать разрешение ещё и ещё, то эффект алиасинга будет наблюдаться всё в меньшей и меньшей степени. Точнее, человеческий глаз станет замечать его всё в меньшей и меньшей степени, поскольку сам эффект алиасинга никуда не денется. Но так же абсолютно понятно и то, что до бесконечности увеличивать разрешение не получится, ведь мониторы, пусть даже и самые современные, имеют конечные разрешения, причём не такие уж и большие, что не позволит нам постоянно увеличивать количество точек. Проще говоря, простейшего эффекта антиалиасинга можно добиться, всего лишь увеличив разрешение экрана, однако разрешение не может расти до бесконечности. Казалось бы, выхода нет? Однако в действительности он был найден, и основан он всё на той же особенности зрения человека. Этого удалось достичь благодаря плавным переходам цветов на изображении. Фактически визуальное улучшение изображения производится не за счёт физического увеличения разрешения, а за счёт, если можно так выразиться, цветового увеличения разрешения. В данной статье мы не будем описывать алгоритмы вычисления этих точек и не будем вдаваться в глубины математических вычислений, а расскажем лишь о принципе работы такого антиалиасинга. Лесенка на границах объектов видна лишь потому, что чаще всего края трёхмерных объектов довольно сильно выделяются по цвету от остальной картинки и представляют собой тонкие линии в один пиксель. Это можно компенсировать, поставив некоторое количество точек с цветами, вычисляемыми по формуле из значений цвета самого края и точек рядом с этим краем. То есть, если край объекта чёрный, а фон белый, то дополнительная точка рядом с чёрной линией края станет серой. Чем больше этих дополнительных точек около края любого 3D-объекта, тем более гладко выглядят его края и тем меньше заметна лесенка. Данный способ называется краевым антиалиасингом.

Качество антиалиасинга, задаваемое в драйвере видеокарты, как то: 2x, 4x, 6x, 8x означает количество проставляемых дополнительных пикселей вокруг линии, нуждающейся в сглаживании.

Анизотропная фильтрация

Для того чтобы понять, что такое фильтрация, необходимо обладать некоторыми основными знаниями. Мы уже выяснили, что изображение на экране состоит из множества пикселей, количество которых определяется разрешением. Для вывода цветного изображения ваша видеокарта должна определять цвет каждого пикселя. Определяется его цвет посредством наложения текстурных изображений на полигоны, которые расположены в трёхмерном пространстве. Текстурные изображения состоят из пикселей, вернее, текселей, то есть тексель — это пиксель двухмерного изображения, наложенного на 3D-поверхность. Главная дилемма заключается в следующем: какой тексель или тексели определяют цвет пикселя на экране. Для представления проблемы фильтрации давайте представим одну картину. Допустим, что ваш экран – это плита с множеством круглых отверстий, каждое из которых является пикселем. Для того чтобы определить, какой цвет имеет пиксель относительно трёхмерной сцены, расположенной за плитой, достаточно просто посмотреть в одно из отверстий. А теперь представим луч света, который проходит через одно из отверстий и попадает на наш текстурированный полигон. Если последний расположен параллельно относительно отверстия, через которое проходит световой луч, то световое пятно будет иметь форму окружности. В противном случае, если полигон расположен не параллельно к отверстию, световое пятно искажается и имеет эллиптическую форму. Мы думаем, что многие читатели в это время задаются одним вопросом: «как связаны все эти плиты, отверстие, луч света с проблемой определения цвета пикселя?» Внимание! Ключевая фраза: все полигоны, расположенные в световом пятне, определяют цвет пикселя. Всё вышеизложенное и есть те необходимые базовые знания, которые нужны для того, чтобы понять различные алгоритмы фильтрации.

А теперь, чтобы вы лучше поняли, для чего нужна фильтрация, рассмотрим происходящие процессы на примере легендарной «Quake 3 Arena». Представьте какой какой-нибудь коридор с множеством квадратов и различных орнаментов (благо, в «Quake 3 Arena» этого хватает). Орнамент в начале коридора сильно детализирован, а ближе к концу коридора (горизонту) элементы орнамента становятся всё меньше и меньше, т.е. они отображаются меньшим числом пикселей. В результате теряются детали типа швов между элементами орнамента, что, соответственно, приводит к ухудшению качества изображения. Проблема заключается в том, что драйвер графической карты не знает, какие детали в текстуре являются важными.

Point Sampling

Point Sampling (поточечная выборка) — самый простой способ определения цвета пикселя. Этот алгоритм основан на текстурном изображении: выбирается всего один тексель, который ближе всех расположен к центру светового пятна, и по нему происходит определение цвета пикселя. Нетрудно догадаться, что это совершенно не верно. Во-первых, цвет пикселя определяется несколькими текселями, а мы выбрали только один. Во-вторых, форма светового пятна может измениться, а алгоритм не принимает это во внимание. Главным недостатком поточной выборки является тот факт, что когда полигон расположен близко к экрану, количество пикселей будет значительно выше, чем текселей, из-за чего качество изображения очень сильно пострадает. Так называемый эффект блочности, как мы полагаем, многие могли наблюдать в старых компьютерных играх, например, в том же легендарном «Doom».

У Point Sampling есть преимущество. Из-за того, что определение цвета пикселя осуществляется всего по одному текселю, данный метод не критичен к пропускной способности памяти, а это автоматически даёт данному способу фильтрации колоссальные диведенды в том плане, что на фильтрацию по данной схеме затрачивается очень мало ресурсов 3D-акселератора.

Bi-Linear Filtering

Bi-Linear Filtering — билинейная фильтрация, основанная на методе использования интерполяционной техники. Для определения нужных текселей используется основная форма светового пятна, то есть круг. В нашем примере с кругом последний аппроксимируется 4 текселями. Как видим, здесь дела обстоят несколько лучше, чем с Point Sampling. Билинейная фильтрация использует уже 4 текселя. Изображение получается более качественным, блочность отсутствует, однако близкие к экрану полигоны выглядят расплывчато, и связано это с тем, что для интерполяции необходимо большее количество текселей, нежели доступные четыре.

Расплывчатость — отнюдь не самая главная проблема билинейной фильтрации. Дело в том, что аппроксимация выполняется корректно лишь для объектов, расположенных параллельно экрану или точке наблюдения, в то время как 99% объектов в любой компьютерной игре расположены непараллельно к точке наблюдения. Отсюда можно сделать вывод, что 99% объектов будут аппроксимироваться неправильно. Возьмём, к примеру, наш круг – полигон расположен непараллельно относительно точки наблюдения, стало быть, мы должны аппроксимировать эллипс, а мы аппроксимируем круг, что крайне неверно. Ко всему прочему билинейная фильтрация значительно требовательней к пропускной полосе данных памяти, что, в общем-то, более чем логично, учитывая то, что билинейная фильтрация использует уже 4 текселя для определения цвета пикселя.
Как видим, билинейная фильтрация выглядит несколько лучше, нежели Point Sampling. И всё же она очень далека от идеала.

Tri-Linear filtering

Tri-Linear filtering — трилинейная фильтрация, представляет собой симбиоз билинейной фильтрации и mip-текстурирования. Прежде чем говорить об алгоритме работы трилинейной фильтрации, давайте выясним, что такое МIP-текстурирование. MIP-текстурирование, или mip-mapping, — это метод уменьшения объёма вычислений, необходимых для точного наложения текстурного изображения на полигон. По сути, мипмеппинг выполняет те же задачи, что и Point Sampling, но делает это на порядок лучше. MIP-текстурирование призвано избавить нас от ухудшений изображений, когда несколько текселей накладываются на один пиксель. Посмотрим на проблему глобальней и попробуем найти решение всему этому. Для того чтобы правильно вывести пиксель на экран, необходимо скомбинировать значения всех текселей, которые и будут накладываться на этот пиксель. Но пропускная способность памяти не бесконечна, а это огромнейший обьём работы, который неблагоприятно отразится на быстродействии вашей видеокарты. Mip-mapping способствует снижению объёмов этой работы. Метод MIP-текстурирования основан на генерации и хранении множества версий исходного текстурного изображения. Эти версии имеют большое количество разрешений, каждое из которых всё меньше и меньше исходного. Во время текстурирования пикселя вам достаточно выбрать версию текстурного изображения. В вашем распоряжении есть 4 близлежащих текселея из текстурного изображения, больших по размеру, чем пиксель, и столько же текселей, меньших по размеру, чем пиксель. По сути, mip-уровни представляют собой заранее рассчитанные, более маленькие версии исходной текстуры, из-за чего обеспечивается лучшая аппроксимация.

Итак, мы выяснили, что такое mip-mapping, теперь вернёмся к нашей трилинейной фильтрации. Как мы уже говорили, Tri-Linear filtering представляет собой симбиоз билинейной фильтрации и mip-текстурирования. По сути, билинейная фильтрация производится на двух mip-уровнях. А в итоге мы имеем 2 текселя, по одному для каждого mip-уровня. Цвет пикселя определяется при помощи интерполяции по цветам двух mip-текстур.

В итоге имеем несколько лучшее качество фильтрации, нежели у билинейной. Стоит отметить, что качество улучшается незначительно, а требования к ширине полосы пропускания памяти в сравнении с той же Bi-Linear Filtering удваиваются.

Anisotropic filtering

Выше мы уже выяснили, что для получения хороших результатов фильтрации недостаточно определять цвет по нескольким пикселям. Используя всего четыре пикселя для определения цвета, мы получаем искажённую картину, используем недостаточный обьём фильтрации или, выражаясь простым языком, совершаем сверхфильтрацию в одном месте нашего светового пятна и недостаточно фильтруем в другом. Добавьте сюда изменение формы светового пятна и то, что ни один из вышеизложенных алгоритмов фильтрации этого не учитывает.

Вполне очевидно — для того чтобы добиться лучшего качества, необходимо использовать все пиксели светового пятна с усреднённым значением. Существуют техники фильтрации, которые применяют от 16 до 32 текселей для определения цвета пикселя. Мы также должны учитывать тот факт, что форма светового пятна изменяется вместе с изменением положения полигона относительно точки наблюдения. Собственно говоря, этим и предлагает пользоваться анизотропная фильтрация.

Всё это, конечно, хорошо, но использование такого количества пикселей требует огромной пропускной способности памяти, поэтому анизотропная фильтрация более-менее сносно может функционировать лишь на мощных современных видеокартах. Помимо всего этого, Anisotropic filtering предлагает задействовать разнообразные фильтры для аппроксимации формы светового пятна. Эти фильтры имеют форму эллипса для нескольких возможных углов положения полигона.

В видеорешениях, использующих тайловую (тайл, говоря простым языком, – участок изображения опредёленного размера, как правило, 32х32 пикселя) архитектуру, благодаря применению тайлов, существенно экономятся ресурсы полосы пропускания памяти, что позволяет использовать анизотропную фильтрацию без значимых потерь быстродействия. При помощи анизотропной фильтрации можно получить лучшее качество изображения. Оно достигается за счёт более точного представления текстур и улучшенной глубины детализации.

Уровень анизотропной фильтрации определяется числом текселей, которые обрабатываются при вычислении конечного пикселя. Современные графические решения позволяют выставить уровень фильтрации в драйвере. Самыми распространёнными уровнями фильтрации являются 2x (16 текселей), 4x (32 текселя), 8x (64 текселя) и 16x (128 текселей). Очевидно, что при повышении уровня анизотропной фильтрации нагрузка на полосу пропускания памяти также увеличивается, а это неминуемо сказывается на производительности.

Оптимизации анизотропной и трилинейной фильтраций

Компании-разработчики графических чипов ATI и NVIDIA всё время стараются выжать дополнительную производительность из своих продуктов. Что, в общем-то, очевидно и оправдано — конкуренцию между двумя гигантами-производителями графических процессоров никто не отменял. Для достижения своих целей вендоры применяют различные оптимизации, которые позволяют увеличить производительность графических решений. Однако зачастую оптимизации повышают производительность, но снижают качество картинки. Увы, но поговорка «сделать быстрей — не значит сделать лучше» очень часто актуальна для ситуации с различными оптимизациями ATI и NVIDIA. Разработчики пытаются играть на всё тех же особенностях зрения человека и стараются повысить производительность за счёт слабозаметного ухудшения качества изображения.

Возьмём, к примеру, брилинейную фильтрацию. Нет-нет, мы не оговорились, именно брилинейная фильтрация. Так сказать, новый вид, который появился благодаря упорным стараниям вендоров. Брилинейная фильтрация представляет собой смешанный режим фильтрации между билинейной и трилинейной — область, в которой граничат соседние mip-уровни, и которая, собственно говоря, подвергается трилинейной фильтрации, была уменьшена. Вследствие этого удалось поднять производительность, что вполне ожидаемо, ведь мы фильтруем гораздо меньше. При этом качество изображения становится хуже, однако ухудшение качества в данном случае явно оправдано, если учесть значительный выигрыш в производительности. Это отчётливо видно, если сравнивать изображения, полученные с помощью полной трилинейной фильтрации.

Брилинейную фильтрацию впервые применила NVIDIA на своих видеокартах GeForce FX 5xxx Новые видеокарты GeForce 6xxx также используют брилинейную фильтрацию, однако компания NVIDIA после критики и различных дискуссий в многочисленных конференциях добавила возможность отключения оптимизации.

В недалёком прошлом продукты компании ATI славились более высоким качеством картинки, нежели таковые от NVIDIA. Однако с выходом графического процессора Radeon 9600 всё изменилось – последний, как и более новое решение Radeon X800, также использует брилинейную фильтрацию. Однако, в отличие от NVIDIA, ATI не соизволила не только объяснить процедуру фильтрации, но и не признала сам факт использования оптимизаций.

Компания ATI пошла на хитрость: драйверы переключаются на полную трилинейную фильтрацию при использовании цветных mip-текстур. Именно последние применяются в стандартных тестах качества, которые используют обозреватели и тестировщики. Однако находчивые ребята с сайта Computerbase обнаружили, что в компьютерной игре «Call Of Duty» X800 даёт меньшую частоту кадров при использовании цветных mip-текстур. После чего обозреватели Computerbase провели сравнение качества изображения. Как оказалось, при применении обычных текстур Radeon X800 использует брилинейную фильтрацию. При употреблении цветных текстур в «Call Of Duty» (1600х1200) общий показатель FPS Radeon Х800 падает на 11-13 fps. Самое интересное, что ATI заявляет об использовании полноценной трилинейной фильтрации и рекомендует тестировщикам отключать оптимизации у конкурентов для обеспечения честного сравнения.

В интервью популярному сайту Toms Hardware Guide компания ATI всячески уходила от конкретного ответа, утверждая, что X800 использует полноценную трилинейную фильтрацию. На этом оптимизации от компании ATI не заканчиваются. Так, продукты канадской фирмы ATI используют ещё один вид оптимизации, который называется «stage optimization» — оптимизацией ступени. Метод оптимизации основан на применении «трилинейной» (брилинейной) фильтрации только к первой ступени текстуры. Остальные ступени 1-7 фильтруются простым билинейным методом.

Стоит отметить, что во многих играх это не критично, поскольку верхние ступени текстур являются либо картами неровностей, либо картами освещения, для которых полноценная фильтрация не критична, поэтому ухудшения изображения вы попросту не заметите. Однако есть и исключения. Популярная компьютерная игра Unreal Tournament использует карты деталей с высоким разрешением на ступенях 1-7, поэтому потери в качестве неизбежны.

Также стоит оговориться, что эта оптимизация функционирует только при насильственном включении анизотропной фильтрации в драйверах вашей видеокарты. Если вы оставляете выбор приложению (by application), то обеспечивается полноценная «трилинейная» (брилинейная) фильтрация ко всем ступеням текстуры.

Компания NVIDIA также стала использовать эту оптимизацию, которая появилась в драйверах версии 51.xx для карт GeForce 5xxx.

Адаптивная анизотропная фильтрация — ещё одна вариация на тему оптимизаций. Её уже давно используют продукты компании ATI. NVIDIA также не отстаёт — в GeForce 6800 эта оптимизация частично реализована.

Алгоритм адаптивной анизотропной фильтрации заключается в том, что поверхности 3D-изображения получают различный уровень анизотропной фильтрации в точке наблюдения. Такой подход позволяет существенно экономить вычислительные ресурсы и тем самым значительно повышать общий fps.

Использование такого метода фильтрации оправданно. Представьте себе сцену из какой-нибудь компьютерной игры: скажем, ваш герой стоит лицом к стене. Фильтровать стену с уровнем анизотропной фильтрации 16х не имеет смысла, то есть картинка будет такой же, как и с 2х. Идея адаптивной анизотропной фильтрации очевидна: «сэкономь вычислительную мощность там, где это можно, дабы последняя не расходовалась впустую».

Вы вряд ли заметите существенное ухудшение качества от использования адаптивной анизотропной фильтрации, однако в некоторых сценах этот алгоритм немного грешит, то есть можно заметить определённую потерю качества.

Напоследок хотелось бы отметить, что вендорам было бы неплохо реализовать возможность отключения адаптивной анизотропной фильтрации.

Автор: 
© Артём Семенков