- PVSM.RU - https://www.pvsm.ru -

Как происходит рендеринг кадра видеоигры

Как происходит рендеринг кадра видеоигры - 1 [1]Deus Ex Human Revolution — это компьютерная игра 2011 года, которая является более успешным продолжением оригинальной Deus Ex, чем Invisible War. Но этот пост не о качестве игры, а о демонстрации её технических принципов. Адриан Курреж провёл несколько часов за реверс-инжинирингом [2], пытаясь понять с помощью инструмента Renderdoc [3], как происходит обработка каждого из кадров Human Revolution, и изложил результаты в своём блоге.

Игра построена на основе модифицированного проприетарного движка Crystal от компании Crystal Dynamics [4]. Human Revolution была одной из первых игр, которая использовала 11 версию DirectX. На момент выхода уровень графики был на отличном уровне, похождения Адама Дженсена по вентиляционным каналам неплохо смотрятся и сейчас. При этом игра была не слишком требовательной к аппаратной составляющей компьютера.

Как происходит рендеринг кадра видеоигры - 2 [5]
Для рассмотрения Адриан выбрал этот кадр. Так его видит игрок.

На первый взгляд может показаться, что Human Revolution использует технику рендеринга Forward+ [6]. Но популяризация этого метода случилась куда позже выхода игры, и «Человеческая революция» обходится схемой Light Pre-Pass [7].

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

Как происходит рендеринг кадра видеоигры - 3 [8]
Карта нормалей, готово 10 %

Как происходит рендеринг кадра видеоигры - 4 [9]
Карта нормалей, готово 40 %

Как происходит рендеринг кадра видеоигры - 5 [10]
Карта нормалей, готово 70 %

Как происходит рендеринг кадра видеоигры - 6 [11]
Карта нормалей, готово 100 %

Одновременно происходит рендеринг карты глубин. Всего для производства обеих компонент потребовалось 166 вызовов отрисовки.

Как происходит рендеринг кадра видеоигры - 7 [12]

Тени генерируются с помощью Parallel-Split Shadow Maps [13]. Каждая из теней рендерится единожды для каждого из источников света, которые могут при взаимодействии с объектами создавать тень. В данной сцене источников света два: один в офисе справа, другой на вершине скульптуры-руки. Каждая из карт теней представляет из себя квадрат 1024×1024 внутри текстуры 4096×3072.

Как происходит рендеринг кадра видеоигры - 8 [14]

Мелкие объекты пропускаются, возможно, часть невидимых для источника света не учитывается, поэтому этот проход требует всего 52 вызова отрисовки. Карты теней и карта глубин собираются для создания текстуры маски теней. Каждый тексель из карты глубин читается, и его видимость считается для каждого из источников света. Конечный результат выдаётся в 8-битной текстуре RGBA, которая работает как маска. Значение по умолчанию — белый цвет (1, 1, 1, 1), которое означает, что тексель ничем не затемнён. Если тексель попадает в тень какого-либо источника света, то байт, отвечающий за этот цвет, приравнивается нулю. Так можно обрабатывать 4 источника света.

Конечно, использовать байт для хранения только единицы и нуля слишком затратно, поэтому во время этого прохода также выполняется percentage close filtering (PCF), и в этих байтах хранится значение между 0 и 1, а не только крайние значения. Это нужно, чтобы края теней имели плавные переходы.

Как происходит рендеринг кадра видеоигры - 9 [15]

По буферу глубины создаётся карта преграждения окружающего света в экранном пространстве (Screen Space Ambient Occlusion [16], SSAO). Если видеоускоритель поддерживает DirectX 11, то шейдером создаётся блюр с ядром 19×19. На старых карточках это делается пиксельным шейдером.

Как происходит рендеринг кадра видеоигры - 10 [17]
SSAO, первый проход

Как происходит рендеринг кадра видеоигры - 11 [18]
Конечный результат с размытием

После генерации значение текстуры SSAO хранится в альфа-канале карты нормалей.

Как происходит рендеринг кадра видеоигры - 12 [11]

Каждый из точечных источников света обрабатывается по одному. Используется только карта нормалей с SSAO и буфер глубины. Эффект на пиксели зависит только от радиуса света и интенсивности. На этой стадии отражение света различными материалами пока неважно, карта освещения показывает, сколько и какого цвета потенциально отражается. Реальное отражение будет посчитано позже на основе характеристик материала. В конкретно этой сцене 45 точечных источников света.

Как происходит рендеринг кадра видеоигры - 13 [19]
Готово 10 %

Как происходит рендеринг кадра видеоигры - 14 [20]
Готово 40 %

Как происходит рендеринг кадра видеоигры - 15 [21]
Готово 70 %

Как происходит рендеринг кадра видеоигры - 16 [22]
Готово 100 %

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

Как происходит рендеринг кадра видеоигры - 17 [23]
10 %

Как происходит рендеринг кадра видеоигры - 18 [24]
40 %

Как происходит рендеринг кадра видеоигры - 19 [25]
70 %

Как происходит рендеринг кадра видеоигры - 20 [26]
100 %

Затем добавляются декали (таблички на стенах, следы от пуль), прозрачные объекты (стекла в окнах) и искусственные объёмные эффекты освещения.

Как происходит рендеринг кадра видеоигры - 21 [27]
Добавлены прозрачные объекты и декали

Как происходит рендеринг кадра видеоигры - 22 [28]
Добавлены эффекты освещения

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

Как происходит рендеринг кадра видеоигры - 23 [29]

Рендер непрозрачных и прозрачных объектов был выполнен с помощью 253 вызовов отрисовки.

Для добавления эффекта засвечивания bloom [30] нужно знать, какие области очень яркие. Human Revolution использует LDR, буфера HDR нет. При предыдущем проходе в альфа-канал передавались данные по интенсивности.

Как происходит рендеринг кадра видеоигры - 24 [31]

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

Как происходит рендеринг кадра видеоигры - 25 [32]

Важной составляющей является сглаживание, иначе изображение будет выглядеть плохо из-за «лесенок» границ. Human Revolution поддерживает множество методов: DLAA, MLAA, FXAA и так далее. В примере Адриана используется FXAA.

Как происходит рендеринг кадра видеоигры - 26 [33]
Без сглаживания

Как происходит рендеринг кадра видеоигры - 27 [34]
Результат применения FXAA

Всё почти готово. По соображениям стиля игра обладает золотистым оттенком, его, конечно, можно убрать с помощью стороннего мода [35]. Но по умолчанию выполняется коррекция цвета.

Как происходит рендеринг кадра видеоигры - 28 [32]
До коррекции цвета

Как происходит рендеринг кадра видеоигры - 29 [36]
После коррекции цвета

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

Как происходит рендеринг кадра видеоигры - 30 [5]

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

Как происходит рендеринг кадра видеоигры - 31 [37]

Но есть и другие интересные детали. В катсценах и диалогах используется эффект глубины резкости (Depth of Field, DoF), когда элементы не в фокусе размыты.

Как происходит рендеринг кадра видеоигры - 32 [38]
Изображение оригинальной сцены уменьшается в два раза

Как происходит рендеринг кадра видеоигры - 33 [39]
Горизонтальное размытие

Как происходит рендеринг кадра видеоигры - 34 [40]
Вертикальное размытие

Как происходит рендеринг кадра видеоигры - 35 [41]
Карта глубин

Как происходит рендеринг кадра видеоигры - 36 [42]
Готовый результат на экране пользователя. В зависимости от карты глубин пиксельный шейдер будет использовать либо части размытого изображения, либо оригинальное без размытия.

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

Как происходит рендеринг кадра видеоигры - 37 [43]
Сцена, которую Адриан привёл для примера

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

Как происходит рендеринг кадра видеоигры - 38 [44]

Как происходит рендеринг кадра видеоигры - 39 [45]

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

Как происходит рендеринг кадра видеоигры - 40 [47]
Силуэт: до

Как происходит рендеринг кадра видеоигры - 41 [43]
Силуэт: после

По материалам блога Адриана Куррежа [2].

Автор: FakeFactFelis

Источник [48]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/igry/86605

Ссылки в тексте:

[1] Image: https://habrastorage.org/files/ec4/be7/574/ec4be7574f1a4d44bbf34bf1f75914df.jpg

[2] провёл несколько часов за реверс-инжинирингом: https://www.adriancourreges.com/blog/2015/03/10/deus-ex-human-revolution-graphics-study/

[3] Renderdoc: https://github.com/baldurk/renderdoc

[4] Crystal Dynamics: https://ru.wikipedia.org/wiki/Crystal_Dynamics

[5] Image: https://habrastorage.org/files/114/eae/b6d/114eaeb6dac14eb993a3cc4c8ea86764.jpg

[6] Forward+: http://www.slideshare.net/takahiroharada/forward-34779335

[7] Light Pre-Pass: http://diaryofagraphicsprogrammer.blogspot.com/2008/03/light-pre-pass-renderer.html

[8] Image: https://habrastorage.org/files/57d/073/3a6/57d0733a6b324670a9ac11c013e804c4.jpg

[9] Image: https://habrastorage.org/files/bc6/cd4/f33/bc6cd4f3392b4521a8b8026b3125db7a.jpg

[10] Image: https://habrastorage.org/files/171/791/926/1717919264894a779f6be5292c021d1c.jpg

[11] Image: https://habrastorage.org/files/60a/09b/8a0/60a09b8a07ba4e8a8014ac26764f8278.jpg

[12] Image: https://habrastorage.org/files/f82/98a/b65/f8298ab652674f6788516385a5084eec.jpg

[13] Parallel-Split Shadow Maps: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html

[14] Image: https://habrastorage.org/files/281/e35/9a9/281e359a90384911a1cfb05df0dd717e.jpg

[15] Image: https://habrastorage.org/files/9ae/cd1/4bf/9aecd14bfe194a3bac11a288fd72462f.jpg

[16] Screen Space Ambient Occlusion: https://ru.wikipedia.org/wiki/Screen_Space_Ambient_Occlusion

[17] Image: https://habrastorage.org/files/2fb/5b9/6ba/2fb5b96baf6c4248954de2f328224cc8.jpg

[18] Image: https://habrastorage.org/files/ba2/183/d93/ba2183d93a144d1786d722de72542a06.jpg

[19] Image: https://habrastorage.org/files/c72/422/081/c72422081c534a36a10d75e5cdc21b91.jpg

[20] Image: https://habrastorage.org/files/173/7cd/8d7/1737cd8d7a884c91b627b40e3ff75e41.jpg

[21] Image: https://habrastorage.org/files/3b2/d11/1e0/3b2d111e08974b79a4a28e5bc9930e95.jpg

[22] Image: https://habrastorage.org/files/f64/da7/7f1/f64da77f14f3494c96d1441f1f95d535.jpg

[23] Image: https://habrastorage.org/files/cf3/f30/2a2/cf3f302a2efe49f4bd165a379cd9558c.jpg

[24] Image: https://habrastorage.org/files/c4b/7d8/f11/c4b7d8f114d94155aaae3712ecf20140.jpg

[25] Image: https://habrastorage.org/files/71c/70e/4aa/71c70e4aa8704effb313a48368375ab9.jpg

[26] Image: https://habrastorage.org/files/6bc/517/aa4/6bc517aa4d5e4aaf9901d26d1a797cc8.jpg

[27] Image: https://habrastorage.org/files/c17/3cf/ccc/c173cfccca384e9a86c234541d171c5d.jpg

[28] Image: https://habrastorage.org/files/510/e5d/cff/510e5dcff8814880b93d594eb8d3e24c.jpg

[29] Image: https://habrastorage.org/files/a7c/c49/9ce/a7cc499ce850476497ca9ad9fe5a9541.jpg

[30] эффекта засвечивания bloom: https://ru.wikipedia.org/wiki/Bloom

[31] Image: https://habrastorage.org/files/570/e8d/897/570e8d8972454503966ec914ef57de97.jpg

[32] Image: https://habrastorage.org/files/acb/3fc/525/acb3fc525b674a768a7a79df39413382.jpg

[33] Image: https://habrastorage.org/files/24b/740/f92/24b740f92d32492d89ef1d15a0d979b2.jpg

[34] Image: https://habrastorage.org/files/eec/39b/e21/eec39be21f5e4f3fbb051cd847843ec1.jpg

[35] стороннего мода: http://kotaku.com/5843146/deus-ex-mod-removes-gold-filter-game-suddenly-looks-even-better/

[36] Image: https://habrastorage.org/files/dce/6fb/ee8/dce6fbee83424fcd85233a851378cc27.jpg

[37] Image: https://habrastorage.org/files/0bb/d90/39e/0bbd9039e860458b8a51384ba7007ac4.png

[38] Image: https://habrastorage.org/files/c13/b03/055/c13b030555e64f44b99581c78e03f51e.jpg

[39] Image: https://habrastorage.org/files/bc9/89a/8e7/bc989a8e78da4b0b9e583074616729fe.jpg

[40] Image: https://habrastorage.org/files/94a/1c1/2ae/94a1c12ae515420bbc7819951e2970a7.jpg

[41] Image: https://habrastorage.org/files/3c9/846/7b6/3c98467b604e4d759fdfb0a5a275916f.jpg

[42] Image: https://habrastorage.org/files/313/233/eeb/313233eeb2b24beda97266fd6240ad72.jpg

[43] Image: https://habrastorage.org/files/b67/959/858/b67959858f31429f8a5f71e14c9dcaa4.jpg

[44] Image: https://habrastorage.org/files/a23/e1e/efb/a23e1eefbc684555846303f2a2cdbafd.jpg

[45] Image: https://habrastorage.org/files/692/688/5b0/6926885b01d843c0a76ccdf1329b8d04.jpg

[46] оператора Собеля: https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80_%D0%A1%D0%BE%D0%B1%D0%B5%D0%BB%D1%8F

[47] Image: https://habrastorage.org/files/69b/30a/5cf/69b30a5cfb2a40ea9aa47d1f214e457f.jpg

[48] Источник: http://geektimes.ru/post/247680/