几何着色

几何着色器对从单个输入图元组装的一组顶点及其相关数据进行操作,并发出零个或多个输出图元以及每个输出图元所需的一组顶点及其相关数据。当管线中包含几何着色器时,启用几何着色。

几何着色器输入图元

每个几何着色器调用都可以访问图元中的所有顶点(及其相关数据),这些顶点作为输入数组呈现给着色器。

几何着色器期望的输入图元类型在几何着色器中使用 OpExecutionMode 指令指定,并且必须与以下项指定的传入图元类型匹配:如果曲面细分未激活,则由管线的图元拓扑指定,或者如果曲面细分激活,则由曲面细分模式指定,如下所示

  • InputPoints 的输入图元类型必须仅与 VK_PRIMITIVE_TOPOLOGY_POINT_LIST 的管线拓扑一起使用,或者与指定 PointMode 的曲面细分着色器一起使用。输入数组始终包含一个元素,如点列表拓扑点模式下的曲面细分所述。

  • InputLines 的输入图元类型必须仅与 VK_PRIMITIVE_TOPOLOGY_LINE_LISTVK_PRIMITIVE_TOPOLOGY_LINE_STRIP 的管线拓扑一起使用,或者与指定不指定 PointModeIsoLines 的曲面细分着色器一起使用。输入数组始终包含两个元素,如线列表拓扑线带拓扑等线曲面细分所述。

  • InputLinesAdjacency 的输入图元类型必须仅在曲面细分未激活时使用,并且具有 VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCYVK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY 的管线拓扑。输入数组始终包含四个元素,如带有邻接拓扑的线列表带有邻接拓扑的线带所述。

  • Triangles 的输入图元类型必须仅与 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LISTVK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIPVK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN 的管线拓扑一起使用;或者与指定不指定 PointModeQuadsTriangles 的曲面细分着色器一起使用。输入数组始终包含三个元素,如三角形列表拓扑三角形带拓扑三角形扇形拓扑或由三角形四边形曲面细分所述。顶点的绝对顺序可能与拓扑指定的顺序不同,但必须遵守指定的缠绕顺序。

  • InputTrianglesAdjacency 的输入图元类型必须仅在曲面细分未激活时使用,并且具有 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCYVK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY 的管线拓扑。输入数组始终包含六个元素,如带有邻接拓扑的三角形列表带有邻接拓扑的三角形带所述。顶点的绝对顺序可能与拓扑指定的顺序不同,但必须遵守指定的缠绕顺序,并且构成主图元的顶点必须仍然出现在第一个、第三个和第五个索引处。

几何着色器输出图元

几何着色器以三种输出模式之一生成图元:点、线带或三角形带。图元模式在着色器中使用 OpExecutionMode 指令指定,分别使用 OutputPointsOutputLineStripOutputTriangleStrip 模式。每个几何着色器必须只包含一个输出图元模式。

几何着色器输出的顶点根据输出图元类型组装成点、线或三角形,然后如光栅化中所述进一步处理。如果几何着色器发出的顶点数不足以生成单个图元,则不完整图元对应的顶点不会被后续管线阶段处理。几何着色器输出的顶点数量限制为着色器中指定的最大计数。

最大输出顶点计数在着色器中使用 OpExecutionMode 指令指定,模式设置为 OutputVertices,并且将由几何着色器生成的最大顶点数指定为字面值。每个几何着色器必须指定最大输出顶点计数。

几何着色器的多次调用

几何着色器可以对每个输入图元调用多次。这被称为几何着色器实例化,通过包含一个 OpExecutionMode 指令来请求,其中 mode 指定为 Invocations,并且将调用次数指定为一个整数文字。

在这种模式下,几何着色器将对每个输入图元至少执行 n 次,其中 n 是在 OpExecutionMode 指令中指定的调用次数。每次调用的实例编号可以通过使用 InvocationId 的内置输入来获得。

几何着色器图元排序

对于几何着色器生成的图元的相对顺序,仅提供有限的保证,因为它们关系到图元顺序

  • 对于实例化几何着色器,从每个输入图元生成的输出图元使用调用编号(从小到大)来排序图元,并将它们传递到后续的管线阶段。

  • 从给定输入图元生成的所有输出图元在任何从后续输入图元生成的输出图元之前,都会被传递到后续的管线阶段。

几何着色器直通

在其输入接口上使用 PassthroughNV 修饰符的几何着色器被认为是直通几何着色器。直通几何着色器中的输出图元必须与输入图元具有相同的拓扑结构,并且不是通过发射顶点产生的。输出图元的顶点具有两种不同的属性类型:每个顶点的属性和每个图元的属性。带有 PassthroughNV 修饰符的几何着色器输入变量被认为产生每个顶点的输出,其中每个输出顶点的值从相应的输入顶点复制而来。任何内置或用户定义的几何着色器输出在直通几何着色器中都被认为是每个图元的输出,其中单个输出值被复制到所有输出顶点。

本节的其余部分详细说明了 PassthroughNV 修饰符的用法,以及在使用直通几何着色器时对接口匹配规则的修改。

PassthroughNV 修饰符

使用 PassthroughNV 修饰符修饰几何着色器输入变量表示该输入的值被复制到输出图元的相应顶点。没有 PassthroughNV 修饰符的输入变量和块成员会被几何着色器消耗,而不会传递到后续阶段。

PassthroughNV 修饰符必须仅在几何着色器中使用。

任何用 PassthroughNV 修饰的变量必须使用 Input 存储类声明。

PassthroughNV 修饰符必须不与以下任何项一起使用:

  • OpExecutionMode 的模式指定的除 InputPointsInputLinesTriangles 之外的输入图元类型。

  • OpExecutionModeInvocations 模式指定的除 1 之外的调用计数。

  • 静态使用 OpEmitVertexOpEndPrimitive 指令的 OpEntryPoint

  • InvocationId 内置修饰符修饰的变量。

  • 使用 Input 存储类声明的、用 PrimitiveId 内置修饰符修饰的变量。

直通接口匹配

当使用直通几何着色器时,涉及几何着色器输入和输出接口的接口匹配规则按本节所述运行。

为了将直通几何着色器输入与先前管线阶段的输出进行匹配,PassthroughNV 修饰符将被忽略。

为了将几何着色器的输出与后续管线阶段进行匹配,具有 PassthroughNV 修饰符的每个输入变量都被认为在输出接口上添加了一个具有相同类型、修饰符(除了 PassthroughNV)、编号和声明顺序的等效输出变量。与用 PassthroughNV 修饰的输入变量对应的输出变量声明将与输入声明相同,只是移除了此类变量的最外层数组维度。与用 PassthroughNV 修饰或具有用 PassthroughNV 修饰的成员的输入块对应的输出块声明将与输入声明相同,只是移除了此类声明的最外层数组维度。

如果输入块用 PassthroughNV 修饰,则等效输出块包含输入块的所有成员。否则,等效输出块仅包含用 PassthroughNV 修饰的输入块成员。对应的输出块的所有成员都被分配了与分配给对应的输入块成员相同的 LocationComponent 修饰符。

从用 PassthroughNV 修饰的输入生成的输出变量和块仅为了接口匹配而存在;这些声明对于几何着色器代码不可用,也不会在模块接口中列出。

为了组件计数,直通几何着色器将所有使用 PassthroughNV 修饰符声明的静态使用的输入变量组件也算作输出组件,因为它们的值将被复制到几何着色器生成的输出图元中。