|
Анизотропный антисемплинг.
Краткий ликбез по 3D, часть первая
Mazur
mazur363@mail.ru
"Мне без разницы, какой уровень анизотропии включен, лучше подскажи, как с
помощью воллдоджа быстро добраться до рулеза!" - вот что я однажды услышал от
геймера, после того как невзначай сказал ему, что экран весь в зазубринах, и
посоветовал включить антиалиасинг. Нет, дело не в наплевательском отношении к
качеству картинки: для грамотной настройки уровня эффектов в игре нужно либо
долго экспериментировать, либо заранее знать, как повлияет включение той или
иной опции на красоту и скорость.
Естественно, ни на то, ни на другое у подавляющего большинства пользователей
не хватает желания и времени. Вот тому подтверждение: во многих современных
играх есть автоопределение уровня графики, или же все настройки ограничиваются
ползунком low-medium-high quality. Ткнул кнопку, хитроумный алгоритм там чего-то
посопел себе под нос и выдал "оптимальные" настройки. Многие важные параметры
можно изменить, лишь вручную отредактировав соответствующий файл или запустив
программу-твикер, выпущенную сторонним разработчиком. Хорошо еще, что advanced
options не исчезли окончательно...
Данная статья - попытка объяснить все непонятные термины, часто встречающиеся
в описаниях игр, дать вам возможность понять их и ознакомиться с нашими
практическими исследованиями в области того, как та или иная фича влияет на
качество картинки и скорость. Ведь автоконфигурация и перемещение одного-двух
ползунков - это не способ получить наиболее красивую картинку без сильной потери
производительности. Иногда мне вообще кажется, что движок просто поиграл в
"любит - не любит", поперемещав ползунки, понаставив галочек в advanced settings
и остановившись на понравившемся ему варианте (не факт, что этим вариантом
останутся довольны пользователь и видеокарта).
Чтобы изучить влияние фич на красоту и производительность, мы взяли две
видеокарточки - GeForce 6600GT и Radeon X1600XT - и три игры, созданные на
наиболее популярных сегодня движках: F.E.A.R, Doom 3 и Unreal Tournament 2004.
Не случайно наш выбор пал на эти платы: 6600GT - очень распространенный
видеоадаптер, удачный по соотношению "цена - производительность", и за это
пользователи его любят, вторая карточка является представителем новой линейки и
продержится на рынке как минимум год. Делать долгосрочные прогнозы не получится:
выйдут новые игры, и появятся более продвинутые железки со своими особенностями
и наворотами.
Базовые понятия
Если вы способны быстро ответить на вопрос о том, что такое мип-бандинг и как
от него избавиться, пропускайте эту главу и читайте дальше.
Давать определения базовым терминам будем, рассматривая конкретные примеры.
Представьте, что перед вами на мониторе уходящий вдаль коридор, застеленный
цветастой текстурой. Вблизи ее рисунок четко различим, по мере удаления четкость
теряется, и в итоге текстура превращается в мешанину разноцветных точек. Более
того, все изображение пестрит и вообще выглядит очень неестественно.
И вот почему возникает такое безобразие: видеоадаптер пытается сопоставить
одному пикселю на мониторе один тексель текстуры, а по мере удаления от объекта
количество пикселей на один и тот же кусок текстуры сокращается (определение
пикселя и других часто встречающихся в тексте терминов приведено во врезке).
Соответственно, в какой-то момент окажется, что на один пиксель приходится
гораздо больше, чем один тексель (разрешение-то у текстуры фиксированное!), и на
выходе появятся вышеописанные артефакты. Кстати, такой метод наложения текстур
называется поточечной выборкой (point sampling), а видеть его в действии можно
на старых системах, только нужно предварительно отключить вообще все улучшающие
картинку функции.
Для исправления багов поточечной выборки придумали мип-мэппинг (mip-mapping).
При его применении у каждой текстуры появляется несколько сестер-близнецов
(мип-уровней), порожденных масштабированием исходной текстуры. У каждого
мип-уровня есть свой номер LOD (Level of Detail), определяющий уровень
детализации. Чем он, LOD, выше, тем меньше разрешение текстуры по сравнению с
первичным. Как нетрудно догадаться, чем дальше объект от нас, тем больше LOD у
натягиваемой на него текстуры. Но есть и обратная сторона медали: появляется
мип-бандинг (mip-banding), то есть крайне неряшливо выглядят переходы от одного
мип-уровня к другому. На помощь приходят различные виды фильтрации.
Фильтрация
Прежде чем обсуждать виды фильтрации, следует провести простой эксперимент.
Возьмите листик в клетку, прикрепите его на стену и, вооружившись тремя-пятью
цветными маркерами, раскрасьте все клетки в разные цвета (желательно, чтобы
клетки одного цвета не находились рядом). Теперь посмотрите на него сквозь
небольшое отверстие, проделанное в другом листе (диаметром около пяти
миллиметров). Далее, не изменяя расстояния между листом с отверстием и глазом,
сделайте маленький шаг назад, потом, скажем, вправо, затем вперед, не упуская из
виду клетчатый лист. Заметьте, сквозь дыру видна не одна, а несколько клеток,
причем в зависимости от расстояния и угла зрения число видимых клеток меняется.
Более того, при любых углах, кроме прямого, какие-то клетки видны отчетливо, а
какие-то - нет.
Переносим все в 3D-пространство: клетчатый лист - это текстура на объекте,
каждая клетка соответствует одному текселю, второй лист - монитор, а дырка в
листе - пиксель на экране. Разница лишь в том, что мы для простоты рассматривали
один пиксель, а их на дисплее многие тысячи. Вывод: на один мониторный пиксель
редко когда приходится один тексель текстуры, чаще всего из-за движения число
"видимых" сквозь пиксель текселей постоянно меняется. Думаю, теперь вам понятно,
почему при поточечной выборке возникает так много различных огрехов: в любой
момент цвет пикселя определяется лишь одним текселем из тех, что приходятся на
пиксель, а это в корне неверно (ведь пиксель, которому соответствуют, скажем,
черный, желтый и синий тексель, должен быть черно-желто-синим, а не черным,
желтым или синим). Теперь, помня об этом наглядном примере (мы еще к нему
вернемся), рассмотрим тему главы, то есть различные виды фильтрации.
Простейшая, билинейная фильтрация (billinear filtering), при применении
которой цвет пикселя определяется по четырем текселям (естественно, тем
текселям, что в тот или иной момент "видны" через пиксель), позволяет избавить
картинку только от пестроты, никакого мип-бандинга: в расчет принимаются тексели
одного мип-уровня. Более продвинутая фильтрация - трилинейная (trillinear
filtering) - использует восемь текселей текстуры для определения цвета пикселя,
по четыре с каждого мип-уровня. Переходы становятся более плавными, но все равно
до идеала далеко.
К лучшему ситуацию изменяет анизотропная фильтрация (anisotropic filtering),
учитывающая шестнадцать и более текселей при формировании цвета пикселя. Кроме
того, когда картинка обрабатывается методами анизотропной фильтрации, в расчет
берется угол наклона текстуры по отношению к наблюдателю. Чтобы понять, зачем
это нужно, вернемся к примеру из предыдущего абзаца: при рассматривании листа
через дырку можно заметить, что чем острее угол, под которым мы смотрим на лист,
тем больше клеток видно через дырку. И, потом, многие из видимых клеток с
уменьшением угла зрения оказываются в зоне плохой видимости. Бывает и
по-другому: из пары десятков клеток четко видны всего три-четыре, остальные
сливаются в одноцветное пятно (это работает анизотропная фильтрация нашего
глаза).

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

Рисунок для тех, кому лень проделывать эксперимент с тетрадным листом и
отверстием.
За все надо платить, в том числе и за облагораживающее влияние анизотропии на
картинку. Чем выше уровень фильтрации (на сегодняшний день диапазон - от 2х до
16х), тем больше ресурсов видеокарточки требуется для отрисовки каждого кадра и
тем резче снижается производительность системы. В основном анизотропия загружает
контроллер памяти, ведь для определения цвета каждого пикселя приходится
считывать несколько десятков текселей из VRAM. По сравнению с анизотропией
билинейная и трилинейная фильтрация нетребовательны, производительность системы
снижают ненамного (вот пример: даже на древних видеокартах семейства GeForce2
активация трилинейки в зависимости от разрешения уменьшала быстродействие в
играх всего на 10-20%), поэтому во многих современных игрушках они включены по
умолчанию.

Работа RGSS (Rotated Grid SuperSampling) AA. Картинка сдвигается по одной из
осей координат, полученные результаты усредняются.
Антиалиасинг
Наверное, нет обзора видеокарты, в котором не было бы ни слова об этой
технологии. Но что же она представляет собой? Разбираемся. Думаю, что с
алиасингом (aliasing) - "ступеньками" на краях полигонов - знаком каждый.
Появляются они из-за того, что разрешение экрана не позволяет сделать четкий и
плавный переход между цветами. Даже в разрешении 1600 х 1200 ступеньки очень
хорошо заметны, особенно на краях поверхностей, расположенных под острым углом.
Столкнувшись в свое время с этой проблемой, разработчики не стали увеличивать
разрешение, они пошли обходным путем - стали немного размывать границу между
цветами. Технология, позволяющая выполнять такую задачу, была названа
антиалиасингом (antialiasing), а в реализации она имеет нечто общее с
анизотропной фильтрацией: разрешение готовой картинки в n раз превосходит
выставленное на мониторе, а перед выводом на экран изображение сжимается до
необходимого размера.
То, во сколько раз расчетное, или виртуальное, разрешение будет превосходить
реальное, определяет субпиксельная маска. Например, если субпиксельная маска
имеет размер 2 х 2 пикселя, то виртуальное разрешение будет превосходить
реальное в два раза и по ширине, и по высоте (то есть для реального разрешения
800 х 600 виртуальное будет 1600 х 1200). Цвет пикселя будет рассчитываться по
четырем соответствующим субпикселям. А значит, при маске 4 х 4 разрешение будет
в четыре раза превосходить оригинальное, и один пиксель будет рассчитываться по
шестнадцати субпикселям. Существуют также и другие, нестандартные маски, одни -
размером 1 х 2 пикселя, другие именуются special (известные также как Quincunx)
или low quality.
Та, что размером 1 х 2 пикселя, позволяет сглаживать только горизонтальные
линии, а маска special использует для определения цвета пикселя не только свои,
"законные" субпиксели, но и несколько соседних (например, в режиме 2 х 2 special
для определения цвета будут использоваться не четыре, а десять субпикселей). В
режиме low quality применение фильтрации (анизотропной, трилинейной)
осуществляется не до того, как картинка ужимается до мониторного разрешения, а
после этого. Такой алгоритм называется overfiltering.
Doom 3 без антиалиасинга, в режиме 2xAA и 4xAA.
Обратите внимание на ручку тележки. Эффект налицо.
Способ антиалиасинга, описанный выше, многим знаком как суперсемплинг
(supersampling, SSAA), точнее, Ordered Grid Supersampling, OGSS. Есть еще один
метод суперсемплинга - Rotated Grid Supersampling, RGSS. При его применении
рассчитывается n версий картинки, смещенных на небольшое расстояние относительно
изначальной картинки в различных направлениях, а потом цвета субпикселей
дочерних изображений, которые имеют одинаковые координаты, смешиваются для
получения цвета итогового пикселя. Думаю, вы лучше поймете последние два
предложения, взглянув на рисунки. Кстати, RGSS применялся на VooDoo5.
А что же такое мультисемплинг (multisampling, MSAA)? Это тот же
суперсемплинг, только применяемый для обработки границ полигонов, а не всей
картинки (раньше этот метод назывался HRAA - High Resolution Antialiasing).
Действительно, антиалиасинг нужен для сглаживания краев полигонов, так зачем
производить ту же самую работу на поверхности каждого полигона?
В последних моделях видеоакселераторов появилось еще несколько видов
анизотропии: Temporal antialiasing и Transparent Supersampling (TSAA). Первый
основан на том, что антиалиасинг работает через кадр, а второй устраняет баг
мультисемплинга, возникающий на прозрачных или полупрозрачных полигонах.
Классический пример: в Half-Life 2 при взгляде через сетку или стекло края
объектов не сглаживаются. Это происходит потому, что все стекла и мелкие сетки
движок воспринимает как один полигон, мультисемплинг, как вы знаете, действует
только на края полигонов, а не на всю их поверхность. TSAA действует просто: на
всех прозрачных и полупрозрачных полигонах включается честный суперсемплинг,
остальные, непрозрачные полигоны подвергаются мультисемплингу.
В действии
Рассуждать о том, нужно ли включать трилинейку с билинейкой, сегодня не
приходится: благодаря высокой производительности современных видеоакселераторов
падение скорости вообще не будет заметно, а без простейшей фильтрации картинка
выглядит безобразно. Так что эти фичи однозначно нужно включать. С низкими (4x -
8x) уровнями анизотропии ситуация такая же: качество изображения повышается
намного, а сокращение количества fps незначительно.
Максимальный уровень анизотропной фильтрации - это на любителя, да и потом, в
таком случае желательно иметь мощную карту (6800GT и выше). Картинка становится
куда красивее, но и количество fps порой уменьшается до невообразимо малых
значений. Да, совсем забыл сказать: все написанное в предыдущем абзаце и далее
справедливо для разрешения 1024 х 768. Конечно, можно выставить 1280 х 1024 или
1600 х 1200, отказавшись от фильтрации и антиалиасинга разных типов и сохранив
тем самым играбельность, но не факт, что увиденное вам понравится. Более того, я
с уверенностью могу сказать, что при 640 х 480 и 16x AF картинка будет выглядеть
лучше, чем при 1024 х 768 и noAF0, а изображение при 1024 х 768 и 16x AF
произведет гораздо более благоприятное впечатление, чем при 1600 x 1200 без
наворотов.
Антиалиасинг, как было сказано раньше, очень ресурсоемкая технология, и не
удивляйтесь, если какой-то 4x MSAA (далеко не самый прожорливый AA) уменьшит
количество fps примерно вдвое. Почему именно 4x, а не 2x? Дело в том, что на
первый взгляд пользы от 2х AA практически нет, а производительность падает.
Включение 4x MSAA заметно сразу же: все мелкие детали становятся гораздо четче,
а на полигонах, наклоненных под углом, близким к 45°, практически исчезают
ступеньки, резавших глаз. Это близкий к идеальному для антиалиасинга вариант:
для расчета пикселя с обеих пограничных полигонов берется равное количество
субпикселей.
С полигонами, наклоненными под острыми углами (до 20°), все с точностью до
наоборот: лесенка остается, лишь переходы между ступенями становятся чуть менее
заметными. Так происходит из-за того, что при расчете пикселей, которые лежат на
границе между двумя полигонами, большинство составляющих их субпикселей
относится к одному из полигонов и сгладить угол почти не получается. Оптимальный
в плане экономии ресурсов выход - изменить алгоритм анизотропии (в данном случае
- на RGSS), но тогда возникнут проблемы с другими углами.
Второй выход из данной ситуации - увеличить число субпикселей (читай повысить
уровень антиалиасинга), но это незамедлительно отразится на производительности.
Собственно, приходится выбирать одно из двух: либо миримся с огрехами, либо
жертвуем скоростью. Можно, конечно, понизить разрешение, но тогда удовольствие
от игры сойдет на нет. Из рассмотренных нами игр только одна - UT2004 -
позволяет пользователю перевести ползунок в положение 8x, не затрагивая другие
настройки, и не столкнуться с тормозами (сказать за это спасибо следует авторам
легкого движка без навороченных эффектов).
В стремлении сделать границы объектов максимально гладкими мы добрались до
наиболее мощного и самого требовательного к ресурсам уровня антиалиасинга - 8x
SSAA. Самое время сравнить его с 8x MSAA по скорости и качеству всей картинки.
Например, в Doom 3 с 8x MSAA отверстие в решетке с зазубренными краями и буквы
на дверях выглядят совершенно неестественно, особенно на фоне гладких прутьев и
краев тех же плит, не спасает положение даже 16x AF. С 8x SSAA все приходит в
норму, плиты выглядят красивее, чем раньше, надписи на дверях перестают быть
угловатыми, счетчик в правом верхнем углу экрана показывает, что мы
лишились10-20 fps.
Таким же образом можно найти баланс качества и производительности в остальных
играх, причем не исключено, что на разных картах (или в разных режимах игры)
придется подыскивать свой оптимум. Например, при прохождении Half-Life 2 на
многих уровнях приходилось прерывать игру для включения TSAA вместо MSAA.
| Результаты тестирования карт в разных режимах. Doom
3, demo1, настройки high quality |
| |
|
|
| |
GeForce
6600GT, fps |
Radeon X1600,
fps |
| |
|
|
| 1024 x 768, no AF, no AA |
84 |
51 |
| 1024 x 768, 4 x AF, no AA |
78 |
48 |
| 1024 x 768, 8 x AF, no AA |
70 |
43 |
| 1024 x 768, 8 x AF, 4 х SSAA |
45 |
- |
| 1024 x 768, 8 x AF, 4 х MSAA |
51 |
39 |
| 1024 x 768, 16 x AF, 8 х SSAA |
24 |
- |
| 1024 x 768, 16 x AF, 6 х MSAA |
34 |
35 |
Прочие технологии
Кроме набивших оскомину антиалиасинга и анизотропии существует масса других
технологий и ухищрений, призванных сделать 3D-картинку красивее и реалистичнее.
Вертикальная синхронизация (VSync). Она может быть лишь включена или выключена.
При активации эта опция синхронизирует fps с частотой обновления монитора (то
есть количество кадров в секунду становится кратным частоте обновления
монитора). Позволяет устранить подергивание изображения, но имеет очень
неприятную особенность - вызывает скачкообразное изменение количества fps.
Мультитекстурирование (multitexturing) - это имеющаяся у современных видеокарт
возможность накладывать на полигон по несколько текстур за такт.
Детализированные текстуры (detail textures) - это практическое использование
мультитекстурирования: поверх текстуры на объекте (назовем ее основной)
накладывается еще одна, призванная показать рельефность поверхности, отражение и
т. д.
Бамп-мэппинг (bump-mapping) - технология, призванная имитировать рельеф с
помощью карты нормалей.
Карта окружения (environment map) - технология для имитации отражения. На
текстуру поверхности накладывается еще одна (карта среды), представляющая собой
вид окружающего объект мира с основной текстуры.
Рельефное текстурирование картами среды (environment map bump mapping, EMBM)
- это, как понятно по ее названию, комбинация из bump-mapping и environment map.
Имитирует рельеф основной текстуры. На нее накладывается карта среды,
имитирующая отражение мира, окружающего объект, от якобы рельефной основной
текстуры.
Расширенный динамический диапазон (high dynamic range, HDR) применяется для
создания естественных световых переходов. Классическая ситуация: в темную пещеру
сквозь дыру в потолке пробивается солнечный луч. Этот пучок света должен быть
ослепительно ярким, однако 32 бит недостаточно для полной передачи данного
эффекта, и солнечный свет выглядит простым светлым пятном на полу, потолке и т.
д. HDR предусматривает использование 64 бит, что, по идее, должно исправить этот
недостаток. К сожалению, игр, поддерживающих эту технологию, мало и оценить
эффект от этой фичи чаще всего не получается.
Отсечение невидимых поверхностей (hidden surfaces removal, HSR) - полезная
функция, позволяющая отсечь невидимые поверхности на ранней стадии рендеринга
картинки и тем самым освободить ресурсы видеоакселератора от ненужной работы.
Motion blur - простая технология, применение которой позволяет создать у
зрителя такое впечатление, будто за объектом в движении тянется шлейф.
Реализуется либо размыванием пикселей по краям движущегося объекта, либо
рендерингом сразу нескольких фаз движения. Активно используется во второй части
NFS Underground при включении нитроускорителя.
Сжатие текстур (texture compression) - архивация текстур на время, пока они
хранятся в видеопамяти. Недостаток данной технологии - качество текстур
неизбежно ухудшается.
Само собой, в этой статье мне удалось охватить не все технологии. Не были
описаны шейдеры, у меня не получилось рассказать о том, как происходит процесс
рендеринга картинки. Все это будет рассмотрено в других материалах этой серии.
Глоссарий
В меню игр и в статьях о видеокартах часто встречаются такие слова, как
bump-mapping, текстура и пиксель. Ниже приводится список наиболее
употребительных терминов и их расшифровка.
Пиксель (pixel, picture element) - минимальный элемент изображения
экрана, имеет два параметра: первый - цвет, второй - его глубина (BPP).
Тексель (texel, texture element) - минимальный элемент текстуры.
Текстура (texture) - обычная картинка, натягиваемая на полигон. Вообще,
вся графика в 3D - дым, пламя, различные эффекты - делается из текстур,
прошедших определенную обработку. Прицел - это тоже текстура.
Процедурная текстура (procedure texture) - текстура, "рождающаяся"
непосредственно в процессе рендеринга. Обычные текстуры готовятся заранее, и на
них приходится значительная часть объема, занимаемого игрой. Хороший пример
использования процедурных текстур - крохотная (вес - 102 кбайт), но очень
красивая игрушка kkriegеr, дико загружающая даже топовые видеокарты.
Полигон (polygon) - многоугольник (обычно треугольник), из них состоят
все трехмерные объекты.
Количество fps (fps, frame per second) - число кадров в секунду. Также
FPS может расшифровываться как first person shooter - игровой жанр, к которому
относятся все "стрелялки" от первого лица, такие как Quake 1-4, Doom 1-3, Unreal
и т. д. (Есть еще одна расшифровка: Федерация парашютного спорта. - Прим. ред.)
Буфер кадров (frame buffer) - так называется участок видеопамяти, в
котором готовится выводимое на экран изображение. Двойная или тройная
буферизация применяется для повышения качества изображения: пока содержимое
одного буфера выводится на экран, в другом строится следующий кадр.
Z-буфер (Z-Buffer) - в нем сравниваются Z-координаты полигонов, у которых
координаты X и Y одинаковые. Полигоны, оказавшиеся перекрытыми другими, то есть
расположенные в невидимой зоне, обрезаются.
|