Как устроена графика в современных играх. Часть 2

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

Первая часть статьи

Начало серии статей доступно по ссылке: Как устроена графика в играх. Начало
Как устроена графика в современных играх

Что не нужно рисовать

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

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

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

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

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

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

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

Есть много трюков, чтобы взять максимум при таком ограничении, и для игр наподобие Watch Dogs это главная проблема. Чем ближе вы можете подойти к пределам, тем визуально точнее получается то же количество объектов, тем лучше будет выглядеть игра.

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

Тур по улице, на которую мы вначале смотрели, демонстрируя все, что отсутствует на боковых улицах и на расстоянии.

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

Читай также:  Compute Shaders: введение в вычислительные шейдеры

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

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

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

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

трехмерная графика в играх

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

каркасный вид сцены в 3D игре

Каркасный вид сцены с видимой областью от камеры, выделенной белым.

Сейчас кто-то может прийти к мысли о красивом маленьком чите чтобы обойти то досадное ограничение на число доступных для рисования объектов. Что если сделать объекты как сложную комбинацию всего подряд, вплоть до рассеянных листьев, на небольшой области? Тогда нарисовать 1000 объектов было бы более чем достаточно.

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

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

карта сложности объектов в сцене

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

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

Один из способов хорошо известен — это разрешение текстур. Тема интересная, так как имеет много подробностей, поэтому постараюсь описать ее получше.

Игровые текстуры обычно являются квадратами с длиной стороны, выраженной в степени 2, то есть 512, 1024, 2048, 4096. На то есть много причин, и одна из них — вы можете сделать текстуру размером 1024×1024 и легко уменьшить ее до 512×512.

По причинам, о которых я скажу дальше, для текстур надо иметь под рукой все уменьшенные размеры. То есть для текстуры 1024×1024 у вас будут 512×512, 256×256, 128×128, 64×64, 32×32, 16×16, 8×8, 4×4, 2×2, 1×1. Для маленьких, удаленных в экранном пространстве объектов, текстура 1024×1024 слишком дорога. Мы можем сэкономить на сложности просто применив уменьшенные версии той же текстуры.

Читай также:  Разработка игр инди глазами Buildbox

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

Примечание

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

Процесс упрощения можно применить также к моделям игры, но это реализуется намного сложнее.

Упрощенные объекты и обрезанные модели могут дать значительную экономию в играх наподобие Watch Dogs, но могут и перетягивать на себя много ресурсов. Необходимо принимать очень тщательное и взвешенное решение, сколько упрощенных версий надо иметь. Слишком мало, и либо нет особой экономии, либо заметен скачок при изменении размера. Слишком много, и вы теряете память и человеческие ресурсы на создание объектов с малой выгодой.

объекты в 3D игре

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

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

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

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

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

cubemap

Это предварительно визуализированное изображение называется «кубическая текстура» (cubemap), оно не совпадает в точности с местом, где стоит Эйден, но очень близко к нему.

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

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

Читай также:  Как стать разработчиком игр? Какие бывают профессии в геймдеве?

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

Решение поместить отражения в игру не принимается свободно и легко. Там, где они есть, пришлось пожертвовать чем-то другим.

отражения в трехмерной графике

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

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

Примечание

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

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

К сожалению, в данном случае Watch Dogs не выступает как хорошая иллюстрация, потому что в нем используется довольно сложный, как я думаю, оптимизированный для городского пейзажа шейдинг. Вместо этого давайте быстро переключимся на кадр из Far Cry 4.

кадр со сценой из Far Cry

Сцена из Far Cry 4, о которой я говорю.

изображения для шейдера тени

Изображения сцены, нужные для шейдера. Всякий раз сцену визуализируют заново.

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

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

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


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

Источник: https://renderdoc.org/blog/Graphics-in-Plain-Language/Part-3.html

Ребята! Пожалуйста, если Вам понравилась статья — пошарьте её в соц. сетях, особенно ценны Facebook и Google+
Это очень поможет нашему блогу, огромное спасибо!