масштаб рендера в играх что
Графические настройки в компьютерных играх — подробный разбор
На сайте PC Gamer появился интересный разбор графических настроек в компьютерных играх, где подробно рассказано обо всех популярных инструментах, фильтрах и механизмах обработки изображения. Мы перевели его на русский язык, чтобы вы могли сами настраивать свои игры, избавляться от лагов и любоваться красивой графикой.
Итак, сегодня мы с вами разберемся, что означают те или иные графические настройки в компьютерных играх.
У Nvidia и AMD есть программное обеспечение для автоматической настройки графики согласно техническим характеристикам вашего компьютера. Со своей задачей программы справляются неплохо, но часто ручная настройка приносит куда больше пользы. Все-таки, мы ПК-бояре, у нас должна быть свобода выбора!
Если вы новичок в области игровой графики, это руководство создано специально для вас. Мы расшифруем основные пункты любого меню «Настройки графики» в ваших играх и объясним, на что они влияют. Эта информация поможет вам избавиться от лагов и фризов в любимой игре, не лишаясь красивой картинки. А владельцы мощных компьютеров поймут, как настроить самую сочную и привлекательную графику, чтобы записывать крутые видео и делать зрелищные скриншоты.
Начнем с фундаментальных понятий, а затем пройдемся по тонким настройкам в рамках нескольких разделов, посвященных анизотропной фильтрации, сглаживанию и постобработке. Для написания этого гайда мы пользовались информацией, полученной от профессионалов: Алекса Остина, дизайнера и программиста Cryptic Sea, Николаса Вайнинга, технического директора и ведущего программиста Gaslamp Games и от представителей Nvidia. Сразу отметим, что статью мы пишем простыми словами, опуская подробные технические детали, чтобы вам было легче понять механизмы работы разных технологий.
Содержание
ОСНОВЫ
Разрешение
Пиксель — основная единица цифрового изображения. Это цветовая точка, а разрешение — количество столбцов и рядов точек на вашем мониторе. Самые распространенные разрешения на сегодня: 1280×720 (720p), 1920×1080 (1080p), 2560×1440 (1440p) и 3840 x 2160 (4K или «Ultra-HD»). Но это для дисплеев формата 16:9. Если у вас соотношение сторон 16:10, разрешения будут слегка отличаться: 1920×1200, 2560×1600 и т.д. У ультрашироких мониторов разрешение тоже другое: 2560×1080, 3440×1440 и т.д.
Кадры в секунду (frames per second, FPS)
Если представить, что игра — это анимационный ролик, то FPS будет числом изображений, показанных за секунду. Это не то же самое, что частота обновления дисплея, измеряемая в герцах. Но эти два параметра легко сравнивать, ведь как монитор на 60 Гц обновляется 60 раз за секунду, так и игра при 60 FPS выдает именно столько кадров за тот же отрезок времени.
Чем сильнее вы загрузите видеокарту обработкой красивых, наполненных деталями игровых сцен, тем ниже будет ваш FPS. Если частота кадров окажется низкой, они будут повторяться и получится эффект подтормаживания и подвисания. Киберспортсмены охотятся за максимальном возможными показателями FPS, особенно в шутерах. А обычные пользователи зачастую довольствуются играбельными показателями — это где-то 60 кадров в секунду. Однако, мониторы на 120-144 Гц становятся более доступными, поэтому потребность в FPS тоже растет. Нет смысла играть на 120 герцах, если система тянет всего 60-70 кадров.
Так как в большинстве игр нет встроенного бенчмарка, для измерения кадров в секунду используется стороннее программное обеспечение, например, ShadowPlay или FRAPS. Однако, некоторые новые игры с DX12 и Vulkan могут некорректно работать с этими программами, чего не наблюдалось со старыми играми на DX11.
Апскейлинг и даунсэмплинг
В некоторых играх есть настройка «разрешение рендеринга» или «rendering resolution» — этот параметр позволяет поддерживать постоянное разрешение экрана, при этом настраивая разрешение, при котором воспроизводится игра. Если разрешение рендеринга игры ниже разрешения экрана, оно будет увеличено до масштабов разрешения экрана (апскейлинг). При этом картинка получится ужасной, ведь она растянется в несколько раз. С другой стороны, если визуализировать игру с большим разрешением экрана (такая опция есть, например, в Shadow of Mordor), она будет выглядеть намного лучше, но производительность станет заметно ниже (даунсэмплинг).
Производительность
На производительность больше всего влияет разрешение, поскольку оно определяет количество обрабатываемых графическим процессором пикселей. Вот почему консольные игры с разрешением 1080p, часто используют апскейлинг, чтобы воспроизводить крутые спецэффекты, сохраняя плавную частоту кадров.
Мы использовали наш Large Pixel Collider (суперкомпьютер от сайта PC Gamer), включив две из четырех доступных видеокарт GTX Titan, чтобы продемонстрировать, как сильно разрешение влияет на производительность.
Тесты проводились в бенчмарке Shadow of Mordor:
1980х720 (½ родного разрешения)
2560х1440 (родное разрешение)
5120х2880 (x2 родного разрешения)
Вертикальная синхронизация и разрывы кадров
Когда цикл обновления дисплея не синхронизирован с циклом рендеринга игры, экран может обновляться в процессе переключения между готовыми кадрами. Получается эффект разрыва кадров, когда мы видим части двух или более кадров одновременно.
Одним из решений этой проблемы стала вертикальная синхронизация, которая почти всегда присутствует в настройках графики. Она не позволяет игре показывать кадр, пока дисплей не завершит цикл обновления. Это вызывает другую проблему — задержка вывода кадров, когда игра способна показать большее количество FPS, но ограничена герцовкой монитора (например, вы могли бы иметь 80 или даже 100 кадров, но монитор позволит показывать только 60).
Адаптивная вертикальная синхронизация
Бывает и так, что частота кадров игры падает ниже частоты обновления монитора. Если частота кадров игры превышена, вертикальная синхронизация привязывает ее к частоте обновления монитора и она, например, на дисплее с 60 Гц не превысит 60 кадров. А вот когда частота кадров падает ниже частоты обновления монитора, вертикальная синхронизация привязывает ее к другому синхронизированному значению, например, 30 FPS. Если частота кадров постоянно колеблется выше и ниже частоты обновления, появляются подтормаживания.
Чтобы решить эту проблему, адаптивная вертикальная синхронизация от Nvidia отключает синхронизацию каждый раз, когда частота кадров падает ниже частоты обновления. Эту функцию можно включить в панели управления Nvidia — она обязательна для тех, кто постоянно включает вертикальную синхронизацию.
Технологии G-sync и FreeSync
Новые технологии помогают разобраться со многими проблемами, которые зачастую основаны на том, что у дисплеев фиксированная частота обновления. Но если частоту дисплея можно было бы изменять в зависимости от FPS, пропали бы разрывы кадров и подтормаживания. Такие технологии уже есть, но для них нужны совместимые видеокарта и дисплей. У Nvidia есть технология G-sync, а у AMD — FreeSync. Если ваш монитор поддерживает одну из них и она подходит к установленной видеокарте, проблемы решены.
Сглаживание (Anti-aliasing, антиалиасинг)
Инструментов для этого достаточно, но легче объяснить на примере суперсэмплинга (SSAA). Эта технология отрисовывает кадры с более высоким разрешением, чем у экрана, а затем сжимает их обратно до его размера. На предыдущей странице вы могли видеть эффект от сглаживания при уменьшении частоты в Shadow of Mordor с 5120х2880 до 1440p.
Взгляните на пиксель черепичной крыши. Он оранжевого цвета. Тут же и пиксель голубоватого неба. Находясь рядом, они создают жесткий зубчатый переход от крыши к небу. Но если визуализировать сцену с четырехкратным разрешением, вместо одного пикселя оранжевой крыши на этом же месте будут четыре пикселя. Некоторые из них будут оранжевыми, некоторые «небесными». Стоит взять значение всех четырех пикселей, как получится нечто среднее — если по такому принципу построить всю сцену, переходы станут мягче и «эффект лестницы» пропадет.
Такова суть технологии. Но, она требует от системы очень много ресурсов. Ей приходится отрисовывать каждый кадр с разрешением в два или более раз больше, чем оригинальное разрешение экрана. Даже в случае с нашими топовыми видеокартами суперсэмплинг с разрешением 2560х1440 кажется нецелесообразным. К счастью, есть альтернативы:
Мультисэмплинг (MSAA): Эффективнее суперсэмплинга, но все еще прожорлив. В старых играх он был стандартом, а его суть объясняется в видео, которое вы увидите ниже.
Усовершенствованный мультисэмплинг (CSAA): более эффективная версия MSAA от Nvidia для ее видеокарт.
Усовершенствованный мультисэмплинг (CFAA): тоже апгрейд MSAA, только от компании AMD для ее карточек.
Метод быстрого приближения (FXAA): вместо анализа каждого отдельного пикселя, FXAA накладывается в качестве фильтра постобработки на всю сцену целиком после ее рендеринга. FXAA также захватывает места, которые пропускаются при включении MSAA. Хотя сам метод быстрого приближения тоже пропускает много неровностей.
Морфологический метод (MLAA): он свойственен видеокартам AMD и тоже пропускает этап рендеринга. MLAA обрабатывает кадр, выискивая алиасинг и сглаживая его. Как нам объяснил Николас Вайнинг: «Морфологическое сглаживание работает с морфологией (паттернами) неровностей на краях моделей; оно вычисляет оптимальный способ удаления лесенок для каждого вида неровностей путем разбиения краев и зубцов на небольшие наборы морфологических операторов. А затем использует специальные типы смешивания для каждого отдельного набора». Включить MLAA можно в панели управления Catalyst.
Улучшенное субпиксельное морфологическое сглаживание (SMAA): еще один вид постобработки, в котором сочетаются детали MLAA, MSAA и SSAA. Такой метод можно совмещать со SweetFX, а многие современные игры поддерживают его изначально.
Временное сглаживание (TAA или TXAA): TXAA изначально разрабатывалась для графических процессоров Nvidia уровня Kepler и более поздних. Но затем появились не настолько специфические формы временного сглаживания, которые обычно обозначаются, как TAA. При таком способе следующий кадр сравнивается с предыдущим, после чего обнаруживаются и устраняются неровности. Происходит это при поддержке разных фильтров, которые уменьшают «ползающую лесенку» в движении.
Николас Вайнинг объясняет: «Идея TAA заключается в ожидании того, что два идущих друг за другом кадра будут очень похожи, ведь пользователь в игре двигается не настолько быстро. Поэтому раз объекты на экране переместились несильно, мы можем получить данные из предыдущего кадра, чтобы дополнить участки, нуждающиеся в сглаживании».
Многокадровое сглаживание (MFAA): появилось с релизом графических процессоров Maxwell от Nvidia. Тогда как MSAA работает с устойчивыми шаблонами, MFAA позволяет их программировать. Представители Nvidia подробно объясняют технологию в видео ниже (о нем мы уже говорили раньше и очень скоро вы его увидите).
Суперсэмплинг с глубоким обучением (DLSS): новейшая технология Nvidia, доступная лишь в некоторых играх и с видеокартами GeForce RTX. По словам компании: «DLSS использует нейронную сеть для определения многомерных особенностей визуализированной сцены и интеллектуального объединения деталей из нескольких кадров для создания высококачественного финального изображения. DLSS использует меньше сэмплов, чем TAA, при этом избегая алгоритмических трудностей с прозрачностями и другими сложными элементами сцен».
Другими словами, DLSS справляется с задачей лучше и эффективнее, чем TAA, но технологию нужно отдельно готовить к каждой игре. Если не обучить ее должным образом, многие места окажутся размытыми.
Что означают цифры?
В настройках сглаживания вы часто видите значения: 2x, 4x, 8x и т.д. Эти цифры рассказывают о количестве используемых образцов цвета и, как правило, чем больше число, тем точнее будет сглаживание (при этом оно потребует больше системных ресурсов).
Но есть исключения. Так, CSAA пытается достичь сглаживания на уровне MSAA с меньшим количеством образцов цвета. Поэтому 8xCSAA фактически использует только четыре образца цвета. Есть и 8QxCSAA — этот способ сглаживания увеличивает количество образцов цвета до восьми, чтобы повысить точность.
Производительность
Мы использовали бенчмарк Batman: Arkham City, чтобы протестировать несколько старых методов сглаживания: MSAA, FXAA и TXAA. Результаты, как и ожидалось, показывают, что FXAA требует меньше всего ресурсов, в то время как MSAA и TXAA сильно влияют на среднюю частоту кадров.
Результаты тестирования сглаживания в Batman: Arkham City (на двух Nvidia GTX Titan SLI):
Рендеринг в 3D-играх: введение
Вы играете в свежую Call of Mario: Deathduty Battleyard на своём совершенном игровом ПК. Смотрите на прекрасный сверширокий 4K-монитор, любуясь великолепными пейзажами и замысловатыми деталями. Вас когда-нибудь интересовало, как графика попадает на экран? Задумывались, как игра заставляет компьютер всё это показать вам?
Добро пожаловать в наш тур по рендерингу в 3D-играх: путешествие для начинающих, из которого вы узнаете, как создаётся один базовый кадр на экране.
Каждый год выходят сотни новых игр для смартфонов, приставок и ПК. Разнообразие форматов и жанров очень велико, но один из них, пожалуй, освоен лучше всего — это 3D-игры. Какая игра была первой — вопрос дискуссионный, и быстрый просмотр базы Книги рекордов Гиннесса дал несколько результатов. Можно считать первой игрой Knight Lore компании Ultimate, вышедшую в 1984-м, но строго говоря, изображения в этой игре были двумерными — никакая информация не использовалась в полноценных трёх измерениях.
Так что если мы действительно хотим разобраться, как современные 3D-игры формируют изображение, то придётся начать с другого примера: Winning Run компании Namco, вышедшей в 1988-м. Пожалуй, это была первая полностью трёхмерная игра, использующая технологии, которые не слишком сильно отличаются от современных. Конечно, любые игры, возраст которых перевалил за 30 лет, совсем не то же самое, что и, скажем, F1 компании Codemasters, вышедшая в 2018-м. Но принципиальные схемы похожи.
В этой статье мы рассмотрим процесс генерирования 3D-игрой базового изображения для монитора или телевизора. Начнём с финального результата и спросим себя: «На что я смотрю?»
Затем мы проанализируем каждый этап формирования картинки, которую мы видим. По ходу действия рассмотрим такие понятия, как вершины и пиксели, текстуры и проходы, буферы и шейдинг, ПО и инструкции. Узнаем, как участвует в процессе видеокарта и для чего она вообще нужна. После этого вы сможете взглянуть на свои игры и ПК в новом свете и начнёте больше ценить видеографику.
Параметры кадры: пиксели и цвета
Запустим 3D-игру, в качестве образца возьмём выпущенную в 2007-м Crysis компании Crytek. Ниже — фотография дисплея, на котором отображается игра:
Такую картинку обычно называют кадром. Но на что именно мы смотрим? Воспользуемся макрообъективом:
К сожалению, блики и внешняя подсветка монитора портят фото, но если его немного улучшить мы получим
Мы видим, что кадр в мониторе состоит из сетки отдельных раскрашенных элементов, а если увеличим их ещё больше, то заметим, что каждый элемент представляет собой блок из трёх кусочков. Такой блок называется пикселем (pixel, сокращение от picture element). В большинстве мониторов пиксели раскрашиваются с помощью трёх цветов: красного, зелёного и синего (RGB, red-green-blue). Чтобы отобразить на дисплее новый кадр, нужно обработать список из тысяч, если не миллионов, RGB-значений и сохранить их во фрагменте памяти, к которой у монитора есть доступ. Такие фрагменты памяти называют буферами, то есть монитор получает содержимое буфера кадров.
Это финальная точка всего процесса, так что теперь будем двигаться в обратном направлении к его началу. Процесс часто описывают термином рендеринг (отрисовка), но на самом деле это последовательность связанных друг с другом отдельных шагов, которые по своей сути сильно различаются. Представьте себе, что вы шеф-повар в ресторане, удостоенном звезды Мишлен: конечный результат — это тарелка со вкусной едой, но сколько всего нужно сделать, чтобы этого добиться. Как и в приготовлении пищи, для рендеринга нужны основные ингредиенты.
Необходимые строительные элементы: модели и текстуры
Основными кирпичиками любой 3D-игры являются визуальные ресурсы, заполняющие мир, который будет отрисован. Фильмам, ТВ-шоу и театрам нужны актёры, костюмы, бутафория, декорации, освещение — список довольно велик. То же самое и с 3D-играми. Всё, что вы видите в сгенерированном кадре, было разработано художниками и специалистами по моделированию. Чтобы было понятнее, обратимся к старой школе и взглянем на модель из игры Quake II компании id Software:
Игра вышла больше 20 лет назад. В то время Quake II был технологическим шедевром, хотя, как и в любой игре тех лет, модели тут выглядят весьма примитивно. Зато легко продемонстрировать, из чего они состоят.
На предыдущей картинке мы видим угловатого чувака, состоящего из соединённых друг с другом треугольников. Каждый угол называется вершиной, или вертексом (vertex). Каждый вертекс действует как точка в пространстве и описывается как минимум тремя числами: координатами x, y, z. Однако 3D-игре этого мало, поэтому у каждого вертекса есть дополнительные значения: цвет, направление лицевой стороны (да, у точки не может быть лицевой стороны… просто читайте дальше!), яркость, степень прозрачности и т. д.
У вертексов всегда есть набор значений, связанный с текстурными картами. Это картинки «одежды», которую носит модель. Но поскольку изображение плоское, карта должна содержать вид с любого направления, откуда мы можем посмотреть на модель. Примере с Quake II иллюстрирует простой подход: изображения спереди, сзади и с боков (руки). А современные 3D-игры уже оперируют для моделей многочисленными текстурными картами, каждая из которых содержит множество деталей, без каких-либо пустых мест между ними. Некоторые карты не выглядят как материалы или свойства, вместо этого они предоставляют информацию о том, как свет отражается от поверхности. У каждого вертекса есть набор координат в связанной с моделью текстурной карте, так что она может быть «натянута» на вертекс. Это означает, что при перемещении вертекса текстура переместится вместе с ним.
В отрисованном трёхмерном мире всё, что вы видите, начинается с набора вершин и текстурных карт. Они загружаются в связанные друг с другом буферы памяти. Вертексный буфер (vertex buffer) содержит текстуры и выделенные для последующей отрисовки порции памяти. Буфер команд (command buffer) содержит список инструкций, что нужно делать с этими ресурсами.
Всё это формирует необходимый фреймворк, который будет использоваться для создания финальной сетки раскрашенных пикселей. В некоторых играх это огромный объём данных, потому что слишком долго пересоздавать буферы для каждого нового кадра. Также игры хранят в буферах информацию, необходимую для формирования целого мира, который игрок может увидеть, или достаточную большую его часть, обновляя по мере необходимости. Например, в гоночной игре наподобие F1 2018 всё будет храниться в одной большой коллекции буферов. А в игре с открытым миром, наподобие Skyrim, данные будут подгружаться в буферы и удаляться из них по мере перемещения камеры по миру.
Настройка сцены: вертексы
Имея всю визуальную информацию, игра затем начнёт процесс визуального отображения. Сцена начинается в некой позиции по умолчанию, с базовым расположением моделей, источников света и т.д. Это будет «нулевой» экран — исходная точка для графики. Он часто не отображается, просто обрабатывается системой. Чтобы проиллюстрировать, что происходит на первом этапе рендеринга, мы воспользуемся онлайн-инструментом Real-Time Rendering. Создадим самую простую «игру»: параллелепипед, стоящий на земле.
Этот объект содержит 8 вершин, каждая из которых описывается списком чисел. Вершины формируют модель, состоящую из 12 треугольников. Каждый треугольник, и даже сам объект называется примитивом. По мере движения, вращения и масштабирования примитивов числа проходят через цепочки математических операций и обновляются.
Обратите внимание, что числа model point не изменяются. Эти числа показывают, где именно расположена модель в виртуальном мире. Рассмотрение соответствующих математических расчётов выходит за рамки статьи, скажем лишь, что сначала все объекты помещаются туда, где они должны быть. А затем начинается окрашивание.
Возьмём другую модель, имеющую в 10 раз больше вершин, чем предыдущий параллелепипед. В ходе самого простого процесса окрашивания берётся цвет каждого вертекса, а затем вычисляются изменения цвета от поверхности к поверхности. Это называется интерполяцией.
Увеличение количества вершин в модели не только позволяет создавать более реалистичные объекты, но и улучшает результат цветовой интерполяции.
На этом этапе рендеринга может подробно вычисляться влияние источников света в сцене. Например, как материалы модели отражают цвет. Такие вычисления должны учитывать положение и направление камеры, а также положение и направление источников света.
Для этого есть целый ряд разных математических методик, одни простенькие, другие очень сложные. На иллюстрации выше мы видим, что объект справа выглядит гораздо приятнее и реалистичнее, но для его отрисовки требуется больше работы.
Важно отметить, что сейчас объекты с небольшим количеством вершин мы сравниваем с самыми современными играми. Пролистайте вверх и внимательно рассмотрите изображение из Crysis: в одной этой сцене отображается больше миллиона треугольников. На примере бенчмарка Unigine Valley можно понять, сколько треугольников используется в современных играх.
Каждый объект на этом изображении состоит из соединённых друг с другом вершин, который образуют состоящие из треугольников примитивы. Бенчмарк можно запускать в каркасном (wireframe) режиме, в котором рёбра каждого треугольника обозначаются белыми линиями.
Как видите, любой объект состоит из треугольников, и для каждого треугольника вычисляется расположение, направление и цвет. При этом учитывается расположение источников света, а также расположение и направление камеры. Все изменения, связанные с вершинами, нужно передать игре, чтобы она имела всю необходимую информацию для отрисовки следующего кадра — это делается с помощью обновления вертексного буфера.
Удивительно, но это не самая сложная часть рендеринга, с подходящим оборудованием все вычисления выполняются за несколько тысячных долей секунды! Идём дальше.
Теряем измерение: растеризация
После обработки всех вершин и завершения размещения всех объектов в нашей трёхмерной сцене, процесс рендеринга переходит к очень важному этапу. До этого момента игра была истинно трёхмерной, но финальный кадр таковым уже не является: в ходе ряда изменений просматриваемый мир преобразуется из 3D-пространства, состоящего из тысяч связанных точек, в двумерное изображение, состоящее из раскрашенных пикселей. В большинстве игр эта процедура состоит минимум из двух этапов: проецирования экранного пространства (screen space projection) и растеризации.
Вернёмся к нашему веб-инструменту для рендеринга, он покажет нам, как объём виртуального мира превращается в плоское изображение. Слева изображена камера, исходящие из неё линии создают усечённую пирамиду видимости (frustum), и всё, что в неё попадает, может быть отображено в финальном кадре. Перпендикулярное сечение пирамиды называется областью просмотра (viewport) — это то, что будет показано на мониторе. Для проецирования всего содержимого пирамиды в область просмотра с учётом перспективы камеры используются многочисленные математические вычисления.
Хотя графика в области просмотра двумерная, данные всё ещё истинно трёхмерны, и позднее эта информация будет использована для вычисления, какие примитивы нам видны, а какие скрыты. Это может быть на удивление сложно сделать, потому что примитивы могут отбрасывать видимые нам тени, даже если сами примитивы скрыты от нас. Удаление скрытых от нас примитивов называется отбрасыванием (culling). Эта операция может существенно повлиять на скорость отрисовки всего кадра. После завершения сортировки на видимые и скрытые примитивы, а также удаления треугольников вне пределов пирамиды видимости, завершается последний этап трёхмерности и с помощью растеризации кадр делается полностью двумерным.
На иллюстрации выше показан очень простой пример кадра, содержащего один примитив. Пиксельная сетка накладывается на геометрическую форму и соответствующие пиксели помечаются для последующей обработки. Конечный результат выглядит не слишком похожим на исходный треугольник, потому что мы используем недостаточно пикселей. В связи с этим возникает проблема алиасинга (aliasing, ступенчатость линий), которая решается различными способами. Поэтому изменение в игре разрешения (общего количества пикселей в кадре) так сильно влияет на конечный результат: больше пикселей не только улучшает отображение форм, но и уменьшает влияние нежелательного алиасинга.
После завершения этой части рендеринга мы переходим к следующему большому этапу: финальному раскрашиванию всех пикселей в кадре.
Несите свет: пиксельный этап
Мы подошли к самому сложному этапу рендеринга. Когда-то он сводился к натягиванию на модели одежды (текстур) с использование информации о пикселях (изначально полученной от вершин). Однако дело в том, что хотя текстуры и сам кадр двумерны, однако виртуальный мир на стадии обработки вертексов был искажён, сдвинут и изменён. Для учёта всего этого применяются дополнительные математические вычисления, однако результату могут быть свойственны новые проблемы.
На этой иллюстрации к плоскости применена текстура шахматной доски. Возникает неприятная визуальная рябь, которая усугубляется алиасингом. Для решения этой проблемы применяют уменьшенные версии текстурных карт (множественные отображения, mipmaps), многократное использование информации из этих текстур (фильтрация, filtering) и дополнительные математические вычисления. Эффект заметен:
Для любой игры это было действительно сложным этапом, но сегодня это уже не так, потому что из-за широкого использования других визуальных эффектов, — таких как отражения и тени, — обработка текстур превратилась в относительно небольшой этап процесса рендеринга. При игре на высоких разрешениях нагрузка на этапах растеризации и обработки пикселей возрастает, но на обработку вертексов это влияет относительно мало. Хотя первичное раскрашивание из-за источников света выполняется на вертексном этапе, однако могут применяться и более изощрённые световые эффекты.
На предыдущей иллюстрации мы уже не видим изменений цвета между разными треугольниками, что даёт нам ощущение гладкого бесшовного объекта. Хотя в этом примере сфера состоит из того же количества треугольников, что и зелёная сфера на иллюстрации выше, однако в результате процедуры раскрашивания пикселей нам кажется, что используется гораздо больше треугольников.
Во многих играх пиксельный этап приходится прогонять несколько раз. Например, чтобы зеркало или поверхность воды отражали окружающий мир, это мир нужно сначала отрисовать. Каждый прогон называется проходом (pass), и для получения финального изображения для каждого кадра легко может использоваться четыре и больше проходов.
Также иногда нужно снова прогонять вертексный этап, чтобы перерисовать мир с другой точки и использовать это изображение в сцене, которая показывается игроку. Для этого применяют однобуферную прорисовку (render targets) — используют буферы, которые действуют как финальное хранилище для кадра, но могут выступать и в роли текстур при другом проходе.
Чтобы оценить сложность пиксельного этапа, можете почитать анализ кадра в Doom 2016. Вы будете потрясены количеством операций, которые необходимы для создания одного кадра.
Всю проделанную работу по созданию кадра нужно сохранить в буфер, будь то финальный или промежуточный результат. В целом игра использует на лету минимум два буфера для финального отображения: один для «текущей работы», а второй буфер либо ожидает обращения к нему монитора, либо находится в процессе отображения. Всегда нужен буфер экрана, в котором будут сохраняться результат рендеринга, и когда все буферы заполняются необходимо двигаться дальше и создавать новый буфер. По завершении работы с кадром даётся простая команда, финальные кадровые буферы меняются местами, монитор получает последний отрисованный кадр и запускается процесс рендеринга следующего кадра.
В этом кадре из Assassin’s Creed Odyssey мы видим содержимое завершённого кадрового буфера. Это содержимое можно представить в виде таблицы, которая содержит только числа. Они в виде электрических сигналов отправляются в монитор или телевизор, и пиксели экрана меняют свои значения. Наши глаза видят плоское сплошное изображение, однако наш мозг интерпретирует его как трёхмерное. За кулисами всего лишь одного кадра в игре скрывается так много работы, что стоит взглянуть, как же программисты с этим справляются.
Управление процессом: API и инструкции
Придумать, как заставить игру выполнять и управлять всеми вычислениями, вершинами, текстурами, освещением, буферами и т.д. — это огромная задача. К счастью, нам помогают в этом программные интерфейсы (application programming interface, API).
API для рендеринга уменьшают общую сложность, предлагая структуры, правила и программные библиотеки, позволяющие использовать упрощённые инструкции, которые не зависят от оборудования. Возьмите любую 3D-игру, выпущенную для ПК в течение последних трёх лет: она создана с использованием одного из трёх популярных API — Direct3D, OpenGL или Vulkan. Есть и другие подобные разработки, особенно в мобильном сегменте, но в этой статье мы будем говорить об упомянутых трёх.
Несмотря на различия в наименованиях инструкций и операций (например, блок кода для обработки пикселей в DirectX называется пиксельным шейдером (pixel shader), а в Vulkan — фрагментным шейдером (fragment shader)), конечный результат не отличается, точнее, не должен отличаться.
Разница будет проявляться в том, какое оборудование используется для рендеринга. Инструкции, генерируемые API, нужно преобразовать в понятные для оборудования команды, которые обрабатываются драйверами устройства. И производителям оборудования приходится тратить много ресурсов и времени на то, чтобы их драйверы выполняли это преобразование как можно быстрее и корректнее.
К примеру, ранняя бета-версия игры The Talos Principle (2014) поддерживала все три упомянутых API. Чтобы продемонстрировать, как могут отличаться результаты работы разных комбинаций драйверов и интерфейсов, мы прогнали стандартный встроенный бенчмарк, выставив разрешение в 1080р и максимальные настройки качества. Процессор Intel Core i7-9700K работал без разгона, видеокарта Nvidia Titan X (Pascal), оперативная память — 32 Гб DDR4 RAM.
Не так-то просто создать с нуля программу, которая рендерит 3D-игру. Поэтому сегодня в очень многих играх применяются лицензированные сторонние системы (например, Unreal Engine). Чтобы оценить их сложность, откройте open source-движок для Quake и просмотрите файл gl_draw.c file: он содержит инструкции для разных операций рендеринга и отражает лишь малую часть всего движка. А ведь Quake вышел больше 20 лет назад, и вся игра (включая все визуальные ресурсы, звуки, музыку и т.д.) занимает 55 Мб. Для сравнения, в Far Cry 5 одни только шейдеры занимают 62 Мб.
Время важнее всего: использование правильного оборудования
Всё вышеописанное может вычислить и обработать процессор любой компьютерной системы. Современные процессоры семейства x86-64 поддерживают все необходимые математические операции и даже содержат для этого отдельные подсистемы. Однако задача отрисовки одного кадра требует выполнения многочисленных повторяющихся вычислений и значительного распараллеливания работы. Центральные процессоры для этого не приспособлены, потому что они создаются для решения как можно более широкого круга задач. Специализированные процессоры для графических вычислений называются GPU (graphics processing units). Они создаются для того, чтобы DirectX, OpenGL и Vulkan могли много и быстро параллельно выполнять математические операции.
Воспользуемся бенчмарком, который позволяет рендерить кадр с помощью центрального процессора или специализированного оборудования — V-ray NEXT компании Chaos Group. На самом деле, он выполняет трассировку лучей, а не рендеринг, но большинство числовых операций здесь так же зависят от оборудования.
Прогоним бенчмарк в трёх режимах: только центральный процессор, только графический процессор, и комбинация обоих процессоров:
Результат не должен вас удивить:
Разница возрастает ещё больше, если прогнать самый сложный тест бенчмарка — Mother Nature. Центральный процессор выдал ничтожные 3,1 кадра/с.! А графический процессор взмыл на 1388 кадра/с.: почти в 450 раз быстрее. Обратите внимание: 3DMark03 вышел 16 назад, а в тесте на центральном процессоре обрабатываются только вершины, графический процессор всё-равно берёт на себя растеризацию и пиксельный этап. Представьте, если бы бенчмарк было современным и большая часть операций выполнялась программно?
Теперь снова попробуем бенчмарк Unigine Valley, обрабатываемая им графика очень похожа на ту, что используется в играх вроде Far Cry 5. Также тут есть полностью программный механизм рендеринга в дополнение к стандартному DirectX 11. При прогоне на видеопроцессоре получили средний результат в 196 кадров/с. А программная версия? После пары падений мощный тестовый ПК выдал в среднем 0,1 кадра/с. — почти в две тысячи раз медленнее.
Причина такого большого различия кроется в математических вычислениях и формате данных, который используется в 3D-рендеринге. Каждое ядро центрального процессора оснащено модулями операций с плавающей запятой. i7-9700K содержит 8 ядер, в каждом по два таких модуля. И хотя архитектура модулей в Titan X другая, оба вида могут выполнять одни и те же вычисления с данными одного и того же формата. Эта видеокарта имеет свыше 3500 модулей для выполнения сравнимых вычислений, и хотя их тактовая частота гораздо ниже, чем в центральном процессоре (1,5 ГГц и 4,7 ГГц), однако видеопроцессор берёт количеством модулей.
Хотя Titan X не является массовой видеокартой, однако даже бюджетная модель обгонит любой центральный процессор. Поэтому все 3D-игры и API спроектированы под специализированное оборудование. Можете скачать V-ray, 3DMark или любой бенчмарк Unigine и протестировать свою систему — сами убедитесь, насколько хорошо видеопроцессоры адаптированы для рендеринга графики в играх.
Заключительные слова
Это был короткий экскурс в процесс создания одного кадра в 3D-играх, от точки в пространстве до красочного изображения на мониторе.
По сути, весь процесс — это лишь работа с числами. Однако очень многое осталось за рамками статьи. Мы не рассматривали конкретные математические вычисления из евклидовой линейной алгебры, тригонометрии и дифференциальных исчислений, выполняемые вертексными и пиксельными шейдерами. Также мы не поговорили о том, как с помощью статистической выборки обрабатываются текстуры. Опустили такие классные визуальные эффекты, как преграждение окружающего света в экранном пространстве, уменьшение помех при трассировке лучей, применение расширенного динамического диапазона и временное сглаживание.
А когда вы в следующий раз запустите современную 3D-игру, надеемся, вы не только посмотрите на графику иными глазами, но и захотите узнать о ней больше.