Что такое компиляция шейдеров

Русские Блоги

предисловие

Этот учебник не рассматривает Effects11 (FX11), но основан на оригинальном HLSL.

Текущие методы компиляции и загрузки шейдеров следующие:

В персональном проекте DX11 используется смешанная форма метода 1 (приоритет) и метода 3. Хотя метод 2 был недавно изучен, люди в настоящее время не рассматривают возможность перехода на этот метод.

Добро пожаловать в группу QQ: 727623616 Вы можете обсудить DX11 вместе и сообщить о любых вопросах здесь.

Расширения файлов, связанные с шейдерами

Чтобы соответствовать соглашениям Microsoft, вам необходимо использовать следующие (измененные) расширения для своего кода шейдера:

Метод 1: Генерация объектных файлов во время компиляции и загрузка их во время выполнения

среди Triangle.hlsli Заголовочный файл HLSL по умолчанию не участвует в процессе компиляции проекта.

После генерации проекта необходимо обратить внимание на то, появляется ли следующий контент в окне вывода (генерация):

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

Связанные операции над кодом или файлами шейдеров находятся в заголовочном файле. d3dcompiler.h И нужно добавить статическую библиотеку d3dcompiler.lib

Далее мы используем следующую функцию для чтения двоичной информации скомпилированного шейдера:

Примечание. Если эта функция не существует в вашем проекте, это означает, что вы, возможно, включили DX SDK заранее. Однако в этом руководстве используется Windows SDK. Эта функция находится в версии D3DCompiler> = 46, поэтому необходимо исключить путь включения DX SDK и Путь к библиотеке.

Он также очень прост в использовании (на примере создания вершинного шейдера и вершинного макета):

Тогда вы можете получить это ID3DBlob Пришло время создать шейдер. Часть создания макета шейдера и вершины не обсуждается в этой статье, пожалуйста, вернитесь к уроку 02, чтобы продолжить просмотр.

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

Способ 2: компилятор создает файл заголовка и включает этот файл в проект

для Triangle_VS.hlsl и Triangle_PS.hlsl Свойства проекта должны быть установлены так:

Здесь имя файла заголовка и имя внутренней глобальной переменной можно определить самостоятельно.

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

Тогда код для создания вершинного шейдера и вершинного макета становится таким:

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

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

Способ 3: скомпилировать код шейдера во время выполнения для генерации байт-кода

Теперь вам нужно понять эти функции

Еще раз обратите внимание: если функция не существует в вашем проекте, это означает, что вы, возможно, включили DX SDK заранее. Однако в этом руководстве используется Windows SDK. Эта функция находится в версии D3DCompiler> = 46, поэтому необходимо исключить путь включения DX SDK И путь к библиотеке.

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

Конкретное использование было включено в следующее CreateShaderFromFile Функция в

Реализация функции CreateShaderFromFile

Ниже CreateShaderFromFile Реализация функции,Теперь эта функция была помещена в d3dUtil.h, Зависит от dxerr И стандартная библиотека filesystem Вы также можете изменить реализацию этой функции самостоятельно:

Использование заключается в следующем:

Добро пожаловать в группу QQ: 727623616 Вы можете обсудить DX11 вместе и сообщить о любых вопросах здесь.

Источник

Компиляция шейдеров

В этом разделе описывается FXC.EXE компилятор, используемый для моделей шейдеров 2 – 5,1. Для Shader Model 6 используется DXC.EXE вместо, который описан в статье Использование dxc.exe и dxcompiler.dll.

Microsoft Visual Studio 2012 теперь может компилировать код шейдера из * файлов. hlsl, включаемых в проект C++.

в рамках процесса сборки Visual Studio 2012 использует компилятор кода fxc.exe HLSL для компиляции HLSL файлов в двоичные файловые файлы шейдеров или в байтовые массивы, определенные в файлах заголовков. Как компилятор кода HLSL компилирует каждый файл HLSL в проекте, зависит от того, как указать свойство файлов выходные данные для этого файла. Дополнительные сведения о страницах свойств HLSL см. в разделе страницы свойств HLSL.

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

Теперь рассмотрим различные способы компиляции кода шейдера и соглашений для расширений файлов для кода шейдера.

Использование расширений файлов кода шейдера

Чтобы согласовать соглашение с Майкрософт, используйте следующие расширения файлов для кода шейдера:

Компиляция во время сборки в объектные файлы

При компиляции HLSL-файлов в двоичные файловые файлы шейдера приложение должно считывать данные из этих файлов объектов (. cso является расширением по умолчанию для этих объектных файлов), назначать данные байтовые массивы и создавать объекты шейдера из этих массивов байтов. Например, чтобы создать шейдер вершин (ID3D11VertexShader * * ), вызовите метод ID3D11Device:: креатевертексшадер с массивом байтов, который содержит скомпилированный байтовый код шейдера вершин. В примере «учебник по Direct3D » показано, как создавать объекты шейдера из байтовых массивов, полученных из. объектно построителей двоичных файлов шейдера. В этом примере кода из примера учебника по Direct3Dсвойство выходные данные Files для файла симплевертексшадер. HLSL определяет компиляцию в объектный файл симплевертексшадер. cso.

Читайте также:  какие упражнения надо делать при межпозвоночной грыже

Компиляция во время сборки в файлы заголовков

Компиляция с помощью D3DCompileFromFile

Можно также использовать функцию D3DCompileFromFile во время выполнения для компиляции кода шейдера. Дополнительные сведения о том, как это сделать, см. в разделе инструкции. Компиляция шейдера.

Windows Приложения Магазина поддерживают использование D3DCompileFromFile для разработки, но не для развертывания.

Источник

Vulkan. Руководство разработчика. Графический конвейер

Я переводчик в IT-компании CG Tribe, и я продолжаю выкладывать перевод руководства к Vulkan API (vulkan-tutorial.com).

Сегодня я хочу поделиться с вами переводом первых двух глав раздела, посвященного графическому конвейеру (Graphics pipeline basics), — Introduction и Shader modules.

9. Загрузка моделей

10. Создание мип-карт

FAQ

Политика конфиденциальности

Вступление

В течение следующих нескольких глав мы будем настраивать графический конвейер, который позволит нам нарисовать первый треугольник. Графический конвейер — это последовательность операций, которые преобразуют вершины и текстуры мешей в пиксели в render target-ах.

Ниже представлена упрощенная схема:

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

Вершинный шейдер (vertex shader) вызывается для каждой вершины и используется, в основном, для трансформации вершин из локальной системы координат в экранную. Также он передает данные каждой вершины далее по конвейеру.

Шейдеры тесселяции (tessellation shaders) позволяют увеличить количество мешей за счет дополнительного разбиения геометрии. Их часто используют, чтобы сделать близлежащие поверхности, например, кирпичные стены или лестницы, менее плоскими.

Геометрический шейдер (geometry shader) вызывается для каждого примитива (треугольник, линия, точка) и может отменить их отрисовку или сгенерировать новые примитивы. Геометрический шейдер похож на шейдер тесселяции, только, в отличие от него, более гибкий. Однако он не часто используется в современных приложениях из-за недостаточно высокой производительности большинства видеокарт, за исключением встроенных графических процессоров Intel.

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

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

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

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

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

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

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

Шейдерные модули

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

Нам не придется писать байт-код вручную. Khronos выпустил собственный компилятор, независимый от производителя, который компилирует GLSL в SPIR-V. Он проверяет, соответствует ли шейдерный код стандарту, и создает бинарный файл SPIR-V для использования в вашей программе. Также этот компилятор можно использовать в качестве библиотеки для создания SPIR-V в рантайме (во время исполнения), но в руководстве мы не будем этого делать. Вместо glslangValidator.exe мы будем использовать glslc.exe от Google. Преимущество glslc в том, что он использует тот же формат командной строки, что и компиляторы GCC или Clang, и включает некоторые дополнительные функции, например, includes. Обе программы уже включены в Vulkan SDK, поэтому не нужно скачивать ничего дополнительно.

Как уже было сказано, для отрисовки треугольника мы должны написать вершинный шейдер и фрагментный шейдер. В следующих двух пунктах мы рассмотрим код GLSL для каждого шейдера и покажем, как создать бинарные файлы SPIR-V и загрузить их в программу.

Вершинный шейдер

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

Координатами в пространстве отсечения называют четырехмерный вектор, принимаемый из вершинного шейдера, который преобразуется в нормализованные координаты устройства в результате деления вектора на его последний компонент. Нормализованные координаты устройства (normalized device coordinate) — это гомогенные координаты, находящиеся в диапазоне [-1, 1], и проецирующиеся на фреймбуфер, как показано на картинке ниже:

Читайте также:  алт 500 что делать

Если до этого вы работали с OpenGL, вы можете заметить, что координата Y теперь зеркально отражена. А для координаты Z задан тот же диапазон, что и в Direct3D, от 0 до 1.

Для нашего первого треугольника мы не будем применять никаких преобразований, а просто укажем положения трех вершин в нормализованных координатах устройства для создания такой фигуры:

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

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

Фрагментный шейдер

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

Цвет каждой вершины

Полностью красный треугольник выглядит слишком просто, может, сделаем его поинтереснее?

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

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

Затем добавим соответствующую ему входную переменную во фрагментный шейдер:

Компиляция шейдеров

Содержимое файла shader.vert должно быть следующим:

А содержимое файла shader.frag следующим:

Замените путь к glslc.exe на путь установки Vulkan SDK. Дважды щелкните по файлу, чтобы запустить его.

Замените путь к glslc на путь установки Vulkan SDK. Сделайте скрипт исполняемым с помощью команды chmod + x compile.sh и запустите его.

Эти две команды говорят компилятору прочитать исходный файл GLSL и вывести его в байт-код SPIR-V с помощью флага -o (output).

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

Компиляция шейдеров в командной строке — один из самых простых способов, который мы будем использовать в руководстве, но вы можете скомпилировать шейдеры непосредственно из вашего кода. Для этого в Vulkan SDK есть libshaderc — библиотека для компиляции кода GLSL в SPIR-V.

Загрузка шейдера

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

Затем мы можем вернуть указатель в начало файла и считать все байты за один вызов:

И, наконец, закроем файл и возвратим буфер:

Создание шейдерных модулей

Функция принимает буфер с байт-кодом в качестве параметра и создает из него VkShaderModule.

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

Шейдерный модуль всего лишь тонкая обертка для шейдерного байт-кода, загруженного из файла, и объявленных в нем функций. Компиляция и линковка байт-кода SPIR-V в машинный код не произойдет до тех пор, пока не будет создан графический конвейер. Это значит, что мы можем уничтожить шейдерные модули сразу после создания конвейера. Поэтому в функции createGraphicsPipeline сделаем их локальными переменными вместо членов класса:

Уничтожим их в конце функции с помощью двух вызовов vkDestroyShaderModule. Остальной код в этой главе будет вставлен перед следующими строками:

Связываем шейдеры и конвейер

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

А теперь сделаем практически то же самое для фрагментного шейдера:

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

В этой главе мы рассмотрели только программируемые этапы конвейера. В следующей главе мы перейдем к непрограммируемым этапам.

Источник

Портирование Detroit: Become Human с Playstation 4 на PC

Введение

В этой серии постов мы расскажем о портировании игры Detroit: Become Human с PlayStation 4 на PC.

Detroit: Become Human была выпущена на PlayStation 4 в мае 2018 года. Мы начали работу над версией для PC в июле 2018 года, а выпустили её в декабре 2019 года. Это адвенчура с тремя играбельными персонажами и множеством сюжетных линий. Она имеет очень качественную графику, а большинство графических технологий было разработано самой компанией Quantic Dream.

3D-движок обладает отличными возможностями:

Detroit: Become Human

Выбор графического API

У нас уже была OpenGL-версия движка, которую мы применяли в наших инструментах разработки.

Но нам не хотелось выпускать игру на OpenGL:

Мы выбирали между DirectX 12 и Vulkan, имеющими очень схожий набор функций. Vulkan в дальнейшем позволил бы нам обеспечить поддержку Linux и мобильных телефонов, а DirectX 12 обеспечивал поддержку Microsoft Xbox. Мы знали, что в конечном итоге нам нужно будет реализовать поддержку обоих API, но для порта разумнее будет сосредоточиться только на одном API.

Читайте также:  Что такое лонги в баре

Vulkan поддерживает Windows 7 и Windows 8. Так как мы хотели сделать Detroit: Become Human доступной как можно большему количеству игроков, это стало очень сильным аргументом. Однако портирование занял один год, и этот аргумент уже маловажен, ведь Windows 10 теперь используется очень широко!

Концепции разных графических API

OpenGL и старые версии DirectX имеют очень простую модель управления GPU. Эти API просты в понимании и очень хорошо подходят для обучения. Они поручают драйверу выполнять большой объём работы, скрытый от разработчика. Следовательно, в них очень сложно будет оптимизировать полнофункциональный 3D-движок.

С другой стороны, PlayStation 4 API очень легковесный и очень близок к «железу».

Vulkan находится где-то посередине. В нём тоже есть абстракции, потому что он работает на разных GPU, но разработчики имеют больше контроля. Допустим, у нас есть задача реализации управления памятью или кэша шейдера. Так как драйверу остаётся меньше работы, её приходится делать нам! Однако мы разрабатывали проекты на PlayStation, и поэтому нам удобнее, когда мы можем всё контролировать.

Сложности

Центральный процессор PlayStation 4 — это AMD Jaguar с 8 ядрами. Очевидно, что он медленнее, чем новое оборудование PC; однако PlayStation 4 имеет важные преимущества, в частности, очень быстрый доступ к «железу». Мы считаем, что графический API PlayStation 4 гораздо эффективнее, чем все API на PC. Он очень прямолинейный и мало тратит ресурсов впустую. Это означает, что мы можем добиться большого количества вызовов отрисовки на кадр. Мы знали, что высокое количество вызовов отрисовки может стать проблемой на слабых PC.

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

Во время разработки Detroit: Become Human на PlayStation 4 художники могли создавать уникальные деревья шейдеров для всех материалов. Из-за этого получалось безумное количество вершинных и пиксельных шейдеров, поэтому мы с самого начала работы над портом знали, что это станет огромной проблемой.

Конвейеры шейдеров

Как мы знаем по нашему OpenGL-движку, компиляция шейдеров может занимать много времени на PC. Во время продакшена игры мы сгенерировали кэш шейдеров по модели GPU наших рабочих станций. Генерация полного кэша шейдеров для Detroit: Become Human заняла целую ночь! Все сотрудники получили доступ к этому кэшу шейдеров на утро. Но игра всё равно тормозила, ведь драйверу нужно было преобразовать этот код в нативный ассемблерный код шейдера GPU.

Оказалось, что Vulkan намного лучше справляется с этой проблемой, чем OpenGL.

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

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

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

Потом мы прогнозировали, что сможем создавать VkPipelines во время загрузки, но когда VkPipelineCache был неактуальным, это было так медленно, что стратегию загрузки в фоновом режиме реализовать не удалось.

В конечном итоге, мы решили генерировать все VkPipeline во время первого запуска игры. Это полностью устранило проблемы с торможением, но теперь мы столкнулись с новой сложностью: генерация VkPipelineCache занимала очень много времени.

У нас появилось несколько идей по оптимизации процесса:

Производительность создания VkPipelines очень сильно варьируется. В частности, оно сильно зависит от количества доступных аппаратных потоков. На AMD Ryzen Threadripper с 64 аппаратными потоками оно может занимать всего две минуты. Но на слабых PC этот процесс, к сожалению, может проходить больше 20 минут.

Последнее было для нас слишком долго. К сожалению, единственным способом ещё сильнее снизить это время было уменьшение количества шейдеров. Нам требовалось бы изменить способ создания материалов, чтобы как можно большее их количество было общим. Для Detroit: Become Human это было невозможно, потому что художникам пришлось бы переделывать все материалы. Мы планируем реализовать в следующей игре правильный инстансинг материалов, но для Detroit: Become Human уже было слишком поздно.

Индексирование дескрипторов

Мы создаём массивы ресурсов для всех типов используемых ресурсов:

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

Оптимизация обновлений наборов дескрипторов

Даже при малом количестве наборов дескрипторов их обновление по-прежнему оставалось узким местом. Обновление набора дескрипторов, если он содержит множество ресурсов, может быть очень затратным. Например, в одном кадре Detroit: Become Human может быть больше четырёх тысяч текстур.

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

В конечном итоге, эта оптимизация снизила время обновления наборов дескрипторов на один-два порядка величин.

Батчинг примитивов

На этом первая часть серии статей завершается. Во второй части инженер по разработке технологий Лу Крамер расскажет о неоднородном индексировании ресурсов на PC и, в частности, в картах AMD.

Источник

Информ портал о технике и не только