Dxr видеокарты что это

Какие видеокарты Nvidia и AMD поддерживают трассировку лучей

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

Ввидеокарты Nvidia с функцией трассировки лучей

С момента запуска линейки RTX (Turing) компания Nvidia интегрировала в свою продукцию функцию трассировки лучей. Поэтому существует множество видеокарт, которые поддерживают эту опцию.

  • Серия RTX: среди них Nvidia GeForce RTX 2060, Nvidia GeForce RTX 2070, Nvidia GeForce RTX 2080 и Nvidia GeForce RTX 2080 Ti. Кроме того, сюда относятся все SUPER-варианты.
  • Pascal-GTX: Классика, поддерживающая трассировку лучей, включает, конечно, Nvidia GeForce GTX 1060 с 6 Гбайт VRAM, Nvidia GeForce GTX 1070, Nvidia GeForce GTX 1070 Ti, Nvidia GeForce GTX 1080 и Nvidia GeForce GTX 1080 Ti.
  • Turing-GTX: Конечно, к серии видеокарт, поддерживающих трассировку лучей, относятся Nvidia GeForce GTX 1660 и Nvidia GeForce GTX 1660 Ti. Не забудем и про GTX 1660 SUPER.
  • Titan: В серии Titan эту опцию поддерживают Nvidia Titan X, XP и V.
  • GeForce RTX 30 Series: Nvidia оснастила все варианты флагмана RTX 30 функцией трассировки лучей. К ним относятся Nvidia GeForce RTX 3070, 3080 и 3090.

Примечание: на некоторых видеокартах Nvidia функция трассировки лучей разблокируется только после установки драйвера Geforce 425.31. Это относится к моделям Titan Xp, Titan X (Pascal), Geforce GTX 1660 Ti, Geforce GTX 1660, Geforce GTX 1080 Ti, Geforce GTX 1080, Geforce GTX 1070 Ti, Geforce GTX 1070 и Geforce GTX 1060 6GB.

Видеокарты AMD с трассировкой лучей

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

Только новейшие видеокарты AMD серии RX 6000 будут поддерживать трассировку лучей. К ним относятся AMD Radeon RX 6800, AMD RADEON RX 6800 XT и AMD RADEON RX 6900 XT. Серия RX 6800 поступила в продажу в ноябре 2020 года, RX 6900 — в декабре 2020 года.

Источник

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. Повсеместная поддержка повышает перспективность технологии.

Читайте также:  Какая память на видеокарте 1660 super

Концептуально 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, top-level acceleration structures
  • создание raytracing pipeline
  • создание shading binding table (SBT) — ассоциирование шейдеров и per-shader ресурсов с геометрией

Разберем подробно эти этапы.

Bottom-level acceleration structure (BLAS)

Объект представляет собой список геометрических объектов, где каждый объект — это массив треугольников. Один объект в BLAS для удобства в дальнейшем будем называть инстансом. Один BLAS может состоять из множества инстансов. Треугольники могут задаваться напрямую как тройки вершин либо индексироваться отдельным буфером. Генерирование BLAS происходит на GPU, и поэтому требует отдельного command list и небольших синхронизаций. Для генерирования требуется итоговый буфер, который и будет содержать BLAS а так же некоторое количество памяти для внутренних нужд (scratch-буфер). DirectX 12, как явное API, предоставляет возможность узнать необходимые размеры с помощью метода ID3D12Device5::GetRaytracingAccelerationStructurePrebuildInfo. В итоге создается буфер с флагом D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE — содержит все необходимые данные для эффективного пересечения лучей с треугольниками.

Читайте также:  Ноутбук msi gx740 видеокарта

Основная структура здесь D3D12_RAYTRACING_GEOMETRY_DESC — описывает один инстанс в BLAS. Необходимо передать буфер вершин и их лэйаут (а так же index-buffer при наличии):

Заполняем общую информацию о BLAS:

И генерируем 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( ).

  1. Библиотеки шейдеров. Необходимо скомпилировать либо заранее либо программно и заполнить поля BytecodeLength и pShaderBytecode структуры D3D12_SHADER_BYTECODE, затем передать в подобъект эту структуру с помощью SetDXILLibrary() и определить имя функции на исполнение DefineExport(). Такой алгоритм проделываем для 3-х шейдеров: raygen, hit, miss.
  2. Hit group (CD3DX12_HIT_GROUP_SUBOBJECT). Необходимо обозначить hit group-ы, которые будут участвовать в трассировке. Придумываем имя группы и устанавливаем с помощью SetHitGroupExport, а так же тип в нашем случае SetHitGroupType(D3D12_HIT_GROUP_TYPE_TRIANGLES). Текущий подобъект лишь указывает на наличие hit-group, конкретный шейдер мы уже добавили на первом шаге.
  3. Конфигурация шейдеров (CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT). Размер payload — данные, которые возвращает TraceRay после обработки пересечения, и барицентрические координаты в closest hit — 2 float.
  4. Конфигурация пайплайна (CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT). Устанавливаем максимальную глубина трассировки 1.
  5. Локальная root signature (CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT). Описание аргументов, которые приходят в hit-шейдер. Конкретные аргументы передаются через SBT (об этом далее).
  6. Ассоциация local root signatore c hit group (CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT). Устанавливаем root signature SetSubobjectToAssociate() и имя группы для которой предназначаются параметры AddExport().
  7. Глобальная root signature (CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT). Описание аргументов, которые доступны во всех шейдерах. Аргументы устанавливаются непосредственно перед трассировкой с помощью стандартных методов SetComputeRootDescriptorTable, SetComputeRootShaderResourceView и SetComputeRoot32BitConstants.

Shader binding table (SBT)

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

Одна ячейка в таблице называется shader record. В нашем случае при конструировании TLAS мы указали что нулевой инстанс будет смотреть на нулевую запись, первый — на первую. Таким образом в рантайме придут разные константы. В общем случае формула расчета индекса в таблице может зависеть не только от номера геометрического инстанса в TLAS и BLAS, но и от типа лучей и передаваемых аргументов в TraceRay(), однако в данной статье мы рассматриваем самый простой случай.

Читайте также:  128 бит видеокарта что это такое

Глобально все делится на 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.

Источник

Adblock
detector