Как сделать рендеринг для нескольких 3D целей в Vulkan? - PullRequest
0 голосов
/ 15 октября 2019

У меня есть некоторый устаревший код DX11, который рендерится для нескольких целей рендеринга 3D. Цель назначения передается через SV_TARGETxx, а срез устанавливается через SV_RenderTargetArrayIndex в GS. Есть ли способ сделать то же самое в Vulkan?

Мой план состоит в том, чтобы создать индивидуальный вид для каждого среза каждой трехмерной цели и передать их все вместе как приложения к буферу одного кадра, тогда в GS я могу иметьчто-то вроде gl_Layer = sliceNo + targetOffsets[xx]. Есть ли лучшее решение?

Ответы [ 2 ]

0 голосов
/ 15 октября 2019

В Vulkan GS SV_RenderTargetArrayIndex называется Layer в SPIR-V или gl_Layer в GLSL. Он ведет себя так же, как в D3D. Вы создаете один вид для каждой трехмерной цели и прикрепляете его к кадровому буферу. Вывод Layer от GS скажет, к какому слою (из всех целей) обращается примитив вывода.

В Vulkan нет "истинных" 3D-вложений кадрового буфера, в том смысле, что после проекции на экранПространственные координаты все существует в 2D плоскости. Таким образом, представления изображений вложения могут иметь размерность 2D_ARRAY, но не 3D. В таблице о совместимости параметров параметров для изображения и изображения указано, что для трехмерного изображения можно создать 2D_ARRAY представление изображения с помощью layerCount >= 1. Обратите внимание, что вы должны создать изображение с флагом VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT.

Поэтому, если вы хотите иметь N 3D-рендеринга целевых изображений:

  • Создайте свой N 3D-изображения с флагом VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT.
  • Создайте один вид изображения для каждого изображения, при этом VK_IMAGE_VIEW_TYPE_2D_ARRAY и layerCount равны количеству фрагментов, которое вы хотите получить. для визуализации в.
  • Создайте VkRenderPass с одним VkAttachmentDescription на цель 3D-рендеринга, плюс все, что вам нужно для глубины / трафарета, разрешения задачи и т. д.
  • Создание VkFrameBuffer основываясь на этом VkRenderPass, и передайте изображения в массиве VkFrameBufferCreateInfo::pAttachments. Установите VkFramebufferCreateInfo::layerCount на количество слоев / срезов, которые вы хотите визуализировать.

[Редактировать: нижний абзац можно игнорировать на основании первого комментария. Оставляя это для прозрачности.]

Я запутался в том, что вы пытаетесь сделать с SV_Target[n]. И в D3D, и в Vulkan, если у вас есть несколько целей рендеринга / цветовых вложений, фрагментный шейдер запишет во все из них - если ваш фрагментный шейдер не предоставляет значение для связанной цели, записанное значение не определено. Так что SV_Target[n] используется, чтобы указать, какие выходные переменные шейдера идут к какой цели, но они не позволяют вам писать одним без записи другим. Вулкан работает аналогично, используя выходные переменные gl_FragData[n] в GLSL.

0 голосов
/ 15 октября 2019

Если вы говорите о том, чтобы один вызов отрисовки отображался с нескольких точек зрения (но в противном случае используется один и тот же конвейер), тогда вам нужно VK_KHR_multiview . Это расширение в Vulkan 1.0, но ядро ​​в 1.1.

Есть пример его использования здесь и соответствующая функциональность шейдера здесь . Это похоже на то, что вы описываете. Вы присоединяете несколько изображений из массива текстур к одному кадровому буферу («rendertarget» в D3D), а затем в вершинном шейдере вы можете определить, какой слой вы рендерите, с помощью переменной gl_ViewIndex. При таком подходе нет необходимости в геометрическом шейдере.

...