Как устроена графика в современных компьютерных играх?
Серия постов, рассчитанных на среднего человека с техническим мышлением, который хочет узнать больше о том, как работает современная 3D графика в играх. Они не научат вас делать что-либо и не предполагают предварительных знаний, но объяснят концепции.
Введение
Многое входит в создание даже простой 3D игры , не говоря уже о такой, как Watch Dogs.
Привет, меня зовут baldurk. Я хочу описать то, что происходит в современных играх, не упуская ничего. Но не буду говорить про математику или программирование. Если вы знаете разницу между процессором и графической картой, то вы знаете, что графическая память не такая же, как на жестком диске. Этого достаточно, и я объясню что-нибудь еще.
В постах я буду опираться на игру Watch Dogs. Она хорошо известна благодаря своей графике (хорошей или плохой, зависит от вашего вкуса), и в ней есть много вещей, которые мы можем рассмотреть в качестве конкретных примеров. В каких-то особых случаях я могу говорить о других играх.
Начну с основ, которые одинаковы от игры к игре, но также рассмотрю некоторые характерные для Watch Dogs методы и визуальные эффекты.
Я использую инструмент RenderDoc, который написал в свободное время. Он используется для отладки графических задач: помогает разобрать графический кадр и посмотреть, как он собран.
Эта анимация показывает, как графическая карта отрисовывает кадр во течение какого-то промежутка времени.
Большинство людей знает, что компьютерная графика (как и любое другое видео) состоит из серии неподвижных кадров, каждый из которых показывается доли секунды. В фильмах традиционно бывает 24 кадра в секунду (FPS), в телевизионных передачах примерно столько же, около 24-30. В играх FPS может быть разным, поскольку каждый раз может происходить много работы. Опускаться ниже 30 нежелательно, хотя это часто случается. 60 FPS приближается к пределу для консольных игр, а к какому из пределов в промежутке от 30 до 60 стремится игра — зависит от ее целей. На компьютере с высококачественным монитором вы можете получить 90, 120 или даже больше FPS. Почему используются именно эти конкретные числа, я объясню позже, это связано с vsync.
Но нам с вами надо перевернуть это с ног на голову. Вместо того, чтобы смотреть, насколько высок FPS, мы посмотрим, насколько малый промежуток времени выделяется на один кадр. При 30 FPS у нас есть только 33 миллисекунды, чтобы нарисовать все что нужно внутри кадра. При 60 FPS — половина этого, около 17 миллисекунд. Учитывая, сколько всего надо успеть сделать, это небольшое время даже для компьютера. Чтобы представить нагляднее, приведу примерный расчет, что пуля за миллисекунду пролетает около 1 метра.
Мы в основном будем говорить о персональных компьютерах, потому что это открытая платформа, и определенные специфичные вещи про консоли нельзя открыть не опасаясь нарушить NDA. Но в основном я не собираюсь говорить о чем-то таком, что сильно отличается в консолях. А если скажу, я обращу на это внимание. Большинство различий между аппаратным обеспечением ПК/консолей и мобильных платформ выходит за рамки этой серии.
А эта красивая картинка стоит здесь для того, чтобы оживить текст.
Вот какая задача нам интересна. Мы не будем переживать, как AI сделает все вычисления, и не будем делать вычислять физику для перемещения частиц и предметов. Граница того, что вы назвали бы «графическим программированием», немного нечеткая. Но я хочу обратить внимание, что графическое программирование начинается тогда, когда у вас есть все нужное для отрисовки кадра. Вы знаете, что происходит, у вас в памяти (не на диске) есть текстуры и модели, анимации анимированы, физика просчитана и теперь нам пора нарисовать готовый кадр.
Отмечу, что многие основные принципы 3D игры с обычной визуализацией, наподобие Watch Dogs, применимы к 2D играм. Но их немного сложнее проиллюстрировать. Также отказ от ответственности, он особенно относится к другим графическим программистам: я хочу во всем разобраться, поэтому могу привести сомнительные или просто неверные объяснения, если они помогут цели.
Части кадра
Основную часть времени мы будем рассматривать только один кадр и говорить о строительных блоках, которые использует игра для создания конечного кадра.
Кадр можно собрать из меньших строительных блоков несколькими путями. Готовый рисунок, который вы видите, рисуется не мгновенно. Это имело место много лет назад, но современные графические движки практически всегда выполняют какие-либо предварительные вычисления. Движок будет рисовать много промежуточных изображений разных типов, чтобы помочь рассчитать окончательное изображение до того как сложить его в кадр, который вы видите на экране.
Эти изображения отличаются от движка к движку и зависят от замысла программиста графики. Например, если надо чтобы солнечный свет давал правильные тени, для этого будет одно изображение. А если надо сделать правильные отражения на поверхности машины, которую ведет игрок — то другое.
Некоторые из промежуточных изображений, которые нужны для создания нашего кадра из Watch Dogs.
Скорее всего, я не буду рассказывать обо всех изображения для кадра в Watch Dogs, но обязательно коснусь самых главных, которые чему-то нас научат. Это та область, в которой технологии все время развиваются. Когда маркетологи говорят о новой характеристике, обычно они имеют в виду ее, хотя инновации внедряют и на других уровнях.
Каждое из этих промежуточных изображений само построено из более мелких частей. Каждый объект в сцене или, возможно, группа связанных объектов отдельно строится как текстурированная модель. Во время создания игры художники делают эти модели в 3D редакторе и создают все необходимые ресурсы. Затем эти модели поместят в игровой мир с помощью редактора уровней, чтобы постепенно построить виртуальный город.
Таковы общие знания, а если вы видели, как за 20 лет повзрослела 3D графика в играх в реальном времени, вы знаете, что современные модели стали намного сложнее. В былые дни текстуры стоили дорого, и везде, где это только можно, их заменяли простым закрашиванием объектов. Оставляли только там, где действительно важны детали, например, для глаз и лиц персонажей.
3D модель целиком состоит из взаимосвязанных треугольников, которые составляют форму объекта. Каждый треугольник имеет три точки, называемые вершинами, а так как треугольники взаимосвязаны, вершины будут общими для нескольких треугольников. Мы вернемся к этому позже, поскольку вершины и треугольники весьма важны. Также стоит помнить, что некоторые объекты, такие как персонажи или деревья, будут анимированы перед рисованием. Модель создается в статической форме по умолчанию, а анимации применяются к каждому кадру — опять же, мы вернемся к этому.
Это 3D модель головы Эйдена Пирса до анимации. Треугольники видны потому, что нарисованы плоскими, а не визуально смягченными, как обычно в игре.
Чтобы сделать 3D модель более детализованной, применяются текстуры. Они представляют собой обычные файлы с плоскими изображениями, обычно квадратными или с простым соотношением сторон вроде 2:1. Как текстуры накладываются на 3D модель, я опишу далее, но вы можете представить это себе как очень аккуратное оборачивание подарка. Вместо простого повторяющегося рисунка на оберточной бумаге изображение для текстуры в точности повторяет то, что должно быть обернуто. Если вы наблюдали в плоском виде бумажные модели для объемного склеивания, то здесь тот же самый принцип.
Аналогия гораздо точнее, чем вы могли бы подумать, потому что при создании текстур 3D модель обычно “разворачивается” в плоскую копию, как и для бумажных моделей, а затем на ней рисуется текстура. Развертка обычно делается автоматически, но для особо сложных объектов может быть сделано и вручную.
Вот текстура, которая относится к приведенной выше модели головы Эйдена Пирса. Для зубов и языка использованы отдельные части. Обратите внимание, что область выше лба не имеет текстуры, потому что она всегда покрыта узнаваемой кепкой.
Примечание
При развертке части, которым нужно больше детализации, часто делаются крупнее — и наоборот.
Часто говорят о различных “скинах” модели, особенно кастомного персонажа. В наши дни изменение скина включает небольшие изменения самой модели (другой ремень или кепку), но первоначально использовалась в точности та же модель, на которую накладывалась иная текстура (или скин), и получался персонаж, который выглядит по-новому. Даже сейчас большинство изменений для неигровых персонажей или объектов выполняется при помощи текстур, так как экономит время и труд от создания множества уникальных моделей. Разная одежда, которую может носить Эйден, в основном получается за счет наложения на одну и ту же модель разных текстур.
Небольшое вращение 3D модели только с одной наложенной текстурой.
На рассматриваемом нами кадре есть около 1700 объектов, нарисованных во время основной визуализации. Некоторые из них будут идентичными. Такие вещи, как цветы в горшках или мусорные ящики никогда не делаются поштучно. Делается набор моделей или одна, и размещаются в разных местах. Однако, общее число уникальных моделей для заполнения кадра грубо оценивается как 4700. Это даст вам представление о том, сколько дополнительной работы надо выполнить помимо простого рисованиях всего этого.
Давайте посмотрим другой пример объекта — кепку Эйдена.
Текстура и модель кепки с наложенной текстурой. Можно заметить, что текстура сделана из нескольких частей, который соединяются на модели.
Примечание
Козырек и донышко кепки в текстуре не прикасаются друг с другом. Так сделано потому, что оборачивание может быть достаточно сложным, при необходимости оно выполняется на нескольких разных частях модели. Иногда, чтобы без видимых проблем или швов наложить текстуру на модель причудливой формы, требуется много изящества.
Все, что мы говорили про голову Эйдена, относится и к его кепке. Помимо специальной текстуры и чисел, которые входят в вычисление развертки, все работает в точности так же.
Давайте теперь немного позабавимся. Большинство текстур имеют стандартный квадратный размер, процедура оборачивания одинакова — так что случатся, если мы “перепутаем” текстуры для разных объектов?
Неузнаваемая кепка Эйдена.
Там, где на кепке был логотип, текстура головы содержит ухо и зубы. В районе козырька получились волосы. Мэппинг остался прежним, а текстура поменялась. Мы получили баг, но подумайте, что бы вы могли делать, если умеете анимировать или перемещать текстуры. В играх эта вещи используются для получения нескольких разных эффектов, которые вы теперь сумеете обнаружить. Например, в Saint’s Row 4 прием реализован неоднократно.
Также полезно подумать обо всем, что это скрывает за собой. Модели и текстуры в играх должны в правильно совпадать.
Конечно, это не абсолютное правило. В некоторых случаях текстура будет обычный тайловый узор, который можно использовать для многих объектов. Или, возможно, для серии связанных объектов (например, газетные стенды). Все будут иметь одну и ту же текстуру для обложек газет, при этом каждая будет использовать только небольшую часть текстуры.
Тем не менее это означает, что если вы хотите рисовать много изображений для создания итогового кадра, вам нужно собрать все строительные блоки, и для этого понадобится много моделей и текстур.
Продолжение серии статей
Следующая часть тут: Как устроена графика в современных компьютерных играх 2?