что такое качество рендеринга в играх
Что такое качество рендеринга в играх
Думаю, с понятием разрешения знакомы уже более-менее все игроки, но на всякий случай вспомним основы. Все же, пожалуй, главный параметр графики в играх.
Изображение, которое вы видите на экране, состоит из пикселей. Разрешение — это количество пикселей в строке, где первое число — их количество по горизонтали, второе — по вертикали. В Full HD эти числа — 1920 и 1080 соответственно. Чем выше разрешение, тем из большего количества пикселей состоит изображение, а значит, тем оно четче и детализированнее.
Влияние на производительность
Очень большое.Увеличение разрешения существенно снижает производительность. Именно поэтому, например, даже топовая RTX 2080 TI неспособна выдать 60 кадров в 4K в некоторых играх, хотя в том же Full HD счетчик с запасом переваливает за 100. Снижение разрешения — один из главных способов поднять FPS. Правда, и картинка станет ощутимо хуже.
В некоторых играх (например, в Titanfall) есть параметр так называемого динамического разрешения. Если включить его, то игра будет в реальном времени автоматически менять разрешение, чтобы добиться заданной вами частоты кадров.
Вертикальная синхронизация
Если частота кадров в игре существенно превосходит частоту развертки монитора, на экране могут появляться так называемые разрывы изображения. Возникают они потому, что видеокарта отправляет на монитор больше кадров, чем тот может показать за единицу времени, а потому картинка рендерится словно «кусками».
Вертикальная синхронизация исправляет эту проблему. Это синхронизация частоты кадров игры с частотой развертки монитора. То если максимум вашего монитора — 60 герц, игра не будет работать с частотой выше 60 кадров в секунду и так далее.
Есть и еще одно полезное свойство этой опции — она помогает снизить нагрузку на «железо» — вместо 200 потенциальных кадров ваша видеокарта будет отрисовывать всего 60, а значит, загружаться не на полную и греться гораздо меньше.
Впрочем, есть у Vsync и недостатки. Главная — очень заметный «инпут-лаг», задержка между вашими командами (например, движениями мыши) и их отображением в игре.
Поэтому играть со включенной вертикальной синхронизацией в мультипеере противопоказано. Кроме того, если ваш компьютер «тянет» игру при частоте ниже, чем заветные 60 FPS, Vsync может автоматически «лочиться» уже на 30 FPS, что приведет к неслабым таким лагам.
Лучший способ бороться с разрывами изображения на сегодняшний день — купить монитор с поддержкой G-Sync или FreeSync и соответствующую видеокарту Nvidia или AMD. Ни разрывов, ни инпут-лага.
Влияние на производительность
В общем и целом — никакого.
Сглаживание(Anti-aliasing)
Если нарисовать из квадратных по своей природе пикселей ровную линию, она получится не гладкой, а с так называемыми «лесенками». Особенно эти лесенки заметны при низких разрешениях. Чтобы устранить этот неприятный дефект и сделать изображения более четким и гладким, и нужно сглаживание.
Здесь и далее — слева изображение с отключенной графической опцией (или установленной на низком значении), справа — с включенной (или установленной на максимальном значении).
Технологий сглаживания несколько, вот основные:
Влияние на производительность
От ничтожного (FXAA) до колоссального (SSAA). В среднем — умеренное.
Качество текстур
Один из самых важных параметров в настройках игры. Поверхности всех предметов во всех современных трехмерных играх покрыты текстурами, а потому чем выше их качество и разрешение — тем четче, реалистичнее картинка. Даже самая красивая игра с ультра-низкими текстурами превратится в фестиваль мыловарения.
Влияние на производительность
Если в видеокарте достаточно видеопамяти, то практически никакого. Если же ее не хватает, вы получите ощутимые фризы и тормоза. 4 гигабайт VRAM хватает для подавляющего числа современных игр, но лучше бы в вашей следующей видеокарте памяти было 8 или хотя бы 6 гигабайт.
Анизотропная фильтрация
Анизотропная фильтрация, или фильтрация текстур, добавляет поверхностям, на которые вы смотрите под углом, четкости. Особенно ее эффективность заметна на удаленных от игрока текстурах земли или стен.
Чем выше степень фильтрации, чем четче будут поверхности в отдалении.
Этот параметр влияет на общее качество картинки довольно сильно, но систему при этом практически не нагружает, так что в графе «фильтрация текстур» советуем всегда выставлять 8x или 16x. Билинейная и трилинейная фильтрации уступают анизотропной, а потому особенного смысла в них уже нет.
Влияние на производительность
Тесселяция
Технология, буквально преображающая поверхности в игре, делающая их выпуклыми, рельефными, натуралистичными. В общем, тесселяция позволяет отрисовывать гораздо более геометрически сложные объекты. Просто посмотрите на скриншоты.
Влияние на производительность
Зависит от игры, от того, как именно движок применяет ее к объектам. Чаще всего — среднее.
Качество теней
Все просто: чем выше этот параметр, тем четче и подробнее тени, отбрасываемые объектами. Добавить тут нечего. Иногда в играх также встречается параметр «Дальность прорисовки теней» (а иногда он «вшит» в общие настройки). Тут все тоже понятно: выше дальность — больше теней вдалеке.
Влияние на производительность
Зависит от игры. Чаще всего разница между низкими и средними настройками не столь велика, а вот ультра-тени способны по полной загрузить ваш ПК, поскольку в этом случае количество объектов, отбрасывающих реалистичные тени, серьезно вырастает.
Глобальное затенение (Ambient Occlusion)
Один из самых важных параметров, влияющий на картинку разительным образом. Если вкратце, то AO помогает имитировать поведения света в трехмерном мире — а именно, затенять места, куда не должны попадать лучи: углы комнат, щели между предметами и стенами, корни деревьев и так далее.
Существует два основных вида глобального затенения:
SSAO (Screen space ambient occlusion). Впервые появилось в Crysis — потому тот и выглядел для своего времени совершенно фантастически. Затеняются пиксели, заблокированные от источников света.
HBAO (Horizon ambient occlusion). Работает по тому же принципу, просто количество затененных объектов и зон гораздо больше, чем при SSAO.
Влияние на производительность
Глубина резкости (Depth of Field)
То самое «боке», которое пытаются симулировать камеры большинства современных объектов. В каком-то смысле это имитация особенностей человеческого зрения: объект, на который мы смотрим, находится в идеальном фокусе, а объекты на фоне — размыты. Чаще всего глубину резкости сейчас используют в шутерах: обратите внимание, что когда вы целитесь через мушку, руки персонажа и часть ствола чаще всего размыты.
Впрочем, иногда DoF только мешает — складывается впечатление, что у героя близорукость.
Влияние на производительность
Целиком и полностью зависит от игры. От ничтожного до довольно сильного (как, например, в Destiny 2).
Bloom (Свечение)
Этот параметр отвечает за интенсивность источников света в игре. Например, с включенным Bloom, свет, пробивающийся из окна в помещение, будет выглядеть куда ярче. А солнце создавать натуральные «засветы». Правда, некоторые игры выглядят куда реалистичнее без свечения — тут нужно проверять самому.
Влияние на производительность
Чаще всего — низкое.
Motion Blur (Размытие в движении)
Motion Blur помогает передать динамику при перемещениях объекта. Работает он просто: когда вы быстро двигаете камерой, изображение начинает «плыть». При этом главный объект (например, руки персонажа с оружием) остается четким.
Что такое рендеринг? И что такое рендер? Словарь разработчиков компьютерных игр!
В продолжении ликбеза по компьютерной графике как для программистов, так и для художников хочу поговорить о том что такое рендеринг. Вопрос не так сложен как кажется, под катом подробное и доступное объяснение!
Я начал писать статьи, которые являются ликбезом для разработчика игр. И поторопился, написав статью про шейдеры, не рассказав что же такое рендеринг. Поэтому эта статья будет приквелом к введению в шейдеры и отправным пунктом в нашем ликбезе.
Что такое рендеринг? (для программистов)
Итак, Википедия дает такое определение: Ре́ндеринг (англ. rendering — «визуализация») — термин в компьютерной графике, обозначающий процесс получения изображения по модели с помощью компьютерной программы.
Довольно неплохое определение, продолжим с ним. Рендеринг — это визуализация. В компьютерной графике и 3д-художники и программисты под рендерингом понимают создание плоской картинки — цифрового растрового изображения из 3д сцены.
То есть, неформальный ответ на наш вопрос «Что такое рендеринг?» — это получение 2д картинки (на экране или в файле не важно). А компьютерная программа, производящая рендеринг, называется рендером (англ. render) или рендерером (англ. renderer).
Рендер
В свою очередь словом «рендер» называют чаще всего результат рендеринга. Но иногда и процесс называют так же (просто в английском глагол — render перенесся в русский, он короче и удобнее). Вы, наверняка, встречали различные картинки в интернете, с подписью «Угадай рендер или фото?». Имеется ввиду это 3D-визуализация или реальная фотография (уж настолько компьютерная графика продвинулась, что порой и не разберешься).
Виды рендеринга
В зависимости от возможности сделать вычисления параллельными существуют:
Существует много алгоритмов рендеринга, но все их можно разделить на две группы по принципу получения изображения: растеризация 3д моделей и трасировка лучей. Оба способа используются в видеоиграх. Но трасировка лучей чаще используется не для получения изображений в режиме реального времени, а для подготовки так называемых лайтмапов — световых карт, которые предрасчитываются во время разработки, а после результаты предрасчета используются во время выполнения.
В чем суть методов? Как работает растеризация и трасировка лучей? Начнем с растеризация.
Растеризация полигональной модели
Сцена состоит из моделей, расположенных на ней. В свою очередь каждая модель состоит из примитивов.
Это могут быть точки, отрезки, треугольники и некоторые другие примитивы, такие как квады например. Но если мы рендерим не точки и не отрезки, любые примитивы превращаются в треугольники.
Задача растеризатора (программа, которая выполняет растеризацию) получить из этих примитивов пиксели результирующего изображения. Растеризация в разрезе графического пайплайна, происходит после вершинного шейдера и до фрагментного (Статья про шейдеры).
*возможно следующей статьёй будет обещанный мной разбор графического пайплайна, напишите в комментариях нужен ли такой разбор, мне будет приятно и полезно узнать скольким людям интересно это всё. Я сделал отдельную страничку где есть список разобранных тем и будущих — Для разработчиков игр
В случае с отрезком нужно получить пиксели линии соединяющей две точки, в случае с треугольником пиксели которые внутри него. Для первой задачи применяется алгоритм Брезенхема, для второй может применяться алгоритм заметания прямыми или проверки барицентрических координат.
Сложная модель персонажа состоит из мельчайших треугольников и растеризатор генерирует из неё вполне достоверную картинку. Почему тогда заморачиваться с трассировкой лучей? Почему не растеризовать и все? А смысл вот в чем, растеризатор знает только своё рутинное дело, треугольники — в пиксели. Он ничего не знает об объектах рядом с треугольником.
А это значит что все физические процессы которые происходят в реальном мире он учесть не в состоянии. Эти процессы прямым образом влияют на изображение. Отражения, рефлексы, тени, подповерхностное рассеивание и так далее! Все без чего мы будем видеть просто пластмассовые модельки в вакууме…
А игроки хотят графоний! Игрокам нужен фотореализм!
И приходится графическим программистам изобретать различные техники, чтобы достичь близости к фотореализму. Для этого шейдерные программы используют текстуры, в которых предрассчитаны разные данные света, отражения, теней и подповерхностного рассеивания.
В свою очередь трассировка лучей позволяет рассчитать эти данные, но ценой большего времени рассчета, которое не может быть произведено во время выполнения. Рассмотрим, что из себя представляет этот метод.
Трасировка лучей (англ. ray tracing)
Помните о корпускулярно волновом дуализме? Напомню в чем суть: свет ведёт себя и как волны и как поток частиц — фотонов. Так вот трассировка (от англ «trace» прослеживать путь), это симуляция лучей света, грубо говоря. Но трассирование каждого луча света в сцене непрактично и занимает неприемлемо долгое время.
Мы ограничимся относительно малым количеством, и будем трассировать лучи по нужным нам направлениям.
А какие направления нам нужны? Нам надо определять какие цвета будут иметь пиксели в результирующей картинке. Тоесть количество лучей мы знаем, оно равно количеству пикселей в изображении.
Что с направлением? Все просто, мы будем трассировать лучи в соответствии с точкой наблюдения (то как наша виртуальная камера направлена). Луч встретится в какой-то точке с объектом сцены (если не встретится, значит там темный пиксель или пиксель неба из скайбокса, например).
При встрече с объектом луч не прекращает своё распространение, а разделяется на три луча-компонента, каждый из которых вносит свой вклад в цвет пикселя на двумерном экране: отражённый, теневой и преломлённый. Количество таких компонентов определяет глубину трассировки и влияет на качество и фотореалистичность изображения. Благодаря своим концептуальным особенностям, метод позволяет получить очень фотореалистичные изображения, однако из-за большой ресурсоёмкости процесс визуализации занимает значительное время.
Рендеринг для художников
Но рендеринг это не только программная визуализация! Хитрые художники тоже используют его. Так что такое рендеринг с точки зрения художника? Примерно то же самое, что и для программистов, только концепт-художники выполняют его сами. Руками. Точно так же как рендерер в видео-игре или V-ray в Maya художники учитывают освещение, подповерхностное рассеивание, туман и др. факторы, влияющие на конечный цвет поверхности.
К примеру картинка выше, поэтапно прорабатывается таким образом: Грубый скетч — Лайн — Цвет — Объем — Рендер материалов.
Рендер материалов включает в себя текстурирование, проработку бликов — металлы, например, чаще всего очень гладкие поверхности, которые имеют четкие блики на гранях. Помимо всего этого художники сталкиваются с растеризацией векторной графики, это примерно то же самое, что и растеризация 3д-модели.
Растеризация векторной графики
Суть примерно такая же, есть данные 2д кривых, это те контуры, которыми заданы объекты. У нас есть конечное растровое изображение и растеризатор переводит данные кривых в пиксели. После этого у нас нет возможности масштабировать картинку без потери качества.
Читайте дальше
Статьи из рубрики «Ликбез для начинающих разработчиков игр«, скорее всего окажутся очень для Вас полезными, позвольте-с отрекомендовать:
Послесловие
В этой статье, я надеюсь, вы осили столько букв, вы получили представление о том, что такое рендеринг, какие виды рендеринга существуют. Если какие-то вопросы остались — смело задавайте их в комментариях, я обязательно отвечу. Буду благодарен за уточнения и указания на какие-то неточности и ошибки.
Что такое рендеринг? И что такое рендер? Словарь разработчиков компьютерных игр!
В продолжении ликбеза по компьютерной графике как для программистов, так и для художников хочу поговорить о том что такое рендеринг. Вопрос не так сложен как кажется, под катом подробное и доступное объяснение!
Я начал писать статьи, которые являются ликбезом для разработчика игр. И поторопился, написав статью про шейдеры, не рассказав что же такое рендеринг. Поэтому эта статья будет приквелом к введению в шейдеры и отправным пунктом в нашем ликбезе.
Что такое рендеринг? (для программистов)
Итак, Википедия дает такое определение: Ре́ндеринг (англ. rendering — «визуализация») — термин в компьютерной графике, обозначающий процесс получения изображения по модели с помощью компьютерной программы.
Довольно неплохое определение, продолжим с ним. Рендеринг — это визуализация. В компьютерной графике и 3д-художники и программисты под рендерингом понимают создание плоской картинки — цифрового растрового изображения из 3д сцены.
То есть, неформальный ответ на наш вопрос «Что такое рендеринг?» — это получение 2д картинки (на экране или в файле не важно). А компьютерная программа, производящая рендеринг, называется рендером (англ. render) или рендерером (англ. renderer).
Рендер
В свою очередь словом «рендер» называют чаще всего результат рендеринга. Но иногда и процесс называют так же (просто в английском глагол — render перенесся в русский, он короче и удобнее). Вы, наверняка, встречали различные картинки в интернете, с подписью «Угадай рендер или фото?». Имеется ввиду это 3D-визуализация или реальная фотография (уж настолько компьютерная графика продвинулась, что порой и не разберешься).
Виды рендеринга
В зависимости от возможности сделать вычисления параллельными существуют:
Существует много алгоритмов рендеринга, но все их можно разделить на две группы по принципу получения изображения: растеризация 3д моделей и трасировка лучей. Оба способа используются в видеоиграх. Но трасировка лучей чаще используется не для получения изображений в режиме реального времени, а для подготовки так называемых лайтмапов — световых карт, которые предрасчитываются во время разработки, а после результаты предрасчета используются во время выполнения.
В чем суть методов? Как работает растеризация и трасировка лучей? Начнем с растеризация.
Растеризация полигональной модели
Сцена состоит из моделей, расположенных на ней. В свою очередь каждая модель состоит из примитивов.
Это могут быть точки, отрезки, треугольники и некоторые другие примитивы, такие как квады например. Но если мы рендерим не точки и не отрезки, любые примитивы превращаются в треугольники.
Задача растеризатора (программа, которая выполняет растеризацию) получить из этих примитивов пиксели результирующего изображения. Растеризация в разрезе графического пайплайна, происходит после вершинного шейдера и до фрагментного (Статья про шейдеры).
*возможно следующей статьёй будет обещанный мной разбор графического пайплайна, напишите в комментариях нужен ли такой разбор, мне будет приятно и полезно узнать скольким людям интересно это всё. Я сделал отдельную страничку где есть список разобранных тем и будущих — Для разработчиков игр
В случае с отрезком нужно получить пиксели линии соединяющей две точки, в случае с треугольником пиксели которые внутри него. Для первой задачи применяется алгоритм Брезенхема, для второй может применяться алгоритм заметания прямыми или проверки барицентрических координат.
Сложная модель персонажа состоит из мельчайших треугольников и растеризатор генерирует из неё вполне достоверную картинку. Почему тогда заморачиваться с трассировкой лучей? Почему не растеризовать и все? А смысл вот в чем, растеризатор знает только своё рутинное дело, треугольники — в пиксели. Он ничего не знает об объектах рядом с треугольником.
А это значит что все физические процессы которые происходят в реальном мире он учесть не в состоянии. Эти процессы прямым образом влияют на изображение. Отражения, рефлексы, тени, подповерхностное рассеивание и так далее! Все без чего мы будем видеть просто пластмассовые модельки в вакууме…
А игроки хотят графоний! Игрокам нужен фотореализм!
И приходится графическим программистам изобретать различные техники, чтобы достичь близости к фотореализму. Для этого шейдерные программы используют текстуры, в которых предрассчитаны разные данные света, отражения, теней и подповерхностного рассеивания.
В свою очередь трассировка лучей позволяет рассчитать эти данные, но ценой большего времени рассчета, которое не может быть произведено во время выполнения. Рассмотрим, что из себя представляет этот метод.
Трасировка лучей (англ. ray tracing)
Помните о корпускулярно волновом дуализме? Напомню в чем суть: свет ведёт себя и как волны и как поток частиц — фотонов. Так вот трассировка (от англ «trace» прослеживать путь), это симуляция лучей света, грубо говоря. Но трассирование каждого луча света в сцене непрактично и занимает неприемлемо долгое время.
Мы ограничимся относительно малым количеством, и будем трассировать лучи по нужным нам направлениям.
А какие направления нам нужны? Нам надо определять какие цвета будут иметь пиксели в результирующей картинке. Тоесть количество лучей мы знаем, оно равно количеству пикселей в изображении.
Что с направлением? Все просто, мы будем трассировать лучи в соответствии с точкой наблюдения (то как наша виртуальная камера направлена). Луч встретится в какой-то точке с объектом сцены (если не встретится, значит там темный пиксель или пиксель неба из скайбокса, например).
При встрече с объектом луч не прекращает своё распространение, а разделяется на три луча-компонента, каждый из которых вносит свой вклад в цвет пикселя на двумерном экране: отражённый, теневой и преломлённый. Количество таких компонентов определяет глубину трассировки и влияет на качество и фотореалистичность изображения. Благодаря своим концептуальным особенностям, метод позволяет получить очень фотореалистичные изображения, однако из-за большой ресурсоёмкости процесс визуализации занимает значительное время.
Рендеринг для художников
Но рендеринг это не только программная визуализация! Хитрые художники тоже используют его. Так что такое рендеринг с точки зрения художника? Примерно то же самое, что и для программистов, только концепт-художники выполняют его сами. Руками. Точно так же как рендерер в видео-игре или V-ray в Maya художники учитывают освещение, подповерхностное рассеивание, туман и др. факторы, влияющие на конечный цвет поверхности.
К примеру картинка выше, поэтапно прорабатывается таким образом: Грубый скетч — Лайн — Цвет — Объем — Рендер материалов.
Рендер материалов включает в себя текстурирование, проработку бликов — металлы, например, чаще всего очень гладкие поверхности, которые имеют четкие блики на гранях. Помимо всего этого художники сталкиваются с растеризацией векторной графики, это примерно то же самое, что и растеризация 3д-модели.
Растеризация векторной графики
Суть примерно такая же, есть данные 2д кривых, это те контуры, которыми заданы объекты. У нас есть конечное растровое изображение и растеризатор переводит данные кривых в пиксели. После этого у нас нет возможности масштабировать картинку без потери качества.
Читайте дальше
Статьи из рубрики «Ликбез для начинающих разработчиков игр«, скорее всего окажутся очень для Вас полезными, позвольте-с отрекомендовать:
Послесловие
В этой статье, я надеюсь, вы осили столько букв, вы получили представление о том, что такое рендеринг, какие виды рендеринга существуют. Если какие-то вопросы остались — смело задавайте их в комментариях, я обязательно отвечу. Буду благодарен за уточнения и указания на какие-то неточности и ошибки.
Дорогой друг! Тебе есть что сказать? Понравился пост? Не стесняйся! Оставь комментарий, нам очень важно ТВОЕ мнение
Рендеринг в 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-игру, надеемся, вы не только посмотрите на графику иными глазами, но и захотите узнать о ней больше.