Настройка текстурирования. MIP-MAP Filtering в процессе выполнения приложения

Как видим, билинейная фильтрация выглядит несколько лучше, нежели 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» – оптимизацией ступени. Метод оптимизации основан на применении «трилинейной» (брилинейной) фильтрации только к первой ступени текстуры (0). Остальные ступени 1-7 фильтруются простым билинейным методом.

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

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

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

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

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

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

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

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

Используйте MIP-текстурирование для масштабирования крупных изображений.

Еще одна новая функция, доступная в проигрывателях Flash Player 10.1 и AIR 2.5 на всех платформах, связана с MIP-текстурированием. В проигрывателях Flash Player 9 и AIR 1.0 представлена функция MIP-текстурирования, позволяющая повысить качество и производительность уменьшенных растровых изображений.

Примечание. Функция MIP-текстурирования подходит только для динамически загружаемых изображений или встроенных растровых изображений. MIP-текстурирование не применяется к отфильтрованным или кэшированным экранным объектам. Обработка MIP-текстурирования возможна, только если ширина и высота растрового изображения являются четными числами. Если ширина или высота растрового изображения является нечетным числом, обработка MIP-текстурирования останавливается. Например, к изображению 250 x 250 можно применить MIP-текстурирование до 125 x 125, но дальнейшее MIP-текстурирование будет невозможно. В этом случае хотя бы один из размеров является нечетным числом. Наиболее оптимальные результаты получаются, если растровые изображения имеют размеры, равные степени двойки, например: 256 x 256, 512 x 512, 1024 x 1024 и так далее.

Например, если загружено изображение 1024 x 1024 и разработчику необходимо масштабировать его для создания миниатюры в галерее. Функция MIP-текстурирования обеспечивает правильную визуализацию изображения при масштабировании с использованием промежуточных субдискретизированных версий растрового изображения в качестве текстур. В предыдущих версиях среды выполнения промежуточные уменьшенные версии растрового изображения создавались в памяти. Если было загружено изображение 1024 x 1024, которое отображалось с размером 64 x 64, в более старых версиях среды выполнения каждый раз создавалось растровое изображение половинного размера. Например, в этом случае создавались растровые изображения 512 x 512, 256 x 256, 128 x 128 и 64 x 64.

Теперь проигрыватели Flash Player 10.1 и AIR 2.5 поддерживают прямое MIP-текстурирование исходного объекта до объекта с необходимым размером. В предыдущем примере создаются только исходное растровое изображение 4 МБ (1024 x 1024) и MIP-текстурированное растровое изображение 16 КБ (64 x 64).

Логика MIP-текстурирования также работает с функцией динамической выгрузки растровых изображений. Если используется только растровое изображение 64 x 64, исходное изображение размером 4 МБ освобождается из памяти. Если необходимо повторно создать MIP-текстурированную версию, исходное изображение загружается повторно. Кроме того, если требуются другие MIP-текстурированные растровые изображения разных размеров, цепочка MIP-текстурированных растровых изображений используется для создания растрового изображения. Например, если необходимо создать растровое изображение 1:8, исследуются растровые изображения 1:4, 1:2 и 1:1 на предмет того, какое изображение было загружено в память первым. Если другие версии не найдены, исходное растровое изображение 1:1 загружается из ресурса и используется.

Программа распаковки JPEG может выполнять MIP-текстурирование в своем собственном формате. Такое прямое MIP-текстурирование позволяет распаковывать большое растровое изображение непосредственно в формате MIP-текстурирования без необходимости загрузки всего несжатого изображения. Создание MIP-текстурированной версии выполняется существенно быстрее, и не происходит выделение и последующее освобождение памяти, используемой большими растровыми изображениями. Качество изображения JPEG сравнимо с качеством изображения, полученного общим методом MIP-текстурирования.

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

Рисунок 1. Шахматная доска без применения MIP-mapping

Технология MIP-mapping (MIP текстурирование) сглаживает отрицательные визуальные проявления данной проблемы и делает искажения менее заметными. Акроним MIP происходит от латинского "multum in parvo ", означающего "множество в малом" или "много вещей на одном пятачке". Для общего образования отметим, что по информации из OpenGL RedBook термин "mipmap" был предложен для использования Ланцем Вильямсом (Lance Williams) в 1983 году, когда на SIGGRAPH"83 он рассказал идею этой новой техники в своем докладе "Pyramidal Parametrics". Правда, Lance Williams использовал несколько инуюрасшифровку термина, а именно: "multim im parvo ", так что не удивляйтесь, если встретите и такую транскрипцию. По другой версии исследователи из Нью-йоркского технологического института впервые применили данный термин в 1979 году, для того, что бы описать технологию преобразования и сжатия множества пикселей в одну малую, специальным образом сформированную текстуру или карту, известную как MIP-map.

Для того, что бы увидеть насколько улучшается визуальная чистота изображения, достаточно поглядеть на Рисунок 2 , который показывает эффект от применения MIP-mapping c билинейной фильтрацией (bilinear filtering ).


Рисунок 2. Шахматная доска с MIP-mapping and bilinear filtering

Для того, что бы понять, что же вызвало проблемы, показанные на
Рис.1 , вы должны заглянуть внутрь процесса наложения текстуры на объекты и понять каким образом процесс дискретизации текстур влияет на конечное изображение, выводимое на экран монитора. Посмотрите на Рисунок 3а , на котором синусоида дискретизируется внешним сигналом со значительно большей частотой. Видно, что мы можем получить достаточно точную копию исходной синусоиды, если восстановить значения амплитуды каждого из сэмплов при частоте внешнего сигнала. Однако, если частота внешнего сигнала (частота дискретизации) будет равна удвоенной частоте синусоиды (Рис. 3b ), то возможны моменты (при равенстве фаз, например), когда моменты дискретизации будут совпадать с моментами прохождения исходной синусоиды через нуль, в результате чего данный сэмпл будет неинформативен. Применение частоты дискретизации меньше удвоенной частоты исходного сигнала (Рис. 3с ) приведет к тому, что сигнал, восстановленный из значений полученных сэмплов, будет синусоидой с частотой меньшей, чем у исходного сигнала. Исходя из изложенного, мы можем предположить, что частота дискретизации должна быть, по крайней мере, в два раза больше частоты дискретизируемого сигнала. Данное соотношение известно под названием предел Найквиста (В России, данное соотношение носит название теоремы Котельникова. Прим. переводчика).


Рисунок 3. Дискретизация синусоиды

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

Знакомство с рядом Фурье

Полное изложение вопросов теории Фурье, может запросто занять несколько отдельных книг, поэтому для тех из вас, читатели, кто не особо утруждался на лекциях по ТЭРЦ (теории электро-радио цепей) в институте, я могу предложить почитать книгу Брейсуэлла, ссылка на которую дана в конце статьи. Что же касается самой статьи, то в ней будет изложено очень сжатое введение в теорию преобразований Фурье, но этого должно быть достаточно для того, что бы понять из чего вытекает значение предела Найквиста (Котельникова).


Рисунок 4а. Графическое представление дискретизации Фурье

Рисунок 4а показывает вид функции h(t)=sinc 2 x и ее представление рядом Фурье H(f). Для удобства будем считать, что H(f) это ряд Фурье (или частотный ряд), а h(t) временной ряд. (Если вас интересует, почему я выбрал в качестве функции именно sinc 2 x, просто потому, что она имеет наиболее простое графическое представление в частотном ряду). Для того, что бы перейти от временного ряда к частотному в теории Фурье применяется следующее преобразование:

В этой формуле, представляющей собой преобразование Фурье, f определяет частоты гармоник (обычных синусоидальных сигналов) составляющих исходный сигнал h(t), а говорит нам о том, что степень является комплексным членом, т. е. имеет вещественные и мнимые части. Оператор Й часто используется для обозначения преобразования по Фурье, т.е. выше приведенную формулу мы можем записать как h(t) Й H(f). Рисунок 4b показывает последовательность импульсов и их предстваление рядом Фурье. Импульс, который мы обозначим d(t) это теоретический сигнал бесконечно малой длительности и бесконечно большой амплитуды приведенной к единице. Интересной особенностью последовательности импульсов с периодом T s , является то, что ряд Фурье этой последовательности будет иметь вид другой последовательности импульсов, но с периодом 1/T s .


Рисунок 4b


Рисунок 4с

Результат преобразования h(t) последовательности импульсов представленных функцией s(t) показан на Рисунке 4с . Во временном ряду преобразования напоминают перемножение h(t) и s(t), тогда как в частотном ряду (ряду Фурье) результатом является конволюция H(f) и S(f).

Конволюция двух любых функций f(x) и g(x) представляется формулой:


Формула 4

Если попытки подстановки в формулу 4 результатов функций h(t) и s(t) преобразованных по Фурье вызывают у вас головную боль и желание пропустить эту "мыльную" статью (стр.72 Ноябрьского выпуска Game Developer ), то все же задержитесь на секунду - все не так сложно, как кажется. Конволюция единичного импульса в момент времени t=t 0 измененного по h(t) это ничто иное, как значение h(t) смещенное на позицию времени t=t 0 .


Формула 5

Применим Формулу 5 для нахождения конволюции H(f) и S(f).


Рисунок 4d

Основы MIP-mapping (MIP текстурирования)

Давайте посмотрим, как MIP-mapping позволяет уменьшить искажения вызываемые дискретизацией изображения (aliasing artifacts ) на примере изображения. Помните, наложение текстур на объекты в сцене применяется исключительно для придания большей реалистичности создаваемым объектам. Однако, все мелкие детали изображения в текстуре это всегда наиболее высокочастотные компоненты, и они же и являются источником aliasing problems . Так, как реально мы не можем изменить частоту дискретизации (1/DU и 1/DV в визуализирующей части нашего игрового движка), то мы вынуждены будем отфильтровать (filtering ) наши текстуры таким образом, чтобы убрать высокочастотные составляющие нашего изображения.

* Примечание переводчика : при использовании двумерных текстур в трехмерном пространстве, возникает необходимость использования двумерной координатной системы текстуры внутри существующей трехмерной координатной системы X, Y, Z. Для того, что бы разделить между собой эти координаты, разработчики ввели дополнительные обозначения двумерных координат U и V для текстур. Также был введен параметр W для того, чтобы расширить пространство Евклида (X, Y, Z) до неевклидова гомогенного (X, Y, Z, W). При эжтом, если W>0, то (X, Y, Z, W) совпадает с (X/W, Y/W, Z/W). Так что, если вам необходимо произвести манипуляции над текстурой уже размещенной в вашей 3D сцене, то вы должны будете использовать каординаты U, V.

Величины DU и DV, упоминаемые выше по тексту, это минимальные единичные приращения текстуры, которые мы можем использовать для вычислений. Обычно эти величины определяются размерностью пикселя, именно он является минимальной дискретизирующей величиной. Отсюда 1/DU и 1/DV будут величинами, определяющими частоту дискретизации изображения текстуры.


Рисунок 5. Пирамидальность MIP-map

Хотя и считается возможным отфильтровать каждый индивидуальный тексель непосредственно в процессе исполнения программы, но этот способ не применяется ввиду сложности его реализации. Более оптимальным считается вариант использования MIP текстур (MIP-map), которые состоят из серии заранее отфильтрованных и отмасштабированных текстур. Фильтрация текстур может быть произведена непосредственно в период начального запуска программы или произведена самим программистом еще в период разработки программы. Другой способ реализации MIP-mapping, это применение графических акселераторов, например, NVIDIA RIVA 128, которые произведут генерацию необходимых MIP-текстур для вашей сцены в момент, когда исходные текстуры загружаются в видео память. Рис. 5 иллюстрирует пирамидальную структуру MIP карты (текстуры), сформированную в результате MIP-mapping для исходной текстуры размерностью в 64х64 пикселя. Как можно видеть, уровень детализации (LOD) уменьшается по мере увеличения MIP уровня (MIP level). Как только текстура была преобразована в
MIP-map, все, что вам необходимо сделать в период выполнения программы для достижения базового per-polygon MIP-mapping - это выбрать корректный MIP уровень для конкретной текстуры и передать его для визуализации в акселератор или модуль программы отвечающей за визуализацию в случае software rendering.

Генерация MIP текстур

Существует несколько способов генерации MIP текстур. Один из них - просто подготовить их заранее, используя графические пакеты типа Adobe PhotoShop. Другой способ - генерация MIP текстур на "лету", т.е. в процессе выполнения программы. Заранее подготовленные MIP текстуры означают дополнительные 30% дискового пространства для текстур в базовой поставке инсталляции игры, но позволяют применять более гибкие методы управления их созданием и позволяют добавлять различные эффекты и дополнительные детали различным MIP уровням. Независимо от того, какой из способов реализации MIP-mapping вы выбрали, MIP текстуры потребуют дополнительные 30% RAM для своего размещения, что значительно увеличивает минимальные требования к количеству оперативной и/или видеопамяти на компьютере.

Давайте начнем с создания MIP карты для 8-битной текстуры.

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

Рассмотрим процесс генерации MIP текстур на "лету". Первый MIP
уровень представляет собой неизмененную исходную текстуру, скопированную в структуру MIP карты. Смотри Listing 1 (С целью экономии печатного пространства все кодовые листинги доступны для загрузки в виде одного архива: nov98.zip (584 Кб).

Создание остальных MIP уровней текстуры это шаг за шагом повторяющийся процесс. Каждый последующий (более высокий) уровень создается на базе предыдущего уровня, имеющего больший масштаб. Каждый созданный уровень располагается в памяти последовательно с предыдущим. Так же в структуре MIP карты хранится стартовый указатель (pointer) на нужный MIP уровень, так что игровой движок с легкостью может извлечь для использования уровень с соответствующим LOD.

Первым шагом в определении цвета нового пикселя будет вычисление усредненой цветности прямоугольника из четырех близлещащих пикселей на предыдущем MIP уровне. См. Listing 2 . Так как, в нашем случае мы работаем с текстурой содержащей палитру цветов, то после того как мы определили значение нового пикселя, нам необходимо найти наиболее соответствующий ему цвет из палитры. Этот процесс показан в Listing 3 . Процесс поиска нужного цвета из палитры прост, но может потребовать значительных временных затрат, так как нам необходимо обработать таким образом все пиксели в каждом из MIP уровней. К счастью, данная процедура требуется только один раз, на этапе инициализации MIP текстуры, значит, это не будет критичным. Однако, если вы пожелаете использовать другие эффекты в процессе рендеринга (визуализации), например билинейная и трилинейная фильтрация, то процесс поиска нужного цвета может стать очень медленным.

В этом случае, нам необходимо отказаться от применения текстур содержащих палитру в заголовке, и перейти к использованию 16 или 24-битных текстур. Ввиду того, что большинство применяемых графических карт поддерживают 16 битные текстуры, то мы рассмотрим в данном разделе именно 16 битную текстуру. Технология создания MIP текстуры для 16 битного изображения, очень близка к той, которую мы применяли для 8 бит, см. Listing 4 . Так как 16 битные текстуры не содержат палитру, усредненные значения цветности для нового пикселя берутся непосредственно из предыдущего MIP уровня. Одна из проблем, которая возникает в результате неоднократно усреднения цветовых величин для каждого из LOD, это то, что каждая последующая текстура будет темнее предыдущей, находящейся на один MIP уровень ниже. Можно компенсировать это некоторым увеличением значений цветовых составляющих пикселя на каждом из новых MIP уровней. Хотя это компенсация обычно не столь необходима ввиду того, что потеря в интенсивности чаще всего не столь значительна, что бы она бросалась в глаза.

Наложение MIP текстур в процессе выполнения приложения

Рисунок 6 (ниже) показывает некоторые из проблем, с которыми вы можете столкнуться, выбирая корректный LOD (уровень детализации) в процессе выполнения программы. На рисунке, прямоугольная текстура, наложенная на треугольник в плоскости самой текстуры, преобразуется в четырехсторонний многоугольник, находящийся в плоскости экрана. Перспективная проекция текстуры вызывает соответствующие преобразования прямоугольных индивидуальных текселей в многоугольники различных размеров. В нашем случае, когда полигон развернут в плоскости экрана, определение корректного LOD, который необходимо применить на полигон, является первостепенной задачей, т.к. именно от него будет зависеть хорошее конечное качество изображения. Если выбранный уровень детализации (LOD) слишком велик (размерность текстуры велика), искажения дискретизации (aliasing) будут видны в "полной своей красе". Если LOD будет недостаточным, то конечное изображение будет слишком размытым. Например, уровень детализации, выбранный для текстуры использованной на Рис. 7 (ниже) слишком мал, поэтому мы можем наблюдать большие грубые тексели в увеличенном окне вынесенном влево. Существует множество различных методов для выбора корректного LOD, каждый из которых имеет свои плюсы и минусы. Существуют два наиболее известных метода, которые мы рассмотрим ниже. Первый, основан на выборе уровня детализации в зависимости от местоположения текстуры в плоскости экрана (Area based); второй, использует для выбора LOD проекции u и v векторов.


Рисунок 6. Искажение текстуры после проекции в плоскости экрана


Рисунок 7. Наложенная текстура имеет неправильный LOD

Следует обратить внимание еще на один момент, дело в том, что вам, возможно, потребуется различное количество текселей для того, что бы прорисовать разные пиксели на экране. Как результат, вам необходимо будет просчитать LOD для каждого из пикселей. Эти вычисления могут быть очень медленными, и именно поэтому большинство программных методов визуализации (software renderers) и некоторые из устаревших видеоакселераторов, производят вычисления LOD основываясь на технологии per-polygon и/или per-triangle. Однако, несомненным плюсом per-polygon технологии в MIP-mapping, особенно при программной визуализации, является то, что для полигонов расположенных на удалении (более мелких) вы применяете более мелкие версии текстур из MIP карты, что значительно снижает требования к количеству кэш-памяти процессора в период интенсивных операций с текстурами. В то же время, по-пиксельный вариант выбора LOD позволяет вам реализовать целый ряд дополнительных преобразований в процессе MIP-mapping, включая такие как: точечная дискретизация; билинейная фильтрация на одном уровне детализации; трилинейная фильтрация между двумя ближайшими LOD.

Per-polygon MIP-mapping

Выбор корректного LOD в per-polygon MIP-mapping считается наиболее выгодным с точки зрения количества вычислений необходимых для его реализации, так как выборка производится однократно для целого полигона. Здесь, однако, есть два недостатка:

Первый - два соприкасающихся полигона могут быть отвизуализированы с применением разных уровней детализации. Визуально это проявляется в виде потери неразрывности восприятия нанесенной на объект текстуры (такие искажения носят название MIP banding). Рис.8 демонстрирует проявление незначительного MIP banding явившегося результатом per-triangle MIP-mapping.

Второй - визуальный недостаток проявляется в резких и неожиданных сменах качества прорисовки на объектах, в те моменты времени, когда происходит замена LOD на текстуре при перемещении точки наблюдения или перемещении полигона, относительно точки наблюдения.


Рисунок 8. Дорога рендеренная с применением per-polygon MIP-mapping

Выбор LOD в зависимости от местоположения текстуры на экране (Area-based LOD selection)

Area based LOD selection реализует по-полигонную технику MIP-mapping. Используя этот метод, вы регулируете LOD путем изменения степени сжатия, которая будет применена к текстуре нужной текстуре. Для того, чтобы определить необходимую степень сжатия, вам нужно определить местоположение полигона в плоскости экрана, а так же определить ту часть текстуры (в проекции текстуры) которая будет покрывать выбранный полигон. Используя пример из Listing 5 , вы можете определить соотношение текселей к пикселю и далее выбрать соответствующий уровень детализации для применения. (С целью экономии печатного пространства все кодовые листинги доступны для загрузки в виде одного архива: nov98.zip (584 Кб).

По-пиксельное MIP текстурирование позволяет реализовать более утонченное управление уровнем применяемой детализации, чем по-полигонное, оно так же допускает применение дополнительных преобразований над текстурами, хотя все это за дополнительную "плату". Все по-пиксельные методы требуют хранения полной MIP текстуры в RAM, а дополнение внутренних циклов в процедурах программы отвечающих за наложение текстур, может привести к значительному падению производительности игрового движка. К счастью, большинство из сущестующих в настоящее время 3D акселераторов аппаратно поддерживают MIP-mapping c билинейной фильтрацией (а некоторые чипы без ущерба могут осуществлять и трилинейную), поэтому мы рассмотрим, что же собственно необходимо для того, что бы реализовать по-пиксельное MIP текстурирование. Хотя и здесь, при выборе уровня детализации, мы можем применить Area based метод, мы все же пойдем по более аккуратному и сложному пути и просчитаем LOD для каждого из пикселей, в отличие от однократного просчитывания LOD на весь полигон.

Выбор LOD на основе краевого сжатия (Edge compression-based LOD selection)

В 1983 году, Поль Хекберт, перед тем как обнаружить, что метод основанный на определении сжатия краев пикселя при обратном проецировании на текстуру, является наиболее эффективной техникой вычисления LOD, он вероятно уже исследовал больше методов вычисления LOD, чем сам мог запомнить. Рис. 9 показывает единичный прямоугольный пиксель в плоскости экрана и соответствующий ему многоугольник в плоскости текстуры. Что бы избежать искажений типа aliasing , мы попробуем определить необходимый LOD основываясь на максимальном сжатии которую претерпевают края пикселя в плоскости текстуры. Она соответствует максимальной длине стороны в плоскости текстуры, и определяется Выражением 7 .


Выражение 7

Значения u x , u y , v x ,v y определяются четырьмя частными производными. См. Рис.9 . Т.к. мы уже знаем, как вычислять значения u и v для любого пикселя на экране, мы можем применить наши знания для вычисления частных производных. Зная текущие градиенты u/z, v/z и 1/z в системе × и y, а так же зная начальные значения u/z, v/z, 1/z в плоскости экрана, мы можем определить значения u и v по формулам 8 и 9. Нотацию, принятую в формулах 8 - 19 вы можете определить из серии статей Криса Хекера (Chris Hecker) по проекционному текстурированию, которые могут быть найдены на его WEB сайте. (См. раздел "Особые благодарности" в конце статьи).


Формула 8


Формула 9

Используя полученные выше результаты, мы можем определить частные производные в соответствии с формулами 10 - 13.

Формула 10

Формула 11

Формула 12

Формула 13

Где, значения a, b, c, d, e, f определяются формулами 14 - 19.

Формула 14

Формула 15

Формула 16

Формула 17

Формула 18

Формула 19

Очень важно заметить, что числители в частных производных u x и v x - функции y, а числители в частных производных u y и v y - функции x. Значения a, b, c, d, e, f вычисляются для всего полигона однократно, точно так же, как и в случае с обычными градиентами текстур. См. Listing 6 . Ну и, наконец, формула для нахождения максимального краевого сжатия дана ниже:


Формула 20

На первый взгляд кажется, что нам необходимо вычислять корень для каждого пикселя. Однако, если внимательнее рассмотреть формулу, то окажется, что значение y l - нам необходимо вычислять только раз на каждое значение × текущего полигона.
Более того, значение x l - достаточно вычислить всего раз для одного прохода луча ЭЛТ монитора (scan line). Listing 7 наглядно показывает как мы производим вычисление значения y l для диапазона × полигона в период нормальной подготовки к нанесению текстуры. Вы также заметите, что x l - вычисляется только раз на проход. И еще, нам не нужно беспокоиться о вычислении значения знаменателя, так как он уже будет вычислен ранее, в процессе стартовой выборки текстуры. Таким образом, вся дополнительная нагрузка к внутренним циклам процедур программы, будет представлять собой две операции умножения и одну операцию сравнения. Теперь, после того, как мы узнали каким образом вычислить краевое сжатие, давайте попробуем произвести выбор необходимого уровня детализации при текстурировании, используя точечную выборку, билинейную и трилинейную фильтрации.

Метод точечной выборки (Point-sampled per-pixel MIP-mapping)

Точечная выборка - самый простой способ реализации по-пиксельного MIP текстурирования и если вы заглянете в Listing 8 вы заметите, что нет значительной разницы между циклами простого наложения текстур и циклами в которых реализуется точечная выборка (point sampling). Как только мы нашли значение краевого сжатия для текущего пикселя, мы можем определить корректный уровень детализации текстуры для визуализации данного пикселя. Предварительные значения краевого сжатия, полученные нами при использовании формул приведенных выше, могут варьироваться в диапазоне значений от 0 до 1. Поэтому нам надо привести эти значения к размерности используемой текстуры, что бы получить значимую высоту в пирамиде примененной MIP текстуры. Как только мы получили значение этой высоты, мы сможем выбрать корректный LOD перемещаясь на уровень выше каждый раз, когда значение высоты будет превышать определенную степень двойки от 1 (например: высота 1 будет означать применение уровня детализации 0; 2 или 3 соответсвует уровню 1; 4 - уровень 2; 8 - уровень 3; 16 - уровень 4 и т.д.). Далее мы используем таблицу соответствий LOD, для получения значения указателя (pointer) внутри нашей MIP текстуры для извлечения соответсвующего текселя. На Рис. 10 показан тот же самый объект, что и на Рис. 8 , только отвизуализированный с применением точечной выборки (point-sampled MIP-mapping). Как можно заметить, при использовании данного метода, по прежнему присутствует проблема MIP banding в тех точках, где происходит смена LOD. Это объясняется тем, что соседние пиксели могут иметь различные уровни детализации, и ощущение неразрывности объекта теряется.


Рисунок 10. Дорога отвизуализированная с применением технологии точечной выборки

По-пиксельное MIP текстурирование с билинейной фильтрацией (Bilinear filtered per-pixel MIP-mapping)

Билинейная фильтрация призвана обеспечить дальнейшее уменьшение искажений типа aliasing на экране, путем усреднения значений четырех соприкасающихся пикселей текстуры, U и V координаты которых наиболее соответствуют реальному пикселю на экране. Рассмотрев Рис.11 и Listing 9 , мы можем заметить, что билинейная интерполяция (аппроксимация) реализуется тремя линейными интерполяциями. Вычисление корректного LOD и извлечение необходимого указателя (pointer) для нашей текстуры производится аналогично тому, что мы делали в случае точечной выборки. Однако, мы извлекаем значения для четырех пикселей текстуры и применяем билинейную интерполяцию для каждого цветового компонента, с целью получения усредненного значения цветности нового пикселя. Рис. 12 показывает, то, как выглядит наша дорога после применения билинейной фильтрации. Хотя заметен значительный прогресс в визуальном представлении по сравнению с Рис. 10 , мы все же можем заметить присутствие MIP banding.


Рисунок 11. Механизм интерполяций при билинейной фильтрации


Рисунок 12. Билинейная фильтрация

По-пиксельное MIP текстурирование с трилинейной фильтрацией (Trilinear filtered per-pixel MIP-mapping)

Способоность аппаратно поддерживать трилинейную фильтрацию при MIP-mapping, является неотемлемой чертой акслелераторов последнего поколения. Трилинейная фильтрация позволяет исключить проявления MIP banding путем сглаживания переходов между различными уровнями детализации. В Listing 10 , вы снова можете заметить, что вычисление корректного LOD производится путем, полностью аналогичным примененному при точечной выборке с той лишь разницей, что мы извлекаем указатели (pointers) для двух LOD: текущего и следущего выше по пирамиде, с меньшей детализацией. Трилинейная фильтрация выполняется путем восьми последовательных линейных интреполяций (апроксимаций). Мы выполняем билинейные интерполяции отдельно для каждого из двух выбранных LOD, а затем производим окончательные интерполяции между самими LOD. Как можно видеть на Рис. 13 , трилинейная фильтрация обеспечивает очень плавный переход между уровнями детализации (хотя это выливается в некоторую размытость линий). К сожалению, "плата" за подобное качество - велика. Непосредственная реализация алгоритмов трилинейной фильтрации требует восьмикратного обращения к текстуре на каждый просчитываемый пиксель, что вызвает производство огромного количества вычислений. Несмотря на то, что мы можем снизить количество обращений к текстуре, путем сохранения значений текселя в промежутках между итерациями цикла, производство самих интерполяций по прежнему будет выполнятся в каждом цикле, отсюда следует, что достижение приемлемых frame rates при использовании трилинейной фильтрации в неакселерированном режиме игрового движка - является очень и очень не простой задачей.


Рисунок 13. Трилинейная фильтрация

Заключение

В данной статье мы осветили довольно большой диапазон вопросов,
связанных с MIP текстурированием, и хотя применение трилинейной фильтрации делает конечное изображение гораздо более привлекательным, по сравнению с методами простого наложения текстур, все же идеального результата мы не получаем. Самой значительной проблемой в наших преобразованиях, является проблема анизотропности алгоритмов сжатия текстур (См. упоминание об этом выше в статье). Мы выбираем необходимый/корректный LOD исходя из максимальной степени краевого сжатия пикселя по одной из его сторон, но что будет если существует заметная разница в компрессии по различным координатным осям. В этом случае, выбранный уровень детализации будет недостаточен для стороны текстуры с меньшей компрессией и наша сцена будет казаться размытой. Посмотрите на Рис. 14 , это скриншот из CHAOSVR demo , который был получен с использованием акселератора на базе 3dfx Voodoo 2 , мы отчетливо видим, что размытие происходит только в направлении одной из осей координат. Данная проблема будет присутствовать при использовании любого 3D акслелератора, который использует алгоритмы вычисления LOD аналогичные разработанным здесь, а не только на Voodoo 2 используемом мной. Определенно, что следующим шагом на пути улучшения качества визуализации будет разработка и принятие алгоритмов анизотропной фильтрации. Уверен, что данная технология не заставит себя долго ждать, и появится на акселераторах следующего поколения.


Рисунок 14. Скриншот из CHAOSVR с использованием трилинейной фильтрации на базе Voodoo 2

Особые благодарности

Огромное спасибо Крису Хекеру (Chris Hecker ), который любезно разрешил мне вставить мои наработки в области MIP-mapping в алгоритмы наложения текстур, разработанные им. Это сэкномило массу времени. Посмотрите материалы на его домашней страничке для получения дополнительной информации по технике наложения текстур и более ранним статьям из Game Developer.

Хочу выразить признательность Полу Хекберту (Paul Heckbert ), за направление в мой адрес материалов публикаций, и наверное единственных, в которых обсуждается MIP текстурирование.

Наконец, я хочу поблагодарить Питера Лофенберга (Peter Laufenberg ) за разрешение использовать скриншот из CHAOSVR demo компнании Virtually Unlimited .

Для дальнейшего изучения:

  • Bracewell, R. N., The Fourier Transform and its applications, McGraw-Hill Book Co., New York, 1986.
  • Williams, L., "Pyramidal Parametrics", Computer Graphics, vol. 17, no. 3, (Proc. SIGGRAPH 1983).
  • Heckbert, P., "Texture Mapping Polygons in Perspective", NYIT Tech. Memo No. 13, 1983

Автор статьи Андрю Флавел (Andrew Flavell ) - еще один безработный Доктор Философии, пытающийся решить для себя, почему он провел все свои предыдущие годы изучая теорию графов и цепей Маркова.

MIP-текстурирование (MIP mapping) - метод текстурирования, использующий несколько копий одной текстуры с разной детализацией. Название происходит от multum in parvo - «много в малом».

Назначение

Изображение лучше всего выглядит, когда детализация текстуры близка к разрешению экрана. Если разрешение экрана высокое (текстура слишком маленькая/объект очень близко), получается размытое изображение. Если же разрешение текстуры слишком высокое (текстура слишком велика/объект очень далеко), получаем случайные пиксели - а значит, потерю мелких деталей, мерцание и большой процент промахов в кэш. Получается, что лучше иметь несколько текстур разной детализации и накладывать на объект ту, которая наиболее подходит в данной ситуации.

Принцип действия

Создаётся так называемая MIP-пирамида - последовательность текстур с разрешением от максимального до 1×1. Например: 1×1, 2×2, 4×4, 8×8, 16×16, 32×32, 64×64, 128×128, 256×256, 512×512 и 1024×1024. Каждая из этих текстур называется MIP-уровнем (MIP level) или уровнем детализации (level of detail).

Недостатки, способы решения

Расход видеопамяти увеличивается на треть. Впрочем, видеопамять сейчас достаточно дешева. К тому же, если объект далеко, его детальную текстуру можно выгрузить в оперативную память.

MIP-текстурирование не решает проблему текстур, находящихся под острым углом к зрителю (например, дорога в автосимуляторе). У таких текстур разрешение по одной оси сильно отличается от разрешения по другой - и, например, по оси X изображение явно размыто, в то время как по оси Y видны мерцания, свойственные завышенному разрешению текстуры. Есть сразу несколько способов решения этого (начиная с наименее качественного):

  1. Установить в видеодрайвере наиболее комфортное значение mip bias - числа́, которое отвечает за выбор номера текстуры в пирамиде. Если оно отрицательное, видеоплата берёт более детальные текстуры, если положительное - менее детальные.
  2. Многие игры сами устанавливают подходящий mip bias для разных типов объектов. Например, в Live for Speed mip bias устанавливается пользователем отдельно для автомобилей, препятствий и дороги.
  3. Воспользоваться

Описание алгоритмов текстурирования: фильтрация текстур

Фильтрация текстур

В последнее время компании, занимающиеся разработкой компьютерной 3D графики, постоянно стремятся увеличить детальность и качество изображения в компьютерной прорисовке. Новые технологии и архитектуры 3D прорисовки безостановочно разрабатываются, улучшаются и модернизируются алгоритмы сжатия для увеличения пропускной способности памяти, претерпевает изменения и архитектура памяти. К сожалению, отрыв передовых идей в 3D графике от обычных ПК довольно велик: реалистичность в современных играх и т.п. сделана с помощью технологий, разработанных 1-2 года назад. Кроме того, мощность обычных ПК очень ограничена, именно поэтому для игр используются довольно простые алгоритмы, о которых мы и расскажем в этой статье: это текстурирование, и более подробно - фильтрация текстур.

Имея идеальный компьютер с производительностью, намного превосходящей существующую, мы бы получили возможность отображать в реальном времени картинку с очень реалистичной прорисовкой. Можно было бы просчитывать миллионы, даже миллиарды пикселей, для каждого их них задавать свой собственный цвет - в таком случае картинку просто нельзя будет отличить от реального видео. Но к сожалению, пока это только мечты: для существующих компьютеров пока что слишком сложно одновременно обрабатывать прорисовку объектов при движении, и т.п. Кроме того, пока что катастрофически не хватает пропускной способности памяти. Для обеспечения хорошего качества в 3D приложениях и разрабатываются технологии, упрощающие процесс прорисовки изображения.

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

Есть еще одно понятие в текстурировании, о котором следует рассказать. При наложении 2D изображения, оно разбивается на множество цветных фрагментов. Это сделано для масштабирования объекта - текстура 2-х мерная, а 3-х мерный объект при приближении или удалении должен меняться. Текстура для сохранения реалистичности и качества также должна меняться. Итак, текстура разбивается на множество цветных фрагментов, которые называются тексели (texels - texture elements). В дальнейшем, к примеру, при приближении к объекту, нет необходимости заново загружать новую текстуру: берутся тексели из оригинальной текстуры и увеличиваются. Конечно же, качество теряется, но оно остается на достаточно высоком уровне, кроме того, при таком подходе значительно разгружается графический процессор и память.

Mip-Mapping (мип-маппинг)

Движение - это характеристика всех отображаемых объектов; даже если сам объект неподвижен, он все равно меняется при изменении угла зрения персонажа вследствии его движения. Поэтому текстура, помещенная на объект, также должна двигаться - это влечет за собой некоторые осложнения и дополнительную обработку. А что если мы смотрим на объект под каким-то углом, к примеру, на пол? Пол может занимать большую площадь, и для сохранения реалистичности, чем дальше он от нас, тем меньше его составляющие (к примеру, плитка). Для обеспечения этого, текстура должна определенным образом уменьшаться. К сожалению, простое изменение разрешения текстур, может повлечь за собой довольно неприятный эффект, когда одна текстура визуально как бы сливается с другой. Другой неприятный эффект может возникнуть, если тексель больше размером, чем требуемое количество пикселей. Это происходит, когда смотришь на текстуру, находящуюся на очень большом расстоянии. Обе ситуации возникают при применении традиционного сглаживания. А вот и реальные примеры этих случаев: в данном реферате нету

Для смягчения таких ситуаций и был создан mip-mapping (мип-маппинг). Эта технология работает очень просто: оригинальная текстура генерируется в различных ситуациях таким образом, чтобы корректно отображать текстуру на разных расстояниях и при разных углах зрения. При приближении к объекту показывается текстура с более высоким разрешением, а при отдалении - с низким. Таким образом, mip-mapping улучшает качество изображения и уменьшает неровности. Ниже представлены те же картинки, только со включенным mip-mapping: в данном реферате картинок нету.

Заметили улучшение качества? Оно особенно заметно на второй картинке с желто-красным рисунком. Обратите внимание: улучшилось качество не только дальних текстур: ближние также выглядят гораздо лучше. В целом изображение с mip-mapping смотрится гораздо лучше, чем без него: отсутствуют многочисленные искажения и искривления, заметные при обычном отображении.

Фильтрация

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

Билинейная фильтрация (Bilineat Filtration)

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

На этой картинке пример прорисовки изображения, используя билинейную фильтрацию и mip-mapping.

Трилинейная фильтрация

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

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

Изображение получается очень качественно только при более прямых углах зрения, при реальной же прорисовке, геометрические формы объекта могут быть нарушены. Посмотрите на картинку от SGI:

Анизотропная фильтрация (Anisotropic filtering)

Форма текстурированных объектов как при билинейной, так и при трилинейной фильтрации может искажаться, т.к. обе эти фильтрации являются изотропными - изображение фильтруется в определенной форме - в форме квадрата. Большинство же формируемых объектов не подходят под эту определенную и неизменную форму: для их качественной обработки необходимо использовать другой тип фильтрации - анизотропный. Анизотропия состоит из нескольких слов на латыни и означает буквально "Ани" - не, "изо" - определенная форма и "тропия" - модель - т.е. модели неопределенной формы. Название этой технологии отражает ее техническую реализацию. Анизотропная фильтрация обычно оперирует не менее чем 8 текселями, во все стороны mip-map уровней, при этом используется модель неопределенной заранее формы. В результате убираются шумы и искажения объектов, а изображение в целом получается более качественным.

Сравните две картинки: на одной использовалась анизотропная фильтрация 16-текселей, с помощью которой исчезли искажения между mip-map уровнями и шум изображения, на второй картинке анизотропная фильтрация была выключена.

Обратите внимание на дальние дистанции изображения: различия между анизотропной и изотропной фильтрацией очевидны. Качество текстуры при анизотропной фильтрации даже на дальних дистанциях остается схожей с оригинальным; при изотропной фильтрации же видна тенденция в "сглаживанию" изображения, в результате теряется качество. Анизотропная фильтрация, как и трилинейная, уменьшает неровность текстур. Но при использовании анизотропной фильтрации качество получается все равно лучшим, т.к. для используется гораздо большее количество блоков для сравнения. Вот еще один пример, показывающий анизотропную фильтрацию в действии:

Долгое время графические платы потребительского уровня не показывали то качество изображения, которое возможно при использовании анизотропной фильтрации. С появлением таких графических чипов, как NVIDIA GeForce2 и ATI Radeon, стало возможным использование анизотропной фильтрации, которая аппаратно анализирует блоки из 16 текселей. Видеокарты GeForce3 и Radeon 8500 используют уже 32 тексельную анизотропную фильтрацию. Картинка ниже показывает изображение, прближенное к тому, которое будет получено с помощью профессиональной 64 тексельной анизотропной фильтрации:

Будущее…

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

Дополнительно:

Антиалиасинг и анизотропная фильтрация сегодня: что, где и почём? Часть первая

На самом деле, статью с таким заголовком можно было бы начать с какой-либо банальности, вроде «каждый пользователь компьютера когда-либо мог наблюдать работу таких техник улучшения трехмёрного изображения, как антиалиасинг или анизотропная фильтрация». Либо такой: «пока наши корабли бороздят космические просторы, программисты NVIDIA и ATI ищут способы, чтобы улучшить работу известных техник улучшений изображения». Вторая банальность имеет куда больше шансов на жизнь в том плане, что она уже интригует неким подобием того, что мы будем заниматься расследованием вопроса о том, кто и каким образом «наоптимизировал» в своих драйверах.

Однако мы, пожалуй, обойдёмся вовсе без банальностей. Потому что куда более интересно порассуждать на тему того, насколько же стали доступны сейчас техники улучшения изображения для простого пользователя или, правильнее будет сказать, для простого геймера. Именно геймеры на сегодняшний день являются наиболее активными потребителями всех новых технологий и нововведений в 3D. По большому счёту, мощный 3D-акселератор на сегодняшний день нужен исключительно для игры в последние компьютерные игры с мощными 3D-движками, оперирующие сложными шейдерами различных версий. Сейчас никого уже не удивишь игрой с пиксельными шейдерами версии 2.0 – в игровом мире такие забавы потихоньку становятся повседневным явлением. Большинство игр по-прежнему выпускается на основе шейдерной модели 1.1 ввиду того, что для разработчиков игр наиболее важно добиться, чтобы их игра сносно работала на железе, которое стоит у подавляющего большинства игроков. Делать супернавороченный движок сейчас – это большое расточительство и даже риск. Судите сами: разработка движка класса «Doom 3» или «Half-Life 2» (ну и приплюсуем сюда первопроходца шейдеров 2.0 во всей красе, детище Crytek – «FarCry», чтобы получилась истинная вездесущая троица) занимает огромное количество времени, что привносит в разработку дополнительные трудности – необходимо разработать движок в такие сроки, чтобы нововведения и оригинальные наработки не устарели во время создания движка.

Если вы сомневаетесь в том, что такое может быть, то совершенно зря – в случае с «Half-Life 2» всё именно так и было (да и «Doom 3» разрабатывался с оглядкой на GeForce 3, а вышел тогда, когда вовсю продавались GeForce FX). Также разработка движков подобного класса сопряжена с большими затратами на разработку: талантливые программисты стоят сегодня недёшево. А ещё в последнее время много внимания (даже больше, чем нужно) уделяется, если можно так выразиться, «политике» в отношении игровых движителей.

Да-да, именно так, вы не ослышались, в сфере 3D уже давно есть своя политика, основанная, естественно, на интересах двух грандов строения графических процессоров: ATI и NVIDIA. Суровая Канада уже давно ведет борьбу против солнечной Калифорнии, и пока конца этому противостоянию не видно, что нам, простым потребителям, конечно, только на руку. Теперь разработать классный движок мало – чтобы иметь успех, нужно заручиться поддержкой либо калифорнийской дивы NVIDIA, либо канадской ATI, благо, теперь и у первой, и у второй есть свои партнёрские программы для разработчиков игр. У NVIDIA такая программа называется «The way it"s meant to be played», а у ATI – «Get it in the game». Всё достаточно красноречиво и понятно: NVIDIA говорит, что «играть нужно так», а совсем не эдак, а ATI уверяет, что всё, что мы только ни пожелаем, мы обязательно получим в самой игре. Достаточно заманчиво, не правда ли? Движки же класса «Doom 3» и «Half-Life 2» (в случае последней движок называется Source, однако для простоты восприятия мы будем называть его именно «Half-Life 2», чтобы сохранить правильную ассоциацию) и вовсе изначально разрабатываются в тесном сотрудничестве с инженерами производителей графических чипов, чтобы игры лучше работали именно на GPU какого-то одного производителя.

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

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

Что такое антиалиасинг и с чем его едят?

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

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

Для начала нужно чётко понимать, что изображение, которое мы с вами можем ежедневно наблюдать на экранах наших с вами мониторов, состоит из так называемых мелких частичек, которые принято называть пикселями. Хорошей аналогией в этом смысле может послужить пример с бумагой в клеточку. Изображение на мониторе – это та же бумага в клеточку, только они в данном случае очень и очень мелкие. Если говорят, что разрешение экрана составляет 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 текселя для определения цвета пикселя.