Секреты игровой индустрии: хитрые трюки, которые используют разработчики
Решил коротко рассказать про некоторые хитрые штуковины, которые используются при разработке игр. Штуки эти общеупотребимы, поэтому используются почти во всех играх. И если вы далеки от разработки игр, то некоторые штуки, думаю, вам будет интересно узнать.
1. LODs (ЛОДЫ)
Замечали ли вы когда-нибудь в играх, что если вы очень-очень-очень быстро бежите или используете какие-нибудь чит-коды на быстрый бег или, скажем, на полёт, то некоторые объекты будто бы меняют свою форму перед вами?
Это и есть лоды (или LOD - Level Of Details, уровень детализации). Т.е. из-за того, что вы слишком сильно летаете по карте, то объекты не успевают подгружать свой уровень детализации.
Если мы посмотрим с вами на картинку выше, то видим, как меняется геометрия персонажа. Т.е. если игрок вблизи персонажа - то мы видим LOD 0. И чем дальше, тем LOD идёт к 7, т.е. геометрия персонажа сильно портится, но игрок этого не увидит, а увидит лишь знакомый силуэт персонажа, но с узнаваемыми чертами.
Зачем это нужно? А дело в том, что мы хотим видеть перед собой красивую модельку, скажем, дробовика. Видеть каждую её деталь. Но зачем нам нужно видеть детализацию дробовика, если дробовик от нас слишком далеко?
В этом нет смысла, потому что чем детализированней объект - тем больше в нём треугольных полигонов, а чем больше полигонов - тем больше нагрузка на железо, а значит риск падения FPS. А треугольники - это вся геометрия, которую вы видите перед собой в играх, потому что игровые движки триангулируют модели, но это уже другая история.
Можем кстати вспомнить ситуацию с Cities Skylines 2, что игра теряла кучу FPS из-за проблемы, что зубы персонажей, которых по факту в игре не видно, имели огромное количество полигонов.
2. CubeMap (КубМапы)
Ловили ли вы когда-нибудь диссонанс, что в игре перед вами зеркало, однако в зеркале отражения какие-то странные, в том числе не отражается персонаж?
Это называется CubeMaps. Т.е. как это работает: берётся игровая сцена, раскладывается на 6 сторон и заносится в текстуру, которая накладывается на "зеркала" и иные отражения в играх. Т.е. вот как это выглядит в "развёрнутом" виде:
Т.е. шесть сторон игровой сцены (слева) собираются в единую текстуру (справа).
Плюс этого способа в том, что этот способ существенно не тратит ваш FPS, потому что по сути перед вами просто картинка. Минус - что зеркало или отражение выглядит неестественно, и что в зеркале не происходят изменения, если что-то меняется на карте.
3. Planar Reflection
Тоже чуть коснёмся отражений. Но что делать, если нам всё-таки нужно нормальное отражение, в отличие от CubeMap, который мы рассмотрели выше?
А вот тут нам на помощь приходит Planar Reflection (Плоское отражение). Суть Planar Reflection в том, чтобы полностью (!) продублировать и отзеркалить сцену. Пример Planar Reflection из Max Payne 2:
Но в чём проблема этого способа? Да, что он полностью дублирует игровую сцену. А это существенная нагрузка на систему. Именно поэтому Planar Reflection в основе своей используется в маленьких помещениях (пример, опять же, - выше. Это небольшая туалетная комната).
Отрендерить повторно небольшую туалетную комнату куда эффективнее, чем какую-нибудь оживлённую улицу. Но даже небольшие помещения могут отзеркаливаться ужасно. Вспоминаем Mafia 3:
Поэтому разработчики используют данный способ, когда нужно качественное отражение без использования Ray Tracing (его мы в статье рассматривать не будем).
4. Screen Space Reflection (SSR)
Тоже про отражения. Уж простите, но с отражениями разработчики хитрят больше всего. Да и тема отражений - довольно интересная, на самом деле.
Окей, но что делать, если нам нужно зеркало или какие-то отражения, но чтобы они были не в маленьких помещениях, как в примере выше, а чтобы, скажем, были отражения на полу или отражения в воде?
Вот тут на помощь приходит SSR (Screen Space Reflection) В чём его суть: он не рендерит всю сцену абсолютно, а рендерит только то, что видит игрок, а точнее - камера игрока.
В чём проблема? Внимание на серебряный факел (?) и на отражение под ним, когда двигается камера.
Если вы не увидели, в чём проблема, то из-за того, что какой-то объект не рендерится, то он "обрезается" прямо перед нашими глазами в отражении. Используется эта система почти везде: Days Gone, Cyberpunk 2077, Control и прочее. Но в моменте - создаёт хорошее отражение без существенной потери в оптимизации.
5. Culling (каллинг, "отсечение")
Итак, давайте теперь поговорим с вами про рендер. Дело в том, что во время игры не обрабатывается вся игра. Какие-то элементы просто отсутствуют в игре, а появляются в процессе. Например, если вы играете в GTA и гуляете в районе Гантона, то другие улицы не подлежат рендеру.
Т.е. если это какие-то близкие улицы к игроку, то используется просто LODs, про которые мы говорили. Но если какие-то улицы слишком далеко от нас, то эти улицы просто не рендерятся (не отображаются).
Потому что зачем создавать персонажей, транспорт, дома и нагружать тем самым систему игрока, если он всё равно этих персонажей, транспорт, дома не увидит.
Но и это ещё не всё. Видов каллинга есть очень много и есть много нюансов. Давайте поговорим про них буквально коротко с простыми примерами:
5.1. Frustum Culling
Это технология, когда рендеру не подлежат те объекты, которые находятся вне зоны видимости камеры игрока. Здесь красным отмечены те объекты, которые по факту не рендерятся, потому что находятся вне зоны видимости камеры. Но если камера наведётся на эти объекты, то они начнут отображаться.
Вот пример Frustum Culling в Horizon Zero Dawn (правда здесь каллин работает чуть «с запасом», а не только в пределах пирамиды):
5.2. Occlusion Culling
Этот тип отсечения работает интереснее. Он рендерит то, что находится в зоне видимости камеры, НО он не рендерит то, что скрывается за другим объектом. Вот пример:
Т.е. красные - это Frustum Culling, о котором мы говорили ранее, а вот синие шарики - они находятся за стенкой, вследствие чего шарики игрок по факту не видит, поэтому они (шарики) и не рендерятся, тем самым не нагружая вашу систему (игра хранит лишь информацию о шариках, т.е. их локацию, цвет, форму и прочее), но не отображает визуал.
Однако вы можете сказать: "Погоди-ка, так вон есть же куб, который тоже находится за стенкой, но он не выделен синим цветом, т.е. он рендерится!" Да, верно, однако посмотрите на картинку выше, а потом на картинку поменьше в углу.
Да, в стене есть окно (точнее - проём), через который видно небольшую часть куба. Т.е. куб игрок видит, пусть и не полностью. Поэтому куб рендеру подлежит.
Есть еще и Distance Culling, но с ним все проще и в отдельный подраздел выделять не буду. Можно настроить так, чтобы объекты не рендерились на определённом расстоянии от игрока, независимо от того, видит он объекты или нет.
6. Level Streaming
Частая ситуация (а особенно в The Callisto Protocol), что игра заставляет вас пролазить через шахты, всякие проёмы и прочее и прочее. Пример ниже - Alien Isolation:
Примеров много, если поискать. Почти в каждой ААА игре вас заставляют через что-то пролазить. И нет, это не потому, что левел дизайнеры такие плохие, заставляют вас уныло лазить много времени.
Дело в том, что это позволяет создавать бесшовный мир (или его иллюзию). Дело в том, что как я и говорил раньше, то в момент начала уровня весь уровень полностью не прогружается. В этом нет смысла. Зачем загружать другую часть уровня, если чтобы вам в него пройти, то нужно сначала найти, условно говоря, лом, взломать вентиляцию (или пройти через ущелье, расколов камни)? Верно, в этом смысла нет.
Поэтому пока вы пролазите через шахту/ущелье/дверь/проходите "проверку костюма на токсины" между двумя дверями/едете в лифте закрытом - то происходит Level Streaming или потоковая загрузка уровня.
Т.е. из памяти компьютера выгружается одна часть уровня и прогружается другая часть уровня. Именно поэтому бывают ситуации, что вы уже вылезли из условной вентиляции, а объекты начинают быстро появляться перед вами, потому что не все успели прогрузиться.
Или что пока вы ползёте по вентиляции, то начинаются какие-то фризы небольшие. Опять же - идёт подгрузка подуровня (ботов, объектов, триггеров и т.д.)
Т.е. выше вы видите по цветам, как разбит уровень. Например, если игрок переходит зеленую зону, то начинает грузиться красная локация. Опять же, это пример на уровне домысла, ибо сам код я не видел, скриншот из Интернета, но скриншот верно передаёт общую суть.
7. Коллизии
Чуть-чуть отдохнём от сложной инфы. Хочу поделиться своей личной болью. Буду чуть-чуть душнить, но... Мы же тут просвещаемся, верно?
В общем, коллизии - это такая штука, которая обрабатывает столкновения. Например, столкновение пули с врагом. Или столкновение игрока со стенкой. Если вы проходите сквозь какой-то объект, то значит у него коллизия есть, но объект сталкивается только с полом (он ведь на чём-то лежит), но не сталкивается с персонажем.
И моя личная боль заключается в том, что когда я слышу от игроков, что они "провалились сквозь текстуры!" или что они «застряли в текстурах» - то это неверно. Провалиться сквозь текстуры невозможно. Текстура - это картинка. С картинкой нельзя столкнуться (только если картинка ни на что не нанесена, но тогда вы не с картинкой столкнётесь, а с объектом).
Поэтому когда вы проваливаетесь сквозь что-то в игре, то вы проваливаетесь не сквозь текстуру, а сквозь коллизию. Поэтому говорить, что вы провалились сквозь текстуру - неверно:) Подушнил? Подушнил. Погнали дальше.
8. Trace
Нет, тут речь идёт не про Ray Tracing. А именно про трассировку. Что такое трассировка? Ну вот смотрите, как игра понимает, какой тип патронов перед вами? Или какой объект перед вами? Интерактивная ли дверь?
С помощью трассировки.
Игры сплошь состоят из трассировок. Лезете по лестнице? Трассировка проверяет, не кончилась ли лестница, чтобы запустить нужную анимацию. Берёте врага в тейкдаун сзади? Игра проверяет, есть ли враг перед вами. И так далее.
Например, здесь мы видим с вами один из видов трейса, который просчитывает траекторию вылета снаряда из гранатомёта. Но суть трейса в том, что игрок трейсы не видит. Картинка выше - это тестовая нода из Unreal, которая вроде называется Predictable Path Trace (точно не помню, но сам такую систему использовал при визуализации траектории полета гранаты).
Но есть и много других трейсов. Например, Linetrace. Т.е. кидается линия (красная ниже), которая проверяет, есть ли какой-то объект перед персонажем, есть ли какая-то кнопка лифта и прочее и прочее.
Т.е. можете здесь представить шарик в виде коробки патронов. Вот игрок кидает такой вот луч (красный), а красные квадраты определяют тип объекта (коробка патронов) и если это коробка патронов - то у игрока повышается боезапас. Зелёные линии - это просто продолжение трейса, не обращайте внимание, оно нам не нужно и неинтересно сейчас.
Поэтому такие вот трейсы в игре вы не видите, но они работают в игре постоянно, каждый кадр. Тут я не уверен (поскольку не видел код), но в слитых скринах GTA 6 мы видим некоторые трейсы, которые идут из персонажа:
9. Фейковый экран загрузки игры
Когда вы видите экран загрузки, то знайте - скорее всего он фейковый и не показывает реальную ситуацию с загрузкой. Вспомните, сколько раз было такое, что полоска загрузки уже достигла максимума (или 100%), а вы ещё сидите и ждёте чего-то.
А дело в том, что этот экран загрузки (а точнее - шкала загрузки), которую видит игрок - фейковая и загрузка идёт как бы "рывками". Почему?
А потому что загрузка игры идёт равномерно, каждый кадр что-то да загружается. И если бы экран загрузки отражал истинную ситуацию с загрузкой игры, то индикатор загрузки шёл бы равномерно постоянно, но игроки в такую загрузку не особо верят, а вот в загрузку игры "рывками" игроки верят охотнее.
Вот что пишет по этому поводу один из геймдизайнеров World of Warcraft:
Пожалуйста оцените статью и поделитесь своим мнением в комментариях — это очень важно для нас!
Комментарии1