我有一些旧的DX11代码可以渲染到多个3d渲染目标。在GS中,目标目标通过SV_TARGETxx
传递,并且切片通过SV_RenderTargetArrayIndex
设置。在Vulkan中有什么方法可以做同样的事情吗?
我的计划是为每个3d目标的每个切片创建单独的视图,并将它们作为附件一起传递到单个帧缓冲区,然后在GS中我可以使用类似gl_Layer = sliceNo + targetOffsets[xx]
的对象。有更好的解决方案吗?
答案 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_ARRAY
和layerCount
等于要渲染到的切片数。VkRenderPass
,每个3D渲染目标一个VkAttachmentDescription
,再加上其他所需的深度/模板,解析目标等。VkFrameBuffer
创建一个VkRenderPass
,然后在VkFrameBufferCreateInfo::pAttachments
数组中传递图像视图。将VkFramebufferCreateInfo::layerCount
设置为您要能够渲染到的层/切片的数量。[编辑:根据第一条评论,可以忽略下面的段落。保持透明。]
我对您要与SV_Target[n]
做的事情感到困惑。在D3D和Vulkan中,如果您具有多个渲染目标/颜色附件,则片段着色器将向它们全部写入-如果您的片段着色器不提供绑定目标的值,则写入的值是不确定的。因此,SV_Target[n]
用来告诉哪些着色器输出变量到达哪个目标,但是它们不允许您在不写入其他对象的情况下写入某些内容。 Vulkan的工作方式与此类似,使用GLSL中的输出变量gl_FragData[n]
。