От переводчика:

Данная публикация является продолжением материала
«Как происходит рендеринг кадра в GTA V». Теперь автор рассматривает вопросы детализации, освещения и пост-обработки кадра. Приятного чтения.

Уровень детализации


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

Огни ночного города


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

Именно с таким заявлением Аарон Гарбут, один из основателей и арт-директоров Rockstar North, выступил незадолго до релиза игры на PS3.

Так ли это? Давайте рассмотрим вот такую ночную сцену:

image
Огоньки «До»
Осторожно! Трафик!

image
Огоньки «После»

Оказывается, так оно и есть: каждое маленькое световое пятно – это квад, визуализированный в виде крошечной текстуры 32х32, подобно той, что вы можете видеть ниже.
image

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

image
Огоньки

image
Светокопия огоньков

image
Тест глубины (пройден / провален)

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

Низкополигональные графические сетки


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

image
Холм всего за один вызов команды отрисовки

Так что же это за крошечный холмик вдалеке?

На самом деле, Вайнвуд-Хиллз отнюдь не маленький. Это большой район в несколько квадратных километров с десятками домов и других построек.

На вершине холма расположились Обсерватория Галилео, театр Сизифа, Озеро Вайнвуд. Чтобы создать все эти достопримечательности — вы можете рассмотреть их поближе или просто проехать мимо — потребовались тысячи вызовов отрисовки и бесчисленное множество полигонов.

Но в нашем случае, эта зона находится далеко, а потому представлена низкополигональной версией: всего один вызов отрисовки, задействовавший каких-то 2500 треугольников.


Низкополигональная модель Вайнвуд-Хиллз

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

Еще один пример аналогичного рендеринга в один вызов отрисовки — район Маленький Сеул, объединивший несколько кварталов города.


Низкополигональная модель Маленького Сеула

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

Предоставление игровых ресурсов


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

GTA V предоставляет игровой ресурс в режиме реального времени, загружая/скачивая модели и текстуры по мере того, как вы передвигаетесь по карте. Причем возможность пользоваться данным контентом в режиме реального времени и при этом наслаждаться игрой без перебоев, действительно, впечатляет.

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

Аарон Гарбут

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

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

Отражение


Поскольку в сцене, которую я анализировал ранее, воды было немного, давайте подробнее остановимся на визуализации бассейна или океана на примере следующей сцены:

image
Бассейн

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

Так сцена выглядит до рендеринга воды:

image
До рендеринга воды

Визуализация поверхности воды – отдельная история, которая никак не связана с созданием кубической текстуры.

Карта отражения


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

image

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

Карта преломления


Извлекается часть изображения — участки с поверхностью воды — позволяющая создать карту преломления. Благодаря этому впоследствии имитируется эффект преломления: свечение из-под воды.

На этом этапе к «непрозрачности воды» добавляется синева (чем глубже, тем насыщеннее оттенок), а также каустики. Итоговая версия карты в два раза меньше сходного буфера.

image
Основа

image
Карта преломления

Комбинирование


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

Для океана же не нормали смещаются, а вся графическая сетка отдельного кадра рисуется вершинами вверх, что имитирует движение волн.

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


Карта отражения, карта преломления и карта рельефа

image
Вода «До»

И, как итог, получаем следующее изображение:

image
Вода «после»

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

Зеркала


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

image
Зеркальное отражение

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

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

Фары



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

Как в таком случае фары авто на следующем скриншоте отражаются в мокром асфальте?

image
Отражения фар

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

image
Фары 0%

image
Фары 50%

image
Фары 80%

image
Фары 100%

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

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

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

image
До построения сетки

image
После построения сетки

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

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

Эффекты пост-обработки



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

В Части 1 мы видели, как накладывались отдельные пост-эффекты, в частности, свечение, сглаживание и тональная компрессия. Сегодня поговорим о других эффектах, встречающихся в GTA V.

Блики и световые полосы

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

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

image
Блики и световые полосы

Как правило, используется 2 способа визуализации таких эффектов:

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

В GTA V задействовано оба метода: способ, использующий изображения, позволяет добавить тонкий синий ореол в нижнем левом углу кадра. По сути, это симметричное отражение содержимого буфера яркости. Но самые заметные искажения в этой сцене появляются благодаря манипуляциям со спрайтами, произведенным с солнцем. Сначала добавляются световые полосы путем визуализации 12 перевернутых четырехугольников вокруг солнца. Затем отрисовывается 70 спрайтов вдоль оси «солнце — центр экрана» для бликов. Эффекты становятся более интенсивными при повороте камеры на солнце.

image
Основа

image
Основа + полосы света

image
Основа + полосы света + блики

image
Основа + полосы света + блики (сверхчувствительная светокопия)

Движок использует несколько спрайтов для имитации различных эффектов искажения линзы:


Эффекты искажения

И, как итог, мы получаем следующий результат:

image
Базовое изображение

image
Базовое изображение + блики

image
Базовое изображение + блики (светокопия)

В GTA V большое внимание уделяется деталям, и блики не исключение: их размер пропорционален диафрагме камеры. Так что, если вы вдруг посмотрите на солнце, блики сначала увеличатся, а затем, как только диафрагма сузится, уменьшатся. Приведенная ниже анимация прекрасно иллюстрирует данную особенность.

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

image
Широкая диафрагма

image
Узкая диафрагма

Анаморфические линзы


Ночью или при игре на темных участках карты моделируется эффект анаморфических линз: длинные вертикальные или горизонтальные, как правило, синие, полосы. В последнее время незначительные полосы от анаморфических линз получили широкое распространение в практике Голливуда, ведь они нередко появляются в новых научно-фантастических фильмах.

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

image
Анаморфный эффект «До»

image
Анаморфный эффект «После»

Глубина резкости


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

image
Базовое изображение

Нужно всего лишь добавить глубину резкости (DoF), размыв области изображения, которые остаются не в фокусе.

Как это сделать? Сначала на основе буфера глубины генерируется карта нерезкости (CoC). Она позволяет вычислить насколько пиксели вне фокуса, а, соответственно, задает и степень предстоящего размытия. Значение CoC отдельного пикселя зависит исключительно от его расстояния до камеры (глубина) и параметров объектива.

Стоит, однако, заметить, что в GTA V CoC присваивается значение от -1 до 1, благодаря чему можно выяснить, находится ли пиксель перед объективом или позади области фокуса. Например, пикселям, расположенным далеко за границами фокуса, присваивается CoC 1, а пикселям вне фокуса, попадающим очень близко к камере, — значение -1. Любой показатель около 0 предполагает, что пиксель будет, практически, не размыт.

Для чего нужны числовые значения?

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

Например, вы не хотите, чтобы пиксель вне фокуса на втором плане не перекрывал соседний из фокуса, расположившийся перед ним. А что если стоит обратная задача: нужно, чтобы размытый пиксель переднего плана перекрывал четкий фрагмент, стоящий позади него. Как только дело доходит до размытия пикселей, вопрос не в том, «насколько сильно размывать», приходится также анализировать близлежащие фрагменты, которые могут быть как перед, так и позади исследуемого пикселя, как вне, так и в фокусе… Числовой формат значений CoC заметно облегчает задачу.

На карте CoC, приведенной ниже, я использовал зеленый канал для CoC> 0 и красный канал для CoC <0, что помогает сориентироваться.

image
Карта глубины

image
Карта CoC

Итак, после изучения карты CoC становится понятно, что Лестер, выделенный черным, будет в фокусе, а Франклин на переднем плане и пейзаж на заднем — вне фокуса.

image
CoC карта размытия переднего плана

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

Почему? Ну, значение CoC для пикселей Франклина равно, примерно, 0,7, в то время как для скамьи прямо за ним, которая попала в фокус, — 0. Теперь, когда размытие завершено, образ Франклина выглядит довольно размытым, а скамья останется четкой, причем область рядом с правой рукой Франклина смотрится странно: получается резкий переход от явно размытой руки к чрезвычайно четким линиям скамьи. Жесткие границы очень заметны… Непорядок, контуры должны соединяться плавно, а пиксели Франклина — слегка перекрывать соседние.

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

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

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


Основа, глубина, CoC карта и CoC карта размытого переднего плана

При использовании двойное размытия с помощью вычислительного шейдера получаем следующее изображение:

image
Глубина резкости «До»

image
Глубина резкости «После»

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

Заключение


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

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

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

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

Комментарии (7)


  1. ragequit
    07.12.2015 12:45
    +4

    О всех неточностях и ошибках в переводе прошу сообщать в ЛС. Спасибо.


  1. engine9
    08.12.2015 01:22
    -4

    Примерно о том же но для веб движка от наших русских разработчиков:


    1. xandr0s
      08.12.2015 12:10

      Ряба получилась неплохо, да


      1. engine9
        08.12.2015 21:33

        Ряба?


        1. xandr0s
          09.12.2015 12:13

          Рябь* т9 ))


  1. entomolog
    08.12.2015 01:54
    +1

    Хотелось бы больше деталей про фары машин и их отражения на асфальте, но это уже к автору, а не к переводчику. А перевод отличный!

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

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

    • BlendEquation: GL_FUNC_ADD
    • source: GL_DST_COLOR
    • destination: GL_ONE

    В итоге мы имеем, что:
    destinationColor = destinationColor + destinationColor * sourceColor
    Теперь, если в текстуру запечь фейковое освещение, то оно будет как бы «добавляться» в уже отрендренную сцену.

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


    1. entomolog
      08.12.2015 02:07

      Вот так оно выглядит