Обзор игры Battlefield V с поддержкой DXR и технологии NVIDIA RTX
Введение
Если у вас ощущение дежа-вю, то это, возможно, потому, что вы уже читали обзоры, посвященные Battlefield V – но еще без поддержки DirectX Raytracing и NVIDIA RTX. С тех пор произошло три важных события: компания Microsoft наконец выпустила Октябрьское обновление-2018 для Windows 10 (которое содержит API DirectX Raytracing), EA-DICE в тот же день выпустили патч к игре с поддержкой DXR, а NVIDIA выпустила WHQL-драйверы GeForce 416.94, обеспечивающие оптимизацию игры с RTX.
Управление опциями DXR в версии DICE осуществляется двумя кнопками: одна позволяет включить или выключить DXR, а другая – выбрать уровень детализации отражений, построенных методом трассировки лучей: низкий, средний, высокий или ультра. Чтобы воспользоваться этими настройками, необходимо выполнить все требования к программному и аппаратному обеспечению, которые подразумевают наличие видеокарты NVIDIA Turing GeForce RTX или Quadro RTX, обновление Windows 10 до версии 1809 (то есть установку Октябрьского обновления-2018) и применение новых патчей Battlefield V и драйверов GeForce; для активации DXR нужно запустить игру в режиме DirectX 12.
Для этого обзора мы протестировали карты GeForce RTX 2080 Ti, RTX 2080 и RTX 2070 с включенной опцией DXR при различных уровнях детализации DXR-отражений на трех разрешениях: 1080p, 1440p и 4K Ultra HD. И для сравнения мы возьмем результаты «без RTX», полученные на старой версии Battlefield V.
Скриншоты
В Battlefield разработчики решили использовать рейтрейсинг для усиления реалистичности картинки только в части отражений. Все остальные элементы изображения строятся традиционными методами. Визуально технология RTX значительно улучшает качество отражений. Эффект заметно отличается от того, который дают карты отражений (reflection map) при растеризации, и достигается в режиме реального времени. Вы видите свое собственное отражение не только в зеркале, но и на других отражающих поверхностях, таких как корпус автомобиля или оконные стекла. В 3D-графике изображать отражения начали с появлением DirectX 9.0c, применяя различные хитрые приемы; например, повторное использование данных с экрана и отрисовка по ним изображения на отражающей поверхности (отражение области экрана, screen space reflection). Этот подход во многих случаях неприменим, поскольку таким способом можно отразить только предметы, которые в данный момент уже присутствуют на экране. Зеркала (которые дают только отражение от плоской непрозрачной поверхности) создавались с помощью «порталов», которые по сути повторно изображали сцену, видимую с позиции зеркала, и затем зеркально переворачивали ее. Метод порталов практически невозможно применить в случае с другими отражающими поверхностями: особенно сложно создать объемный эффект «зала зеркал», а также воспроизвести отражение от неплоской поверхности, которая искажает исходный образ. Можно было бы исказить отражение «перед» отражающей поверхностью, но это будет неточно и потребует от машины больших затрат.
Оконное стекло отражает антураж, находящийся позади игрока, что ранее (до появления RTX) было невозможно. При этом вы видите и предметы, расположенные за стеклом, реалистично совмещенные с отражениями.
В этих сценах, как можно заметить, для отражения вашего персонажа недостаточно освещения, а в комнате за оконным стеклом слишком темно.
Здесь обратите внимание на мизансцену: горящий грузовик слева и автомобиль справа. На корпусе автомобиля вы видите красное отражение, которое является отражением красной отделки на открытой дверце автомобиля.
Теперь мы переместились вправо и стоим перед автомобилем, а горящий грузовик находится позади нас. Обратите внимание на слабые отсветы пламени немного выше прицела. А также на то, что отражение красной отделки дверцы исчезло, поскольку не является предварительно заготовленным художественным эффектом.
Сравнение настроек RTX Low vs. RTX Ultra
Ниже приведены сравнительные иллюстрации самых низких (Low) и самых высоких (Ultra) настроек отражений DXR. Иллюстрации слева соответствуют уровню Low, справа – Ultra. При переходе на уровень Low вы не потеряете слишком много в части реалистичности картинки, но значительно снизите потери в части производительности.
Графические настройки DirectX Raytracing
Большая часть показанных здесь настроек не изменялась. Мы только включили новую опцию DXR и варьировали уровень качества DXR-отражений.
Опция «DXR Enabled» стала доступной после выхода последнего патча Battlefield V, и, как уже было сказано, для ее активации помимо этого патча вам понадобится также видеокарта серии GeForce RTX, Октябрьское обновление-2018 для Windows 10 и драйверы NVIDIA 416.94. Кроме того, Battlefield V с DXR должна запускаться в режиме DirectX 12.
Доступные уровни качества отражений в DXR: Low, Medium, High и Ultra.
Тестовая конфигурация системы
| Процессор | Intel Core i7-8700K @ 4.8 ГГц (Coffee Lake, кэш 12 МБ) |
| Материнская плата | ASUS Maximus X Code Intel Z370 |
| Память | G.SKILL 16 ГБ Trident-Z DDR4 @ 3866 МГц 18-19-19-39 |
| Накопитель | 2x Patriot Ignite 960 ГБ SSD |
| Блок питания | Antec HCP-1200 1200 Вт |
| Дисплей | Acer CB240HYKbmjdpr 24″ 3840×2160 |
| Система охлаждения CPU | Cryorig R1 Universal с двумя вентиляторами 140 мм |
| Операционная система | Windows 10 64-разрядная с Октябрьским обновлением-2018 |
| Драйверы | NVIDIA: 416.94 WHQL for RTX Testing NVIDIA: 416.81 WHQL for Other NVIDIA cards AMD: Catalyst 18.11.1 Beta |
Результаты бенчмарков из других обзоров сравнимы с нашими только при условии использования такой же системной конфигурации.
Использование видеопамяти
Включение DirectX Raytracing увеличивает используемый объем памяти примерно на 1,0-1,5 ГБ сверх обычного. Но даже тогда он остается в пределах 8 ГБ.
Производительность
Заключение
Технологии DirectX Raytracing и NVIDIA RTX представляют собой такой же амбициозный проект, как Ageia PhysX (который впоследствии приобрела и популяризировала NVIDIA). И подобно PhysX, DXR на начальном этапе внедрения тоже сталкивается с множеством «болезней роста». Он требует от вас не только Windows 10, но обязательно последнюю ее версию – «Октябрьское обновление-2018». И когда мы успешно справляемся со всеми подготовительными мероприятиями и запускаем DXR, нас встречают удивительные результаты. Производительность флагманской карты GeForce RTX 2080 Ti при первом же запуске DXR на разрешении 1920×1080 уменьшилась вдвое; мы не думали, что для настроек качества DXR-отражений DICE по умолчанию установит уровень Ultra (на выбор предлагаются также уровни Low, Medium и High).
Очень важно понимать, что методы DXR не распространяются на всю сцену целиком. Все изображения в Battlefield V, даже при включенной опции DXR, строятся и выглядят точно так же, как и в режиме обычного рендеринга с DirectX 12. Единственное исключение – поверхности, которые разработчики обозначили как «отражающие». Когда строится одна такая поверхность, для точного воспроизведения отражений используются необходимые данные сцены и алгоритмы трассировки лучей, в результате чего получается изумительный эффект – по реалистичности превосходящий все, что мы видели когда-либо раньше.
Однако, действие Battlefield V по большей части происходит не в городской обстановке, и вероятность того, что вы встретитесь с отражающими поверхностями природного происхождения, достаточно мала; исключение составляет Роттердам, где много тех самых автомобилей и витрин, о которых шла речь в примерах. Но DXR в любом случае бьет по производительности – независимо от того, присутствуют на экране блестящие поверхности или нет.
По нашему субъективному впечатлению, DXR вносит сравнительно небольшой вклад в общую картину игры, которая и без DXR выглядит отлично. К тому же нет существенной визуальной разницы между настройками DXR Ultra и Low, и вы можете еще раз сами проверить наши скриншоты. С другой стороны, это означает, что вы можете выставить «низкие» настройки RTX для сохранения лучшей производительности и при этом все-таки получить RTX-эффекты. С объективной точки зрения, реализация RTX в Battlefield V – это разновидность минимализма: отражения, построенные методом трассировки лучей, просто фантастически реалистичны, но рейтрейсинг заключает в себе гораздо больше возможностей; например, с помощью RTX можно реалистично воспроизводить свет и тени (и другие разработчики уже работают над этим).
Производительность карты RTX 2080 Ti снижается примерно на 58% просто при переключении в режим DXR, и ситуация в целом не улучшается при переходе с уровня настроек Ultra на уровень High или Medium. Улучшение наблюдается только на уровне Low (минус 44% по сравнению с исходной производительностью). RTX съедает более 50% производительности на разрешении 1080p, где карте удается всего лишь удерживать высокую частоту кадров – в районе 60 fps. На разрешении 1440p переход на уровень Low также улучшает производительность; однако частота кадров при настройках Ultra, High и Medium в целом остается в районе 45 fps, и это мы все еще говорим только про RTX 2080 Ti! Перейдя на разрешение 4K UHD, мы начинаем осознавать всю тяжесть ситуации. Игровой процесс еле-еле обеспечивается частотой кадров в районе двадцати с чем-то кадров в секунду в режиме DXR Ultra/High/Medium и выходит на 44 fps только при уровне настроек Low. А без RTX мы летели бы со скоростью 88 fps!
Карта GeForce RTX 2080 аналогичным образом на разрешении 1080p теряет 60% своей частоты кадров, опускаясь с приемлемого для 120 Гц-дисплея уровня 138 fps до 54 fps, что уже едва-едва дотягивает до уровня дисплея с частотой обновления 60 Гц. На разрешении 1440p частота кадров падает со 111 fps до 39 fps – играть еще можно, но потери производительности составляют целых 64%. Результат на разрешении 4K UHD болтается в районе неудовлетворительных оценок – около 22 fps, что, прямо скажем, не подходит для онлайн-геймплея со многими партнерами. Карта RTX 2070 в режиме включенной опции RTX опускается до показателей уровня GTX 970: на разрешении 1080p – более-менее нормально, на 1440p – уже с натяжкой, а на 4K UHD играть практически невозможно; это очень разочаровывающий результат, поскольку RTX 2070 широко рекламируется в качестве потенциально наиболее популярного SKU из этой серии по причине своей относительной дешевизны.
Интервью с NVIDIA о поддержке трассировки лучей и эксклюзивных технологиях
Эффекты на основе трассировки лучей в реальном времени станут широко распространёнными в играх нового поколения. NVIDIA поддерживает технологию с помощью аппаратных ядер RT с момента запуска архитектуры Turing и даже расширила поддержку до поколения Pascal через обновления драйверов, несмотря на то, что эти карты не имеют аппаратных блоков. Компания ответила порталу WCCFTech на ряд вопросов в этой области.
С предстоящим выпуском консолей следующего поколения и видеокарт Radeon RX 6000 Series разговоры об эффектах трассировки лучей в играх стали ещё более актуальными, но они также вызывают некоторые вопросы у потребителей и энтузиастов. Недавно AMD заявила о поддержке трассировки лучей и о том, какие игры будут совместимы с её ускорителями: «AMD будет поддерживать все игры, где реализована трассировка лучей с использованием таких отраслевых стандартов, как Microsoft DirectX 12 DXR или готовящийся к выходу API Vulkan Raytracing от Kronos. Игры, использующие патентованные API и расширения трассировки лучей, поддерживаться не будут».
Наибольшее внимание привлекла информация, касающаяся патентованных технологий. Это странно, поскольку недавно сообщалось, будто Intel работает с Kronos над поддержкой API трассировки лучей с открытым исходным кодом, но рассмотрит возможность использования расширений NVIDIA, если их начнут использовать больше разработчиков. Значит, NVIDIA не закрыла свои технологии для других компаний? В общем, вопросы есть, и журналисты WCCFTech решили обратиться за разъяснениями к Брайану Бёрку (Brian Burke) из маркетингового отдела NVIDIA.
— Какие вы бы назвали игры с поддержкой трассировки лучей, в которых используются эксклюзивные технологии NVIDIA?
— Подавляющее большинство игр, выпущенных с поддержкой трассировки лучей, используют стандартный отраслевой API Microsoft DirectX Ray Tracing (DXR). Нам известны три исключения: Quake II RTX, Wolfenstein: Youngblood и JX3, которые используют расширения трассировки лучей NVIDIA для Vulkan.
— Поддерживает ли NVIDIA использование собственных методов для добавления в игры трассировки лучей?
— Мы поддерживаем использование стандартных отраслевых API, таких как DXR и предстоящее расширение Vulkan Ray Tracing. В преддверии выпуска официального расширения Vulkan Ray Tracing мы позволили разработчикам, использующим Vulkan, реализовать трассировку лучей через расширение NVIDIA.
— Почему NVIDIA использовала расширения, которые будут работать только на графических процессорах NVIDIA в Quake II, Wolfenstein: Youngblood и JX3?
— Мы верим в совместное применение как быстрых новаций, так и открытых стандартов. В то время, когда разрабатывались эти первые игры с поддержкой трассировки, рабочая группа Vulkan ещё не выпустила никаких спецификаций, и поэтому использование расширения от производителя было единственным способом задействовать новые технологии этими разработчиками и предоставить нашим клиентам возможность наслаждаться эффектами трассировки лучей. Это также помогло собрать отзывы для разработки спецификацией группой Khronos. Использование ранних расширений от производителя является обычным шагом в процессе стандартизации.
— Как выглядит этот процесс?
— Создание каждого открытого стандарта проходит в несколько этапов по мере того, как новая функциональность получает более широкую поддержку в отрасли. Vulkan использует новую функциональность с помощью расширений до полноценной интеграции в виде стандарта. Для важных новых областей API обычно первый поставщик оборудования с такой функциональностью выпускает своё расширение, чтобы обеспечить раннюю поддержку и возможность собрать отзывы от разработчиков. Когда несколько производителей оборудования заинтересованы в создании общего стандарта для новой функциональности, Khronos предлагает этим компаниям хорошо зарекомендовавший себя процесс сотрудничества и разработки открытого стандарта Khronos или расширения API KHR. Для важных новых возможностей Khronos часто предпочитает распространять предварительную версию расширения KHR, чтобы обеспечить обратную связь с отраслью параллельно с окончательной доработкой спецификации и проведением тестов на соответствие требованиям. Когда в спецификацию включены все отзывы ключевых сторон, выпускается окончательная версия расширения KHR, прошедшая тесты на соответствие, так что любой поставщик оборудования, реализующий спецификацию, может официально соответствовать требованиям для надёжной работы на любом оборудовании.
Развитие Vulkan Ray Tracing шло в соответствии со всеми этими шагами, в том числе NVIDIA предложила своё собственное расширение трассировки лучей для Vulkan, что было необходимым первым шагом в обеспечении раннего доступа для разработчиков и сбора отзывов от создателей игр на первом этапе.
— Создаёт ли NVIDIA какие-либо препятствия через издательства или Khronos Group, которые помешали бы AMD добавить поддержку трассировки лучей в Quake II, Wolfenstein: Youngblood и JX3, если они захотят?
— Абсолютно нет. Мы вносим свой вклад в рост экосистемы трассировки лучей в течение многих лет и приветствуем желание других независимых производителей оборудования добавить поддержку.
— Какую работу проделала NVIDIA, чтобы обеспечить поддержку трассировки лучей в Vulkan?
— Внедрение трассировки лучей в Vulkan является результатом многолетних усилий многих компаний, и NVIDIA заняла активную лидирующую позицию на каждом этапе своего развития. Мы были избраны председателем подгруппы по трассировке лучей Vulkan в Khronos, мы внесли в Khronos наше собственное расширение, чтобы помочь рабочей группе Vulkan добиться быстрого прогресса, и мы выпустили драйверы для предварительной версии расширения трассировки лучей Vulkan, чтобы дать разработчикам обратную связь для подгруппы. Кроме того, мы намерены выпустить драйверы для окончательной версии расширения KHR в тот же день, когда спецификация будет выпущена Khronos.
— Будут ли игры DXR работать на графических процессорах AMD?
— DirectX Ray Tracing — это API, утверждённый Microsoft для реализации любым поставщиком оборудования. Игры, созданные с использованием DXR, должны работать на любом графическом процессоре, совместимом с DXR. NVIDIA не может говорить о планах других производителей по поддержке DXR.
— Я читал, что трассировка лучей в Cyberpunk 2077 будет работать только на графических процессорах NVIDIA. Почему?
— Cyberpunk 2077 использует стандартный отраслевой API DirectX для трассировки лучей. Он будет работать на любом графическом ускорителе, совместимом с DXR. В Cyberpunk 2077 нет ничего, связанного с трассировкой лучей, что было бы собственностью NVIDIA.
DirectX raytracing — всплываем
В 2018 году компания Microsoft анонсировала raytracing API (DXR) как часть DirectX 12. Подход рейтрейсинга заставляет полностью переосмыслить способ ренедринга трехмерных сцен, смещающий классический подход растеризации на второй план. АПИ модернизируются, разрабатываются более производительные GPU, разработчики пакетов визуализации пробуют новые возможности. Однако даже на наиболее производительных видеокартах мощности хватает на генерирование всего нескольких лучей на пиксель для обеспечения стабильной частоты смены кадров. К тому же, производительность во многом зависит от сложности материалов и сцены. Но уже сегодня продвинутые алгоритмы шумоподавления и аккумуляции результата освещенности позволяют достичь высокой степени реализма. Все это мотивирует к экспериментам в данной области.
Возможность трассировки лучей на GPU стала возможна относительно недавно. В 2009 году вышел DirectX 11 с compute shaders — это дало толчок в развитии вычислений не связанных с графикой. Однако конструирование ускоряющих структур ложилось полностью на плечи программиста, что замедляло разработку. Получили распространение специализированные библиотеки по пересечению, например, Radeon Rays от AMD. В DXR ускоряющие структуры представлены по принципу черного ящика и пересечение происходит с помощью специальных аппаратных блоков. Трассировка лучей была так же добавлена в Vulkan в качестве расширения VK_NV_ray_tracing для карт Nvidia. В марте 2020 с небольшими изменениями вышло расширения VK_KHR_ray_tracing, перестало быть vendor-specific, возможно его включат в спецификацию Vulkan 1.3. Планируется полноценная работа трассировки лучей и в AMD до конца 2020. Повсеместная поддержка повышает перспективность технологии.
Концептуально DXR предоставляет возможность пересечения лучей с предварительно загруженными геометрическими объектами. В местах пересечений возможно выполнение определенных пользователем программ — шейдеров. Грубо говоря, объект это массив треугольников. Однако уточняющая форма, которая, например, говорит о прозрачности объекта может определяться и во время выполнения в отдельном шейдере. Такая возможность полезна, если степень прозрачности задается текстурой или в случае полностью процедурно сгенерированных объектов (облака, огонь). Любые события, которые возникают на пути луча (hit, miss, procedural hit, closest hit), подвержены программированию, например, в месте пересечений можно генерировать вторичные лучи, продолжающие движение. Такой pipeline похож на распространение света.
Окружение
Для запуска требуется DXR-совместимый GPU Nvidia RTX 2060 и выше. Windows SDK 19041 (для нашего примера подойдет и более раннее, но официальные Miscrosoft сэмплы ориентируются именно на эту версию), в качестве IDE используется Visual Studio 2019, язык C++.
Терминология
Как и в любой трассировке в DXR все начинается с генерирования необходимых лучей, за это отвечает отдельный raygen-шейдер. Глобально на стороне программы вызывается ID3D12GraphicsCommandList4::DispatchRays() c необходимым количеством лучей, а конкретные направления задает шейдер с помощью TraceRay(). Трассировка производится на определенной top level acceleration structure. Дальнейшее выполнение может происходить по разным сценариям, зависящим от сцены. Например, могут обрабатываться всевозможные пересечения на пути следования луча, либо вызываться отдельные шейдеры для процедурной геометрии, либо обрабатываться только ближайшее пересечение (closest hit). Для простоты мы рассмотрим последний случай, общий иллюстрирует следующая схема.
В процессе выполнение может передаваться разным miss и hit-шейдерам. Инстансы шейдеров для одного луча могут обмениваться небольшой областью памятью называемой payload — обычно это и есть результат вычислений. Ресурсы могут передаваться и быть видимым глобально для всех шейдеров с помощью стандартных средств DirectX, в этом случае создается global root signature. Либо локально per-shader ресурсы, в этом случае на каждый шейдер создается своя local root signature и передача параметров осуществляется с помощью Shader binding table. В такой ситуации надо следить, чтобы регистры глобальных ресурсов не пересекались с регистрами локальных.
Инициализация
На высоком уровне вся настройка делится на следующие этапы:
Разберем подробно эти этапы.
Bottom-level acceleration structure (BLAS)
Объект представляет собой список геометрических объектов, где каждый объект — это массив треугольников. Один объект в BLAS для удобства в дальнейшем будем называть инстансом. Один BLAS может состоять из множества инстансов. Треугольники могут задаваться напрямую как тройки вершин либо индексироваться отдельным буфером. Генерирование BLAS происходит на GPU, и поэтому требует отдельного command list и небольших синхронизаций. Для генерирования требуется итоговый буфер, который и будет содержать BLAS а так же некоторое количество памяти для внутренних нужд (scratch-буфер). DirectX 12, как явное API, предоставляет возможность узнать необходимые размеры с помощью метода ID3D12Device5::GetRaytracingAccelerationStructurePrebuildInfo. В итоге создается буфер с флагом D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE — содержит все необходимые данные для эффективного пересечения лучей с треугольниками.
Основная структура здесь D3D12_RAYTRACING_GEOMETRY_DESC — описывает один инстанс в BLAS. Необходимо передать буфер вершин и их лэйаут (а так же index-buffer при наличии):
Заполняем общую информацию о BLAS:
Top-level acceleration structure (TLAS)
TLAS представляется матрицей трансформации с уже созданными BLAS и флагами специфичными для данного инстанса. Она может инстанциировать один и тот же BLAS много раз, используя разные матрицы для рендеринга одинаковых моделей в разных позициях. Создание TLAS во многом похож на BLAS — здесь так же требуется дополнительный scratch-буфер. Более того, мы можем использовать один и тот же scratch-буфер, так как TLAS создается после BLAS. В нашем случае записываем в TLAS две одинаковые модели с разными матрицами трансформации:
Заполнение общей информации о TLAS (D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS и D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC) производится аналогично BLAS.
Raytracing pipeline
Как и для graphic и compute нам требуется raytracing pipeline state object — это текущая конфигурация трассировки. RT pipeline состоит из множества подобъектов и объектов-ассоциаторов, которые связывают уже созданные подобъекты. Для удобства будем использовать вспомогательный класс CD3DX12_STATE_OBJECT_DESC и метод CreateSubobject( ).
Shader binding table (SBT)
SBT — это соединение геометрических данных и шейдеров вместе. Фактически таблица хранит информацию о том, какие нужно выполнить шейдеры и с какими аргументами для инстансов с которыми произошло пересечение, поэтому это часть подверженная активному изменению с точки зрения программиста. Технически это не является таблицей, она представляется размеченной GPU-памятью, в которой записаны идентификаторы шейдеров и аргументы по определенным правилам. Но для удобства продолжим называть ее таблицей.
Одна ячейка в таблице называется shader record. В нашем случае при конструировании TLAS мы указали что нулевой инстанс будет смотреть на нулевую запись, первый — на первую. Таким образом в рантайме придут разные константы. В общем случае формула расчета индекса в таблице может зависеть не только от номера геометрического инстанса в TLAS и BLAS, но и от типа лучей и передаваемых аргументов в TraceRay(), однако в данной статье мы рассматриваем самый простой случай.
Глобально все делится на 3 шейдера: ray generation, hit и miss, соответственно, можно сказать, что и таблиц буде тоже три. Мы можем разместить таблицы в разных буферах, либо в одном. В последнем случае нам нужно правильно рассчитать GPU-адрес на начало каждой из таблиц, которые принимает DispatchRays(). В таблице может быть любое количество shader record-ов.
Размер буфера который нам нужно аллоцировать для одной таблицы это размером одного shader record-a умноженный на их количество. Для raygen и miss у нас будет по одному шейдеру без каких либо локальных аргументов, поэтому размер shader record-a минимально возможный. Для глобальных аргументов, как мы уже знаем, которые видны всем шейдерам, мы создаем отдельную root signature, ее аргументы не записываются в SBT. Между shader record требуется выравнивание D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT (сейчас 32 байта).
Идентификатор шейдера представляет собой void*, который возвращает GetShaderIdentifier() из объекта ID3D12StateObjectProperties, последний можно получить из COM-интерфейса созданного ранее raytracing pipeline. Для raygen-шейдера (miss аналогично) это выглядит примерно так:
Указатель мы записываем в начало нашего буфера. SBT для raygen и miss шейдеров сформированы.
Для hit мы передаем в шейдер float4 и здесь более интересная ситуация. Запись аргументов в SBT очень похожа на установку в root signature: константы записываются напрямую либо передается virtual GPU-address/GPU-handle. В нашей ситуации два инстанса необходимо обработать одним шейдером но с разными constant buffer, поэтому в hit SBT будет два shader record-а. Запись состоит из 32-байтного идентификатора и 4×4-байт константы, всего 48, но из-за выравнивания получится 64 байта. Расположение записей иллюстрируются следующей картинкой:
Шейдеры
В отличие от классического подхода vertex-fragment shader в трассировке требуется минимум 3: raygen, hit, miss.
raygen:
Задаем исходную точку и направление луча на основании позиции пикселя и системы координат камеры. Затем передаем TLAS, маски и набор параметров, отвечающих за расчет выполнения определенных шейдеров в SBT. TraceRay() возвращает payload после серии пересечений и результат записываем в выходой буфер. Идентификатор [shader(«raygeneration»)] говорит системе, что это именно шейдер, генерирующий лучи, а вот название функции «RayGen» может быть любое, его нужно будет экспортировать после компиляции.
closesthit
Выполняется только в случае ближайшего к камере пересечения. В результате мы должны записать что-нибудь в payload. В шейдер передается буфер вершин и нормалей и цвет текущей модели. Барицентрические координаты и номер треугольника передаются системой. Находим нормаль в точке пересечения с помощью барицентрических координат, и производим расчет освещения.
Наиболее просто выглядит miss.
В этом случае у нас нет пересечения — записываем цвет фона.
Main loop
Основная выдержка из main loop выглядит следующим образом:
Заключение
В статье мы рассмотрели основные объекты необходимые для начала работы с DXR, а так же применили эти знания на практике. Намеренно были пропущены вопросы инициализации DirectX, загрузки моделей, компиляции шейдеров, и т.д., которые не относятся к теме. В следующих статьях планируется сместить акцент на, собственно, графику, нежели работу с API.




























