Новости

Покадровый разбор: как работает графический движок League of Legends

Автор Дата 29.01.2017

Наше вам с кисточкой, я Тони Альбрехт, один из инженеров Render Strike Team — нового начинания в League of Legends. Буква команда должна улучшить движок рендеринга зрелище, и нам не терпится приступить к работе. Я телеграфным слогом расскажу о том, как движок работает безотложно.

Для меня это отличный отмазка пройтись по этапам графического конвейера ради того, чтобы команда поняла, по-над чем нам предстоит работать. Я расскажу, в качестве кого League of Legends строит и отображает спорадичный кадр в игре (напомню, на мощных компьютерах сие происходит более 100 раз в постойте). Обсуждение будет насыщено техническими подробностями, однако я надеюсь, окажется доступным даже чтобы тех, у кого нет опыта в рендеринге.

Пользу кого начала — пара слов о доступных нам графических библиотеках. League of Legends должна делать максимально эффективно на многих платформах. Как-то, Windows XP сейчас четвёртая по популярности ОС посредь наших игроков (после Windows 7, 10 и 8). Всякий месяц пользователи Windows XP участвуют в сильнее чем 10 миллионах матчей, и воеже сохранить обратную совместимость, мы должны стоять на стороне DirectX 9 и использовать только его фишки. Да мы с тобой пользуемся в целом аналогичным набором функций изо OpenGL 1.5 на компьютерах с OS X, а это скоро изменится.

Рендеринг ради начинающих

В большей части компьютеров установлены CPU (коренной процессор) и GPU (графический процессор). Центральный вычислитель отвечает за логику и вычисления зрелище, в то время как графический получает с него треугольники (triangles) и текстуры и отображает их сверху экране как пиксели. Пиксельные шейдеры (pixel shaders) — небольшие программы сверху GPU, позволяющие нам влиять на ведь, как проходит рендеринг.

Например, только и можно изменить то, как текстуры накладываются получай треугольники, или заставить GPU выполнить выкладки для каждого тексела текстуры. Таким образом, поди применить текстуру к треугольнику, или отбузовать на него множество различных текстур, либо — либо запустить более сложные процессы, нав бамп-маппинга (bump mapping), освещения, отражений река высокореалистичных шейдеров кожи. Все видимые объекты отрисовываются в кадровом буфере и показываются для экране, когда рендеринг завершён.

Рассмотрим по образу и подобию. Вот изображение Гарена, демонстрирующее однако 6336 треугольников на каркасе — монолитная образчик без текстур. Её создали наши художники и экспортировали в размер, который может читать и анимировать указатель League of Legends. Можно заметить неплоское тенение: это ограничение приложения, используемого к исследования рендеринга.

Изображение модели помимо текстур не только скучное, же и неясное. Оно не передаёт того Гарена, которого пишущий эти строки все знаем. Чтобы оживить героя, нужны текстуры.

Текстуры Гарена лежат получай диске в виде DDS- или TGA-файлов, выглядящих не хуже кого кадр из фильма ужасов. Же если корректно применить их к модели, да мы с тобой получим такое изображение:

Это сейчас на что-то похоже. Шейдер, какой рендерит наши сетки со скиннингом (skinned meshes), мало-: неграмотный только накладывает текстуры на модели, же об этом мы ещё поговорим в дальнейшем.

Это основы, но League of Legends должна рендерить безлюдный (=малолюдный) только модель чемпиона и текстуры. Рассмотрим шаг за шагом весь рендеринг приведённой ниже сцены.

Отрезок 0: туман войны

До основные принципы отрисовывания сцены мы должны обработать туман войны и тени (туман и тени — важно зловеще). Центральный процессор хранит туча войны в виде сетки (grid) 128 в 128, которая масштабируется до квадратной текстуры 512 нате 512. После мы размываем эту текстуру и с её через затемняем соответствующие зоны и области получи и распишись миникарте.

Этап 1: тени

Тени — обязательная отделение 3D-сцены, без них будет каков кто (собой, что объекты висят в воздухе. Тени должно рендерить относительно источника света, дабы казалось, что их отбрасывают миньоны неужели чемпион. Расстояние от источника света до самого объекта, отбрасывающего тень, учитывается пользу кого каждого пикселя в RGB-компонентах, а альфа-звено обнуляется.

На первом изображении вверху — поле высоты теней (shadow height field) осаждённой башни, миньонов и двух чемпионов в RGB. Сверху втором — только альфа-компонент. Текстуры были обрезаны, с тем чтоб детали теней были виднее: миньоны внизу, а донжон и чемпионы — наверху.

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

Этап 2: статичная геометрия

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

Обратите внимание на тени миньонов, а и на туман войны, залезающий получай границы сцены. На карте Стремнина призывателей (The Summoner’s Rift) для статичной геометрии никак не рендерятся динамические тени. Главный источник света мало-: неграмотный движется, поэтому тени статичных сеток (static meshes) «запекаются» держи их текстурах. Так художники могут превыше контролировать внешний вид карты, и улучшается режим (поскольку не нужно рендерить тени через статичных сеток). Тени могут кидать только миньоны, башни и чемпионы.

Раунд 3: скиннинг

На рельеф и тени сделано можно накладывать объекты. В первую ряд — миньонов, чемпионов и башни, — то проглатывать те, что должны реалистично (пере)двигать(ся) и иметь сгибающиеся суставы (bending joints).

Каждая анимированная комарник (animated mesh) содержит скелет (основа из иерархически выстроенных костей) и сетку треугольников (mesh of triangles), наравне на изображении Гарена выше. Каждая яйла связана с костями (от одной вплоть до четырёх), при движении которых вершины двигаются в манер кожи — отсюда и название «скиннинг». Наши художники создают сетки и анимации для того всех объектов и экспортируют их в параметры, который загружается в League of Legends в начале зрелище.

Все кости сетки модели Гарена продемонстрированы получи изображениях выше. Слева — его прах с названиями. Справа — вершины (голубые кубы) и жёлтые контуры, показывающие их привязку к костям, которые управляют их положением.

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

Этап 4: контуры

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

Контуры получаются с через масштабированной глубины с предыдущего этапа, к которой применяется фильтр Собеля (Sobel filter), извлекающий размер, которые мы рендерим на каждую сетку точно по отдельности. Если же GPU не может совершать рендеринг на несколько объектов единовременно, применяется резервный метод с использованием стенсил-яички.

Этап 5: трава

Тени травы — отделение текстуры земли, они не рендерятся подвижно. Теперь добавляем траву:

Пучки травы — также сетки со скиннингом. Так пишущий эти строки можем анимировать их, когда минуя них проходят персонажи или присутствие дуновении ветра в Ущелье Призывателей (Summoner’s Rift).

Фаза 6: вода

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

Пусть подчеркнуть эффекты воды (которые без- особо бросаются в глаза), я убрал геометрию перед водой, но сохранил прозрачность. Сие подчёркивает эффекты, чтобы нам было уймись их изучить.

На следующем изображении выделен остов всей ряби.

Здесь хорошо видны эффекты воды у берегов реки, кругом камней и кувшинок.

Анимированная и при нормальном рендеринге агиасма выглядит так:

Этап 7: декали

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

Этап 8: особая обводка

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

Этап 9: частицы

Ниже идёт один из самых важных этапов: частицы. Я ранее писал о них статью раньше. Каждое мольба, усиление и эффект — это система частиц, которую нужно анимировать и обновляться. Конкретно эта сцена не таково динамична, как, скажем, бой 5 сверху 5, но в ней всё в равной степени немало частиц.

Отобразив только частицы (заключая убрав фон), мы увидим следующее:

Разве что показать треугольники частиц (без текстур), пишущий эти строки увидим фиолетовую геометрию:

А так выглядят частицы около обычной отрисовке.

Этап 10: заключительная обработка. Ant. предобработка

Теперь, когда основная часть сцены отрисована, нужно её «отполировать». Для того этого мы сначала делаем доступ с антиалиасингом (АА) — сглаживаем границы и делаем ухажер «чище». На статичном изображении настоящий эффект не очень заметен, да он здорово помогает снизить коэффициент полезного действия мерцающих пикселей, который возникает близ перемещении высококонтрастных границ по экрану. В League of Legends да мы с тобой используем алгоритм быстрого сглаживания Fast Approximate Anti-Aliasing.

Получай картинке слева — миньон без сглаживания, а направо — сглаженный с помощью FXAA. Обратите рачительность, как смягчились границы.

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

Этап 11: вред и полоски здоровья

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

Этап 12: пользовательский интерфейс (HUD)

Напоследок, отрисовывается пользовательский интерфейс. Текст, иконки и предметы накладываются сверх всего остального, как отдельные текстуры. В этой сцене близко тысячи треугольников используются для интерфейса, едва не 300 для мини-карты и 700 — чтобы всего остального.

Объединяем всё

Все сцена содержит около 200 тысяч треугольников, примерно 90 тысяч из них используются только лишь для частиц. За 625 вызовов отрисовки (draw calls) рендерится 28 миллионов пикселей. На комфортной игры это должно свершаться максимально быстро. Можно достичь больше 60 кадров в секунду, если по сию пору этапы проходятся менее чем вслед за 16,66 миллисекунд.

То, что автор описали, происходит со стороны графического процессора. Ключевой процессор за это время обсчитывает всю игровую логику, обрабатывает команды ввода пользователя, коллизию, частицы, анимацию и подаёт команды для GPU. Если частота кадров у вас достигает 300, из чего следует всё это происходит менее нежели за 3,3 миллисекунды.

Зачем пересобирать указатель рендеринга

Теперь вы понимаете, с какими сложностями связан рендер отдельного приятельница League of Legends. Но это лишь только со стороны вывода данных. Возьми экране вы видите результат сотен тысяч вызовов функций к движку рендеринга — спирт постоянно меняется и развивается, чтобы протестовать требованиям времени. В кодовой базе зрелище есть разные формы рендеринга про поддержки нового и старого оборудования.

Игра в карты работают по-разному: Ущелье призывателей (Summoner’s Rift) выполняет рендеринг два-три иначе, чем Воющая бездна (Howling Abyss) неужели Проклятый лес (Twisted Treeline). Какие-ведь части движка рендеринга остались ото прошлых версий League, другие — (на)столь(ко) и не раскрыли свой потенциал.

Начальствование Render Strike Team должна пережечь код, чтобы рендеринг выполнялся сверх один и тот же интерфейс. Коли мы с этим справимся — игроки маловыгодный заметят разницы (кроме, возможно, улучшения производительности в некоторых моментах). Да после завершения работы мы сможем вводить изменения во все режимы зрелище одновременно.

Источник: vc.ru