如何在Vulkan中渲染多个3d目标?

时间:2019-10-15 17:09:51

标签: vulkan

我有一些旧的DX11代码可以渲染到多个3d渲染目标。在GS中,目标目标通过SV_TARGETxx传递,并且切片通过SV_RenderTargetArrayIndex设置。在Vulkan中有什么方法可以做同样的事情吗?

我的计划是为每个3d目标的每个切片创建单独的视图,并将它们作为附件一起传递到单个帧缓冲区,然后在GS中我可以使用类似gl_Layer = sliceNo + targetOffsets[xx]的对象。有更好的解决方案吗?

2 个答案:

答案 0 :(得分:0)

如果要从多个角度渲染1个绘制调用(但要使用相同的管道),则需要VK_KHR_multiview。这是Vulkan 1.0的扩展,但是1.1的核心。

有一个用法示例here,相应的着色器功能为here。它的功能类似于您似乎要描述的内容。将纹理阵列中的多个图像附加到单个帧缓冲区(在D3D中为“ rendertarget”),然后在顶点着色器中,可以通过gl_ViewIndex变量确定要渲染到的图层。这种方法不需要几何着色器。

答案 1 :(得分:0)

在Vulkan中,GSP SV_RenderTargetArrayIndex在SPIR-V中称为Layer,在GLSL中称为gl_Layer。它的行为与D3D中的相同。您为每个3D目标创建一个视图,并将其附加到帧缓冲区。 GS的Layer输出将说明输出基元被绘制到哪一层(所有目标中)。

在Vulkan中,没有“真正的” 3D帧缓冲区附件,因为在投影到屏幕空间之后,所有东西都存在于2D平面中。因此,附件图像视图可以具有2D_ARRAY维度,但不能具有3D。 Image and image view parameter compatibility requirements表显示,给定3D图像,您可以使用2D_ARRAY创建一个layerCount >= 1图像视图。请注意,您必须使用VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT标志创建图像。

因此,如果您想拥有 N 3D渲染目标图像:

  • 使用VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT标志创建 N 3D图像。
  • 为每个图像创建一个图像视图,其中VK_IMAGE_VIEW_TYPE_2D_ARRAYlayerCount等于要渲染到的切片数。
  • 创建一个VkRenderPass,每个3D渲染目标一个VkAttachmentDescription,再加上其他所需的深度/模板,解析目标等。
  • 基于该VkFrameBuffer创建一个VkRenderPass,然后在VkFrameBufferCreateInfo::pAttachments数组中传递图像视图。将VkFramebufferCreateInfo::layerCount设置为您要能够渲染到的层/切片的数量。

[编辑:根据第一条评论,可以忽略下面的段落。保持透明。]

我对您要与SV_Target[n]做的事情感到困惑。在D3D和Vulkan中,如果您具有多个渲染目标/颜色附件,则片段着色器将向它们全部写入-如果您的片段着色器不提供绑定目标的值,则写入的值是不确定的。因此,SV_Target[n]用来告诉哪些着色器输出变量到达哪个目标,但是它们不允许您在不写入其他对象的情况下写入某些内容。 Vulkan的工作方式与此类似,使用GLSL中的输出变量gl_FragData[n]