В комментах к предыдущим двум частям "Технологий графики в современных играх" меня не раз спрашивали про антиалайзинг. Как говорится, «получите, распишитесь».
Вообще рассказать про АА я собирался в третьей части, но я не успеваю закончить её за эти выходные. Плюс, стиль изложения в данном случае никак не согласуется с остальной серией статей (слишком суровая теория).
Поэтому я решил выделить тему о сглаживании в такой мини-спин-офф. Но читать настоятельно рекомендуется в продолжение самой третьей части.
Anti-Aliasing (AA) в современных играх
Или, по-нашему — … тоже антиалайзинг. Полноценного русского названия для этой технологии просто нет. Можно перевести его как «устранение эффекта лесенки» или «устранение ступенчатости». В играх его часто переводят как «сглаживание». Но все эти варианты не совсем корректны, и в среде людей, занимающихся графикой, просто используют кальку с английского названия.
Чтоб разобраться, что это за зверь такой — "антиалайзинг" — и с чем его едят, надо сперва выяснить, что такое «алайзинг» (aliasing) и откуда он берётся.
Внимание!
Расстановка точек над АА невозможна без некоторой суровой теории. И картинки по ходу тоже будут не красивыми скриншотами из ААА-игр, а специальными синтетическими примерами.
Если тебе такое не по силам / не интересно — крути вниз, к кратким выводам.
Дело в том, что компьютерная графика, как и всё компьютерное, дискретна.
Если брать конкретно изображение — то с точки зрения процессора это всего-навсего таблица из пикселей. Об этом ты и без меня знал. Но вот из-за этой фундаментальной вещи — начинаются проблемы.
Допустим, у нас в кадре есть чайник (так уж повелось у 3D-шников: брать его в качестве болванки).
Для камеры он будет выглядеть вот так:
В реальной природе (например, на матрице фотоаппарата) каждый пиксель получит средний цвет той области, которую он представляет. То есть,
Но так обстоят дела в реальной природе. Когда же изображение создаётся искуственно, компьютер не может получить средний цвет в области, потому что никаких «областей» и нет. Есть лишь пиксели. И цвета для них ему надо откуда-то «придумать». Что он и делает.
Рендеринговый движок при создании картинки «стреляет» из камеры лучами в центр каждого пикселя:
… потом — смотрит, в какую точку на поверхности этот луч попал, и вычисляет в ней цвет.
Вот тут-то — и лежит наш камень преткновения, именуемый алайзингом.
Как ты уже, наверняка, понял, лишь одна эта точка раскрашивает весь пиксель. Хотя на самом деле должна влиять вся область, которую он охватывает.
И в компьютерной графике в принципе нет способа «по-честному» вычислить именно цвет области. Только так: стреляем семпл (англ sample, «проба») в каком-то направлении -> находим, куда он попал -> вычисляем там цвет -> назначаем цвет этого семпла соответствующему пикселю.
В результате — возникает сразу 2 проблемы:
1. Любой семпл в любую поверхность может либо попасть, либо нет. Только 2 варианта. Поверхность не может находиться в пикселе частично.
2. В связи с этим — рендеринговый движок может вообще «не увидеть» поверхность в каком-то пикселе. Просто потому, что соответствующий семпл в неё не попал.
Но даже на этом беды не заканчиваются. Как следствие, вылазит ещё одна проблема: муар.
Это такой неестественный эффект, который вылазит на мелкой-мелкой повторяющейся фактуре:
Своего врага мы теперь знаем в лицо. Осталось разобраться, как с ним бороться.
Super-Sampling (SSAA)
Корень зла — в том, что каждый семпл «видит» цвет лишь в одной точке. И не важно, в центре пикселя мы его «стреляем» или сбоку: попав в одном направлении, он тем самым упускает всё остальное.
Так что самое простое и очевидное решение — «стрелять» по несколько семплов в каждом пикселе, а потом усреднять их цвета. Это и есть суперсемплинг.
Решение, что называется, «в лоб» (брутфорсное), и это палка о двух концах. С одной стороны, брутфорс всегда корректнее, чем всякие имитации. С другой — он и ресурсов требует гораздо больше.
Фактически, если мы стреляем в каждом пикселе по 2, 4, 8 семплов — это всё равно что рендерить картинку в разрешении, которое больше во столько же раз. То есть, и производительность падает пропорционально.
Со временем придумали разные алгоритмы для генерации дополнительных семплов, но они лишь повышали качество картинки, а требовательность к ресурсам оставалась прежней.
Взято с Википедии, там же — плюсы и минусы каждого метода. Если вкратце, то они улучшаются в таком порядке (если говорить только о реалтаймовой графике):
Grid:
Random / Stochastic:
Poisson disc:
Jittered:
Rotated grid:
Так что если ты увидишь в меню варианты вида «SSAA grid» и «SSAA rotated grid» — ты поймёшь, что речь как раз об этом. Grid — это самый первый (самый «дубовый») вариант, все остальные выглядят лучше при том же числе семплов.
Суперсемплинг также называют FSAA (Full-Scene AA), но на мой взгляд это весьма неудачная аббревиатура, т.к. возникают разночтения с FullScreen AA. То есть, с «полноэкранным антиалайзингом» — общим названием вообще всех видов АА как такового.
Ещё помнится, что я встречал в какой-то игре вариант перевода «избыточная выборка» — это тоже SSAA, только глазами надмозгов.
Multi-Sampling (MSAA)
В скором времени появилось развитие технологии суперсемплинга — мультисемплинг (надмозгами также именуемый «множественная выборка»). В отличие от SSAA, MSAA плодит (вернее, учитывает) дополнительные семплы не во всех пикселях, а лишь по мере необходимости. Обычно — только на границах объектов.
Кроме того, в этом алгоритме по-другому реализована генерация семплов: у некоторых пикселей они общие, что позволяет сократить их количество.
А также добавлено хитрое размытие/усреднение в проблемных местах. Так что даже без дополнительных семплов MSAA уже немного «гасит» алайзинг.
Как видно, MSAA немного размывает картинку. И оттого она получается не столь корректной, как при «честном» SSAA. Но он гораздо быстрее по производительности, что позволяет, скажем, вместо SSAAx2 использовать MSAAx4.
CSAA (Coverage Sampling AA)
Разработка от NVIDIA. Это просто слегка усовершенствованный алгоритм MSAA. Делает то же самое, но немного по-другому, а оттого — ощутимо быстрее.
Грубо говоря, 8xCSAA позволяет получить почти такую же картинку, как при 8xMSAA, но при этом видеопамяти требует немногим больше, чем 4xMSAA.
Есть также симметричный алгоритм от AMD — CFAA (Custom-Filter AA).
АА как пост-эффект
MSAA/CSAA показали, что важно не только плодить дополнительные семплы на соседних пикселях с высокой контрастностью, но и просто умело размывать их. Что породило ещё кучу новых видов АА, которые уже и вовсе являются не трёхмерными технологиями, а чисто двухмерными.
Они оперируют с готовым изображением (как фильтр в фотошопе), просто по-разному размывая уже имеющиеся пиксели/семплы. Соответственно, применяются они в самом конце, что позволяет комбинировать их с «честным» SSAA и «условно-честным» MSAA.
Всего их на сегодняшний день понаплодилось —
DLAA — Directionally Localized AntiAliasing
EQAA — Enhanced Quality AntiAliasing
EdgeAA — Edge AntiAliasing
FXAA — Fast approXimate AntiAliasing
GPAA — Geometric Post-process AntiAliasing
GBAA — Geometry Buffer AntiAliasing
MLAA — MorphoLogical AntiAliasing
NFAA — Normal Filter AntiAliasing
SRAA — Subpixel Reconstruction AntiAliasing
SDAA — Second Depth AntiAliasing
SMAA — Subpixel Morphological AntiAliasing
TAA — Transparent AntiAliasing
Я в настоящее время пользуюсь Юнити, так что для сравнения могу показать лишь эти виды:
Сами по себе эти алгоритмы способны лишь устранить явную ступенчатость. Но, например, на длинных объектах тоньше пикселя (провода, верёвки) они ситуацию не спасают.
Впрочем, и использовать их надо не как самостоятельный АА, а лишь как дополнение к более брутфорсным братьям. Которое относительно дёшево позволяет немного повысить качество уже сглаженной картинки.
Кроме того, у всех пост-эффектных режимов сглаживания есть одно колоссальное преимущество: они дружат с deffered освещением. Что это такое — как-нибудь в другой раз, но штука эта в современных играх архи-нужная.
Из всего длиннющего списка пост-эффектных АА хочется выделить несколько:
FXAA (Fast approXimate AA) — самый эффективный метод по соотношению ресурсы/качество. Он весьма удачно справляется со сглаживанием на краях объектов. На верёвках, естественно, не особо помогает (как и все остальные в этом списке). Но он действительно шустрый. Что и позволило ему доминировать на консолях предыдущего поколения.
К сожалению, по природе своей, он не только сглаживает границы, но и слегка размывает текстуры. Однако это с лихвой оправдывается тем, что он практически бесплатен в сравнении с MSAA/CSAA.
MLAA (MorphoLogical AA) — неожиданный «ход конём». В отличие от всех остальных видов антиалайзинга, этот работает не на видюхе, а на проце. Ощутимо медленнее, чем FXAA, зато и картинка гораздо корректнее.
SMAA (Subpixel Morphological AA) — смесь двух предыдущих. По сути своей — усовершенствованный FXAA, но:
а) он также использует алгоритм MLAA;
б) он очень тесно связан с SSAA/MSAA.
Для игрока это означает следующее: этот режим хоть и медленнее FXAA, но быстрее MSAA. Зато текстуры он не блюрит, и вообще по качеству соизмерим скорее со вторым, чем с первым.
Эпичная видео-демонстрация SMAA от СryTek под саундтрек из TRON: Legacy (vimeo)
TXAA (Temporal AA)
Самая убер-новая мега-последняя гипер-крутая технология сглаживания от NVIDIA.
Она комбинирует все существующие алгоритмы антиалайзинга: MSAA, пост-эффектный AA (TAA), а также собственный нвидишный новый фильтр временного (temporal) сглаживания.
До этого момента мы рассматривали неподвижную картинку. Но когда объекты в кадре движутся, они постоянно то попадают под новые семлы (в новые пиксели), то покидают их. В результате — возникает весьма неприятный эффект «дребезжания», который особо заметен при очень медленном движении (доля пикселя за кадр) и очень мелкой фактуре объектов (ширина полигона — примерно пиксель).
По идее, с этим эффектом уже весьма удачно справляется SMAA, но нвидия решила возвести решение этой проблемы в абсолют. Короче, лучше один раз увидеть, чем 100 раз услышать:
В отличие от SMAA, TXAA немного блюрит (размывает) картинку. Зато характерного «дребезжания» нет вообще.
ИЧСХ, во всех демонстрациях TXAA почему-то сравнивают не с другими режимами антиалайзинга, а с его отсутствием. Мне лично кажется, что в паре SMAA-TXAA выиграет первый, но по ютубу оценить трудно, а у самого прогнать синтетические тесты — нет возможности. Так что, как говорится, на вкус и цвет.
Краткие выводы
0. Отсутствие AA — жуть и безобразие.
1. SSAA — самый правильный, но и самый (до безобразия) тормозной алгоритм.
2. MSAA — относительно правильный, и приемлимо тормозной (если нет тех, что дальше).
3. CSAA — по качеству такой же, как MSAA, но значительно быстрее.
4. FXAA — практически бесплатный, но самый «мыльный».
5. MLAA — такой же, как CSAA/MSAA по качеству, но гораздо быстрее по скорости. И, как и FXAA, совместим с современными технологиями (deferred lighting).
6. SMAA — гораздо лучше по качеству, чем FXAA и MLAA, медленнее их по скорости, но по-прежнему быстрее, чем MSAA.
7. TXAA — адская вундервафля, про которую пока мало чего ясно. Соперничает с SMAA, но при этом стремится по скорости к MSAA, а по качеству — к FXAA. Но она единственная полностью устраняет эффект дребезжания (во всяком случае, так заявлено, а на глаз она это делает ничем не лучше, чем SMAA).
Ну и напоследок — срыв покровов.
Все эти режимы сглаживания в будущем могут оказаться попросту не нужны. Разрешения мониторов растут, уже достигли 4K, и при этом некоторые умудряются играть на нескольких мониторах. На всяких retina display — и вовсе невозможно разглядеть отдельный пиксель.
Так что предлагаю тебе сперва провести простой эксперимент:
1. сделать в фотошопе чёрную картинку с пятью-шестью одиночными яркими пикселями разных цветов. Разрешение картинки — как у твоего монитора. Желательно, если ты в ФШ ткнёшь карандашом в случайные места (чтоб сам не знал, где каждый пиксель).
2. Сохраняешь в PNG, открываешь картинку на весь экран через твой просмотровщик (вроде IrfanView).
3. Садишься на том расстоянии от монитора, на котором ты играешь, и ищешь глазами эти цветные пиксели.
Если на поиск у тебя ушло около минуты или больше — поздравляю! Тебе можно вообще класть болт на все эти навороченные антиалайзинги. По той причине, что ты просто не увидишь лесенку в игре, как бы ты ни старался. Грубо говоря, разрешение твоего монитора — больше, чем разрешение твоего глаза (на эту область).
Включай FXAA как почти-бесплатный — и радуйся бескомпромиссному качеству картинки.
Если же ты не из тех счастливчиков с адскими видюхами и гигантскими мониторами, то, по крайней мере, ты теперь знаешь, как подбирать оптимальный режим сглаживания. И чем именно придётся жертвовать в том или ином случае.
Лучшие комментарии
Третья часть в процессе. Это — такой «вынесенный отрывок» из неё.
Но вот тут сказано, что коллектив уже устоявшийся, и им особо никто не нужен. Напрашиваться не вижу смысла.
Хотя тем — много, до пенсии хватит. И, по ходу, я таки нашёл ту аудиторию, которой мои около-профессиональные разглагольствования интересны.
В общем, закончу эту серию — а там посмотрим.
Всегда можно будет сюда снова заглянуть, если что-то забудется. :)
Но волюметрика в принципе:
Правда, даже в таком качестве и даже на «титанах» — скорости пока что далеки от приемлемых.
Если нет, то возможно скоро такой случай будет ;)
Q — означает «Quality». Т.е., алгоритм немного изменён так, что качество чуть выше, скорость чуть ниже. И под этой волшебной буквой может скрываться всё, что угодно. Вопросы к разработчикам.
Так что надо гуглить в каждом конкретном случае, что именно делает Q-модификация.
Отсутствие 2xQ CSAA может быть по двум причинам: либо алгоритм в принципе требует как минимум 4 семпла на пиксель (или кратное им), либо разрабы просто решили, что 2xQ CSAA от просто 2xCSAA практически не отличается, так что незачем путать игрока.
Интересно это как-то связано с той дилеммой из Oblivion? Либо сглаживание, либо HDR
Печально, но факт)) Хотя на старых игрушках я себя просто б-ом чувствую, типа: «Ну вот мы и встретились, Gothic 3, муха-ха-ха...»))
SSAA — это, считай, «повысили разрешение в N раз, потом уменьшили обратно». Т.е., 1024*576 с SSAA 2x2 (4 семпла на пиксель) — это всё равно, что 2048*1152. Т.е., даже медленнее, чем ФуллХД.
Все остальные виды АА — существенно быстрее, чем SSAA.
SMAA — это смесь FXAA и MLAA.
Самая высокое число семплов в АА — 16.
Так что конкретно в твоём примере — вывод очевиден: если не рассматривать «дубовый» SSAA, то 1080p с любым антиалайзингом гарантированно будет быстрее, чем 4K даже без него вообще:
1080p даже с MSAA 16x — это всё равно быстрее, чем 1080p с SSAA 16x.
А 4K = 1080p + SSAA 16x.
А вообще,
А вообще благодарствую. Что к чему не запомнил, но будем надеяться, что в памяти что-то то хоть отложилось)
ЗЫ. Не помню, чтобы в блогах когда-либо меня что-то так забирало, как эта серия постов.
Подозреваю, что на цвет и вкус фломастеры разные. Но я так понял, что самую вкусную картинку дает Full Scene AA + пост-эффектный AA. Что-то вроде MSAA(или CSAA)+SMAA?
Ну и в контексте сравнения NFAA, FXAA, DLAA мне больше всего понравился FXAA, что несколько неожиданно, ибо типо «самый дешевый» о.О
P.S. Серия статей даже заставила меня откопать логин/пароль на SG. =)