Что такое Ambient Occlusion (AO).

Стоит только начать обсуждение новой игры для ПК, как неотвратимо всплывет слово «оптимизация». Deus Ex: Mankind Divided? «Похоже, что эту игру ВООБЩЕ не оптимизировали», - пишет кто-то из игроков в Steam. Metro: Last Light? «Если коротко, то оптимизация выполнена ужасно», - пишет другой.

Жалобы на плохую оптимизацию, как правило, идут бок о бок с фразами наподобие «у меня эта игра тормозит». Но связана ли производительность с ошибками программистов, которые не смогли эффективно написать код? Как понять, игра на самом деле плохо оптимизирована или для нее просто не хватает мощности вашего ПК?

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

Что такое оптимизация, и чем её измерить?

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

Вот простой пример. Допустим, вам необходимо вычислить следующее:

a = b*c + b*c + b*c

Если вместо этого мы определим:

d = b*c, и запишем a = d + d + d

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

Так как же нам рассуждать об оптимизации, сохранив хоть какую-то объективность? Вот какое определение дали мне в QLOC:

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

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

Дин Секулич из Croteam оптимизирует игры уже 20 лет и уверен, что «с одной стороны, невозможно сравнить, насколько оптимизированы разные игры», но с другой? всегда можно составить мнение, визуально оценив качество двух разных игр и уровень производительности, который ими достигнут. Однако он также отмечает, что «есть много всего скрытого от глаз», влияющего на поведение игры.

Что же это? Понимание того, что такое оптимизация и что на неё влияет, подразумевает получение ответа на этот вопрос. Мы начнем с оценки того, как на производительность могут влиять те визуальные эффекты, которые дают наибольшую нагрузку на современные аппаратные средства.

Современные эффекты и производительность

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

Качество изображения

Возможно, самый простой параметр, который заметно влияет на производительность и позволяет сравнивать уровень оптимизации, это разрешение экрана . Вполне естественно сравнивать игры на одинаковом разрешении, поскольку этот параметр состоит всего из двух чисел (к примеру, 1920×1080) и доступен для настройки практически в каждой игре. Важный факт, который часто упускается из виду: с изменением разрешения меняется количество выводимых пикселей - 4k дает нагрузку примерно в четыре, а не в два раза больше, чем 2k.

Сглаживание - это намного более сложная тема, когда дело касается сравнений. В современных играх вы можете встретить любую из этих настроек:

  • Чистые методы работы с экранным пространством, такие как FXAA или SMAA (1x). Работают с уже сгенерированным изображением. На этапе постобработки производится попытка выявить и устранить артефакты визуализации, к примеру, «лесенки».
  • Методы временного сглаживания. Делают движения более плавными, генерируя изображение с наложением предыдущего кадра и выводят промежуточный результат.
  • Множественная выборка сглаживания или мультисэмплинг (MSAA). На разных этапах визуализации пиксели на гранях полигонов генерируются на основе нескольких предварительных виртуальных моделей.
  • Избыточная выборка сглаживания или суперсэмплинг. На разных этапах визуализации все пиксели генерируются на основе нескольких предварительных виртуальных моделей.
  • Комбинации из вышеописанных методов (к примеру, TXAA)

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

Освещение и тени

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

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

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

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

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

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

Прочие визуальные эффекты

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


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

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

Особенности оптимизации

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

Стандартные настройки и системные требования

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

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

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

Игрокам не всегда до конца известно, каким образом определяются системные требования. В то время как

каждый разработчик использует собственные стандарты, в Croteam «минимальные» требования означают, что игра должна хорошо работать на низких настройках, и если эти требования не соблюдены, техническая поддержка не предоставляется. «Рекомендуемые» же системные требования подразумевают, что игра должна хорошо работать («не на средних, а на высоких», как сказал мне Дин) c разрешением 1080p.

Как оценивать оптимизацию игры

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

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

Поднялся громкий вой на Dying Light, как на «ужасно не оптимизированный порт на ПК» из-за того, что она не соответствовала (произвольно выбранным) стандартам на максимальных настройках графики. Как выяснилось, ползунок настройки дальности прорисовки, установленный на минимум, в первоначальной версии игры определял более высокую дальность прорисовки, чем на консоли. В сущности, люди были недовольны тем, что разработчик подразумевал, что в ранних патчах игрокам придется устанавливать ползунок дальности прорисовки на 55% от максимального значения.

Выглядела бы игра более «оптимизированной», если бы этот простой шаг был сделан до релиза? Я в этом уверен. При этом была бы она на самом деле «лучше оптимизирована»? Разумеется, нет. Dying Light – не только хороший пример того, как сложно оценить качество оптимизации, но и того, что должны учитывать разработчики при определении доступных настроек графики.

Похожая история недавно произошла с Deus Ex: Mankind Divided, в которой важное значение имеет настройка MSAA (до 8x). Поскольку в игре используется отложенное освещение и затенение – универсальная техника визуализации, которая делает намного менее эффективной простую реализацию MSAA с аппаратным ускорением - MSAA давала большую нагрузку на производительность, которой от нее никто не ожидал. И снова, игра выглядела бы более «оптимизированной» в том случае, если бы не предоставляла такую настройку, при чем, опять же, проблема с оптимизацией совсем не в этом.

Игра редко представляет из себя монолитную сущность, которая либо оптимизирована, либо нет. Не оптимизированы могут быть отдельные эффекты, в отличие от игры в целом. Это особенно распространено при использовании нововведений: когда в оригинальной Crysis впервые было использовано рассеянное затенение, оно было плохо оптимизировано по сравнению с современными реализациями. Кроме того, первая реализация воксельного рассеянного затенения в Rise of the Tomb Raider – в целом хорошо оптимизированной и красивой игры – может оказаться хуже грядущих реализаций.

Metro 2033 стала одной из первых игр, где были широко использованы объемные лучи, и позиционировалась она как духовный приемник Crysis в том, что касается производительности на высоких настройках. Это же актуально и для недавнего и последующего использования теней с контактным уплотнением. Тем не менее, я считаю, что необходимо экспериментировать с внедрением новых возможностей, несмотря на то, что первые реализации не всегда можно использовать из-за их нагрузки на производительность. Благодаря этому процесс развития игровой разработки не стоит на месте, и появляются хорошо оптимизированные визуальные эффекты. Прелесть платформы ПК заключается в том, что эффект, который был «не оптимизирован» в 2010 году, может быть использован по максимуму в 2016-м, и игра будет выглядеть лучше даже на средней аппаратной конфигурации.

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

Трудности оптимизации

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

Когда верхняя функция занимает 3% времени, это означает, что если вам удастся вдвое сократить время ее выполнения - для чего могут потребоваться титанические усилия - в целом программа ускорится на 1,5%. Из-за того, что подобные ситуации возникают постоянно, оптимизация готового кода превращается в поэтапный и трудоемкий процесс.

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

Таким образом, как говорит Дин, в оптимизации программы «не бывает простых и очевидных решений».
К вопросу о DirectX 12: Низкоуровневые интерфейсы вроде DirectX 12 иногда становятся простым ответом на споры об оптимизации, однако множество игр с DirectX 12 так и не показали значительных результатов в производительности.

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

Дин Секулич уверен, что «парадигму движков визуализации пора менять», но при этом видит огромный потенциал для Vulkan в будущем. Он дает наполовину шуточный совет разработчикам: «Если вы используете Vulkan, добавляйте на экран побольше объектов», подразумевая, что в будущем могут возникнуть ситуации, которые невозможно качественно воспроизвести, используя возможности современных интерфейсов.

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

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

Подводя итог

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

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

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

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

Одной из ведущих отраслей компьютерной индустрии является «изготовление» игр. Специально для игр разрабатываются особые материнские платы, видеокарты, чипсеты. Но, как всем известно, главное требование любой современной игры – мощная видеокарта. Правда видеокарта является и самой дорогостоящей деталью персонального компьютера. Поэтому не все могут позволить менять видуокарту как перчатки, а значит вопрос о том, как настроить графику в играх – всегда актуален!

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

Если вы уже пытались разобраться в установках игры, то, вероятно, поняли максимум половину из написанного. Допустим анизотропная фильтрация. Анизотропная фильтрация очень хороша при генерации сильно наклонённых относительно камеры объектах. Она оставляет текстуру равнозначно чёткой, а не частично размытой. Обойдёмся без заумных слов, объясню всё просто и понятно. Когда текстура рисунка воспроизводится на экране, то отображается либо уменьшенной, либо увеличенной. Уменьшением-увеличением и занимается анизотропная фильтрация. Иными словами она убирает «лиш¬ние» пикселы или, наоборот, при необходимости вставляет дополнительные. Ещё этот вид фильтрации лишен генерации большинства артефактов.

У Анизотропной фильтрации всего одна настройка – это коэффициент фильтрации. Возможные значения этого коэффициента могут принимать такие значения: 2x, 4x, 8x и 16x. Текстуры выгля¬дят четче и естественнее при более высоком значении. Для получения нормальной картинки достаточно 4x или 8x. Даже, если вы поставите 8x или 16x, особо на быстродействие это не скажется.

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

Parallax mapping симулирует рельефность текстур. Он ничего не создаёт, а только манипулирует текстурами. Например, ваш персонаж может «вставить» ногу в камень.
Эффект работает удачно только когда высота предмета меняется плавно, иначе у картинки появляются изъяны. Parallax mapping существенно экономит вычислительные ресур¬сы компьютера.

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

Ещё одно отличие от Parallax mapping в том, что тесселяция значительно загружает компьютер и работает только с DirectX 11.

Теперь об эффекте, убирающем лесенку на краях предметов – сглаживании (Anti-Aliasing). Есть несколько видов сглаживания разной эффективности и «тяжести» для видеокарты: FSAA, MSAA, CSAA, SSAA. CSAA уже морально устарел. MSAA и SSAA по принципу работы практически идентичны. MSAA сглаживает только края предметов. Это экономит ресурсы видеокарты. FSAA превосходно всё сглаживает, но количество кадров в секунду будет очень низким.

Сглаживание, как и фильтрация, имеет один параметр – коэффициент сглаживания (2x, 4x, 8x, 16x, 32х). Раньше сглаживание существенно влияло на количество кадров, сейчас это влияние практически почти не сказывается.

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

Эффект HIGH DYNAMIC RANGE (HDR) часто используется в сценах с контрастным освещением. Без этого эффекта в сценах с контрастным освещением всё становится монотонным и теряет деталировку. Предварительные просчёты проводятся повышенной точности: 64 или 96 бит. Только при выводе на экран, картинка подгоняется под 24 бит. Этот эффект часто используется для создания иллюзии адаптации зрения при выходе героя из туннеля на ярко освещённую поверхность.

MOTION BLUR – эффект смазывания при быстром перемещении камеры. Он добавляет кинематографичности в происходящее на экране. Зачастую используется в гоночных играх для добавления динамики.

В настройках также можно встретить такую технику, как SSAO (Screen Space Ambient Occlusion). Данная техника используется, чтобы придать сцене фотореалистичности. Она построена на принципе создания более реалистичного освещения сцены с учётом характеристик отражения и поглощения света. Ее предшественник, Ambient occlusion, не нашел применения на современных GPU из-за высокого уровня их быстродействия. Понятно, что SSAO даёт более слабый результат, но его вполне достаточно. Вообще, SSAO – золотая середина между качеством картинки и производительности.

Я думаю, в шутерах многие стыкались с такой опцией, как BLOOM. Она симулирует эффект съёмки ярких сцен обычными камерами, когда яркий свет за предметами «заливает» предметы перед собой. Данный эффект может создавать артефакты на краях предметов.
Иногда игры основывают на эффекте CEL SHADING. В нём каждый кадр доводится практически до рисунка от руки или фрагмента из мультика. Грубо говоря – это просто комиксы-раскраски. Игры в таком стиле начали выпускать с 2000 г.

Ещё один эффект – это FILM GRAIN: зернистость. Артефакт возникает в аналоговом ТВ при плохом сигнале, фотогра¬фиях (сделанных при недостаточном освещении) или на старых магнит¬ных кассетах. Обычно данный эффект только мешает, но в некоторых играх (ужастиках, например, Silent Hill) он только добавляет атмосферности.

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

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

Кстати, рекомендую вот этот гайд для очистки ПК от мусора и соответственн оускорения его работы. Ссылка на гайд: http://pcguide.biz/del-trash.html

Графика в играх – видео разбор:

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

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

Конечно, многое зависит от разрешения (Resolution) как такового. Простым изменением разрешения на одну ступень ниже можно добиться прироста производительности в 30-40%. Однако при этом, независимо от остальных настроек, картинка на экране будет выглядеть "замыленной". Поэтому самую "вкусную" картинку в игре можно получить, если разрешение соответствует максимальному разрешению (стандартному заводскому) монитора.

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

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

Это создает гораздо более реалистичную картинку с необходимыми затенениями в углах, но ОЧЕНЬ нагружает видеокарту. На сегодняшний день эта технология доступна в двух вариантах: чуть более простой SSAO (Screen Space Ambient Occlusion) и гораздо более продвинутый и прожорливый HBAO (Horizon-Based Ambient Occlusion).

Есть еще Анизотропная фильтрация (anisotropic filtering, AF) или фильтрация текстур. Она нужна для того, чтобы текстуры, которые находятся под углом или далеко от камеры не выглядели слишком мутными и на них не было никаких цветовых артефактов.

Чем выше значение - тем лучше результат фильтрации, однако сразу скажу - эти значения можно выкручивать сразу на "16x", т.е. на максимальное, и это никак не отразится на производительности даже самой бюджетной видеокарты.

Про сглаживание в играх

Сглаживание (anti aliasing). Что же такое сглаживание? Вы наверняка в играх довольно часто встречались с тем, что у объектов, которые должны в принципе выглядеть ровно и гладко, на краях появляются какие-то непонятные лесенки и зазубрины. Естественно, разработчики игр и видеокарт об этой проблеме знают, поэтому и появилась технология, которая называется "сглаживание", она и нужна чтобы эти неровности сгладить (что очевидно).

Существует довольно много методов осуществить сглаживание. Первый из них взаимодействует с изображением еще на уровне его построения . К первому методу относится: способ сглаживания SSAA (Supersample anti-aliasing) и MSAA (Multisample anti-aliasing), и еще между ними недавно затесался CSAA (Coverage Sampling Antialiasing) - последний, нечто среднее по производительности и по качеству.

Как все эти способы сглаживания работают? Они создают картинку в несколько раз большую, чем необходимо, а потом сжимают ее до размеров экрана, получается довольно неплохой результат, но нагрузка на видеокарту в этот момент просто нечеловеческая. Потому что в зависимости от того, что вы выберете в настройках игры (2x, 4x или 8x), соответственно и изображение будет в два, четыре или в восемь раз больше необходимого, получается, что и нагрузка в два, четыре или восемь раз больше.

Но, к счастью для нас, есть второй метод, который основан на так называемой пост-обработке , т.е. когда сглаживание применяется уже к сформированной сцене. К этому методу относятся уже 3 способа сглаживания: FXAA (Fast approXimate Anti-Aliasing) - по качеству сравним с четырех кратным MSAA сглаживанием, но при этом он не создает вообще никакой нагрузки на видеокарту, ну или настолько малую, что ее практически незаметно. Правда у FXAA есть один небольшой минус - при этом совсем слегка замыливаются текстуры. На глаз это почти незаметно.

Но если вам это мыло прям режет глаза, для вас есть второй способ SMAA (Sub-pixel Morphological Anti-Aliasing), он дает чуть меньшее размытие, но и настолько же меньшее качество сглаживания, при том, что все так же не нагружает видеокарту. И наконец третий способ - TXAA (Temporal anti-aliasing, если я правильно понял, доступно только на видеокартах от Nvidia), он дает очень плавную, киношную картинку, но при этом ощутимо нагружает видеокарту. Если сравнить его с эталонным MSAA, то двукратный TXAA = восьмикратному MSAA, при этом нагрузка на видеокарту такая же, как при двукратном MSAA.

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

P.S. : чуть не забыл сказать про HDAO - то же самое, что HBAO, только от компании ATI-Radeon.

Недавно игра 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 определяется мощностью вашей видеокарты.

  • 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 учитываются в коэффициентах размытия.

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

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