• Что можно приготовить из кальмаров: быстро и вкусно

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

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

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

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

    Учитывая объем обрабатываемых данных (а в сцене может быть множество 32-битовых текстур высокого разрешения), анизотропная фильтрация особенно требовательна к пропускной способности памяти. Уменьшить трафик можно в первую очередь за счет компрессии текстур, которая сейчас применяется повсеместно. Ранее, когда она практиковалась не так часто, а пропуская способность видеопамяти была гораздо ниже, анизотропная фильтрация ощутимо снижала количество кадров. На современных же видеокартах она почти не влияет на fps.

    Анизотропная фильтрация имеет лишь одну настройку - коэффициент фильтрации (2x, 4x, 8x, 16x). Чем он выше, тем четче и естественнее выглядят текстуры. Обычно при высоком значении небольшие артефакты заметны лишь на самых удаленных пикселах наклоненных текстур. Значений 4x и 8x, как правило, вполне достаточно для избавления от львиной доли визуальных искажений. Интересно, что при переходе от 8x к 16x снижение производительности будет довольно слабым даже в теории, поскольку дополнительная обработка понадобится лишь для малого числа ранее не фильтрованных пикселов.

    Шейдеры

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

    Шейдеры делятся на три типа: вершинные (Vertex Shader) оперируют координатами, геометрические (Geometry Shader) могут обрабатывать не только отдельные вершины, но и целые геометрические фигуры, состоящие максимум из 6 вершин, пиксельные (Pixel Shader) работают с отдельными пикселами и их параметрами.

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

    Шейдеры очень продуктивно работают в параллельном режиме, и именно поэтому в современных графических адаптерах так много потоковых процессоров, которые тоже называют шейдерами. Например, в GeForce GTX 580 их целых 512 штук.

    Parallax mapping

    Parallax mapping - это модифицированная версия известной техники bumpmapping, используемой для придания текстурам рельефности. Parallax mapping не создает 3D-объектов в обычном понимании этого слова. Например, пол или стена в игровой сцене будут выглядеть шероховатыми, оставаясь на самом деле абсолютно плоскими. Эффект рельефности здесь достигается лишь за счет манипуляций с текстурами.

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

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

    Эффект чаще всего применяется для каменных мостовых, стен, кирпичей и плитки.

    Anti-Aliasing

    До появления DirectX 8 сглаживание в играх осуществлялось методом SuperSampling Anti-Aliasing (SSAA), известным также как Full-Scene Anti-Aliasing (FSAA). Его применение приводило к значительному снижению быстродействия, поэтому с выходом DX8 от него тут же отказались и заменили на Multisample Аnti-Аliasing (MSAA). Несмотря на то что данный способ давал худшие результаты, он был гораздо производительнее своего предшественника. С тех пор появились и более продвинутые алгоритмы, например CSAA.

    Учитывая, что за последние несколько лет быстродействие видеокарт заметно увеличилось, как AMD, так и NVIDIA вновь вернули в свои ускорители поддержку технологии SSAA. Тем не менее использовать ее даже сейчас в современных играх не получится, поскольку количество кадров/с будет очень низким. SSAA окажется эффективной лишь в проектах предыдущих лет, либо в нынешних, но со скромными настройками других графических параметров. AMD реализовала поддержку SSAA только для DX9-игр, а вот в NVIDIA SSAA функционирует также в режимах DX10 и DX11.

    Принцип работы сглаживания очень прост. До вывода кадра на экран определенная информация рассчитывается не в родном разрешении, а увеличенном и кратном двум. Затем результат уменьшают до требуемых размеров, и тогда «лесенка» по краям объекта становится не такой заметной. Чем выше исходное изображение и коэффициент сглаживания (2x, 4x, 8x, 16x, 32x), тем меньше ступенек будет на моделях. MSAA в отличие от FSAA сглаживает лишь края объектов, что значительно экономит ресурсы видеокарты, однако такая техника может оставлять артефакты внутри полигонов.

    Раньше Anti-Aliasing всегда существенно снижал fps в играх, однако теперь влияет на количество кадров незначительно, а иногда и вовсе никак не cказывается.

    Тесселяция

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

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

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

    Чтобы игра могла использовать тесселяцию, ей требуется видеокарта с поддержкой DirectX 11.

    Вертикальная синхронизация

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

    Если частота обновления монитора составляет 60 Гц, и видео-карта успевает просчитывать 3D-сцену как минимум с таким же количеством кадров, то каждое обновление монитора будет отображать новый кадр. Другими словами, с интервалом 16,66 мс пользователь будет видеть полное обновление игровой сцены на экране.

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

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

    Post-processing

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

    High dynamic range (HDR)

    Эффект, часто используемый в игровых сценах с контрастным освещением. Если одна область экрана является очень яркой, а другая, наоборот, затемненной, многие детали в каждой из них теряются, и они выглядят монотонными. HDR добавляет больше градаций в кадр и позволяет детализировать сцену. Для его применения обычно приходится работать с более широким диапазоном оттенков, чем может обеспечить стандартная 24-битовая точность. Предварительные просчеты происходят в повышенной точности (64 или 96 бит), и лишь на финальной стадии изображение подгоняется под 24 бита.

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

    Bloom

    Bloom нередко применяется совместно с HDR, а еще у него есть довольно близкий родственник - Glow, именно поэтому эти три техники часто путают.

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

    Film Grain

    Зернистость - артефакт, возникающий в аналоговом ТВ при плохом сигнале, на старых магнитных видеокассетах или фотографиях (в частности, цифровых изображениях, сделанных при недостаточном освещении). Игроки часто отключают данный эффект, поскольку он в определенной мере портит картинку, а не улучшает ее. Чтобы понять это, можно запустить Mass Effect в каждом из режимов. В некоторых «ужастиках», например Silent Hill, шум на экране, наоборот, добавляет атмосферности.

    Motion Blur

    Motion Blur - эффект смазывания изображения при быстром перемещении камеры. Может быть удачно применен, когда сцене следует придать больше динамики и скорости, поэтому особенно востребован в гоночных играх. В шутерах же использование размытия не всегда воспринимается однозначно. Правильное применение Motion Blur способно добавить кинематографичности в происходящее на экране.

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

    SSAO

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

    Screen Space Ambient Occlusion является модифицированной версией Ambient Occlusion и тоже имитирует непрямое освещение и затенение. Появление SSAO было обусловлено тем, что при современном уровне быстродействия GPU Ambient Occlusion не мог использоваться для просчета сцен в режиме реального времени. За повышенную производительность в SSAO приходится расплачиваться более низким качеством, однако даже его хватает для улучшения реалистичности картинки.

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

    Cel shading

    Игры с эффектом Cel shading начали делать с 2000 г., причем в первую очередь они появились на консолях. На ПК по-настоящему популярной данная техника стала лишь через пару лет, после выхода нашумевшего шутера XIII. С помощью Cel shading каждый кадр практически превращается в рисунок, сделанный от руки, или фрагмент из детского мультика.

    В похожем стиле создают комиксы, поэтому прием часто используют именно в играх, имеющих к ним отношение. Из последних известных релизов можно назвать шутер Borderlands, где Cel shading заметен невооруженным глазом.

    Особенностями технологии является применение ограниченного набора цветов, а также отсутствие плавных градиентов. Название эффекта происходит от слова Cel (Celluloid), т. е. прозрачного материала (пленки), на котором рисуют анимационные фильмы.

    Depth of field

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

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

    Лицезреть эффект глубины резкости в гипертрофированной форме можно на некоторых фотографиях. Именно такую степень размытия часто и пытаются симулировать в 3D-сценах.

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

    Влияние на производительность

    Чтобы выяснить, как включение тех или иных опций сказывается на производительности, мы воспользовались игровым бенчмарком Heaven DX11 Benchmark 2.5. Все тесты проводились на системе Intel Core2 Duo e6300, GeForce GTX460 в разрешении 1280×800 точек (за исключением вертикальной синхронизации, где разрешение составляло 1680×1050).

    Как уже упоминалось, анизо-тропная фильтрация практически не влияет на количество кадров. Разница между отключенной анизотропией и 16x составляет всего лишь 2 кадра, поэтому рекомендуем ее всегда ставить на максимум.

    Сглаживание в Heaven Benchmark снизило fps существеннее, чем мы того ожидали, особенно в самом тяжелом режиме 8x. Тем не менее, поскольку для ощутимого улучшения картинки достаточно и 2x, советуем выбирать именно такой вариант, если на более высоких играть некомфортно.

    Тесселяция в отличие от предыдущих параметров может принимать произвольное значение в каждой отдельной игре. В Heaven Benchmark картинка без нее существенно ухудшается, а на максимальном уровне, наоборот, становится немного нереалистичной. Поэтому следует устанавливать промежуточные значения - moderate или normal.

    Для вертикальной синхронизации было выбрано более высокое разрешение, чтобы fps не ограничивался вертикальной частотой развертки экрана. Как и предполагалось, количество кадров на протяжении почти всего теста при включенной синхронизации держалось четко на отметке 20 или 30 кадров/с. Это связано с тем, что они выводятся одновременно с обновлением экрана, и при частоте развертки 60 Гц это удается сделать не с каждым импульсом, а лишь с каждым вторым (60/2 = 30 кадров/с) или третьим (60/3 = 20 кадров/с). При отключении V-Sync число кадров увеличилось, однако на экране появились характерные артефакты. Тройная буферизация не оказала никакого положительного эффекта на плавность сцены. Возможно, это связано с тем, что в настройках драйвера видеокарты нет опции принудительного отключения буферизации, а обычное деактивирование игнорируется бенчмарком, и он все равно использует эту функцию.

    Если бы Heaven Benchmark был игрой, то на максимальных настройках (1280×800; AA - 8x; AF - 16x; Tessellation Extreme) в нее было бы некомфортно играть, поскольку 24 кадров для этого явно недостаточно. С минимальной потерей качества (1280×800; AA - 2x; AF - 16x, Tessellation Normal) можно добиться более приемлемого показателя в 45 кадров/с.

    • Tutorial

    Привет, хабрапользователь! После небольшого перерыва можно опять браться за трехмерную графику. В этот раз мы поговорим о таком алгоритме глобального затенения, как . Интересно? Под кат!

    Но сначала чуть-чуть новостей

    Я отказался от использования XNA, мощностей DX9 мне стало не хватать: конечно, в целом ничего не поменялось, но написание кода стало куда менее костыльным. Все последующие примеры будут реализованы с помощью фреймворка SharpDX.Toolkit : не пугайтесь, это духовный наследник XNA , еще и OpenSource и с поддержкой DX11 .

    Классически - теории

    Самой важной частью в графическом движке любой игры (которая имеет претензии на реалистичность) - это освещение. Сейчас невозможно полностью смоделировать освещение в игре real-time так, как это происходит в нашем, реальном мире. Условно говоря, не в real-time приложениях: освещение считается “пусканием” фотонов из источника света в нужных направлениях и регистрации этих фотонов камерой (глазом). Для подобных процессов в реальном времени требуется апромиксация, например: у нас есть некоторая поверхность и источник света, и для того что-бы создать освещение – требуется рассчитать “освещенность” каждого пикселя принадлежащей поверхности, т.е. учитывается только прямое влияние источника света на тексель. В данной апромиксации не учитывается непрямое освещение, т.е. в случае с real-time фотон может отразиться от какой-либо поверхности и повлиять на совершено другой “тексель”. Для единичных, небольших источников света это не особо критично, но стоит взять большой источник света и “бесконечно удаленный”, например, солнце (небо выступает как мощный «рассеиватель» света от солнца), то сразу возникают проблемы, примерно такие:

    В реальном же мире, на подобной сцене не было бы такой черной черноты в местах теней. Развивая дальше тему, можно ввести некоторое значение ambient, которое будет отображать общую освещенность всей сцены, своеобразная аппроксимация непрямого освещения. Но дело в том, что подобное освещение на всей сцене везде одинаково, даже в тех местах, где непрямой свет будет оказывать наименьшее влияние. Но и тут можно схитрить и усложнить апромиксацию путем затенения тех участков, куда отраженному свету сложнее всего добраться. Таким образом мы подошли к понятию называемым “глобальное затенение” (ambient occlusion ). Суть такого подхода заключается в том, что мы для каждого фрагменты сцены находим некоторый заграждающий фактор, т.е. кол-во не загражденных направлений падения “фотона” деленное на общее кол-во всевозможных направлений.

    Рассмотрим следующую картинку:

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

    Но теперь нужно подумать, как подобный алгоритм внедрить в пайп-лайн рендера графического конвейера. Сложность возникает в том, что отрисовка геометрии происходит постепенно. В следствии чего, первый объект в сцене не будет знать о существовании других. Можно, конечно, заранее рассчитать AO (на этапе загрузки) для сцены, но в таком случае мы не будем учитывать динамически изменяемую геометрию: физические объекты, персонажей, etc. И тут на помощь приходит работа с геометрией в экранном пространстве (Screen Space). Я его уже , когда рассказывал об SSLR-алгоритме. Этим можно воспользоваться и считать AO в экранном пространстве. Тут появляется самая классическая реализация SSAO, придумали его классные ребята из крайтек ровно 8 лет назад. Их алгоритм заключался в следующем: после рисования всей геометрии у них был в наличии буфер глубины, который несет в себе информацию об всей видимой геометрии, строя сферы для каждого текселя они считали кол-во затенения для сцены:

    Тут, кстати, возникает еще одна сложность. Дело в том, что мы не можем учесть абсолютно все направления в real-time, во первых, потому, что пространство дискретно, а во вторых на производительности можно ставить крест. Мы не можем учесть даже 250 направлений (а именно столько необходимо для минимально-вменяемого качества изображения). Для того, чтобы сократить кол-во выборок – используют некоторое ядро направлений (от 8 до 32), которое вращают каждый раз на случайное значение. После этих операций нам доступен AO в реал-тайме:

    Самое тяжелое в алгоритме SSAO это определение заграждения, ведь это чтение из float-текстуры.
    Чуть позже была придумана модификация алгоритма SSAO: Normal-oriented Hemisphere SSAO . Суть модификации в том, что мы можем увеличить точность алгоритма за счет учета нормалей (по сути нужен GBuffer ). Для пространства выборок мы будем использовать не сферу, а полусферу, которая ориентирована по нормали текущего текселя. Такой подход позволяет увеличить кол-во полезных выборок в двое.

    Если посмотреть на рисунок, то можно понять, о чем я говорю:

    Завершающим этапом алгоритма будет размытие изображения AO для того, чтобы убрать шум, вызванным случайными выборками. В конечном счете – реализация нашего алгоритма будет выглядеть так:

    С теорией пока все ясно, можно перейти к практике.

    Зона, свободная от теории

    Советую прочитать статью, там я рассказывал про суть работы Screen Space пространством. Но, а в практике я приведу особо важные участки кода с нужными комментариями.

    Самое первое , что нам понадобится, это информация о геометрии: GBuffer . Т.к. его построение не входит в тему статьи – о нем подробно расскажу как-нибудь в другой раз.

    Второе - это полусфера со случайными направлениями:

    SamplesKernel = new Vector3; for (int i = 0; i < _samplesKernel.Length; i++) { _samplesKernel[i].X = random.NextFloat(-1f, 1f); _samplesKernel[i].Z = random.NextFloat(-1f, 1f); _samplesKernel[i].Y = random.NextFloat(0f, 1f); _samplesKernel[i].Normalize(); float scale = (float)i / (float)_samplesKernel.Length; scale = MathUtil.Lerp(0.1f, 1.0f, scale * scale); _samplesKernel[i] *= scale; }
    Тут важно отметить, что в шейдере у нас не будет трассировки, т.к. мы сильно ограничены в инструкциях, взамен этому – мы будем считать факт нахождения конечной точки в какой-либо геометрии, поэтому необходимо учитывать больше ближней геометрии, чем дальней. Для этого достаточно взять набор точек с нормальным распределением в полусфере. Это можно получить честным нормальным распределением, можно просто дважды умножить вектор на случайное число от 0 до 1, а можно воспользоваться небольшим хаком: задавать длину какой-либо функцией, например квадратичной. Это нам даст более лучший “сорт” ядра.

    Третье – это набор каких-нибудь случайных векторов, для того, чтобы разнообразить конечные выборки, у меня оно генерируется в случайным образом:

    Color randomNormal = new Color[_randomNormalTexture.Width * _randomNormalTexture.Height]; for (int i = 0; i < randomNormal.Length; i++) { Vector3 tsRandomNormal = new Vector3(random.NextFloat(0f, 1f), 1f, random.NextFloat(0f, 1f)); tsRandomNormal.Normalize(); randomNormal[i] = new Color(tsRandomNormal, 1f); }
    Но выглядит оно примерно так:

    Не стоит использовать подобную текстуру больше чем 4x4-8x8, потому, что подобное вращение ядра дает низкочастотный шум, который размыть в будущем куда проще.

    Теперь поглядим на тело шейдера SSAO:

    Float depth = GetDepth(UV); float3 texelNormal = GetNormal(UV); float3 texelPosition = GetPosition2(UV, depth) + texelNormal * NORMAL_BIAS; float3 random = normalize(RandomTexture.Sample(NoiseSampler, UV * RNTextureSize).xyz); float ssao = 0; for(int i = 0; i < MAX_SAMPLE_COUNT; i++) { float3 hemisphereRandomNormal = reflect(SamplesKernel[i], random); float3 hemisphereNormalOrientated = hemisphereRandomNormal * sign(dot(hemisphereRandomNormal, texelNormal)); ssao += calculateOcclusion(texelPosition, texelNormal, hemisphereNormalOrientated, RADIUS); } return (ssao / MAX_SAMPLE_COUNT);
    Тут мы получаем нелинейную глубину, получаем мировую позицию и нормаль, получаем набор случайных векторов растянутых на весь экран. Стоит сразу заранее сказать про два хака.

    Первый заключается в том, что мы сдвигаем позицию текселя на нормаль умноженную на некоторое маленькое значение, это необходимо для того, чтобы избавится от ненужных пересечений из-за дискретности screen space пространства:

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

    Float depthAssessment_invsqrt(float nonLinearDepth) { return 1 / sqrt(1.0 - nonLinearDepth); }
    Отдельно стоит сказать, что хорошо бы сделать unroll-цикла, т.к. кол-во выборок заранее известно, подобный код будет работать быстрее.

    Float3 hemisphereRandomNormal = reflect(SamplesKernel[i], random); float3 hemisphereNormalOrientated = hemisphereRandomNormal * sign(dot(hemisphereRandomNormal, texelNormal));
    И передаем функции расчета заграждения:

    Float calculateOcclusion(float3 texelPosition, float3 texelNormal, float3 sampleDir, float radius) { float3 position = texelPosition + sampleDir * radius; float3 sampleProjected = GetUV(position); float sampleRealDepth = GetDepth(sampleProjected.xy); float assessProjected = depthAssessment_invsqrt(sampleProjected.z); float assessReaded = depthAssessment_invsqrt(sampleRealDepth); float differnce = (assessReaded - assessProjected); float occlussion = step(differnce, 0); // (x >= y) ? 1: 0 float distanceCheck = min(1.0, radius / abs(assessmentDepth - assessReaded)); return occlussion * distanceCheck; }
    Берем сэмпл и проектируем его в экранное пространство (получаем новые значения UV.xy и нелинейную глубину):

    Float3 position = texelPosition + sampleDir * radius; float3 sampleProjected = GetUV(position);

    Функция проекции выглядит следующим образом:
    float3 _innerGetUV(float3 position, float4x4 VP) { float4 pVP = mul(float4(position, 1.0f), VP); pVP.xy = float2(0.5f, 0.5f) + float2(0.5f, -0.5f) * pVP.xy / pVP.w; return float3(pVP.xy, pVP.z / pVP.w); } float3 GetUV(float3 position) { return _innerGetUV(position, ViewProjection); }
    Константы 0.5f напрашиваются, чтобы их зашили в матричку.

    После этого мы получаем новое значение глубины:
    float assessProjected = depthAssessment_invsqrt(sampleProjected.z); float assessReaded = depthAssessment_invsqrt(sampleRealDepth); float differnce = (assessReaded - assessProjected); float occlussion = step(differnce, 0); // (x >= y) ? 1: 0
    Факт заграждения мы определяем как: “видна ли точка наблюдателю”, т.е. если точка не лежит в какой-либо геометрии – то assessReaded будет всегда строго меньше assessProjected .

    Ну и с учетом того, что в экранном пространстве полно такого явления как information lost, мы должны регулировать кол-во затенения в зависимости от дистанции “проникновения” в геометрию. Это необходимо для того, что мы ничего не знаем о геометрии за видимой частью экранного пространства:

    Float distanceCheck = min(1.0, radius / abs(differnce));
    Ну и финальный этап, это размытие. Я лишь скажу то, что нельзя размывать буффер SSAO без учета неоднородности глубины как это делают многие. Так же, хорошо бы учесть и нормали при размытии, примерно так:

    If(DepthAnalysis) { float lDepthR = LinearizeDepth(GetDepth(UVR)); float lDepthL = LinearizeDepth(GetDepth(UVL)); depthFactorR = saturate(1.0f / (abs(lDepthR - lDepthC) / DepthAnalysisFactor)); depthFactorL = saturate(1.0f / (abs(lDepthL - lDepthC) / DepthAnalysisFactor)); } if(NormalAnalysis) { float3 normalR = GetNormal(UVR); float3 normalL = GetNormal(UVL); normalFactorL = saturate(max(0.0f, dot(normalC, normalL))); normalFactorR = saturate(max(0.0f, dot(normalC, normalR))); }
    Коэффициенты depthFactor и normalFactor учитываются в коэффициентах размытия.

    Взамен заключения

    Для более подробного изучения – я оставлю полный исходный код

    Но, так как мы будем использовать view space нам нужно будет восстанавливать положение точки во view space по глубине. О том, как это сделать смотрите в последнем разделе «Ништяки». Пока, пускай у нас будут четыре функции в шейдере:

    float restoreViewSpaceDistance(in float depth) vec3 restoreViewSpacePosition(in vec2 texCoords, in float depth) float projectViewSpaceDistance(in float z) vec3 projectViewSpacePosition(in vec3 viewSpace)

    Также, для того, чтобы придать разнообразия нашему расчету AO, нам понадобится текстура с шумом. Самая обычная текстура с шумом, я даже показывать её здесь не буду. В дополнение к этой текстуре нам специально для неё нужны будут текстурные координаты. Такие, чтобы текстура рисовалась на экране в пиксель. По большому счету, это не обязательно, но очень желательно, чтобы выборки были «более случайными».

    Итого, на входе во фрагментный шейдер у нас есть три текстуры и два набора текстурных координат.

    Надо заметить, что в моем движке для того, чтобы поддерживались разные версии шейдеров, сделаны следующие штуки:
    Входящая переменная во фрагментный шейдер - etFragmentIn . В старых шейдерах заменяется на varying , в новых на in .
    Результат фрагментного шейдера записывается в переменную etFragmentOut (gl_FragColor в старых шейдерах и "out vec4 ... " + glBindFragDataLocation в новых версиях).

    Итого, кусочек шейдера у нас уже есть:

    uniform sampler2D texture_diffuse; uniform sampler2D texture_normal; uniform sampler2D texture_depth; uniform sampler2D texture_noise; etFragmentIn vec2 TexCoord; etFragmentIn vec2 NoiseTexCoord;

    Теперь можно приступить непосредственно к расчету нашего затенения.

    3. Расчет SSAO

    Общая идея такова: в данной точке получить положение и нормаль, затем сгенерировать несколько случайных направлений на полусфере, заданой нормалью, и проверить затенения в них. Результат собрать и поделить на количество выборок. Таким образом мы хотим контролировать как минимум три параметрa:
    1) количество выборок;
    2) минимальное расстояние, на котором мы проверяем затенение (оно нужно нам, чтобы избавиться от некоторых неприятных артефактов);
    3) максимальное расстояние, на котором мы проверяем затенение;

    Вот пару картинок для сравнения параметров: количество выборок - чем больше, тем более плавное и красивое затенение у нас получается:

    Максимальное расстояние - чем оно больше, тем «шире» и мягче у нас затенение:

    Для тестовой сцены (Crytek Sponza) я использовал такие параметры:

    #define NUM_SAMPLES 64 #define MIN_SAMPLE_SIZE 1 .0 #define SAMPLE_SIZE 32 .0

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

    Итак, у нас все есть для того, чтобы рассчитать затенение каждой точки на экране. Для начала нам нужно найти нормаль в этой точке и её положение (не забывайте, что мы работает во view space). Делается это просто чтением нормали из текстуры и восстановлением положения по глубине:

    void main() { vec4 noiseSample = etTexture2D(texture_noise, NoiseTexCoord) ; vec3 normalSample = decodeNormal(etTexture2D(texture_normal, TexCoord) .xy) ; float depthSample = 2 .0 * etTexture2D(texture_depth, TexCoord) .x - 1 .0 ; vec3 viewSpacePosition = restoreViewSpacePosition(2 .0 * TexCoord - 1 .0 , depthSample) ; ...

    Функция etTexture2D - это тоже магия моего движка. Для старых версий GLSL она превращается в texture2D, для новых в texture.

    Теперь, чтобы не городить все в теле функции main(), заведем специальную функцию, которая рассчитывает затенение в данной точке. Я пафосно назвал её performRaytracingInViewSpace:

    float performRaytracingInViewSpace(in vec3 vp, in vec3 vn, in vec4 noise)

    Недавно игра Rise of the Tomb Raider получила обновление, которое добавило поддержку нового затенения по технологии NVIDIA VXAO и поддержку DirectX 12. Мы рассмотрим особенности VXAO, сравним качество этого затенения с другими режимами и проведем сравнительное тестирование, чтобы выявить ресурсоемкость каждого метода Ambient Occlusion.

    В отдельной статье уже рассмотрены особенности работы HBAO+ в Rise of the Tomb Raider. По итогам сравнения хорошо видно, что это затенение позволяет лучше выделить отдельные детали окружения и неровности рельефа. VXAO является еще более качественным вариантом. Этот метод Ambient Occlusion (AO) позволяет реализовать еще более точное затенение с учетом освещенности и влияния объектов друг на друга. VXAO является частью технологии объемного освещения VXGI (Voxel Global Illumination), которая корректно учитывает прямой и отраженной свет. В VXGI сцена разбивается на вексельную сетку, а потом осуществляется трассировка сцены с учетом разных параметров для каждого сегмента. Кроме корректного моделирования освещенности каждого участка при таком методе получается более точное затенение Ambient Occlusion. Наглядный пример ниже.

    С обычным SSAO имеют место некорректные тени вокруг астронавта и прямо под корпусом посадочного модуля. Эти ореолы помогают оттенить объекты на общем фоне. Но объекты удалены от поверхности, таких теней не может быть. С воксельным AO их и нет, есть тени под опорами, которые стоят на земле. При этом точнее ложатся тени на мелкие элементы корпуса, лучше их выделяя.

    Чтобы в полной мере оценить преимущества нового алгоритма затенения NVIDIA мы проведем несколько полных сравнений в разных режимах, и отдельно сконцентрируемся на сравнении HBAO+ и VXAO.

    За основу взята конфигурация настроек максимального качества графики. По умолчанию этот профиль нам предлагает режим HBAO+, но мы вначале отключим это затенение, а потом будем поэтапно включать разные варианты AO (параметр «преграждение окружающего света»).

    При включении SSAO мы видим, как однотонные тени на снегу становятся сложнее. Усиливаются темные зоны под краном и в месте стыка каменных глыб.

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

    VXAO продолжает отмеченную тенденцию. Тень под краном еще интенсивнее, немного возрастает интенсивность теней в районе деревьев справа. Темнее зона прямо под героиней.

    Посмотрим на другой пример.

    SSAO создает дополнительные полутени в расщелинах скалы на заднем плане, появляется тень от растительности на переднем плане. HBAO+ усиливает выделение неровней на поверхности скалы. Появляется тень на поваленном дереве слева и тень в нижней части дерева справа. Усиливаются тени от растительности. В итоге все объекты на переднем плане приобретают дополнительный объем. VXAO уже глобально не меняет ситуацию. Разница с HBAO+ видна только по тени у обрыва в нижней правой части кадра. Также обратите внимание на зеленую зону под поваленным деревом, с VXAO ее неровности выделяются чуть лучше.

    Пример другой сцены показывает кардинальную разницу между режимом без AO и с SSAO. На втором скриншоте темнеют слабо освещенные зоны пещеры по бокам, появляются легкие тени вокруг камней. С HBAO+ выделение этих камней еще лучше, тени даже помогают выделить отдельные элементы этих камней. Усиливаются темные зоны за опорами слева, что лучше выделяет эти элементы. Нечто подобное заметно на поверхности пещеры справа.

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

    По итогам сравнения скриншотов в трех сценах мы видим, что VXAO дает картинку близкую к HBAO+. Можно отметить дополнительное усиление некоторых теней в слабоосвещенных зонах. Еще один такой пример ниже.

    На поверхность скалы за выступом слева попадает меньше света. С VXAO эта зона темнее в сравнении с HBAO+. И наиболее интенсивное затенение между расщелинами и кустами.

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

    В пещере один источник освещения - солнечные лучи пробиваются сквозь щель в потолке, частично освещая помещение. Обратите внимание на правую зону обоих скриншотов. С HBAO+ есть слабый желтоватый оттенок на колонне, хотя она вне освещаемой зоны. С VXAO вся зона все конуса света чуть темнее и холоднее. Еще лучше видна разница по сравнению тел в лучах света. С HBAO+ они все ярко освещены, как и камни вокруг. VXAO погружает обратную сторону камней в тень, ведь лучи на них падают с другой стороны, и нам видна именно темная сторона. Тело на копье становится неравномерно освещенным, вверху светлее, внизу темнее. Другой объем для сравнения - ближний скелет, который прислонен к цилиндрическому куску обрушившейся конструкции. Этот элемент должен укрывать скелет от света, но с HBAO+ он слегка освещен и имеет характерный желтоватый оттенок. VXAO усиливает затенение скелета. Возле этого скелета частично освещенная грань какой-то опоры у стены, которая тоже повернута к нам и закрыта от прямого света. Она не может быть такой яркой, и VXAO тоже это исправляет.

    В итоге видно, что VXAO не просто усиливает тени и расширяет затененную зону, а корректнее воссоздает реальную картину затенения с учетом направления лучей света.

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

    Между SSAO и HBAO+ нет кардинальной разницы в этой сцене. Второй вариант усиливает затенение дальнего угла и зоны справа от шкафчика. Меняется освещенность боковых граней досок слева. VXAO же резко меняет все изображение. Яркие пятна света на полу и куртке героини становятся ярче. Ярче изображение между щелями досок, оно превращается в яркое световое пятно. При этом дальний угол помещения и тени на том же шкафчике еще темнее.

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

    В качестве дополнительного наглядного материала вы можете посмотреть аналогичное сравнение режимов AO в видеоформате.

    После визуального сравнения проведем тестирование производительности в разных режимах.

    Тестовый стенд

    • процессор: Intel Core i7-3930K @4,4 ГГц
    • материнская плата: ASUS Rampage IV Formula
    • видеокарта: GeForce GTX 980 Ti
    • память: Kingston KHX2133C11D3K4/16GX, 1866 МГц, 4x4 ГБ
    • жесткий диск: Hitachi HDS721010CLA332, 1 TБ
    • блок питания: Seasonic SS-750KM
    • операционная система: Windows 7 Ultimate SP1 x64
    • драйвер GeForce: NVIDIA GeForce 364.51

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

    Изначально выбран профиль качества «Очень высокого», менялись только режимы AO. Сглаживание FXAA, разрешение 1920x1080, DirectX 11.

    SSAO и HBAO слабо сказываются на общей производительности, снижая частоту кадров лишь на несколько процентов. При этом между двумя режимами можно провести знак примерного равенства, с HBAO+ на топовой видеокарте NVIDIA минимальный fps даже чуть лучше. Это немного отличается от старых результатов , где производительность SSAO на GeForce GTX 980 Ti все же была чуть выше. Это говорит о лучшей оптимизации в новом видеодрайвере, и о том, что программисты NVIDIA постоянно работают над улучшением быстродействия своих продуктов.

    VXAO уже дается с заметными потерями производительности. Разница с HBAO+ на уровне 22-26%.

    Выводы

    По итогам знакомства с NVIDIA VXAO в Rise of the Tomb Raider можно констатировать, что это самый прогрессивный алгоритм Ambient Occlusion. VXAO добавляет дополнительные тени и меняет картину затенения в соответствии с реальной освещенностью объектов. Это позволяет лучше выделить некоторые детали окружения и воссоздать ощущение направленного света. Но конечный эффект зависит от освещения в сцене, поэтому не всегда VXAO даст картинку кардинально отличающуюся от HBAO+. Особенно впечатляет, что VXAO улучшает восприятие света в сценах с резкими перепадами освещенности. Слепящий яркий свет, контрастирующий с темным окружением, выглядит более достоверно, лучше отражая особенности восприятия таких сцен человеческим глазом. То есть влияние VXAO более глобально, оно не ограничивается одной лишь проработкой теней. К сожалению, этот метод AO серьезно сказывается на производительности. Если вы обладатель топовой видеокарты, то смело включайте VXAO. Владельцы более простых графических карт могут ограничиться HBAO+, который лучше обычного SSAO при том же уровне ресурсоемкости. В итоге обе технологии NVIDIA GameWorks позволяют улучшить изображение и расширить визуальные впечатления от Rise of the Tomb Raider, а выбор метода AO определяется мощностью вашей видеокарты.

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

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

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

    Триленейная

    Анизатропная

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

    Учитывая объем обрабатываемых данных (а в сцене может быть множество 32-битовых текстур высокого разрешения), анизотропная фильтрация особенно требовательна к пропускной способности памяти. Уменьшить трафик можно в первую очередь за счет компрессии текстур, которая сейчас применяется повсеместно. Ранее, когда она практиковалась не так часто, а пропуская способность видеопамяти была гораздо ниже, анизотропная фильтрация ощутимо снижала количество кадров. На современных же видеокартах она почти не влияет на fps.

    Анизотропная фильтрация имеет лишь одну настройку – коэффициент фильтрации (2x, 4x, 8x, 16x). Чем он выше, тем четче и естественнее выглядят текстуры. Обычно при высоком значении небольшие артефакты заметны лишь на самых удаленных пикселах наклоненных текстур. Значений 4x и 8x, как правило, вполне достаточно для избавления от львиной доли визуальных искажений. Интересно, что при переходе от 8x к 16x снижение производительности будет довольно слабым даже в теории, поскольку дополнительная обработка понадобится лишь для малого числа ранее не фильтрованных пикселов.

    Шейдеры

    Шейдеры – это небольшие программы, которые могут производить определенные манипуляции с 3D-сценой, например, изменять освещенность, накладывать текстуру, добавлять постобработку и другие эффекты.

    Шейдеры делятся на три типа: вершинные (Vertex Shader) оперируют координатами, геометрические (Geometry Shader) могут обрабатывать не только отдельные вершины, но и целые геометрические фигуры, состоящие максимум из 6 вершин, пиксельные (Pixel Shader) работают с отдельными пикселами и их параметрами.

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

    Шейдеры очень продуктивно работают в параллельном режиме, и именно поэтому в современных графических адаптерах так много потоковых процессоров, которые тоже называют шейдерами. Например, в GeForce GTX 580 их целых 512 штук.

    Parallax mapping

    Parallax mapping – это модифицированная версия известной техники bumpmapping, используемой для придания текстурам рельефности. Parallax mapping не создает 3D-объектов в обычном понимании этого слова. Например, пол или стена в игровой сцене будут выглядеть шероховатыми, оставаясь на самом деле абсолютно плоскими. Эффект рельефности здесь достигается лишь за счет манипуляций с текстурами.

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

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

    Эффект чаще всего применяется для каменных мостовых, стен, кирпичей и плитки.

    Anti-Aliasing

    До появления DirectX 8 сглаживание в играх осуществлялось методом SuperSampling Anti-Aliasing (SSAA), известным также как Full-Scene Anti-Aliasing (FSAA). Его применение приводило к значительному снижению быстродействия, поэтому с выходом DX8 от него тут же отказались и заменили на Multisample Аnti-Аliasing (MSAA). Несмотря на то что данный способ давал худшие результаты, он был гораздо производительнее своего предшественника. С тех пор появились и более продвинутые алгоритмы, например CSAA.

    AA выключено

    AA включено

    Учитывая, что за последние несколько лет быстродействие видеокарт заметно увеличилось, как AMD, так и NVIDIA вновь вернули в свои ускорители поддержку технологии SSAA. Тем не менее использовать ее даже сейчас в современных играх не получится, поскольку количество кадров/с будет очень низким. SSAA окажется эффективной лишь в проектах предыдущих лет, либо в нынешних, но со скромными настройками других графических параметров. AMD реализовала поддержку SSAA только для DX9-игр, а вот в NVIDIA SSAA функционирует также в режимах DX10 и DX11.

    Принцип работы сглаживания очень прост. До вывода кадра на экран определенная информация рассчитывается не в родном разрешении, а увеличенном и кратном двум. Затем результат уменьшают до требуемых размеров, и тогда «лесенка» по краям объекта становится не такой заметной. Чем выше исходное изображение и коэффициент сглаживания (2x, 4x, 8x, 16x, 32x), тем меньше ступенек будет на моделях. MSAA в отличие от FSAA сглаживает лишь края объектов, что значительно экономит ресурсы видеокарты, однако такая техника может оставлять артефакты внутри полигонов.

    Раньше Anti-Aliasing всегда существенно снижал fps в играх, однако теперь влияет на количество кадров незначительно, а иногда и вовсе никак не cказывается.

    Тесселяция

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

    Выключена

    Включена

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

    Технология тесселяции известна в кинематографе еще с 80-х го­дов, однако в играх она стала поддерживаться лишь недавно, а точнее после того, как графические ускорители наконец достигли необходимого уровня производительности, при котором она может выполняться в режиме реального времени.

    Чтобы игра могла использовать тесселяцию, ей требуется видеокарта с поддержкой DirectX 11.

    Вертикальная синхронизация

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

    Если частота обновления монитора составляет 60 Гц, и видео­карта успевает просчитывать 3D-сцену как минимум с таким же количеством кадров, то каждое обновление монитора будет отображать новый кадр. Другими словами, с интервалом 16,66 мс пользователь будет видеть полное обновление игровой сцены на экране.

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

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

    Post-processing

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

    High dynamic range (HDR)

    Эффект, часто используемый в игровых сценах с контрастным освещением. Если одна область экрана является очень яркой, а другая, наоборот, затемненной, многие детали в каждой из них теряются, и они выглядят монотонными. HDR добавляет больше градаций в кадр и позволяет детализировать сцену. Для его применения обычно приходится работать с более широким диапазоном оттенков, чем может обеспечить стандартная 24-битовая точность. Предварительные просчеты происходят в повышенной точности (64 или 96 бит), и лишь на финальной стадии изображение подгоняется под 24 бита.

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

    Bloom

    Bloom нередко применяется совместно с HDR, а еще у него есть довольно близкий родственник – Glow, именно поэтому эти три техники часто путают

    .

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

    Film Grain

    Зернистость – артефакт, возникающий в аналоговом ТВ при плохом сигнале, на старых магнитных видеокассетах или фотографиях (в частности, цифровых изображениях, сделанных при недостаточном освещении). Игроки часто отключают данный эффект, поскольку он в определенной мере портит картинку, а не улучшает ее. Чтобы понять это, можно запустить Mass Effect в каждом из режимов. В некоторых «ужастиках», например Silent Hill, шум на экране, наоборот, добавляет атмосферности.

    Motion Blur

    Motion Blur – эффект смазывания изображения при быстром перемещении камеры. Может быть удачно применен, когда сцене следует придать больше динамики и скорости, поэтому особенно востребован в гоночных играх. В шутерах же использование размытия не всегда воспринимается однозначно. Правильное применение Motion Blur способно добавить кинематографичности в происходящее на экране.

    Выключен

    Включен

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

    SSAO

    Ambient occlusion – техника, применяемая для придания сцене фотореалистичности за счет создания более правдоподобного освещения находящихся в ней объектов, при котором учитывается наличие поблизости других предметов со своими характеристиками поглощения и отражения света.

    Screen Space Ambient Occlusion является модифицированной версией Ambient Occlusion и тоже имитирует непрямое освещение и затенение. Появление SSAO было обусловлено тем, что при современном уровне быстродействия GPU Ambient Occlusion не мог использоваться для просчета сцен в режиме реального времени. За повышенную производительность в SSAO приходится расплачиваться более низким качеством, однако даже его хватает для улучшения реалистичности картинки.

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

    Cel shading

    Игры с эффектом Cel shading начали делать с 2000 г., причем в первую очередь они появились на консолях. На ПК по-настоящему популярной данная техника стала лишь через пару лет, после выхода нашумевшего шутера XIII. С помощью Cel shading каждый кадр практически превращается в рисунок, сделанный от руки, или фрагмент из детского мультика.

    В похожем стиле создают комиксы, поэтому прием часто используют именно в играх, имеющих к ним отношение. Из последних известных релизов можно назвать шутер Borderlands, где Cel shading заметен невооруженным глазом.

    Особенностями технологии является применение ограниченного набора цветов, а также отсутствие плавных градиентов. Название эффекта происходит от слова Cel (Celluloid), т. е. прозрачного материала (пленки), на котором рисуют анимационные фильмы.

    Depth of field

    Глубина резкости – это расстояние между ближней и дальней границей пространства, в пределах которого все объекты будут в фокусе, в то время как остальная сцена окажется размытой.

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

    Лицезреть эффект глубины резкости в гипертрофированной форме можно на некоторых фотографиях. Именно такую степень размытия часто и пытаются симулировать в 3D-сценах.

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

    Влияние на производительность

    Чтобы выяснить, как включение тех или иных опций сказывается на производительности, мы воспользовались игровым бенчмарком Heaven DX11 Benchmark 2.5. Все тесты проводились на системе Intel Core2 Duo e6300, GeForce GTX460 в разрешении 1280×800 точек (за исключением вертикальной синхронизации, где разрешение составляло 1680×1050).

    Как уже упоминалось, анизо­тропная фильтрация практически не влияет на количество кадров. Разница между отключенной анизотропией и 16x составляет всего лишь 2 кадра, поэтому рекомендуем ее всегда ставить на максимум.

    Сглаживание в Heaven Benchmark снизило fps существеннее, чем мы того ожидали, особенно в самом тяжелом режиме 8x. Тем не менее, поскольку для ощутимого улучшения картинки достаточно и 2x, советуем выбирать именно такой вариант, если на более высоких играть некомфортно.

    Тесселяция в отличие от предыдущих параметров может принимать произвольное значение в каждой отдельной игре. В Heaven Benchmark картинка без нее существенно ухудшается, а на максимальном уровне, наоборот, становится немного нереалистичной. Поэтому следует устанавливать промежуточные значения – moderate или normal.

    Для вертикальной синхронизации было выбрано более высокое разрешение, чтобы fps не ограничивался вертикальной частотой развертки экрана. Как и предполагалось, количество кадров на протяжении почти всего теста при включенной синхронизации держалось четко на отметке 20 или 30 кадров/с. Это связано с тем, что они выводятся одновременно с обновлением экрана, и при частоте развертки 60 Гц это удается сделать не с каждым импульсом, а лишь с каждым вторым (60/2 = 30 кадров/с) или третьим (60/3 = 20 кадров/с). При отключении V-Sync число кадров увеличилось, однако на экране появились характерные артефакты. Тройная буферизация не оказала никакого положительного эффекта на плавность сцены. Возможно, это связано с тем, что в настройках драйвера видеокарты нет опции принудительного отключения буферизации, а обычное деактивирование игнорируется бенчмарком, и он все равно использует эту функцию.

    Если бы Heaven Benchmark был игрой, то на максимальных настройках (1280×800; AA – 8x; AF – 16x; Tessellation Extreme) в нее было бы некомфортно играть, поскольку 24 кадров для этого явно недостаточно. С минимальной потерей качества (1280×800; AA – 2x; AF – 16x, Tessellation Normal) можно добиться более приемлемого показателя в 45 кадров/с.

    Надеюсь данная статья не только позволит вам лучше оптимизировать игру под свой компьютер, но и расширит ваш кругозор. Совсем скоро появится статья о реальном влиянии количества FPS на восприятие игры.