我收到如下 Vulkan 验证错误:
[VULKAN][INFO] Vulkan 验证层回调:验证错误:[ UNASSIGNED-CoreValidation-Shader-PointSizeMissing] 对象 0: VK_NULL_HANDLE,类型= VK_OBJECT_TYPE_PIPELINE; |消息ID = 0xf3693078 |管道拓扑设置为 POINT_LIST,但 PointSize 为 未写入对应的着色器中 VK_SHADER_STAGE_VERTEX_BIT。
我搜索并找到了以下信息:
Vulkan 对于点大小的规则有点古怪。如果你只有一个 顶点着色器并且您使用点,那么您必须将 PointSize 写入 你的顶点着色器。如果您有几何或曲面细分着色器, 那么它依赖于着色器TessellationAndGeometryPointSize 设备功能。
我想知道我是否总是需要两个不同的着色器,具体取决于我是否绘制点或其他拓扑。我认为点大小会像线宽一样由管道状态决定并在创建管道时设置,但我认为情况并非如此。
渲染点时,这些点的大小将由最新顶点处理阶段输出的标记为
PointSize
的变量值定义。任何未由着色器阶段写入的此类变量的值都是未定义的。因此,具有最新顶点处理阶段未设置此值的着色器管道的渲染点的行为是未定义的。
这与线宽不同,因为线宽不是由着色器设置的。它是管道状态值。点大小始终来自着色器,并且与 OpenGL 不同,没有默认的上下文点大小。
因此,如果您希望着色器模块能够在有点和无点的情况下使用,则其顶点处理阶段必须始终写入PointSize
修饰的输出变量。至于您链接到的匿名文件,这些陈述的准确性令人怀疑。
shaderTessellationAndGeometryPointSize
是独立于
tessellationShader
或
geometryShader
的功能。这意味着理论上可以实现支持曲面细分和/或几何着色器,但不支持从这些着色器设置点大小。如果没有此功能,从 TES 或 GS 发出的点的大小为 1.0f。
VkDynamicState
进行了一些扩展,如here 所指定,所讨论的扩展是
VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY
。这允许我们将不同的原始拓扑记录到命令缓冲区中,例如在
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
和
VK_PRIMITIVE_TOPOLOGY_POINT_LIST
之间切换。在 Vulkan 1.3 之前这是不可能的。但是,管道仍然是使用顶点缓冲区绑定创建的,因此如果点和三角形渲染都应使用相同的管道,则它们还必须使用具有相同
layout(location)
说明符(即顶点属性)的相同着色器程序作为输入。因此,如果三角形渲染具有每顶点纹理坐标,那么点渲染也必须具有每顶点纹理坐标。对单个点颜色进行点渲染查找 2D 纹理是绝对可行的,但点数据本身可能需要一些预处理才能正常工作。
这是渲染点数据的顶点着色器的示例:
#version 450
layout (location = 0) in vec3 aPosition;
layout (set = 0, binding = 0) uniform CameraUniform
{
mat4 viewProjection;
};
void main()
{
gl_Position = viewProjection * vec4(aPosition, 1.0f);
gl_PointSize = 2.0f;
}
在我看来,创建两个单独的管道对象更容易、更实用。